Find a file
shinji c67b83efb1 tests: refresh stale load-bootstrap expectations to the proven default shape
Three test files pinned the pre-2026-09-21 s2c load-spine shape. The code
changed intentionally (committed, with disassembly-level justification); the
tests were never updated. Verified against pristine main in a clean env
(all BLAZE_* unset), which is how these unit tests are meant to run.

test_content_path_2026-06-05.py
  - order_equals_literal_spec: the #5 rung was cid=170 DropBaseline; the
    NO_INLOAD_DROPBASELINE default flip (commit c9b29ac) suppresses cid=170
    (it set the client's baselineDropped byte, making the sublevel installer
    FUN_1416b8600 return NULL for every subsequent entry) and replaces it with
    the trailing SkipWaitForBaseline=1 cid=207 one-shot. Updated the literal to
    match; the module's own EXPECTED_S2C_ORDER already carried the new shape.
  - cid=260 LoadLevel: commit 7d00ffb ("Root/Root NO-PUSH fix") set the default
    LevelSetup to StartPoint=TutorialHeartOfRage_001 + a GameMode inclusion
    option, growing the body from 239 to 635 bits. Decode the full LevelSetup
    (InclusionOptions count + entries) and byte-match the Blaze builder fed the
    same fields; the gameserver<->Blaze byte-match still holds.
  - cid=170 DropBaseline body check: the default path no longer emits it, so
    capture it from a second bootstrap with emit_inload_dropbaseline=True to
    keep proving the (unchanged) body builder round-trips + byte-matches.

test_ea_spine_knobs_2026-06-11.py
  - NO_INLOAD_DROPBASELINE default is now True, not False. Renamed
    test_inload_dropbaseline_default_unchanged ->
    test_inload_dropbaseline_default_suppresses_cid170 and inverted its
    assertions; fixed the same "is False" pin in test_default_flags_are_off
    and the module docstring.

No production code changed. cid=54 FirstPlayerEntered is unaffected: it is
emitted on the default path; it is only held when BLAZE_HOLD_FIRSTPLAYER is set.
2026-09-28 22:18:22 +02:00
_archive Replace non-ASCII typography with ASCII throughout 2026-09-19 10:51:29 +02:00
content load_bootstrap: complete the globals compartment chain (add inx 10, fix inx 9 parent) 2026-09-24 22:48:02 +02:00
gameplay Correct cid=207 self-host owner framing: content constants, not per-session captures 2026-09-28 16:52:54 +02:00
inbound c2s decoder: read slot-12 MessageManager at the true c2s offset + size cid=224 2026-09-22 19:40:54 +02:00
integration Replace non-ASCII typography with ASCII throughout 2026-09-19 10:51:29 +02:00
messages load_bootstrap/classids: apply 2026-09-24 verification corrections 2026-09-24 04:22:48 +02:00
stream re: bit-10 is an s2c ghost-family replication manager, not a gbc=0 generic 2026-09-22 22:58:40 +02:00
tests tests: refresh stale load-bootstrap expectations to the proven default shape 2026-09-28 22:18:22 +02:00
transport Replace non-ASCII typography with ASCII throughout 2026-09-19 10:51:29 +02:00
.gitignore gameserver_udp: new Py3 content-server package (Track 2) - core wire stack 80/80 2026-06-04 11:38:38 +02:00
__init__.py Replace non-ASCII typography with ASCII throughout 2026-09-19 10:51:29 +02:00
_ping_test.py Squash-merge worktree-xbox-decomp-pipeline into main (2026-08-24) 2026-08-24 22:35:05 +02:00
README.md Replace non-ASCII typography with ASCII throughout 2026-09-19 10:51:29 +02:00
server.py gameserver: hard-guard in-load cid=170 (DropBaseline) at the wire + name the leaking emitter 2026-09-28 21:58:05 +02:00

gameserver_udp - proper Anthem content-serving game server (Track 2)

(!) STALE 2026-06-07 - two framing claims below are superseded; the wire stack/port intent stands. See documentation/04-reverse-engineering/DOCUMENTATION_STATUS.md, SESSION_2026-06-07.md, DECODER_VALIDATION_2026-06-07.md.

  1. "It is NOT the fix for the 20% wall ... the 20% plateau is Step D (isLoaded bits 2/9) ... only the DLL eviction-spare (Option C) can clear it" is STALE. The 20% wall (Step A m_level) is DOWN via cid=207 IsBaselineMessage=True (2026-06-04). The menu-peer teardown (bus 0x4551edba -> FUN_14a60f760, gated client+0x60, nulls the gameconfig singleton DAT_1446c8130) is the LATER, post-Ingame wall - not the 20% plateau. Fort Tarsis loads & is playable via Model-A (StartServer / host-from-disk). This package is still correctly scoped as Track 2 (gameplay after the load wall).
  2. "cid=56 SubLevelName ... Bit-exact across EA captures" (see "Three content regions" below) is STALE. cid=56 = plain ASCII (u32 LSN + u12 count + N*{u16 idx, u10 strlen, ASCII}); EA sends ZERO cid=56 on every stream (0-7). There is nothing to be "bit-exact" against - the old string-compression / canonical-name-table reading is FALSIFIED.

Status: WIP - overnight build 2026-06-04 (owner-greenlit). UNTESTED LIVE. Isolated package; the live baseline (code/blaze_realudp_fork) is untouched. Nothing here is wired into the running system yet - the owner integrates + validates when ready.

Build status (2026-06-04, offline test-gated)

Run the suites from code/ (NOT the repo root, or gameserver_udp won't resolve as a package): py -3 -m gameserver_udp.tests.test_roundtrip_core and py -3 -m gameserver_udp.tests.test_runtime_smoke.

  • Core wire stack (transport/ stream/ messages/) - IMPLEMENTED, validator 80/80 (tests/test_roundtrip_core.py): round-trips + EA bit-exact (cid=260=239b, cid=170, ghost=64b, ...).
  • Runtime (server.py, inbound/probe.py, inbound/dispatch.py, content/load_bootstrap.py, content/keepalive.py) - IMPLEMENTED, smoke 27/27 (tests/test_runtime_smoke.py): bootstrap order byte-matches LOAD_SEQUENCE; outbound<->inbound loopback round-trips; real EA probe bytes drive the handshake FSM to ConnReady. (This is REPLAY/loopback proof - still UNTESTED against a live client.)
  • Integration (integration/session.py) - SCAFFOLD: localhost session-feed (:21099) for the ProtoTunnel key+ctx; the Blaze (Py2.7) side is the TODO (needs the off-limits baseline).
  • Gameplay G2 (gameplay/ghost_stub.py) - STUB: ghostCount=0 keepalive only; the Anthem ghost/replication format is the make-or-break ~3-4wk RE gap (captures confirmed plaintext = tractable).
  • Honestly-flagged core TODOs: fragment frag_idx width (live-6-bit vs doc-39-bit) and sublevel-name string compression past ~byte 23 remain uncracked.

What this is (and is NOT)

This is the UDP-21081 Frostbite engine-stream producer - the real backend that serves game content over the mission CommUDP connection, so the stock Anthem client can load levels and (eventually) play. It is a clean, modular reimplementation that ports the proven, byte-correct wire pieces out of the accreted blaze_realudp_fork/mission_fsm.py into a maintainable package.

It is NOT the fix for the 20% wall. Per documentation/04-reverse-engineering/REVISED_THESIS_2026-06-04: the 20% plateau is Step D (isLoaded bits 2/9) = the menu-peer eviction killing the bundle-cache singleton, which has no server-pushed wire setter - only the DLL eviction-spare (Option C) can clear it. This server addresses Track 2: actual gameplay, after that wall. Don't expect it to move the 20% number.

Wire stack (all KNOWN / byte-proven - see AGENT15_game_server_architecture_2026-06-04.md)

UDP 21081
  +- CommUDP framing (seq/ack/kind envelope; kind-mask demux)
     +- ProtoTunnel (RC4 + HMAC; key = <UUID1>-<UUID2>-<UUID1> from the mission NGS)
        +- Spike "Secure" header (bitsInLastOctet)
           +- 39-bit fragment header (u16 seq, u6 frag_idx, u15 body_bits, u1 final) + reassembly
              +- outer manager bitmap (0x1400)
                 +- slot 10  StreamManagerGhost  (64-bit; steady-state ghostCount=0 keepalive)
                 +- slot 12  StreamManagerEngine / MessageManager
                       +- inner 7-bit submanager bitmap -> numMsg(4) streamId(3) classId(9) cmd(3)
                          +- classId + body  (LSN dispatch gate)

Three content regions:

  • Load bootstrap = CANNED/known - cid=260 LevelSetup, cid=56 SubLevelName, cid=170/204/207 SubLevel cascade, cid=245 TimeSync, cid=270 TinyEvent. Bit-exact across EA captures.
  • Ingame keepalive = LIVE-TRIVIAL - 10 Hz slot-10 ghostCount=0 + cid=0/8/9 dylan-overlay pulses.
  • Gameplay = LIVE-STATEFUL, UNDECODED (G2) - the real make-or-break: the Anthem ghost/replication format (onWriteGhostCreateHeader / NetInit / compression-vector / Player layouts). ~3-4 weeks RE. Scaffolded as a documented stub here.

Module layout (target)

gameserver_udp/
  README.md                  (this file)
  transport/
    commudp.py               CommUDP framing + kind-mask demux
    prototunnel.py           RC4 + HMAC; key derivation from NGS UUIDs
    secure.py                Spike Secure header
  stream/
    fragment.py              39-bit fragment header + reassembly
    bitmap.py                outer manager bitmap (0x1400) + slot dispatch
    slot10_ghost.py          StreamManagerGhost (64-bit keepalive body)
    slot12_engine.py         StreamManagerEngine/MessageManager (inner bitmap, classId+body)
  messages/
    bitwriter.py             bitstream writer suite (port of the encoder)
    classids.py              cid table + bit-exact body builders (260/56/170/204/207/245/270/0/8/9)
  content/
    load_bootstrap.py        load sequence orchestration + LSN gating (port the proven sequence)
    keepalive.py             Ingame keepalive pulses
  gameplay/
    ghost_stub.py            G2 stub + the RE gap documented
  server.py                  asyncio UDP server that ties it together (standalone Py3; the session +
                             ProtoTunnel-key coordination with the Py2.7 Blaze = integration/ TODO)
  tests/
    test_roundtrip.py        validator: every encoder round-trips + matches EA reference bytes

Build rules (for contributing agents + the owner)

  • Python 3 (clean modern package; the wire-stack/encoder modules are framework-agnostic pure functions; server.py uses asyncio - or Twisted-on-Py3). This is a standalone Py3 process; it coordinates session state + the ProtoTunnel keys (which originate in the Py2.7 Blaze's mission NGS) via an integration layer (TODO) - IPC/shared-state/network, NOT a Py2 import. Do not import the Py2.7 blaze_realudp_fork package; port the LOGIC into clean Py3.
  • Py3 notes: bytes are bytes/bytearray (indexing yields int - cleaner than Py2); use int.from_bytes/to_bytes; keep encoders as pure (...) -> bytes/bit-list functions.
  • Port, don't reinvent. The bit-exact bodies + LSN timing in blaze_realudp_fork/mission_fsm.py
    • Components_Client/Game.py + Utils/ are months of hard-won, byte-validated RE. Re-express them cleanly in Py3; preserve the byte/bit output exactly. Cross-check against the RE memory docs
    • EA captures.
  • Validator-gated. code/tools/round_trip_validator.py is Py2; either port its round-trip logic to a Py3 tests/ harness or validate directly against EA reference bytes using the Py3 decoders (code/tools/decode_ngs_full.py, diff_ea_vs_our_ngs_2026-06-04.py). An encoder isn't done until it round-trips AND matches the EA reference bytes byte-for-byte.
  • No live run, no exe, no edits to the live baseline during this overnight build.

Provenance

Architecture: code/tools/output/AGENT15_game_server_architecture_2026-06-04.md. Root-cause context (why this is Track 2): documentation/04-reverse-engineering/REVISED_THESIS_2026-06-04_menu_peer_root_cause.md.