State carries across sessions.
A multi-session campaign you can chip away at over weeks. Kills stay killed, captured bases stay captured, author flags carry across server restarts.
When persistence makes sense
Persistence is fundamentally a PvE pattern. Pure PvP is one-shot — fight the round, score it, done. The scenarios where persistence delivers real value:
- PvE campaigns — squadron chips away at a fixed enemy IADS / force-package over multiple nights (the canonical use case)
- PvP base-capture — WW2-style front line where captured airbases stay captured between sessions
- Dynamic-faction wars — long-running scenarios with territorial state (think Liberation, but multi-night)
Pure dogfight PvP doesn't benefit — there's nothing to persist between sessions if the round is decided before the server stops.
The squadron-night flow
- Squadron flies the campaign mission Wednesday evening. Three SAMs killed, one airbase captured.
- End of night: drop to a training mission as a “parking spot” so the server stays online but doesn't advance the campaign.
- Saturday morning: load the campaign mission again. The framework finds the prior save, destroys the killed groups, restores the captured-base flag, picks up where Wednesday left off.
- Repeat over weeks. The squadron has an ongoing war they hop into when they have time.
What persists (v1)
- Dead unit IDs — every unit destroyed during the session
- Dead group IDs — when a whole group is wiped, the parent group is recorded too
- Author-range flags 600-899 — captured-base flags, scoring counters, mission-state flags
- Session counter — monotonic, tells you which session this is
What does NOT persist (v1)
- Airborne unit positions (DCS hates re-spawning airborne — they'd come back at home base)
- Per-player kills / scoreboards (defer to v2 once we have player-id tracking)
- Damaged-but-alive units (DCS doesn't expose damage state cleanly)
- SAM ammo counts (DCS doesn't expose magazine state)
How it works under the hood
Every persistent .miz bundles a Fox3Persistence.lua framework that:
- Hooks
S_EVENT_DEADto track destroyed units in real-time - Writes the save file every 60 seconds (heartbeat) and on
S_EVENT_MISSION_END(last-gasp save) - On mission load, reads the save file and calls
Group:destroy()on the units that were dead, sets the saved flag values - Save file format: JSON, atomic write via
.tmp+ rename so a server crash mid-write can't corrupt the save - Save file location:
Saved Games/DCS.openbeta_server/Fox3_Persistence/{mission_id}.json
The mission_id is derived at build time from map + era + scenario + player_composition hash — so if you re-build the same scenario with new fragments, the save file carries over. Different scenarios get different saves automatically.
⚠️ When triggers actually fire
Fox3Persistence loads via a DCS triggerStart rule. These rules fire once the simulation clock actually advances — which on a multiplayer server with pause_on_load = true (the default) means once the first player connects + slots in.
On a single-player editor open, or a server with pause_on_load = false, the trigger fires immediately. On a typical MP server, it fires the moment a real pilot slots in. Once it fires, the framework runs forever (heartbeat + event hooks), even after that pilot leaves — so the save-on-exit still works for a server that goes empty mid-session.
Server requirements
Fox3-fleet servers: nothing to do — your MissionScripting.lua already has os/io unsanitized (needed for SRS-TTS, MOOSE, MIST, etc.). Persistence works out of the box.
Non-Fox3 servers: edit Scripts/MissionScripting.lua in the DCS install — comment out the sanitizeModule('io') and sanitizeModule('os') lines. One-time setup. (Most communities running MOOSE/MIST/CTLD already have this done.)
How to use it
- On /build, expand the Build Options section.
- Toggle Persistent campaign mode.
- Build + download the .miz. Place it in your server's
Missionsfolder. - Load it for your first session. Fly. Save state writes automatically every 60s + at mission end.
- Next session: load the same mission. Watch the dcs.log for
Fox3Persistence: vN.N.N loaded prior save: session 1 -> 2, destroyed K groups, restored M flags.
Resetting a campaign
Delete the save file at Saved Games/DCS.openbeta_server/Fox3_Persistence/{mission_id}.json on the server. Next mission load starts fresh.
Roadmap to v2
- Per-player kill / score persistence (linked to player UCID)
- Web visibility — your /history page shows current campaign state with a map view
- Multi-server snapshot routing — campaign state can move between servers in your fleet
- Auto-rotation — server alternates between campaign + training mission on a schedule
- Discord webhook updates — “Blue captured Senaki at 21:14 UTC”