Merge owned systems into one addon while preserving resource identities. Gate player admission on the replicated prison scene, restore the original framed door, and hold enemy AI until escape. Correct scenario branding and author metadata, include publishing assets, and retain regression and native verification evidence.
69 lines
3.1 KiB
Markdown
69 lines
3.1 KiB
Markdown
# T7 — Budget enforcement, metrics and anti-thrash
|
||
|
||
Read `docs/living-island/README.md` first, including the rules section. Depends on T1–T6.
|
||
|
||
## Goal
|
||
|
||
Prove the living island stays inside its CPU budget, and make it obvious when it
|
||
does not. Without this task the rest is a plausible design with no evidence.
|
||
|
||
## What to build
|
||
|
||
1. **A metrics surface.** `addons/core/Scripts/Game/ERR/ERR_ForceMetrics.c`:
|
||
|
||
- active agents, physical records, dormant records, refused spawns
|
||
- state flips in the last minute (the thrash indicator)
|
||
- simulation tick duration, presence tick duration (min / mean / max)
|
||
- budget headroom, and how long the budget has been saturated
|
||
|
||
Expose through the existing admin menu and `ERR_HQ.Event` journal (ai side).
|
||
Reuse `ERR_AdminProvider`; do not build a new UI.
|
||
|
||
2. **Thrash guard.** If any record flips state more than twice per minute, widen
|
||
that record's hysteresis bands automatically and log it. Repeated flipping is
|
||
the failure mode that turns this design from a saving into a cost.
|
||
|
||
3. **Saturation policy.** When the budget stays full for more than 60 s, shed
|
||
load in a defined order and log each step:
|
||
`ambient (T6)` → `distant patrols` → `checkpoint garrisons beyond 1.5 km` →
|
||
never shed: objective garrisons, HQ-pinned records, anything in combat.
|
||
|
||
4. **Tick cost discipline.** Measure the simulation and presence ticks. If either
|
||
exceeds its allowance (2 ms simulation, 3 ms presence) for 5 consecutive
|
||
ticks, halve the records processed per tick by increasing the stagger, and log.
|
||
Degrade smoothly rather than stuttering.
|
||
|
||
5. **A measured comparison.** Extend the existing performance-comparison tooling
|
||
(`docs/performance-comparison.md`) with a living-island run: same route, same
|
||
duration, ledger enabled versus disabled. Record active agents and frame time.
|
||
This is the number that decides whether the design worked.
|
||
|
||
## Acceptance criteria
|
||
|
||
1. A 20-minute session with a player driving the full route keeps active agents
|
||
at or under `activeAgentBudget` at every sample.
|
||
2. Total state flips across all records stay under 2 per minute on average.
|
||
3. Simulation and presence ticks stay inside their allowances at 128 records.
|
||
4. The shed order is observable in the journal when the budget saturates.
|
||
5. The comparison run is recorded with real numbers, and the write-up states
|
||
plainly whether frame time improved, stayed flat, or regressed.
|
||
6. `python3 tools/check.py` passes.
|
||
|
||
## Tests to write
|
||
|
||
`tests/test_force_metrics.py`:
|
||
|
||
- The thrash guard widens bands after the third flip inside a minute.
|
||
- The shed order never selects a pinned, in-combat or objective record, even when
|
||
everything else has already been shed.
|
||
- The tick-cost governor increases stagger after 5 consecutive overruns and
|
||
restores it after sustained headroom.
|
||
|
||
## Reporting rules
|
||
|
||
Follow the repo's evidence discipline. State which numbers came from a real
|
||
Workbench or server run and which came from scripted fixtures. If the comparison
|
||
was not run in the real game, say so in the write-up rather than implying it was.
|
||
A regression that is reported honestly is more useful than an improvement that is
|
||
not reproducible.
|