Files
Commonwealth-Online-Public/server/README.md
T
andrew 9ceb6601ae Add LAN discovery and Local servers UI
Adds LAN server discovery and a Local tab in the multiplayer UI so clients can find relays on the same LAN. Introduces a new F4T::LanDiscovery module (plugin/include/F4TLanDiscovery.h, plugin/src/F4TLanDiscovery.cpp) that probes LAN hosts via UDP discover (port 7778) and TCP welcome fallback (port 7777). Server-side support includes a UDP responder (server/lan_discovery.py) and integration in server_core.py to start/stop discovery.

Plugin changes (F4TServerBrowserBridge/Data) add background scanning, dispatch results to the game thread, new local-server storage and events (scanLocalServers, localServersUpdated, localScanStarted/localScanFinished), and small join/recent handling updates. UI changes (ui/.../app.js and components) add localServers state, scanning UX, Recent persistence (localStorage), and join logic for local/direct entries. Docs updated (docs/protocol.md, docs/dev-log.md, server/README.md) and build script links iphlpapi. Also removes two unused exported sprite PNGs.
2026-06-22 15:53:17 +12:00

11 KiB

Server

This folder is for the external multiplayer test server.

The current server is a TCP relay test server. It listens on 0.0.0.0:7777 (all network interfaces), accepts one or more clients, reads newline-separated JSON packets, assigns incrementing playerId values, sends welcome packets, adds playerId and serverTime to transform packets, broadcasts transform packets to every other connected client, and broadcasts disconnect packets when clients disconnect.

The server also listens on UDP port 7778 for LAN discovery probes. Clients can send a discover packet (see docs/protocol.md) and receive a discoverResponse with the game port and current player count.

Transform packets may include optional movement-state fields such as isMoving, isSprinting, isSneaking, isJumping, isCrouching, weaponDrawn, and movementSpeed. The server preserves these fields automatically because it broadcasts the original transform packet after adding server-owned fields.

This is still a local prototype. It does not make Fallout 4 multiplayer playable yet.

Run

Terminal server:

cd server
python server.py

Developer GUI server:

cd server
pip install -r requirements.txt
python dev_server_app.py

Then launch Fallout 4 through F4SE and move the player. The plugin should send local player transform packets, and this server should print matching transform packets.

Network access

The server binds to 0.0.0.0, so it accepts connections on every network interface on this PC.

  • Same machine: connect clients to 127.0.0.1:7777.
  • Other devices on your LAN: use the host PC's LAN IP and port, for example 192.168.1.50:7777. The server logs detected LAN addresses on startup.
  • Outside your network: forward TCP port 7777 on your router to the host PC, then give remote players your public IP (or hostname) and port.

You may need to allow inbound TCP 7777 and UDP 7778 through Windows Firewall on the host PC.

In the developer GUI, the Fake Clients tab can create simple synthetic TCP clients for local relay testing. Click Start Server, then click + Add Fake Client. Each fake client connects to 127.0.0.1:7777, receives a server-assigned playerId, appears in both GUI client tables, and sends one idle transform per second for F4TTestCell01.

Select a fake client row to use the movement controls:

  • Set Idle: returns the selected fake client to idle mode. It keeps its current position, sends non-moving transforms once per second, and reports movementSpeed=0.0.
  • Walk To Player: makes the selected fake client walk in a straight line toward the lowest connected real client with a valid transform snapshot. The target point is offset by +150 units on X so the fake client does not stand inside the real player. While moving, it sends normal transform packets at about 10 Hz with isMoving=true; when it reaches the stop distance, it returns to low-rate idle keep-alive transforms.
  • Walk Circle: makes the selected fake client move continuously around a simple circle in F4TTestCell01, sending normal moving transforms at about 10 Hz.
  • Jump Once: sends a short normal-movement jump arc with isJumping=true, then restores the fake client's ground Z and resumes the current script.
  • Toggle Sneak: toggles the fake client's persistent isSneaking flag. It does not move the fake client by itself.
  • Leave Cell: sends a cell_change transform to fake cell DEADBEEF and keeps the fake client connected in a low-rate Left Cell mode.
  • Return To Cell: sends a cell_change transform back to 0B000F99, restores worldspaceId="", and returns the fake client to Idle.
  • Teleport Test: sends one movementType=teleport transform to a deterministic test-cell offset, then returns the fake client to Idle.

These controls are developer test tooling only. They do not change the network protocol, server relay behavior, or Fallout 4 plugin behavior.

If the server is not running, the plugin should log a warning and Fallout 4 should continue launching normally.

Structure

  • server.py: thin terminal launcher for the local test server.
  • server_core.py: reusable FalloutTogetherServer core for networking, lifecycle control, packet relay, stats, client snapshots, and log callbacks.
  • client_session.py: ClientSession state model for connected clients.
  • dev_server_app.py: PySide6 developer GUI that starts/stops the reusable server core, displays logs, shows live stats, and lists connected clients.
  • fake_player.py: GUI fake-player test tooling. It owns background synthetic TCP clients that connect through the normal server socket, send transform packets, and run simple dev movement scripts such as Idle and Walk To Player.
  • fake_client.py: lightweight receiver for testing welcome, transform, and disconnect packets without launching a second Fallout 4 instance.
  • requirements.txt: optional Python dependencies for the desktop developer GUI.

The reusable server core exposes methods intended for a future desktop dev server UI:

  • start()
  • serve_forever()
  • stop()
  • is_running()
  • get_clients()
  • get_stats()
  • add_log_listener()
  • remove_log_listener()

get_clients() and get_stats() return snapshot dictionaries, not live internal server state. Log listeners receive the same useful console messages that the terminal launcher prints today.

Current Test Flow

Terminal 1:

cd server
python server.py

Terminal 2:

cd server
python fake_client.py

Then launch Fallout 4 through F4SE and move the player.

Alternative GUI flow:

cd server
pip install -r requirements.txt
python dev_server_app.py

Click Start Server, then run python fake_client.py or launch Fallout 4 through F4SE. You can also click + Add Fake Client to create a GUI-managed synthetic client that sends an idle transform once per second. Select a fake client row and click Set Idle, Walk To Player, Walk Circle, Jump Once, Toggle Sneak, Leave Cell, Return To Cell, or Teleport Test to control its dev script/action. Click - Remove Selected to disconnect it cleanly.

Expected behavior:

  • The server assigns a playerId to each connected client and sends each client a welcome packet.
  • The server receives transforms from the Fallout 4 plugin.
  • The server adds playerId and serverTime to each transform packet before broadcast.
  • The server preserves optional movement-state fields on transform packets.
  • The server broadcasts those transform packets to connected clients except the sender.
  • fake_client.py receives broadcast transform packets.
  • fake_client.py stores remote player state by playerId.
  • GUI fake clients connect as ordinary external TCP clients, receive a welcome packet, store their assigned playerId, and send idle transforms for cell 0B000F99.
  • GUI fake clients can be switched between Idle and Walk To Player scripts from the Fake Clients tab.
  • GUI fake clients can also run Walk Circle, Left Cell, and one-shot jump, sneak toggle, return-to-cell, and teleport test actions from the Fake Clients tab.
  • Walk To Player uses FalloutTogetherServer.get_clients() snapshots to find the lowest non-fake client with a valid last transform, then walks gradually toward that player with a simple straight-line movement test.
  • When a client disconnects, the server removes that client and broadcasts a disconnect packet with the departed playerId to the remaining clients.
  • fake_client.py removes disconnected players from its in-memory remote_players table.

The fake client exists so broadcast behavior can be tested before coordinating a second Fallout 4/F4SE instance. It stores remote player transform state only; it does not spawn remote actors or send movement.

Validation

From inside this folder:

python -m py_compile server.py server_core.py client_session.py fake_client.py dev_server_app.py fake_player.py

Then run the terminal server:

python server.py

In another terminal, run:

python fake_client.py

To validate the developer GUI instead of the terminal launcher:

pip install -r requirements.txt
python dev_server_app.py

Click Start Server, then connect fake_client.py or the Fallout 4 plugin. To validate GUI fake clients, click + Add Fake Client and confirm the fake client appears in the Fake Clients table and Connected Clients table with an assigned player ID. Select the fake client, click each Fake Clients action, and confirm the Script, Cell ID, Position, and console log output update as expected. Click Walk To Player with no real Fallout 4 client connected and confirm the GUI logs that no real player target is available. Click - Remove Selected and confirm it disconnects.

For in-game validation, launch Fallout 4 through F4SE and confirm the plugin connects, receives a welcome packet, sends transforms, and receives relayed remote transforms or disconnect packets when another client is connected. In F4TTestCell01, select a GUI fake client and click Walk To Player; the fake client should walk smoothly toward the real player's latest transform offset and then stop near that offset. Test Walk Circle, Jump Once, Toggle Sneak, Leave Cell, Return To Cell, and Teleport Test while watching the proxy to confirm movement, jump/sneak state, cell mismatch holding, return, and teleport snap behavior.

Implemented

  • Start local server
  • Accept client connections
  • Assign server-owned player IDs
  • Send welcome packets
  • Receive transform packets
  • Add server timestamps
  • Preserve optional transform fields
  • Broadcast transforms to other connected clients
  • Broadcast disconnect packets
  • Handle disconnect cleanup
  • Reusable server core with thread-safe client/stat snapshots
  • Log callbacks for future server console UI
  • PySide6 developer server GUI with live logs, stats, connected-client table, and a Fake Clients tab that can spawn idle synthetic TCP clients
  • GUI-managed fake clients that receive welcome packets and send idle transforms
  • Fake Clients tab movement controls for Set Idle and Walk To Player
  • GUI-managed fake clients that can walk gradually toward a real Fallout 4 client using normal transform packets
  • Fake Clients tab dev scripts/actions for Jump Once, Toggle Sneak, Walk Circle, Leave Cell, Return To Cell, and Teleport Test

Working In Fake Client Only

  • Receiving welcome packets
  • Receiving transform broadcasts
  • Storing remote player state
  • Removing disconnected remote players

Planned Later

  • Additional fake client scripts such as Walk Square, Follow Player, Sprint Toggle, Weapon Drawn Toggle, Disconnect After Delay, and multi-fake-player choreography
  • Gameplay synchronization
  • Authentication
  • Public matchmaking
  • Anti-cheat
  • Persistence
  • Quest state
  • Settlement state
  • Large-scale world simulation