17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-10-17 23:49:19 +02:00
Commit Graph

22 Commits

Author SHA1 Message Date
54d8b112b8 multiplayer stage 7: versioned snapshots instead of replaying the session
Joining meant replaying backbuffer.bin from the very first frame of the
session, so the longer a session ran, the longer it took to get in - and the
whole history had to be kept for it.

- network/snapshot: a chunked container with a version of its own. Every
  section carries its length, so a peer built before a section existed reads
  a newer snapshot and simply walks past what it does not know. Version 1
  carries the session (tick, clock, weather, the state of the random engine),
  the vehicles (position on the track, speed, direction, controls, brake
  pressures, whether the AI is driving) and the crew roster. Switches,
  memcells, signals and the event queue are the next sections
- joining is now: handshake -> load the scenario -> CLIENT_READY -> the server
  takes a snapshot on the spot and sends it -> the peer goes live. Because the
  snapshot is taken at the moment the peer becomes active there is no backlog
  to replay at all; the frame by frame catch-up is gone
- the server refuses a peer that loaded a different scenario, with a readable
  reason instead of a silent desync
- reconnecting into a session that is already loaded asks for a fresh snapshot
  straight away rather than waiting for a loader that will not run again
- a vehicle is only put back on the rails when it really is somewhere else; the
  arithmetic that turns the recorded bogie offset back into the nose distance
  place_on_track() expects mirrors what that function itself does
- the session log is still written out - it is useful when picking a desync
  apart - but nothing depends on replaying it any more
2026-09-06 19:37:28 +00:00
b255c8120a multiplayer stage 6: a logical simulation tick and a real state digest
The protocol hung off whatever frame the renderer happened to be drawing, and
the only thing standing in for synchronisation was the sum of every vehicle's
coordinates with a random number added on top - a value that cannot be equal on
two machines and therefore reported a desync on every single step.

- Global.simulation_tick: the authority counts the steps, a client takes the
  number from the authoritative frame it is executing. FRAME_INFO and the
  command requests carry it, so the network timeline has one unambiguous order
  independent of frame rates
- network/statehash: a versioned FNV digest of the gameplay critical state -
  vehicle position, speed, direction, brake pipe and cylinder pressure, plus the
  clock. Values are quantized so that float noise is not mistaken for drift, and
  vehicles are folded in under their own identity and summed, so the digest does
  not depend on the order the scenario created them in. Switches, memcells and
  the event queue are the next candidates; they go in when stage 7 pins down
  what a snapshot contains
- a client compares its own digest against the authoritative one and reports the
  drift when it starts and then only now and then, rather than every step; the
  overlay says how long it has been out of step and at which tick
- refusing to compare at all when the two builds disagree on the digest layout

EU07_NETWORK_VERSION is now 4.
2026-09-06 19:21:12 +00:00
3f62fd5927 multiplayer stage 3: crew model, claim handshake and AI handover
A vehicle is not owned by one player: two people share a cab, so the session
needs a crew relation rather than an owner field. The server keeps it and is
the only one allowed to change it.

- network/session: vehicle_crew { entity_id, crew, ai_before_claim } and a
  crew_registry holding the roster. the host goes through exactly the same
  path as a remote peer (claim -> crew -> grant), only without transport
- CLAIM_VEHICLE / CLAIM_GRANTED / CLAIM_DENIED / LEAVE_VEHICLE / CREW_UPDATE;
  the server validates the vehicle exists, is present in the scenario and has
  room in the crew, and answers a refusal with a reason the lobby shows
- the cab of a claimed vehicle is created by the authority posting the
  ordinary replicated entervehicle, so every peer builds it and the vehicle is
  never moved. the claiming peer only walks in once the cab appears locally
- AI transitions follow the crew size: 0 -> 1 remembers whether an AI was
  really driving and takes the vehicle over, 1 -> 2 and 2 -> 1 change nothing,
  1 -> 0 hands the vehicle back but only if there was an AI driver to begin
  with. driver mode no longer fires aidriverdisable of its own in multiplayer
- losing a connection removes that peer from every crew it was on; a vehicle
  with somebody still on board carries on untouched
- the lobby lists who is on board, offers "join crew" for a vehicle another
  player already occupies, and lets a player step off

The AI and cab handling runs as a reconciliation pass rather than as edge
triggered actions, so a request that has not taken effect yet (the cab needs a
frame to appear) is simply repeated, with a cooldown to keep it off the wire.
2026-09-06 18:08:06 +00:00
b9bd0ee33d multiplayer stage 2: peer identity, stable vehicle ids and a session lobby
TTrain::id() numbers cabs with a local counter, in the order each peer happens
to create them, so it cannot address a vehicle across the session. Neither was
there any way for a player to see what is available to drive.

- network/entities: PeerId (the host is peer 1, remote peers are numbered from
  2, so it is a participant rather than a special case) and NetworkEntityId,
  plus a registry that numbers the drivable vehicles of the loaded scenario in
  name order and resolves ids back to TDynamicObject
- the server owns the numbering and publishes it as VEHICLE_LIST - name, crew
  occupancy, crew capacity, AI state, availability - on every change and at
  least every 120 frames, out of band so it stays out of the replay backbuffer;
  a client binds the received ids to its own copy of the scenario by name
- SERVER_HELLO hands the joining peer its PeerId
- a multiplayer lobby listing that roster, with vehicles taken by other players
  shown as such rather than hidden; entering one goes through the existing
  entervehicle command, the vehicle is never moved

The lobby lives inside the driver mode instead of a mode of its own: the world
has to keep running while somebody is choosing (a client stops consuming the
server's frames the moment its mode is not a command processor), and the same
screen is what a player needs to change vehicles later on.

Crew occupancy is still derived from the presence of a cab instance; the real
crew model, claim handshake and AI takeover follow in stage 3.
2026-09-06 17:48:35 +00:00
copilot-swe-agent[bot]
7e49aa8740 Rewrite #includes to use explicit subdirectory paths
Co-authored-by: Hirek193 <23196899+Hirek193@users.noreply.github.com>
2026-03-14 19:16:48 +00:00
milek7
29f8f91ad8 Merge remote-tracking branch 'tmj/master' into sim 2020-10-18 23:35:14 +02:00
tmj-fstate
7a0c89f508 milek7/sim branch network code import 2020-02-16 03:03:17 +01:00
milek7
5c84f8b156 remove DBG_NEW new preprocessor kludges, ensure stdafx.h is included everywhere, add debug build to Azure CI 2019-08-30 23:35:58 +02:00
milek7
d391851c66 network improvements 2019-02-13 21:41:10 +01:00
milek7
6962e25042 network improvements and fixes 2019-02-06 00:03:48 +01:00
milek7
85ad17af3c network fixes and improvements, code refactoring 2019-02-03 23:24:34 +01:00
milek7
cf6cbe9a8e work 2019-01-29 19:02:16 +01:00
milek7
d5760c9e9c work 2019-01-28 00:34:36 +01:00
milek7
90f18ea651 work 2019-01-27 20:38:03 +01:00
milek7
f63bd04bfe work 2019-01-18 00:26:48 +01:00
milek7
f55a5465ef work 2019-01-14 22:45:22 +01:00
milek7
3db9efd3f7 work 2019-01-11 23:15:03 +01:00
milek7
b1cb4ad1ea work 2019-01-02 22:31:46 +01:00
milek7
63afece4a6 work 2019-01-01 00:26:11 +01:00
milek7
21fff27903 work 2018-12-20 20:47:19 +01:00
milek7
35af6d48d6 work 2018-12-09 19:03:02 +01:00
milek7
f525a77e23 work 2018-12-03 23:12:33 +01:00