Feature 01 / FF Horror
The missionfeels you
No canned jump scares. Every client reports who is aware, where the shots came from and how close the horde is. The server turns that into a 0–100 threat score, picks a mood and keeps one music timeline for every player in the session.
aware enemies + shots · 0–100
Fades never snap: at least 10 s out, 10 s in.
Illustrative readout. The real numbers are live: Zeus footer, debug panel or FFATM_* state.
What it reads
Three inputs. One number.
Clients scan nearby Man entities inside 120 m every two seconds. The server ignores reports
older than eight seconds and reports from dead players, so a stale client cannot pin the session in combat.
Aware enemies
Enemy units on the configured sides, weighted per zombie class and filtered by knowsAbout.
The default threshold is 1.5.
Raw count and weighted danger are both visible to Zeus.
Gunfire
FiredMan and FiredNear fill a rolling shot window. Sustained fire near OPFOR adds a
separate gunfire charge of up to 35.
Shooting alone can raise tension; it cannot start combat.
Players nearby
Each player's report is evaluated separately and the strongest encounter wins — never the sum. Nearby players scale the pressure so a crowd does not multiply threat.
A squad spread across a town is not one giant encounter.
Mood machine
Quiet → tension → combat
Thresholds have hysteresis, so a score hovering on a boundary does not flap between tracks. A steep rise can enter tension early, and a large aware horde with heavy shooting can jump straight to combat.
| Transition | Threshold | Result |
|---|---|---|
| Quiet → tension | 25 | Track fades out over 10 s, the new one fades in over 10 s |
| Tension → quiet | below 10 | Pressure released, not cut |
| Tension → combat | 75 | Combat pool takes over |
| Combat → tension | below 40 | Descending fade, at least 10 s |
| Combat exit | ~8 s without OPFOR | Combat cannot loop on a single straggler |
Playback
One timeline. Late joiners included.
Shared offset
The server publishes mode, track, source, volume and a start timestamp. Clients measure the track and seek to the correct offset, so someone joining mid-song hears the same part as everyone else.
Overlays follow the same mood
The server mood also drives FF_Overlay2_fade on each client. Pressure becomes something you can see,
not only hear. Mission scripts can still write the overlay values directly.
Priority and horde cues
Priority tracks, forced moods with durations and horde cues are server state. Two Zeus clients cannot disagree about what is playing.
Soul takes precedence
Death stops local music; the shared track returns two seconds after a living West character is stable.
FFATM_soulActive is the explicit hook for other soul systems.
Author it
Drop in your own music. Keep the machine.
extraTracks appends to the 15-track catalog instead of replacing it, and moodPools
remaps which keys belong to quiet, tension and combat. Mission-owned intros and outros keep working.
FF_horror_atmosphereConfig = createHashMapFromArray [
["extraTracks", [["myIntro", "My intro", "MyIntroMusic", 128, 0.8]]],
["moodPools", createHashMapFromArray [["combat", ["pressure_02", "myIntro"]]]],
["playerSides", [west]],
["enemySides", [east]],
["knowledgeThreshold", 1.5]
];
Dependency: WebKnight (WBK) Zombies. FF Horror does not ship zombie units. FFATM_fnc_zombieProfile
maps a class to a threat weight and urgency radius; override it for another zombie pack.
Feature 01 / 08 Every system deep dive