New Acoustics system (globals/acoustics.gd):
- Occlusion: rays from listener to source collect up to 3 occluding bodies;
each surface's material adds transmission loss and lowers the lowpass
cutoff. A gunshot through wood stays warm (-8dB, 1.4kHz), brick muffles
hard (-15dB, 600Hz), concrete harder (-18dB, 450Hz), metal keeps more
highs (-11dB, 1kHz), glass barely muffles (-5dB, 2.6kHz). Applied via
each AudioStreamPlayer3D's attenuation filter.
- Early reflections: loud sounds (gunfire, explosions) probe 8 directions
for nearby walls; each close surface plays a quiet, delayed (path/343ms),
material-filtered copy from the mirror point — shots audibly slap back
off structures so players can triangulate. Sub-30ms echoes are skipped
(they perceptually merge with the direct sound).
- Surface classification: builder-set acoustic_material meta -> node-name
keywords -> metallic-material inference -> concrete default; cached.
Integration:
- AudioManager.play_3d applies occlusion at fire time and re-filters all
playing positional sounds every 0.12s (walking behind a wall mid-sound
audibly muffles it); flight loops opt in via "acoustic_occluded" group
- Remote players' gunshots were entirely SILENT — rpc_play_fire_effects now
plays the right weapon's shot at the shooter's position, occluded and
reflected like everything else
- Remote players' footsteps were also silent — now positional + occluded,
cadence scaled to their speed
- Test level tagged: brick arena walls, wooden platforms/obstacles, metal
wall-run corridor/rails/dash platforms; dust2 sandstone reads as brick
Tests: debug/acoustics_test.gd (12 checks: per-material loss ordering,
multi-wall stacking, reflection delay/filter, name classification) — all
pass; movement 11/11; smoke 0 failures.
Co-Authored-By: Claude Fable 5 <[email protected]>
- toon.gdshader: banded diffuse with cool-tinted shadows (3 tones), stepped
specular, rim light, and an optional world-triplanar albedo path so level
geometry keeps the 0.5 m grid with no UVs
- toon_outline.gdshader: inverted-hull ink outline, applied via
material_overlay so it works on skinned (deforming) meshes
- LevelMaterials: tinted() now returns toon grid materials; toonify()/
apply_toon_recursive() convert imported character/prop materials in place
- SkinnedPlayerModel: characters get toon shading + outline on load
- LevelEnvironment: shared stylized environment for all maps — saturated
anime sky, linear tonemap (filmic/ACES crush cel bands), bloom for
emissives, saturation+contrast grade, light depth haze; test level and
dust2 now use it and the procedural arena (which had NO environment)
gets it plus runtime toonification of its baked geometry
Co-Authored-By: Claude Fable 5 <[email protected]>
- Generated CC0-style prototype grid textures (0.5 m cells) and a shared
LevelMaterials factory: world-space triplanar mapping over every code-built
level (test level, dust2, procedural arena) with the existing color coding
kept as tints. Readable surfaces at speed instead of flat color boxes;
materials are cached per tint so identical surfaces batch.
- .gdignore + .gitignore the raw downloaded asset packs in addons/ whose
overlong paths broke Godot import scans and spammed git warnings.
- Replaced the rotted FSM test file (invalid call(t) on Callables, stateless
stub nodes, hung forever without quitting) with a real suite: 10 tests
covering state registration, jump bookkeeping, wall-run momentum
preservation and upward-carry cap, per-player dash cooldown (regression for
the old shared static), dash speed stacking, chain soft cap, landing
events, and slide entry momentum. New headless entrypoint:
godot --headless --path . -s res://movement/tests/run_fsm_tests.gd
Co-Authored-By: Claude Fable 5 <[email protected]>