Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Darkwaar33 — Seedwake : Asynchronous Multiplaye...

Darkwaar33 — Seedwake : Asynchronous Multiplayer Without a Server

Présentation canonique Slidewire par Mathieu Ledru (@matyo91), Darkwood. 14 slides, 31 pages PDF : pagination des contenus denses et captures statiques. Version interactive (mise en ligne à venir) : https://slides.darkwood.com/slides/darkwaar33-seedwake

Avatar for Mathieu Ledru

Mathieu Ledru

November 06, 2026

More Decks by Mathieu Ledru

Other Decks in Programming

Transcript

  1. Slide 1 · 1/3 · représentation statique Darkwaar 33 Seedwake

    Asynchronous Multiplayer Without a Server Same seed. Same dark. Different choices. 01 | 14 Version interactive (mise en ligne à venir) : https://slides.darkwood.com/slides/darkwaar33-seedwake @matyo91
  2. Slide 1 · 2/3 · représentation statique Darkwaar 33 Seedwake

    01 | 14 Version interactive (mise en ligne à venir) : https://slides.darkwood.com/slides/darkwaar33-seedwake @matyo91
  3. Slide 1 · 3/3 · représentation statique Darkwaar 33 Seedwake

    01 | 14 Version interactive (mise en ligne à venir) : https://slides.darkwood.com/slides/darkwaar33-seedwake @matyo91
  4. The question Can multiplayer exist without a server? LIVE AUTHORITY

    Player A → Serv er S E E D WA K E ← Player Playe B rA → code → Run Playe rB Players share a simulation history, not a live session. 02 | 14 @matyo91
  5. Slide 3 · 1/3 · représentation statique Procedural generation as

    shared reference One seed, one world Capture statique : Démonstration interactive 03 | 14 Version interactive (mise en ligne à venir) : https://slides.darkwood.com/slides/darkwaar33-seedwake @matyo91
  6. Slide 3 · 2/3 · représentation statique Procedural generation as

    shared reference One seed, one world Capture statique : Démonstration interactive 03 | 14 Version interactive (mise en ligne à venir) : https://slides.darkwood.com/slides/darkwaar33-seedwake @matyo91
  7. Slide 3 · 3/3 · représentation statique Procedural generation as

    shared reference One seed, one world Actual generated layout: identical walls, enemies, glints, start and stair. second board 03 | 14 Version interactive (mise en ligne à venir) : https://slides.darkwood.com/slides/darkwaar33-seedwake @matyo91
  8. Slide 4 · 1/2 · représentation statique Player choice is

    the variable The same world does not mean the same outcome Amber and cyan share a path until one action differs. Deterministic rules make decisions the only source of divergence. Capture statique : Démonstration interactive 04 | 14 Version interactive (mise en ligne à venir) : https://slides.darkwood.com/slides/darkwaar33-seedwake @matyo91
  9. Slide 4 · 2/2 · représentation statique Player choice is

    the variable The same world does not mean the same outcome Amber and cyan share a path until one action differs. cyan route 04 | 14 Version interactive (mise en ligne à venir) : https://slides.darkwood.com/slides/darkwaar33-seedwake @matyo91
  10. Deterministic simulation Same state + same action = same result

    State N board, HP, intents, floor turn static func apply( st_in: Dictionary, action: int ) -> Dictionary 05 | 14 + Action 0…12 → Rules.apply(state, action) { ok, reason, state, events } Combat executes drawn intents. No RNG calls during play. No Node calls, time, frame delta or engine RNG in rules.gd. @matyo91
  11. Slide 6 · 1/3 · représentation statique Randomness without drift

    Independent generation streams Capture statique : Schéma ou tableau 06 | 14 Version interactive (mise en ligne à venir) : https://slides.darkwood.com/slides/darkwaar33-seedwake @matyo91
  12. Slide 6 · 2/3 · représentation statique Randomness without drift

    Independent generation streams Lecture du schéma : SEED Floor 1 map enemy offer Floor 2 map enemy offer Floor 7 map enemy offer static func stream(seed, floor_n, name): var h = fnv1a32( "dw33|%d|%d|%s" % [seed, floor_n, name] ) return h if h != 0 else 1 static func xorshift32(s): s ^= (s << 13) & MASK 06 | 14 Version interactive (mise en ligne à venir) : https://slides.darkwood.com/slides/darkwaar33-seedwake @matyo91
  13. Slide 6 · 3/3 · représentation statique Randomness without drift

    Independent generation streams s ^= s >> 17 s ^= (s << 5) & MASK return s & MASK No random stream advances during gameplay. streams all streams 06 | 14 Version interactive (mise en ligne à venir) : https://slides.darkwood.com/slides/darkwaar33-seedwake @matyo91
  14. Slide 7 · 1/2 · représentation statique A small architecture

    Rules, rendering and interaction stay separate main.gd Input, screens, rival tracking. Calls Rules.apply(). rules.gd Pure state transitions, generation, replay trace and ghost lookup. board_view.gd 07 | 14 Version interactive (mise en ligne à venir) : https://slides.darkwood.com/slides/darkwaar33-seedwake @matyo91
  15. Slide 7 · 2/2 · représentation statique A small architecture

    Rules, rendering and interaction stay separate Reads state and events. Draws animation, intents, ghost and fork. codec.gd Encodes runs. Imports through Rules.simulate(). Dependency direction ends at rules.gd. The rules never call the view. 07 | 14 Version interactive (mise en ligne à venir) : https://slides.darkwood.com/slides/darkwaar33-seedwake @matyo91
  16. Replay as data A replay is a list of actions

    Seed K7Q2MX N E E WAI W N T W resolves as PUSH when an enemy occupies the destination. PUSH is not a separate encoded action. static func simulate( seed: int, actions: PackedByteArray ) -> Dictionary Reconstructed run final state + trace No video recording. No saved state snapshots. 08 | 14 @matyo91
  17. Slide 9 · 1/4 · représentation statique Portable run codes

    A complete game history in a short string SW1-04V9P-NR2B5-… Abbreviated for display. This fragment is not importable. Version rules v1 Seed 32 bits 09 | 14 Version interactive (mise en ligne à venir) : https://slides.darkwood.com/slides/darkwaar33-seedwake @matyo91
  18. Slide 9 · 2/4 · représentation statique Portable run codes

    A complete game history in a short string Player tag 3 letters Result score, floors, turns Actions 4 bits each 09 | 14 Version interactive (mise en ligne à venir) : https://slides.darkwood.com/slides/darkwaar33-seedwake @matyo91
  19. Slide 9 · 3/4 · représentation statique Portable run codes

    A complete game history in a short string Checksum FNV-1a, 16 bits Crockford base32 Uppercase, copyable, tolerant of O/0 and I/L/1. 09 | 14 Version interactive (mise en ligne à venir) : https://slides.darkwood.com/slides/darkwaar33-seedwake @matyo91
  20. Slide 9 · 4/4 · représentation statique Portable run codes

    A complete game history in a short string hi = actions[i] & 15 lo = actions[i + 1] & 15 byte = (hi << 4) | lo 09 | 14 Version interactive (mise en ligne à venir) : https://slides.darkwood.com/slides/darkwaar33-seedwake @matyo91
  21. Replay validation Never trust the claimed result Decode Checksum Version

    Simulate Compare results Decision ACCEPT REJECT same score, floors and turns corrupt, illegal, unfinished or mismatched Consistency check, not cryptographic anti-cheat. 10 | 14 @matyo91
  22. Slide 11 · 1/3 · représentation statique The rival ghost

    Another player’s history, not another live player Cyan ghost + four-cell wake 11 | 14 Version interactive (mise en ligne à venir) : https://slides.darkwood.com/slides/darkwaar33-seedwake @matyo91
  23. Slide 11 · 2/3 · représentation statique The rival ghost

    Another player’s history, not another live player Rendered from the rival trace. Floor and floor-turn synchronization Floor 2, turn 6 maps to the rival’s floor 2, turn 6. Exit and death markers The last position remains visible after the rival stops walking. 11 | 14 Version interactive (mise en ligne à venir) : https://slides.darkwood.com/slides/darkwaar33-seedwake @matyo91
  24. Slide 11 · 3/3 · représentation statique The rival ghost

    Another player’s history, not another live player The ghost never mutates your world. 11 | 14 Version interactive (mise en ligne à venir) : https://slides.darkwood.com/slides/darkwaar33-seedwake @matyo91
  25. Slide 12 · 1/2 · représentation statique Decision comparison Where

    did our decisions become different? Capture statique : Schéma ou tableau Lecture du schéma : Turn 1 2 3 4 5 6 Player A N E E N W S Player B N E E W N 12 | 14 Version interactive (mise en ligne à venir) : https://slides.darkwood.com/slides/darkwaar33-seedwake @matyo91
  26. Slide 12 · 2/2 · représentation statique Decision comparison Where

    did our decisions become different? S The fork identifies a decision, not merely a score difference. Rules.first_split(mine, theirs) returns the first unequal action index, or −1 while one run remains a prefix. split 12 | 14 Version interactive (mise en ligne à venir) : https://slides.darkwood.com/slides/darkwaar33-seedwake @matyo91
  27. Slide 13 · 1/2 · représentation statique Infrastructure avoided by

    design Why no backend? Traditional online competition Authentication Persistent storage Matchmaking Server-side validation Global leaderboards Seedwake rivalry 13 | 14 Version interactive (mise en ligne à venir) : https://slides.darkwood.com/slides/darkwaar33-seedwake @matyo91
  28. Slide 13 · 2/2 · représentation statique Infrastructure avoided by

    design Why no backend? Shared seed Recorded actions Deterministic simulation Portable run code Local verification Trade-off: no opponent discovery, global leaderboard or authoritative anti-cheat. 13 | 14 Version interactive (mise en ligne à venir) : https://slides.darkwood.com/slides/darkwaar33-seedwake @matyo91
  29. Slide 14 · 1/3 · représentation statique Conclusion Determinism makes

    gameplay portable Seed defines the world Actions define the history Replay 14 | 14 Version interactive (mise en ligne à venir) : https://slides.darkwood.com/slides/darkwaar33-seedwake @matyo91
  30. Slide 14 · 2/3 · représentation statique Conclusion Determinism makes

    gameplay portable reconstructs the result Darkwaar33 — Seedwake darkwoodcom.itch.io/darkwaar33 Same seed. Same dark. Different choices. 14 | 14 Version interactive (mise en ligne à venir) : https://slides.darkwood.com/slides/darkwaar33-seedwake @matyo91
  31. Slide 14 · 3/3 · représentation statique Conclusion Determinism makes

    gameplay portable 14 | 14 Version interactive (mise en ligne à venir) : https://slides.darkwood.com/slides/darkwaar33-seedwake @matyo91