5.9 KiB
name, description
| name | description |
|---|---|
| th1-network-sync | TH1 project-specific network synchronization guide for Unity C# multiplayer, Steam P2P, GameNetSender/GameNetReceiver, SteamLobbyManager, SimpleP2P, MapData/NetData recovery, action sync, host start/resume, ForceUpdate, heartbeat, ordered delivery, large message chunking, send-failure handling, and lobby UI rollback. Use whenever Codex works on TH1 networking, multiplayer saves, deterministic sync, P2P queueing, MapData broadcasts, ActionConfirm/ActionExecute, reconnect, Timer-driven network callbacks, or any bug that may affect multiplayer reliability or ordering. |
TH1 Network Sync
Core Rule
Treat multiplayer changes as state-machine changes, not only message sends. Before editing, trace the full path:
GameNetSender -> SteamLobbyManager -> SimpleP2P -> GameNetReceiver -> Main/ActionLogic/MapData.
Do not let one peer advance local game state unless the matching network send/receive contract succeeded.
First Files To Read
Unity/Assets/Scripts/TH1_Logic/Steam/SimpleP2P.csUnity/Assets/Scripts/TH1_Logic/Steam/SteamLobbyManager.csUnity/Assets/Scripts/TH1_Logic/Steam/GameNetSender.csUnity/Assets/Scripts/TH1_Logic/Steam/GameNetReceiver.csUnity/Assets/Scripts/TH1_Data/NetData.csUnity/Assets/Scripts/TH1_Data/MapData.csUnity/Assets/Scripts/TH1_Logic/Core/Main.csUnity/Assets/Scripts/TH1_Logic/Action/ActionLogic.csUnity/Assets/Scripts/TH1_Instance/Timer.csUnity/Assets/Scripts/TH1_Logic/Editor/NetworkStressEditorWindow.cswhen changing or interpreting network stress tests
For the current network contract summary, read references/network-contract.md.
For the one-click Steam P2P stress tool, report fields, and current healthy baseline, read references/network-stress.md.
Workflow
-
Classify the message.
- Critical:
GameStart,ForceUpdate,ActionConfirm,ActionExecute, fullMapData, reconnect/restore messages. - Health/status: heartbeat, map confirm, lobby state, chat.
- Critical messages must return
boolor otherwise expose failure to the caller before local state advances.
- Critical:
-
Preserve ordering.
- Keep game messages on
SimpleP2Pper-peer outgoing queues. - Do not bypass ordered envelopes for normal game messages.
- Do not send direct raw Steam messages for gameplay sync unless you also preserve FIFO and failure semantics.
- Keep game messages on
-
Preserve all-or-nothing broadcast for critical messages.
- Broadcast through
SteamLobbyManager.BroadcastMessage. - Preflight all lobby targets before enqueueing any target.
- If any target cannot queue, return failure and avoid local progression.
- Never accept "some peers got the critical message" as a valid state.
- Broadcast through
-
Gate local state on send success.
- Host
GameStartmust succeed beforeSaveMapData,RefreshTurn, room UI close, or final success return. - Owner
ActionExecutebroadcast must succeed before owner local execute. - Client
ActionConfirmmust succeed before client local execute;TurnEndmay send and then stop local execution. - Heartbeat send timestamps should only update after the send was accepted.
- Host
-
Validate
MapDatabefore sending or applying.- Reject null maps,
DeserializedMissingCriticalData, wrongNetMode, and missing core maps. - Call
Net.RefreshPlayerNet(mapData)and respect itsboolresult. - Ensure every current lobby member maps to a valid
PlayerId. - Do not repair missing critical data silently during deserialization.
- Reject null maps,
-
Roll back failed start/resume.
- Snapshot
MapData,InputLogic,MapInteractionLogic, andMapGeneratorLogicbefore host start/resume mutation. - On failure or exception, restore the snapshot, dispose/reinitialize render state as appropriate, cancel pending start timers, and keep lobby UI open.
- UI code must only invoke room-close/start callbacks after the start method returns
true.
- Snapshot
-
Keep receiver failure atomic.
- Deserialize and dispatch inside try/catch.
- If incoming
GameStartorForceUpdatevalidation fails, do not hide room UI and do not leave the game inForceUpdating. - Restore previous game state if
NetResumeMatchfails.
-
Preserve the stress-test path.
NetworkStressMessageis a diagnostics message and must not mutate gameplay state.GameNetReceivershould ignoreP2PMsgType.NetworkStress; the editor tool listens throughSimpleP2P.OnMessageReceivedEvent.- Stress probes must still use
Lobby.BroadcastMessage/SendMessageToPeerso they cover the real ordered queue and large-message chunking path. - Keep per-run
RunIdisolation so stale packets or ACKs from a previous test cannot pollute a new report. - The host should export after collecting client reports or after the configured report wait timeout; clients should retry report sends briefly after test completion.
Checks Before Finishing
Run:
dotnet build Unity/Assembly-CSharp.csproj --no-restore
If editor tooling changed, also run:
dotnet build Unity/Assembly-CSharp-Editor.csproj --no-restore
For network-heavy changes, inspect these risks explicitly:
- Could a critical broadcast partially enqueue?
- Could a caller ignore a failed send and still mutate game state?
- Could
MapDatadeserialize with missing core fields and still be used? - Could a timer callback fire after the target UI/object state is gone?
- Could a retry loop or ordered gap wait forever?
- If stress tooling or queue throughput changed, does the one-click two-machine report meet the baseline in
references/network-stress.md?
What Not To Do
- Do not add a new direct send path around
SimpleP2Pqueues for gameplay sync. - Do not silently swallow
SendMessageToPeerorBroadcastMessagefailure. - Do not call
GameNetReceiverfrom a partial large-message chunk. - Do not close the multiplayer room UI before host start returns success.
- Do not call
GC.Collect()in match entry paths as a networking fix.