Add staging step and reorganize assets

Add stage-mod.bat and update build scripts to stage the mod package instead of automatically deploying (build-all.bat now calls stage-mod.bat; build.bat prints plugin output path and packaging hint). Reorganize Creation Kit assets into DataFolder and RawAssets directories, add new mesh/texture files, and update CommonwealthOnline_Vault109.esp. Also include ancillary updates to deploy scripts, docs, and server code to reflect the new packaging workflow.
This commit is contained in:
2026-06-17 23:03:30 +12:00
parent f56b6cf113
commit 3d14918ee8
148 changed files with 385 additions and 79 deletions
+15 -2
View File
@@ -2,8 +2,8 @@
This folder is for the external multiplayer test server.
The current server is a local-only TCP test server. It listens on
`127.0.0.1:7777`, accepts one or more clients, reads newline-separated JSON
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
@@ -38,6 +38,19 @@ 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` 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
+4 -1
View File
@@ -5,10 +5,13 @@ This folder is for server configuration templates.
Possible future config values:
```text
host=127.0.0.1
host=0.0.0.0
port=7777
max_players=2
tick_rate=20
```
`0.0.0.0` listens on all network interfaces. Use `127.0.0.1` only if you want
local-only access again.
Do not commit private IPs, tokens, or secrets.
+12 -1
View File
@@ -428,7 +428,7 @@ class DevServerWindow(QMainWindow):
is_running = bool(stats.get("isRunning", False))
self.stat_labels["status"].setText("Running" if is_running else "Stopped")
self.stat_labels["host"].setText(str(stats.get("host", "-")))
self.stat_labels["host"].setText(self._format_host_stat(stats))
self.stat_labels["port"].setText(str(stats.get("port", "-")))
self.stat_labels["uptime"].setText(self._format_duration(float(stats.get("uptimeSeconds", 0.0))))
self.stat_labels["connectedClients"].setText(str(stats.get("connectedClients", 0)))
@@ -525,6 +525,17 @@ class DevServerWindow(QMainWindow):
except (TypeError, ValueError):
return None
@staticmethod
def _format_host_stat(stats: dict[str, Any]) -> str:
host = str(stats.get("host", "-"))
port = stats.get("port")
lan_addresses = stats.get("lanAddresses") or []
if not lan_addresses or port is None:
return host
connect_targets = ", ".join(f"{address}:{port}" for address in lan_addresses)
return f"{host} (LAN: {connect_targets})"
@staticmethod
def _format_duration(seconds: float) -> str:
total_seconds = max(0, int(seconds))
+24 -2
View File
@@ -10,11 +10,21 @@ from typing import Any
from client_session import ClientSession
HOST = "127.0.0.1"
HOST = "0.0.0.0"
PORT = 7777
ACCEPT_TIMEOUT_SECONDS = 0.5
def get_lan_addresses() -> list[str]:
"""Return likely LAN IPv4 addresses for this machine."""
try:
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as probe:
probe.connect(("8.8.8.8", 80))
return [probe.getsockname()[0]]
except OSError:
return []
class FalloutTogetherServer:
def __init__(self, host: str = HOST, port: int = PORT) -> None:
self.host = host
@@ -101,6 +111,7 @@ class FalloutTogetherServer:
{
"host": self.host,
"port": self.port,
"lanAddresses": get_lan_addresses() if self._running and self.host == "0.0.0.0" else [],
"isRunning": self._running,
"startedAt": started_at,
"uptimeSeconds": time.time() - started_at if started_at is not None else 0.0,
@@ -137,7 +148,18 @@ class FalloutTogetherServer:
self._running = True
self._started_at = time.time()
self._log(f"Commonwealth Online local test server listening on {self.host}:{self.port}")
self._log(f"Commonwealth Online server listening on {self.host}:{self.port}")
if self.host == "0.0.0.0":
self._log(f"Local clients can connect at 127.0.0.1:{self.port}")
lan_addresses = get_lan_addresses()
for address in lan_addresses:
self._log(f"LAN clients can connect at {address}:{self.port}")
if not lan_addresses:
self._log("Could not detect a LAN IPv4 address for this machine.")
self._log(
"Forward this port on your router and allow it through Windows Firewall "
"for connections from outside your network."
)
self._log("Waiting for newline-separated JSON transform packets...")
def _accept_loop(self) -> None: