2026-05-15 18:08:16 +08:00

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

  • SendMessageToPeer returns bool; precheck failures must call the same failure path used by P2P send failures.
  • BroadcastMessage returns bool.
  • 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.
  • GameStart must validate MapData and return broadcast success.
  • ActionConfirm must return send success.
  • ActionExecute must return broadcast success.
  • ForceUpdate and full MapData sends 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 through SimpleP2P.OnMessageReceivedEvent before gameplay dispatch.
  • Validate incoming GameStart and ForceUpdate maps before applying.
  • NetStartGame and NetResumeMatch return bool; UI should only close/hide after success.
  • ForceUpdate should restore previous game state if resume fails.
  • MapConfirm must 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.BroadcastMessage and Lobby.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.DeserializedMissingCriticalData means the save/network map must not be used.
  • OnAfterMemoryPackDeserialize may coalesce non-critical containers to avoid callback NREs but must not silently accept missing core data.
  • NetData.RefreshPlayerNet(MapData) returns bool.
  • In multiplayer mode, every current lobby member must have a valid, non-duplicate PlayerId.
  • Host resume/start must fail before assigning global MapData if player network mapping is invalid.

Main And UI

  • Host start/resume snapshots MapData, InputLogic, MapInteractionLogic, and MapGeneratorLogic.
  • Host GameStart failure must roll back and must not save, refresh turn, or report success.
  • Custom map load must check mapRecord == null before RegenerateMap.
  • UIOutsideMultiplayView.ShowLoadingAndStartGame must only invoke OnStartGame after the host start/resume method returns true.
  • Timer callbacks for start announcements should be cancelled during abort paths.

ActionLogic

  • Client ActionConfirm failure aborts local action execution.
  • Owner ActionExecute broadcast failure aborts owner local action execution.
  • TurnEnd can 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.