4.5 KiB
4.5 KiB
TH1 Network Contract
This reference summarizes the multiplayer contract after the May 2026 pre-release network audit.
SimpleP2P
- All normal game messages use per-peer outgoing queues.
- Per-peer FIFO is required.
- Ordered envelopes are used for game payloads; do not bypass them for gameplay sync.
- Outgoing sequence is committed only after enqueue succeeds.
- Large payloads are chunked after ordered wrapping.
- Outgoing queue processing may send multiple messages per update within a per-frame message/byte budget, but must preserve FIFO per peer.
- Incoming large chunks must validate magic, version, message id, chunk index, chunk count, total length, and payload length.
- Large incoming messages and outgoing queues have per-peer and global byte budgets.
- Ordered gaps and large-message receives must timeout and disconnect/clean state rather than wait forever.
- Steam message pointers must be released in
finally.
SteamLobbyManager
SendMessageToPeerreturnsbool; precheck failures must call the same failure path used by P2P send failures.BroadcastMessagereturnsbool.- Critical broadcast must gather current lobby members, skip self, preflight all targets through
SimpleP2P.CanQueueMessages, and only then enqueue. - Missing connection, non-lobby target, invalid data, or queue budget failure must surface through
OnLobbyErrorEvent/ send-failure logging.
GameNetSender
- Sender methods that gate local state must return
bool. GameStartmust validateMapDataand return broadcast success.ActionConfirmmust return send success.ActionExecutemust return broadcast success.ForceUpdateand fullMapDatasends must validate multiplayer map data before sending.- Heartbeat send timestamps should only update after send acceptance.
GameNetReceiver
- Wrap deserialization and dispatch in try/catch.
- Ignore
P2PMsgType.NetworkStress; the editor stress tool consumes diagnostics packets throughSimpleP2P.OnMessageReceivedEventbefore gameplay dispatch. - Validate incoming
GameStartandForceUpdatemaps before applying. NetStartGameandNetResumeMatchreturnbool; UI should only close/hide after success.ForceUpdateshould restore previous game state if resume fails.MapConfirmmust guard null maps, missing actions, and null action payloads.
Network Stress Tool
- Tool path:
Unity/Assets/Scripts/TH1_Logic/Editor/NetworkStressEditorWindow.cs. - Diagnostics message:
NetworkStressMessage/P2PMsgType.NetworkStress. - The tool must send probes through
Lobby.BroadcastMessageandLobby.SendMessageToPeer, not through a raw side channel. - The host starts one-click tests; clients auto-start on
ControlStart. - Reports are keyed by
RunId; stale packets, ACKs, and reports from previous runs must be ignored. - Host export should contain one report per lobby member when clients are reachable. If a report is late, host may update the same export file after receipt.
- Current default test is a one-minute flow: 50 seconds of traffic and up to 10 seconds of report collection.
MapData And NetData
MapData.DeserializedMissingCriticalDatameans the save/network map must not be used.OnAfterMemoryPackDeserializemay coalesce non-critical containers to avoid callback NREs but must not silently accept missing core data.NetData.RefreshPlayerNet(MapData)returnsbool.- In multiplayer mode, every current lobby member must have a valid, non-duplicate
PlayerId. - Host resume/start must fail before assigning global
MapDataif player network mapping is invalid.
Main And UI
- Host start/resume snapshots
MapData,InputLogic,MapInteractionLogic, andMapGeneratorLogic. - Host
GameStartfailure must roll back and must not save, refresh turn, or report success. - Custom map load must check
mapRecord == nullbeforeRegenerateMap. UIOutsideMultiplayView.ShowLoadingAndStartGamemust only invokeOnStartGameafter the host start/resume method returnstrue.- Timer callbacks for start announcements should be cancelled during abort paths.
ActionLogic
- Client
ActionConfirmfailure aborts local action execution. - Owner
ActionExecutebroadcast failure aborts owner local action execution. TurnEndcan send confirmation and stop local execution as designed.
Timer/Event Notes
- Timer callbacks should guard destroyed Unity targets.
- Timer mutation during callback must not remove the wrong task.
- Event publish should isolate listener exceptions so one bad listener does not block others.