12 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 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
Gh4zi d9f497322e Sun shadows: script models out of view still cast into it
Favela's hanging laundry is animated script models. They were posed only
when the camera's scene-entity walk reached them, so once the clothes left
the screen their shadows on the wall below vanished (only the static rope's
stayed). IW4 culls scene entities for each sun partition apart from the
camera; here a script model the walk hid is kept for the sun shadow only
(colour refused, no lighting request) while its bound is inside one of the
sun partitions.

The partitions are published before the models are posed, from one shared
builder the command context now uses as well, so both see the same planes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 17:13:49 +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 f1f4c07feb Bind prepared runtime assets to their owners and correct T6 rendering 2026-10-06 21:37:31 +03: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
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
chazmm 7af11e5500 Roughly double no-bot frame rate by cutting per-frame CPU work
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 18:35:44 +03:00
vtroc7 bca31343e5 Bots that fight and take objectives, and glass that cracks into real shards
Host bots bake a navigation graph off the clip map and walk it — drop and
break-glass edges, routes that resume across ticks under a shared per-tick
query budget, firing positions chosen from baked supports rather than a ring
around the bot. They pick a weapon, reload or switch when the magazine runs
out, and plant, defuse and claim flags on their own.

A broken pane now builds a planar crack graph and emits shards carrying their
holes and open cracks, so tessellation and repeated hits read the stored
geometry instead of assuming a convex fan from vertex zero.

Sun cascades are clipped to the view. Class select and the options menu match
the layout players expect. Weapon definitions load from IW5 and T5 fastfiles.

The test suite is removed: it had grown into scaffolding for the dig rather
than a description of the runtime, and new tests will be written against the
behaviour that stayed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-21 02:49:55 +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 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