Phase 7: Windows client export, preset fix, code fixes

- Fix: export_presets.cfg — platform='Windows Desktop' (not 'Windows'), Windows as [preset.0]
- Fix: plugin_manager.gd — removed class_name (autoload conflict), fixed multiline % formatting
- Fix: Disabled GDExtension temporarily for clean export
- Add: Windows PE32+ x86_64 client binary (109MB) at build/tactical-shooter-windows-x86_64/
- Add: tactical-shooter-windows.zip (portable zip package)
- Build: Linux server binary (78MB) rebuilt
This commit is contained in:
2026-07-01 19:46:52 -04:00
parent e385eae0f5
commit 9ea98aa7b8
36 changed files with 1094 additions and 64 deletions
+204
View File
@@ -0,0 +1,204 @@
# Playtest Guide — Tactical Shooter
> Phase 0 dedicated server (headless ENet, 128-tick simulation, GDExtension core).
> For internal / LAN playtesting only.
---
## Server Address
| 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) |
**Port:** `34197` (default — ENet gameplay port)
Override via environment variable:
```bash
SERVER_PORT=34197 ./tactical-shooter-server.x86_64 --headless
```
---
## 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:
```
[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
```
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 (232 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 |
---
## Quick-Start Cheat Sheet
```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
```
---
*Last updated: July 2026*