48 Commits

Author SHA1 Message Date
vtroc7 acc57a5c9d Make underbarrel attachments work across families, bound transport and qualify match publication
- Underbarrel attachments work across IW4, IW5, T5 and T6, including
  per-family impact FX, T5 flamethrower streams and T6 launcher fuses.
- Viewmodel notetrack sounds play in third person.
- Transport operations and queues are bounded; Quinn congestion control
  returns to its default.
- Match publication, presentation context and prepared content semantics
  are qualified and validated; cosmetic and entity occurrence lifecycles
  are preserved.
- GPU skinning batches within supported device budgets.
- Immutable UI projections and correlated class replies are reconciled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 16:28:56 +03:00
vtroc7 c47684e141 Improve native rendering, background menus and community setup 2026-10-12 20:34:48 +03:00
vtroc7 08b4224efd Add Theater editing and chat, improve controller UI, audio, combat and network recovery
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 21:43:30 +03:00
vtroc7 a2f189df10 Scope match lifetimes and restore gameplay and menu presentation
Prepare progression and loading through Bevy scheduling, preserve round HUD and bombsite props, restore grenade and T5 shadow presentation, and keep menus usable while classes load. Report update progress and continue startup after update failures.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 23:01:34 +03:00
vtroc7 5273074e72 Integrate contributor rendering, gameplay and development fixes 2026-10-10 01:33:23 +03:00
JohnM 9f21620750 Never strand a return to the menu behind a late disconnect
When the match scripts end a match, the session swap requests a
MatchEnded teardown. A disconnect that arrives before the teardown fact
is read turns the pending Menu target into a leave, and the swap then
waits for a Disconnect teardown that never comes. No ReturnedToMenu is
written, and every later map or Start Game fails with "session swap
already in progress" until a restart.

A swap back to the menu now finishes on whichever teardown fact arrives,
but still waits for one. The reason reported with the return still
follows the target, so a late disconnect lands on the main menu.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 02:19:00 +08:00
JohnM da8ec04bb7 Return the host to the private lobby when the match ends
When the match scripts end a private match, the session swap already
tears the world down as MatchEnded, but ReturnedToMenu did not carry the
reason. The frontend treated every return from a world like a disconnect:
it reset the party, so the host landed on the bare main menu and Start
Game refused with "Only the lobby host can start a match" until a new
lobby was created.

ReturnedToMenu now carries the teardown reason (None for a failed load).
After a MatchEnded return the host of a private lobby keeps the party,
and once the main menu is open again the frontend reopens game_lobby over
it with map, mode and rules kept. If the main menu does not come up
within five seconds, the party is reset as before. Disconnects, failed
loads, public lobbies and clients still go to the main menu. Creating a
lobby or starting a match clears a pending reopen, so it cannot reset
the party later.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 02:19:00 +08:00
JohnM 7157feb9bd Bind the script glass functions so Strike loads
mp_strike's map script breaks its "brokenglass01" panes in main() with
GetGlassArray and DestroyGlass. Neither native was bound, and an unbound
native refuses the whole program at install ("2 unbound natives:
destroyglass getglassarray"), so the map never loaded.

The glass reset now also reads the map's named glass table (a targetname
and its piece indices), and the session installs it next to the glass
panes as a GlassNames resource. getglassarray, getglass, destroyglass
(the existing script shatter), isglassdestroyed and getglassorigin are
bound on top of it. The map script only runs at the next scheduler pass,
after the glass is installed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 01:18:51 +08:00
vtroc7 91217cd0ac Restore native effects and objectives, scope zoom, camouflage and lighting 2026-10-08 22:04:32 +03:00
vtroc7 983fd97853 Publish prepared presentation contracts and predict local bullet impacts 2026-10-07 22:44:14 +03:00
vtroc7 a1fc0f902c Align hosted match epochs for first-person weapons 2026-10-07 21:11:35 +03:00
vtroc7 25c008b391 Prepare coherent match assets, native camouflages and server releases
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 20:30:21 +03:00
vtroc7 7eff9406fb Connect native soldier hands and finalize match rule integration 2026-10-07 12:52:50 +03:00
vtroc7 ea45cf7dcc Preserve native families, soldier hands and T6 world materials 2026-10-07 00:13:36 +03:00
vtroc7 f1f4c07feb Bind prepared runtime assets to their owners and correct T6 rendering 2026-10-06 21:37:31 +03:00
vtroc7 d655b952cb Prepare asset products, restore T6 rendering and select community servers 2026-10-06 15:57:22 +03:00
vtroc7 f026f5fca0 Improve runtime readiness, rendering, audio and Linux game discovery 2026-10-05 23:41:16 +03:00
vtroc7 65052d3f51 Add native T5 audio, Black Ops II maps, independent movement, late join, skill ratings and varied bot loadouts
Decode Black Ops audio natively and load Black Ops II worlds, faction
models, equipment, materials, lighting and weapon camouflage.

Rework capsule collision, solid recovery, penetration, recoil, effects
and sentry placement; synchronize late joins and player event delivery.
Keep local skill ratings and signed player accounts.

Show the selected community and master ping on the main menu. Add twenty
asset-filtered class presets across IW4, IW5, T5 and T6, plus fifty-two
unique player-style names shared by AI bots and dummies. Honor the chosen
dev descriptor in the two-client approved scenario and credit contributors
and weapon, map and attachment QA testers.

Validated with the approved gameplay lifecycle and two-client dev-master
scenarios, installed class-asset audit, bot-name uniqueness checks and
Linux IW4/IW5/T5/T6 gameplay smoke runs. Foreign-weapon match-stat schema
coverage remains incomplete.
2026-10-05 13:13:28 +03:00
vtroc7 9313f6c8be Merge pull requests #59 #64 #65 from gitoutofthere and NeptuneTheGoat 2026-10-04 16:20:36 +03:00
neptune 9c00565bd9 Give MW2 weapons their camouflage
A weapon's gunXModel / worldModel slots 1-8 are its camouflage models
(woodland ... orange_fall, numbered as mp/camoTable.csv). They are now
captured, aliased arrays included, and bound per weapon.

Classes carry a camouflage per weapon (classes.txt: two optional trailing
fields, written only when one is set; PersonalClass on the wire, protocol
103). MW2's _class.gsc reads it from customClasses...camo and gives the
weapon with its number; giveWeapon stores it as the slot's weaponModel in
weapon_data, which replicates. First person swaps the gun's materials for
the camouflage model's (it shares the gun's surfaces); third person draws
the camouflage world model.

Create-a-Class goes weapon, attachment, then camouflage, as MW2 does,
offering only the camouflage the weapon has, and MW2's panel shows it
behind the weapon. Console: give ... camo=<name|slot>, bot give ...
camo=<name>.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 21:05:05 -04:00
neptune 818ba83cc8 Run Black Ops II equipment as Black Ops II does
Tactical insertion: under IW4 rules offhands are bridged by name only, so
the upstream slot stand-ins no longer hand the scripts a flash for it (it
plants and sets the spawn again); hidden entities stay usable, so its
owner picks it back up.

Equipment stats: read T6 detonate delay/time, damage cone, forward and
view-relative up speed, the detonator flag (C4 detonates) and the
retrievable flag (owner pickup only where T6 allows it).

Equipment behaviour: iw4l_t6/equipment ports T6's bouncing betty, shock
charge, trophy system, sensor and EMP grenades onto IW4's scripts, plus
T6's one-of-each counts, claymore grace and respawn cleanup. The engine
reports those items under their own names, tags thrown grenades with
nativename/weaponmodel, keeps sensors planted, drops the claymore laser
from betty and trophy, and lets objective_team address one player (sensor
pings, drawn in FFA too; protocol 103).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 16:12:02 -04:00
neptune f7c3b953ee Merge upstream master (d352dbd) into bo2-weapons
Conflicts kept both sides: Steam discovery next to Game Folders and
sibling titles, upstream's profile/account persistence next to the
folder picks and saved position, SAB/FLAC beside blake3, the T6
localize loader on the raw-bytes catalog (cache format 3), and our
tactical insertion equipment mapping with upstream's specialty_null.
The fire-delay fix takes upstream's form. Exit silencing now mutes the
new audio runtime instead of Bevy audio sinks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 14:04:01 -04:00
vtroc7 3694c35041 Audio control runtime, typed player accounts, self-updates, thermal and shellshock screens, third person, guided killstreak HUD, player cards, a lobby cheats toggle and god mode
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 15:57:27 +03:00
neptune a921065c08 Play weapons' first raise after they are given
A weapon raised for the first time since it was given (on spawn, on
pickup, or switched to after a give) takes its first raise animation
and iFirstRaiseTime, as IW4 does: the first byte of a held weapon's
equipped state (usedBefore) is set once it is raised and cleared when
it is given. The first raise sends EV_FIRST_RAISE_WEAPON.

First raise times are read from IW4 WeaponCompleteDef (0x54) and T6
WeaponDef (1228) into the catalog and combat facts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 03:43:56 -04:00
neptune 6f15ecf64e Fix T6 alternate modes, iron sights, riot shield bash and fire delay
- Each T6 configuration with an alternate weapon (grenade launcher,
  select fire, dual optic) gets an alternate row of its own: it wears the
  configuration's attachments and returns to it. Select fire and dual
  optic fire from the configuration's magazine (WeaponAttachment
  sharedAmmo). A switch plays only the raise of the weapon switched to;
  select fire uses its attachment's in/out clips.
- weapon_iw4: a weapon with a fire delay re-armed the delay when it ran
  out and never fired; the delayed shot now fires.
- Configurations hide only their attachments' gun bones, not the bare
  weapon's (the Ballista's iron sights under its scope).
- A T6 riot shield bashes with the fire button (`fire_melees`).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 19:20:02 -04:00
neptune af8ee254c1 Add Black Ops II weapons, native T6 shaders and Game Folders
T6 (Black Ops II) weapons load from the BO2 install beside MW2 and play
with their own models, materials, animations, sounds and icons, standing
in for an MW2 weapon row for gameplay.

- fastfile_t6: T6 zone walking and weapon views; IPak/SAB image and sound
  sources in asset_transport.
- dxbc_sm5: DX11 shader bytecode lowered to WGSL, so T6 materials draw
  with their own technique sets (t6_techset, dxbc_abi).
- Materials: borrowed draw states come from the stand-in's opaque body,
  never a lens; colour-map alpha (the camo mask) reads as one on opaque
  surfaces; specular and probe reflection scaled for IW4 lighting; maps
  named by another kind's samplers fall back to the same-role map.
- Dual wield (`X_dw` + `X_lh`) through the shared secondary-gun viewmodel,
  and the `dw` attachment from T6's attachment table.
- Melee: guns without their own melee clip (and pistols, whose clip is the
  tactical knife's) borrow knife_mp's knife and swings; the hip ADS layer
  returns after a melee.
- T6 clip names match case-insensitively.
- Game Folders option for BO1/MW3/BO2 installs, multi-game lookup fixes,
  clean exit, crosshairs, save/load/loadspawn console commands.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 15:56:23 -04:00
Liam McElhaney 062d633ad3 Take the cheat switch from the launch options
The match bootstrap set allow_debug_actions to true for every match.
The host therefore accepted the debug actions from any peer.

Add the --cheats launch switch for map, serve and menu.
The switch sets the HostCheats resource. The match install reads it.
Cheats are off when the switch is absent.
Pass --cheats in make map, the live recipes and the scripted harnesses.
2026-10-01 13:31:10 -04:00
vtroc7 bfe3c2aa70 Breath, shields, crossbow, car destruction, remote animation and GSC services
Scoped weapons hold breath with recovery feedback and sound. Riot shields
block and deflect bullets in hand and on the back; explosive crossbow bolts,
destructible map cars with round resets, and T5 map model collision work.
Remote players show last stand, weapon change, jump, mantle, landing,
ladder and stun animations, and server hitboxes follow the shared torso tree.

GSC gains spectator follow cameras, chat, kick, vehicle paths and flight
controls, physics spheres, slow motion, slide and mantle movers, damage
triggers, music, ambience, rumble and live audio fades over a shared mixer.

IW5 and T5 maps get sun shadows with per-stage sun selection; post-fx
pipelines compile before a vision blend needs them. The lobby browser keeps
focus and selection, and rooms can be password protected. Console supply
and give commands search every item category. Frames and replays decode
only the current wire protocol.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 19:18:44 +03:00
awsms 32d6dae721 Fix reload ADS timing
Holding aim originally allowed zooming throughout a reload. The blanket
reload-state restriction added in a2093b9 overcorrected this by blocking
ADS until the entire reload finished, delaying the return to aim compared
to MW2.

Replace that restriction with the original engine's ADS fraction logic.
Decode WeaponDef::iPositionReloadTransTime from IW4 assets and carry it
through the weapon catalog, combat facts and shared movement context.
Include the field in the simulation content fingerprint.

Magazine reloads suppress ADS while remaining weapon time exceeds the
weapon's authored transition window. Segmented reloads suppress ADS during
the start and insertion states, then use that window during reload end.
Keep ADS intent available so holding aim resumes the blend at the original
boundary. The comparison uses weapon-timer milliseconds, preserving the
existing Sleight of Hand timer scaling without an extra fixed delay.

Validation: play build, targeted formatting and diff checks passed. A
temporary reference probe compared 4,704 cases against the original
MW2/IW4x instruction block at 0x4a84ab..0x4a8513, including transition
boundaries and segmented reloads. Runtime traces verified authored windows
and early ADS recovery on M9, USP, Intervention and Barrett with Sleight
of Hand. The user confirmed the resulting behavior in game.

Temporary diagnostics and probes are excluded. The runtime test encountered
the previously observed shutdown SIGSEGV after process_exit code=0; this
change does not address that shutdown issue.
2026-10-01 08:06:24 +02:00
vtroc7 03016c48d6 Script-driven post effects, fog and earthquakes; equipment recovery, akimbo viewmodels, end-game leave and scope edges
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 20:01:29 +03:00
vtroc7 56c6d8ebcb Improve equipment, missile guidance, animations and weapon audio
Remove unused weapon summaries and catalog APIs, share model geometry helpers, and consolidate per-frame renderer census resets.
2026-09-30 08:30:12 +03:00
Bulat Fatykh b7f04c53f3 Remove unused runtime code and dependencies 2026-09-30 07:53:22 +03:00
chazmm f1f8c0d554 Add controller support: button layouts, stick aim and aim assist
Controller buttons bind through the same table as keys: every command on
the controls page shows its key and its button, and either is rebound by
pressing a key or a button. The options gain a Controller page: button
layout (Default, Tactical, Lefty, Bumper Jumper, Bumper Jumper Tactical),
stick layout, look and aim-down-sight sensitivity, invert, response curve,
aim assist, vibration and deadzones, all kept in settings.cfg.

The look stick turns at rates that build up to full deflection, slower
down the sight and scaled by the zoom. Aim assist works over visible
enemies within each weapon's own aim assist ranges, read from the weapon
data: slowdown and lock-on, and on Full a pull onto a target when the
sight comes up. It applies only while aiming with the controller.

Menus take the D-pad or left stick, A and B, and Start opens them. Focus
moves by screen position rather than by menu file order, which jumped
around the options pages for arrow keys too; left and right on a button
cross columns. The Advanced Video page no longer draws the FOV slider
over Bloom.

The controller in use is the last one pressed or moved, so a virtual
joystick or an idle second pad stays out of the way; rumble follows it and
the vibration setting. Use/reload reloads when nothing usable is in reach.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 04:41:49 +03:00
vtroc7 60f550a2b7 Support personal loadouts and fix lobby and menu interactions 2026-09-30 04:38:21 +03:00
vtroc7 1a0daffd18 Play T5 and IW5 maps under IW4 match rules 2026-09-28 20:48:06 +03:00
vtroc7 38aa9cf741 Run IW4 match flow, menus and killstreaks from the game scripts
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 18:35:44 +03:00
vtroc7 72ee2098da Improve killcams, combat effects, and asset presentation 2026-09-25 00:05:20 +03:00
vtroc7 73ea661667 Add killstreaks and fix collision, materials, and HUD 2026-09-24 18:54:31 +03:00
vtroc7 69cf9ff9fa Prepare weapon presentation and add alternate modes, device feedback and collision fixes 2026-09-24 05:30:17 +03:00
vtroc7 f357ef16be IW5 attachments and weapon overrides, a blood film on the HUD, and team-tinted obituaries
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 23:45:43 +03:00
vtroc7 94e3983bfc Shared common content, prepared weapon families, and one way out of a session
- One common set per content profile, shared by every match and the loadout
  menu; a restart over the same map keeps its images and static geometry.
- Weapons resolve as families: attachments are chosen from each game's own
  tables, checked, and composed into prepared configurations with their
  first-person skeleton assembled once.
- Sessions end through one teardown and one process exit; retired resources
  are dropped on a worker, not the frame.
- Sound is captured by the walks that already read each zone.
- A loading screen that reports what the load is doing.
- Tests live only in crates/approved_tests (heavy_gameplay_lifecycle);
  publish-check refuses them anywhere else.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 17:10:02 +03:00
vtroc7 52d31f1ee2 A loading screen that says what the load is doing, and a first-person rig prepared once per composition
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-21 23:28:55 +03:00
vtroc7 b7e00544bb Destructible props, a live scoreboard, and film vision on the console
Destructibles walk their stage staircase on the host: each stage carries
its model, the parts it throws off, the effects it fires on the way out
and the health it bleeds afterwards, and the loops a prop is speaking are
published as sound aliases the client resolves through the configstring.

The scoreboard, overhead names and the compass draw against the live
roster -- team identity survives player-supplied color escapes, ranks and
prestige come out of the menu tables, and the final snapshot is kept when
it lands ahead of the next scores command.

Film vision presets load from the map and common fastfiles; visionSetNaked
and visionReset transition between them.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-21 14:41:01 +03:00
vtroc 311c8fa336 Time a whole run in one process, and keep a hitch from ending the session.
`make bench` is one recipe over one run now. `IW4L_BENCH=1` arms an in-process
recorder on the spans that already feed Perfetto, and at exit the run prints
two independent reports and writes them to `iw4l-artifacts/bench/<stamp>.txt`:
the waterfall from the shell command to a playable map, carrying the time each
load stage held the pool alone, and frame time as a span tree whose nesting is
recorded rather than declared. Neither needs a trace file or Trace Processor,
and either can be MISS while the other stands. `bench-demo` and `bench-load`
are gone — a goal after `bench` is a demo, `ZONE=` is a live map.

A bot is no longer minted onto an id a real client already owns. The roster
steps over the ids the authority and the local player hold, and a slot that
still lands on the local player is retired, because `is_bot` would otherwise
claim the player and nothing could drive the slot anyway.

A stretch with no authority ack re-adopts the next snapshot and counts one
stall; three of them still fail the link. Failing on the first turned every
long frame into a permanent disconnect.

The loading overlay comes down once the world is installed rather than waiting
on the class-select hop, which a replay never makes — it was playing the whole
demo behind `UiLayer::Loading`, with map ambience held back.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013bHwyKwUjaYmtVG1F3Ttku
2026-09-15 14:56:07 +03:00
vtroc a7c0958668 Shatter glass, finish ordinary fire, walk host bots on the clip, and run radiation's authored toys.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-14 19:29:22 +03:00
vtroc 58e47025f7 Register mapent destructibles as toys and publish asset catalogs by value.
Mapent TVs, lights, fuse boxes, lockers, fans, ACs, bins, hydrants,
transformers, copiers, generators, mirrors and cop cars become toys and
vehicles, so a shot husks them, throws the authored FX and explodes.

Weapon, xanim, FPV/body/world-gun/projectile mesh and FX catalogs publish
without the capture cursors and zone slots that stamped them, so the runtime
registry cannot restamp an edge after install. World and smodel tess tables
become published Arcs that extract steals a share of instead of cloning.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KkgiSVEPTbsVZ1RpARujF6
2026-09-14 12:51:34 +03:00
vtroc 7dcdd6831e Give every loaded population one owner, and publish it without the walk that built it.
The zone walk and the runtime were the same types. A catalog carried the
walk's `Ptr → row` link maps, its half-captured names and its scratch into
the published result, so nothing said the linking was over except a
convention — and the runtime, which has no zone open any more, could not
have used them anyway.

Build and published types are now separate for materials, effects, tracers
and reticles: `MaterialDefinitions`, `FxDefinitions`, `TracerDefinitions`
are what a finished build hands on, `publish` is the only way to get one,
and the pointer lookups and absorbs stay behind on the builder. The
presence those pointers stood in for is one shared type, `AuthoredRef {
slot, alias }`. Every published asset type is free of zone pointers except
`WeaponCombatFx`, which waits on splitting `WeaponRegistry` the same way.
That split also turned up dead code the old types had hidden:
`resolve_after_absorb` looked weapon icons up by pointer after `finalize`
had emptied the map, so every lookup there returned `None`.

Map load is a transaction with one terminal outcome. Preflight assembles a
`MatchInstallPlan` — nothing to publish exists until every check that can
refuse has passed — and any refusal writes `MapLoadFailed` for the request,
including "no drawable world", which used to be a `MatchInstalled` the
lifecycle read as success and the UI read as failure. A canceled walk
returns `MatchLoadOutcome` instead of orchestrating on with empty products.
The match carries one material population (`PreparedMatch.materials`)
rather than reaching for it through geometry that may not exist, and the
transport schema around the boundary — the six `LoadCapture` wrappers,
`PreparedSpawn`, the doubly-owned map facts, `ZoneMemory` held to the end
of install — is gone.

Copies that had no reason to exist: the absorbs that already consume their
donor now move its rows instead of cloning every `ModelSkel` and
`RawXAnimParts`; sim and the dyn-ent physics share one `ClipMeshTables`
behind an Arc instead of each holding a deep copy of the collision.

Ownership on the live side follows the same cut. `SessionCore` takes a full
room identity and revision before any transport effect, so a stale
teardown cannot override a different match key. `HostMatchEvent::Applied`
carries no match key, so the peer's phase is its whole guard — it now
passes before anything is written, instead of landing a retired match's
connection id on the live peer on the way to being refused. `ClipStore` owns every PCM
conversion and every terminal decode failure, with Play/Stop on one ordered
channel scoped by namespace, entity and epoch. `SimContent` holds the
immutable definitions behind a consumed builder, so authority and
prediction share one backing instead of deep-copying per tick. Direct UDP
launch is removed; relay, listen and replay stay.

In the renderer each producer publishes whether its rows actually moved,
and the xmodel merge stops re-hashing seven producers' draws, materials and
vertex counts every frame to find out. Payload fields are `pub(crate)`
behind read-only accessors, so a consumer that wanted to finish a
producer's work no longer compiles. Colour extract is split from the
installed world, scene and shadow get their own bind caches, and record
census stays off the hot refusal path.

Docs: `CONTEXT.md` gains "Before shipping: the scaffolding goes back out",
and `make mr` and `cargo xtask mr` point at it. MAP-LOAD describes the
transaction as it now ends.

Scaffolding: the share and census probes that only proved the split are
out. What stays is five tests, each holding several independent systems to
one claim and each verified to fail when that claim is broken:

  - one alias carried from two-zone capture through absorb, edge binding,
    the alias-chain walk, the prep workers' decode and finally cancel —
    every stage has to mean the same clip by it;
  - a replacement match driven through all three cores that decide whether
    a player is in one (host admission, session view, local load), then
    every event the retired match still had in flight, replayed against a
    live peer, moving nothing;
  - a rejected room view leaving no bridge identity, membership, bootstrap
    or admission effect behind;
  - the seven draw producers published through their own API and asked of
    the consumer that replaced the merge's per-frame hashing: the stamp
    moves for exactly the producers whose rows moved;
  - authority and prediction proved to share one immutable world by
    tracing it, and to keep tracing their own after the other replaces it.
2026-09-13 23:23:58 +03:00
vtroc 0f387098e7 IW4L 2026-09-13 13:52:33 +03:00