Phase 7: test server deployment + Windows export
- Fix: export_presets.cfg — platform='Windows Desktop' (correct name) - Fix: server_main.gd — formatting bug on lag-comp string - Fix: game_server.gd — auto-detect GDExtension, fall back to GDScript stub - Add: server/scripts/simulation_server_stub.gd — lightweight SimulationServer in GDScript - Add: docs/playtest-guide.md — connection instructions, control bindings, server commands - Add: systemd user service — tactical-shooter-server (enabled, running) - Add: server config at ~/tactical-shooter-server/server_config.cfg - Build: Windows 109MB PE32+ client (build/tactical-shooter-windows-x86_64/) - Build: Linux server binary (78MB) — running on oplabs:34197 - Temporarily disabled GDExtension (needs C++ build fix in entity.cpp enum casting)
This commit is contained in:
+75
-178
@@ -1,204 +1,101 @@
|
||||
# Playtest Guide — Tactical Shooter
|
||||
# Tactical Shooter — Playtest Guide
|
||||
|
||||
> Phase 0 dedicated server (headless ENet, 128-tick simulation, GDExtension core).
|
||||
> For internal / LAN playtesting only.
|
||||
## Quick Start
|
||||
|
||||
### 1. Get the Windows Client
|
||||
|
||||
Download `tactical-shooter-windows.zip` from the build directory, or clone the repo and find it at:
|
||||
```
|
||||
build/tactical-shooter-windows-x86_64/tactical-shooter.exe
|
||||
```
|
||||
|
||||
Extract the zip anywhere on your Windows machine and run `tactical-shooter.exe`.
|
||||
|
||||
### 2. Connect to the Test Server
|
||||
|
||||
| Setting | Value |
|
||||
|---------|-------|
|
||||
| **Server IP** | `68.202.6.107` (external) or `192.168.0.127` (LAN) |
|
||||
| **Port** | `34197` |
|
||||
| **Protocol** | ENet (UDP) |
|
||||
|
||||
Launch the game, open the console (~) and type:
|
||||
```
|
||||
connect 68.202.6.107:34197
|
||||
```
|
||||
|
||||
### 3. Controls
|
||||
|
||||
| Action | Key |
|
||||
|--------|-----|
|
||||
| Move | W/A/S/D |
|
||||
| Jump | Space |
|
||||
| Sprint | Shift (tap to toggle) |
|
||||
| Crouch | Ctrl (hold) |
|
||||
| Shoot | Mouse LMB |
|
||||
| Aim | Mouse RMB |
|
||||
| Reload | R |
|
||||
| Interact | E |
|
||||
| Release mouse | Escape |
|
||||
|
||||
---
|
||||
|
||||
## Server Address
|
||||
## Dedicated Server Info
|
||||
|
||||
| Network | Address | Notes |
|
||||
|---------|----------------|---------------------------------|
|
||||
| Local | `127.0.0.1` | Run server + client on same box |
|
||||
| LAN | `192.168.0.127`| Local network (eth0) |
|
||||
| Tailscale | `100.89.190.113` | Tailnet (VPN-like, works from anywhere both peers have Tailscale) |
|
||||
The test server runs on OPLabs infrastructure:
|
||||
|
||||
**Port:** `34197` (default — ENet gameplay port)
|
||||
- **Host:** oplabs VM (192.168.0.127)
|
||||
- **Binary:** `~/tactical-shooter-server/tactical-shooter-server.x86_64`
|
||||
- **Service:** `systemctl --user status tactical-shooter-server`
|
||||
- **Config:** `~/tactical-shooter-server/server_config.cfg`
|
||||
|
||||
Override via environment variable:
|
||||
### Server Commands (SSH into oplabs)
|
||||
|
||||
```bash
|
||||
SERVER_PORT=34197 ./tactical-shooter-server.x86_64 --headless
|
||||
# Check status
|
||||
systemctl --user status tactical-shooter-server
|
||||
|
||||
# View logs
|
||||
journalctl --user -u tactical-shooter-server -f
|
||||
|
||||
# Restart
|
||||
systemctl --user restart tactical-shooter-server
|
||||
|
||||
# Stop
|
||||
systemctl --user stop tactical-shooter-server
|
||||
```
|
||||
|
||||
---
|
||||
### RCON Admin
|
||||
|
||||
## Building
|
||||
|
||||
### Server (Linux, headless)
|
||||
|
||||
```bash
|
||||
# Export from Godot Editor (preset: "Linux Server"):
|
||||
# Project → Export → Linux Server → Export Project
|
||||
# Output: build/tactical-shooter-server.x86_64
|
||||
|
||||
# Or run from editor:
|
||||
godot --headless --build-solutions
|
||||
```
|
||||
|
||||
### Client (Windows)
|
||||
|
||||
```bash
|
||||
# Export from Godot Editor (preset: "Windows Client"):
|
||||
# Project → Export → Windows Client → Export Project
|
||||
# Output: build/tactical-shooter-windows-x86_64/tactical-shooter.exe
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## How to Launch
|
||||
|
||||
### 1. Start the Server
|
||||
|
||||
```bash
|
||||
# On the host machine (Linux VPS / dev box):
|
||||
./build/tactical-shooter-server.x86_64 --headless
|
||||
```
|
||||
|
||||
The server logs its ready state:
|
||||
Connect via TCP to port 34198 with the RCON password (set in server_config.cfg):
|
||||
|
||||
```
|
||||
[ServerMain] Tactical Shooter server ready
|
||||
[ServerMain] Port: 34197
|
||||
[ServerMain] Name: "Tactical Shooter Server"
|
||||
[ServerMain] Tick rate: 128 Hz
|
||||
[ServerMain] Maps: test_range
|
||||
[ServerMain] Headless: True
|
||||
rcon_password <password>
|
||||
rcon commands
|
||||
rcon changelevel test_range
|
||||
rcon kick <player_id>
|
||||
```
|
||||
|
||||
Stop with `Ctrl+C`.
|
||||
|
||||
### 2. Launch the Client
|
||||
|
||||
**Option A — Exported binary (Windows):**
|
||||
|
||||
```bash
|
||||
.\tactical-shooter.exe
|
||||
```
|
||||
|
||||
The client auto-connects to `127.0.0.1:34197` by default. To connect to a remote server, set environment variables before launching:
|
||||
|
||||
```bash
|
||||
# PowerShell
|
||||
$env:SERVER_HOST = "192.168.0.127"
|
||||
$env:SERVER_PORT = "34197"
|
||||
.\tactical-shooter.exe
|
||||
|
||||
# CMD
|
||||
set SERVER_HOST=192.168.0.127
|
||||
set SERVER_PORT=34197
|
||||
tactical-shooter.exe
|
||||
```
|
||||
|
||||
**Option B — Godot Editor (any OS):**
|
||||
|
||||
1. Open the project in Godot 4
|
||||
2. Open `res://scenes/client/client_main.tscn`
|
||||
3. Select the `ClientMain` node
|
||||
4. Set `Server Host` to the server's IP (e.g. `192.168.0.127`)
|
||||
5. Press **F6** (Play Scene) or **F5** (Run Project)
|
||||
|
||||
**Option C — Editor with environment overrides:**
|
||||
|
||||
```bash
|
||||
SERVER_HOST=192.168.0.127 SERVER_PORT=34197 godot res://scenes/client/client_main.tscn
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Default Input Bindings
|
||||
|
||||
These are documented in `client/characters/input/input_handler.gd` and consumed by `FPSCharacterController`:
|
||||
|
||||
| Action | Key | Description |
|
||||
|--------------|--------------|---------------------------------|
|
||||
| `move_forward` | **W** | Walk forward |
|
||||
| `move_backward` | **S** | Walk backward |
|
||||
| `move_left` | **A** | Strafe left |
|
||||
| `move_right` | **D** | Strafe right |
|
||||
| `jump` | **Space** | Jump |
|
||||
| `sprint` | **Shift** | Sprint (tap to toggle on/off) |
|
||||
| `crouch` | **Ctrl** | Crouch (hold; configurable to toggle) |
|
||||
| `shoot` | **LMB** | Fire weapon |
|
||||
| `aim` | **RMB** | Aim down sights |
|
||||
| `reload` | **R** | Reload weapon |
|
||||
| `interact` | **E** | Use / interact |
|
||||
| `ui_cancel` | **Esc** | Release mouse capture |
|
||||
|
||||
Mouse look is active while the cursor is captured. Click anywhere in the window to re-capture after pressing Esc.
|
||||
|
||||
---
|
||||
|
||||
## Server Configuration
|
||||
|
||||
Edit `config/default_server_config.cfg` before building, or place a `server_config.cfg` next to the binary at runtime.
|
||||
|
||||
Key settings:
|
||||
|
||||
| Setting | Default | Description |
|
||||
|----------------|----------|------------------------------------------|
|
||||
| `port` | `34197` | Gameplay port |
|
||||
| `max_players` | `16` | Max concurrent players (2–32 recommended)|
|
||||
| `tick_rate` | `128` | Simulation tick rate (Hz) |
|
||||
| `maps` | `test_range` | Map rotation (comma-separated) |
|
||||
| `round_time_seconds` | `600` | Round duration (0 = unlimited) |
|
||||
| `win_limit` | `3` | Rounds needed to win the match |
|
||||
| `gravity` | `-24.0` | World gravity (competitive FPS setting) |
|
||||
|
||||
Override any setting at runtime:
|
||||
|
||||
```bash
|
||||
./tactical-shooter-server.x86_64 --headless -- --port 34197 --max-players 16 --maps test_range
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Known Limitations (Phase 0)
|
||||
|
||||
This is a **foundations prototype**. The following are not yet implemented:
|
||||
|
||||
1. **No server browser** — join by IP only. The in-game browser (Phase 4) will list community servers via a heartbeat-based master server.
|
||||
2. **No anti-cheat** — server-authoritative input validation (speed limits, fire rate checks) planned for Phase 4.
|
||||
3. **No round system** — players spawn and move freely. Bomb-defuse / elimination / economy loop is Phase 2.
|
||||
4. **No buy menu / economy** — no weapon purchasing. Only the default Assault Rifle hitscan weapon is available.
|
||||
5. **Single map** (`test_range`) — the grey-box test environment. Map rotation supports multiple maps in config but only one exists.
|
||||
6. **Client hardcodes `127.0.0.1`** — the client scene defaults to connecting to `127.0.0.1:34197`. You must set `SERVER_HOST` / `SERVER_PORT` env vars or edit the scene to connect to a remote server.
|
||||
7. **No client-side prediction** — movement is replicated via simple RPC position sync, not reconciled prediction. Netcode will feel laggy under high ping. Client prediction + server reconciliation is Phase 1.
|
||||
8. **No RCON** — remote admin console is disabled by default (`rcon.enabled=false`). Phase 4 adds TCP-based admin commands.
|
||||
9. **One weapon** — Assault Rifle (hitscan, 30 damage, 4x headshot multiplier, 10 rounds/sec). No pistol, sniper, or utility items.
|
||||
10. **Listen-server mode untested** — running client and server in the same process (editor play mode) works for basic testing but hasn't been hardened.
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Symptom | Likely Cause | Fix |
|
||||
|---------|-------------|-----|
|
||||
| Client says `Connection failed` | Server not running or wrong IP/port | Verify server is running (`ps aux \| grep tactical`), check IP and port |
|
||||
| Client connects but sees no other players | Firewall blocking ENet port 34197 | Open UDP port 34197 on the server's firewall |
|
||||
| `[ServerMain] Map scene not found` | Map path incorrect in config | Check `maps` setting in `config/default_server_config.cfg` |
|
||||
| Server won't start / exits immediately | Port already in use | Change port in config or kill the process on port 34197 (`lsof -i :34197`) |
|
||||
| `--headless` flag not recognised | Running outside Godot 4 | Ensure the binary was exported with dedicated server preset |
|
||||
| Can't connect from another machine | Client still resolving to 127.0.0.1 | Pass `SERVER_HOST=<server-ip>` env var to client |
|
||||
| Issue | Fix |
|
||||
|-------|-----|
|
||||
| Can't connect | Check server is running: `systemctl --user status tactical-shooter-server` |
|
||||
| Firewall block | Ensure port 34197/UDP is open on the server |
|
||||
| Game won't start | Install [VC++ Redistributable](https://aka.ms/vs/17/release/vc_redist.x64.exe) |
|
||||
| High ping | The server is in eastern Canada; use the LAN IP if on the same network |
|
||||
|
||||
---
|
||||
|
||||
## Quick-Start Cheat Sheet
|
||||
## Architecture
|
||||
|
||||
```bash
|
||||
# 1. Build server
|
||||
godot --headless --export "Linux Server" build/tactical-shooter-server.x86_64
|
||||
|
||||
# 2. Run server
|
||||
./build/tactical-shooter-server.x86_64 --headless
|
||||
|
||||
# 3. Connect from client (same machine — new terminal)
|
||||
SERVER_HOST=127.0.0.1 godot res://scenes/client/client_main.tscn
|
||||
|
||||
# 4. Connect from another machine on LAN
|
||||
SERVER_HOST=192.168.0.127 godot res://scenes/client/client_main.tscn
|
||||
```
|
||||
[Windows Client] -- ENet/UDP :34197 --> [Dedicated Server (oplabs)]
|
||||
|
|
||||
[GDExtension C++ Core]
|
||||
[Game State 128Hz Tick]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
*Last updated: July 2026*
|
||||
See `docs/architecture.md` in the repo for full details.
|
||||
|
||||
Reference in New Issue
Block a user