A map zone streams the materials it shares with common_mp as ",name"
references: stubs with no textures and no technique set. Since
capture_material refuses a material without a technique set, the slot of
such a reference was never bound and every model surface on it was
dropped: 97 of the 14551 map model surfaces on mp_terminal and 28 of the
14125 on mp_favela, among them a surface of the wall fan cs_wallfan1 and
one of the air conditioner com_ex_airconditioner.
When the capture refuses a reference, the slot is now bound to the real
material of the same name and namespace, which the common pool already
holds. A reference with no real counterpart stays unbound as before.
",mc/shadowcaster" references bind now too, so scene_lit_pass_material
skips shadow-only materials for script models and dyn ents, as the static
model path already does.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Constant Radar (Gameplay Options) keeps every player's radar constant
unless an EMP blocks it, and the compass shows every living enemy each
frame, Cold-Blooded or not. Enemy Bots (0-9) and Friendly Bots (0-8, team
modes only) under Team Options add that many bots when the match starts;
a sided bot waits for the local player's team, then answers the team menu
with it or the other one. Free-for-all ignores the friendly count.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each FX random draw is a BLAKE3 hash. Velocity graph walks hashed the
same three per-element draws for every sample they touched, and the
element seed was rehashed several times per element per frame across
update, sort and draw. Take the velocity draws once per walk and keep
the element seed on the slot, set at spawn from the same inputs, so
every value is unchanged.
12 bots on mp_rust: fx_update 0.57 -> 0.25 ms per frame.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
One pass over the waiters instead of a quadratic dead-thread scan; a
validated serial-to-entity cache for find_thread; heap collection every
ten ticks walking ids by reference; execute no longer clones each
instruction's location, and keeps the runaway-loop budget local, syncing
it with the runtime only around instructions that can run other threads.
With 12 bots the authority step falls from about 7.1 to 3.6 ms a tick.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MW2's friction scales its control speed by 0.3 while a hard landing lasts;
the port doubled it. With walk acceleration also quartered then, a player
who took fall damage could not get moving for up to 2 s.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MW2's class scripts set specialty_quickdraw, specialty_holdbreath and
specialty_spygame for the pro perks, but no perk bit was mapped, so they
did nothing. With MW2's bits and values:
- quickdraw (perk 26) moves into and out of ADS 1.5 times as fast
(perk_quickDrawSpeedScale) and shortens the ADS-only fire delay to match;
- holdbreath (perk 4) holds the breath 5 s longer (perk_extraBreath), in
the movement code, the breath hint and the gasp sound;
- spygame (perk 32, bit 0 of perks[1]) hides the player's name from
enemies aiming at them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A landing from above 128 units hurts, rising linearly to 100 at 300
(bg_fallDamageMinHeight/MaxHeight); surfaces flagged no-damage spare the
player and soft-landing ones cap it at 10. A hurting landing short of 100
holds the player in a hard landing for damage * 35 + 500 ms (at most 2000)
keeping 0.5 to 0.2 of their speed, as MW2's PM_CrashLand does; heavier
ones keep 0.67. Pmove raises the landing-pain event with the damage and
the authority deals it as MOD_FALLING through the script damage path, so
the game scripts handle it (Commando's immunity included).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Without a strafe, MW2's ladder move takes speed along the ladder down at
16 per second (at least 1 unit/s a tick); the port kept it, so a jump
onto a ladder at an angle kept sliding along it and off its edge. Also
keep the strafe direction unnormalized after projecting it onto the
ladder, as MW2 does.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The contact solver projects a move flush onto the planes it touches. At
map-scale coordinates the rounded target lands slightly inside the plane,
the trace stops it at once on that same plane, and the solver gives up
with zero velocity, so players stuck on any slope too steep to walk.
Retry that move once lifted 1/32 unit off the planes it presses into,
as IW4's overclip keeps moves just off a surface.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
BO2 lit shaders decode the reflection probe as rgb / alpha, the HDR
encoding of BO2's own probes. The probes bound to them come from MW2,
MW3 and BO1 maps, whose alpha is not a scale, so dividing by it made BO2
weapons glossy and speckled with white. Treat the probe's alpha as one
for BO2 shaders.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Picking up a dropped weapon took the press itself. It now takes use held
for ITEM_USE_HOLD_MS (250 ms) on the same weapon; thrown items such as
knives still go on the press. The press start travels in the client
match state, so the protocol is 110.
Over a weapon, use+reload used to do nothing on a tap. The client holds
the reload back while the button is down and sends it on a release
before the hold time, if the same item is still selected, so a tap
reloads and a hold picks the weapon up.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The stance button's press was timed on the virtual clock while its hold
was sampled on the real one, so after a loading stall any press already
counted as a hold and went straight to prone. Time both on the real clock.
Holding jump cleared the stance latch every frame, so crouch pressed
while still holding jump never took; jump now stands once, on its press.
The hold toward prone only counts on the ground, so crouch held through
a jump lands crouched.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
- Format with rustfmt and clear the clippy warnings on lines this branch
adds (fixed-size chunks via as_chunks, explicit fallbacks instead of
unwrap_or_default, range patterns, elided lifetimes).
- The engine-supplied equipment script is t6_equipment.gsc.txt, since
publish-check treats any .gsc as game data; FNV constants are named.
- NOTICE credits the Plutonium t6-scripts dump that the equipment
behaviour was worked out from.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The camouflage picker showed its swatch in the square attachment preview;
it now fills the weapon-wide preview, as the class panel shows it behind
the weapon.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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>
iw4l_t6/equipment plays T6's equipment effects and sounds: team-coloured
lights on bouncing betties, trophy systems, shock charges and C4, the
betty's launch and burst, the trophy's deploy and intercept flashes, the
shock charge's warning and zap, the sensor's scan, EMP fizzles.
T6 effects are captured with every effect they play in turn (runners and
spawned children), and the report names any the converter refuses. T6
rows use their own projectile explosion effect when it was captured. T6
equipment aliases are captured, and T6 aliases record whether they loop
so scripts can play them. Script effects honour hide()/showToPlayer()
(protocol 104), so team lights, and IW4's tactical insertion flares, show
to their side only.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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>
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>
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>
T6 effects named in T6_EFFECTS are captured from the T6 zones and
converted to IW4 effects: a T6 element is laid out as a T5 one, lines
become tails along the effect's forward axis at half size, and sample
colours go from RGBA to BGRA. Their materials stand in on IW4's glow
stick material with the T6 colour maps.
The flare glows IW4's scripts light on a T6 tactical insertion play the
T6 team or enemy light instead, from the insertion, straight up. The
planted model lies flat as in Black Ops II.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The T6 tactical insertion sits in the tactical slot and throws with the
tactical button beside the lethal: the class script is handed a smoke
grenade standing for it, and its giving starts IW4's tactical insertion
perk. The glow stick IW4's scripts plant for it carries the T6 planted
model, drawn as a projectile mesh standing on end, and the thrown grenade
is removed once it is planted.
IW4's own tactical insertion chosen as the lethal is given as the
equipment perk instead of a frag.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Reticles draw T6's emissive technique (T6 "unlit" is Radiant's preview);
packed constant rows, floatZ stand-in, blended surfaces drop depth writes
- Zone pointer lookups go through per-asset bound slots (reused memory)
- Holo and rangefinder swap to their ADS models when fully aimed
- BO2 scope overlays (variant/unique overlay materials); sights looked
through (ACOG, iron sights) on snipers aim down the 3D sight
- Select fire and other zero-timed alt raises last their clip
- Stat-only configurations (FMJ) keep the bare weapon's hides
- HUD names configurations with their attachments; equipment uses its
BO2 HUD icon; attachment and overlay icons decoded for the class menu
- World models (planted equipment, third person) use native T6 materials
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 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>
Each T6 attachment configuration takes the numbers of the attachment's
WeaponAttachment (fastfile_t6::weapon::attachment, offsets checked against
known effects): clip size, fire time, reload times, ADS in/out times, ADS
zoom FOV and zoom fractions, damage range, hip spread, ADS move speed,
ADS view kick centring, ADS idle sway, and FMJ penetration.
- ADS move speed is relative to walking as in IW4 (SMGs 2, rifles 1); a
stock raises it up to running pace.
- A pump shotgun's fast mag loads two shells a stroke.
- T6 weapons had no penetration multiplier; they take the stand-in's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every attachment a T6 weapon offers, alone or in a compatible pair, is a
weapon row (`an94_acog_grip`) built from the base row and the weapon's
WeaponAttachmentUnique assets: the attachment's first-person and world
models at the weapon's own placement, hidden gun bones, clip overrides,
fire sounds and alternate weapon. Stat-only attachments make rows that
change nothing shown yet.
- fastfile_t6: AttachmentUniqueView; loaded assets record the asset each
pointer field named at load time, since walk memory is reused.
- Each attachment model is captured per weapon (`model@unique`) with its
offset as root rest and the gun bone it hangs from (ModelSkel::mount_tag).
- T6 guns hide parts by collapsing bones in skinning: their sights share
the body's surfaces.
- Bare T6 rows hide what their `none` unique hides.
- The full T6 attachment table loads; stats-table names like `acog_sniper`
map to `acog`.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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>