Skip to content

Implement a deterministic spawn-zone population controller #79

Description

@zoeyrose

Outcome

Implement a pure deterministic domain controller that turns compiled spawn-zone
policies plus explicit simulation inputs into bounded population and pack
requests.

This issue owns target calculation, live/reserved accounting, token refill,
role-constrained pack planning, scheduling, and decision diagnostics. Entity
creation, placement, persistence integration, and offering activation are
separate native sub-issues.

Controller contract

Use integer/fixed-point math and explicit inputs:

target threat = bounded curve(authored difficulty, world scalar,
                              captured instance challenge,
                              debounced eligible-player count)
accounted threat = alive threat + reserved threat
deficit = max(0, target threat - accounted threat)
available spend = min(deficit, capped refill tokens)
  • Inject simulation clocks and a purpose-specific seeded RNG stream. Stable
    content coordinates, initial state, seed, deadlines, and player inputs must
    reproduce the same ordered decisions and digest.
  • Evaluate due zones in stable (deadline, map instance, zone ID) order under
    per-tick zone, search-step, request, entity, and world budgets. Do not create
    a goroutine/timer per zone or entity.
  • Debounce player eligibility and use hysteresis for target transitions.
    Scaling down pauses requests; it never destroys or mutates living monsters.
  • Refill through a bounded token bucket with an authored base cadence and burst
    cap. Idle/unloaded zones cannot accumulate unlimited spend.
  • Filter candidate eligibility before weighting. Use bounded stable-order
    search to satisfy required roles before optional roles and specialists; no
    unbounded rejection sampling.
  • Reserve both entity and threat cost before publishing a pack request. Typed
    commit/cancel outcomes release a reservation exactly once.
  • Define explicit decisions such as inactive, population-full, budget-empty,
    no-valid-pack, requested, deferred-overload, and invalid-generation.
  • Operational metrics may observe decisions but never feed the gameplay
    formula. Do not use gear, level, death rate, kill speed, health, or telemetry
    as hidden adaptive inputs in this version.

Acceptance criteria

  • The same versioned fixture, initial controller state, seed, clock, and
    ordered inputs produces the same requests, events, and state digest over
    repeated runs.
  • Alive plus reserved entity/threat cost never exceeds zone, map/partition,
    or world caps under concurrent deaths, cancellations, target changes, and
    stale callbacks.
  • Target/refill behavior converges with bounded hysteresis for difficulty,
    world scalar, instance challenge, and eligible-player transitions and
    cannot oscillate or burst after a long idle period.
  • Role-constrained selection finds a valid bounded pack or returns a typed
    reason in bounded work; expensive leaders/casters consume more budget than
    ordinary members.
  • Scaling down never removes active actors solely to meet the new target.
  • Queue saturation and tick-budget exhaustion defer deterministically with
    backpressure rather than dropping ownership or spinning.
  • Domain code has no filesystem paths, legacy syntax, toolkit/Rust types,
    SQLite rows, protocol messages, mutable globals, telemetry inputs, or
    goroutine ownership.
  • Property/replay tests cover zero/full population, min/max bounds,
    overflow, impossible packs, reservation races, cancellation, stale
    generations, player-count flapping, deadlines, overload, and shutdown.
  • Dense-zone benchmarks establish CPU, allocation, queue, and memory budgets
    and an offline fake-time report exposes expected target/pack/refill
    distributions without a network or display.
  • tools/validate.sh and git diff --check pass.

Dependencies and parallel work

Native sub-issue:

Depends on the compiled encounter fixture plus
server#32,
server#36,
server#37,
server#38, and
server#41. It can begin as a pure
package against synthetic immutable fixtures while map/entity/persistence
adapters land. Reuse #47 for deterministic scenario/replay conventions.

Independent implementation

New Go code and tests are fresh MIT work. Classic behavior may inform an
externally written product specification, but Classic GPL code/tests are not
copied or mechanically translated.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Fields

    No fields configured for Initiative.

    Projects

    Status
    Inbox

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions