Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Control GORNA adaptation

This guide shows you how to pin or bound an agent’s adaptation from game or host code, so GORNA’s automatic strategy switching stays within limits you choose — and how to record and replay the decisions it makes.

Prerequisites: you have read GORNA.

This is the developer-control surface over the adaptive core: the DCC observes and proposes, but you decide how much latitude it has. A safety stop can still force the lowest strategy in any mode — safety overrides developer control.

Step 1 — Choose an AdaptationMode

AdaptationMode sets how much freedom GORNA has for one agent:

ModeBehaviour
Learning (default)Full negotiation — GORNA freely picks the best-fitting strategy each tick.
Manual(StrategyId)Pinned — the agent stays on the given strategy; GORNA observes but never switches it.
StablePredictable — GORNA may downgrade under budget pressure but never makes an opportunistic upgrade, so the strategy doesn’t flap.
Bounded { min, max }Learning within limits — the chosen strategy is clamped to [min, max] (LowPower < Balanced < HighPerformance; Custom ranks above HighPerformance).

Step 2 — Apply it through DccService::set_adaptation_mode

Call set_adaptation_mode on the DccService with the target AgentId and the mode. It is thread-safe and takes effect on the next arbitration tick.

#![allow(unused)]
fn main() {
use khora_core::control::gorna::{AdaptationMode, AgentId, StrategyId};

// Pin the renderer to LowPower (e.g. on battery): GORNA will not upgrade it.
dcc.set_adaptation_mode(AgentId::Renderer, AdaptationMode::Manual(StrategyId::LowPower));

// Or let physics learn, but never below Balanced and never above HighPerformance:
dcc.set_adaptation_mode(
    AgentId::Physics,
    AdaptationMode::Bounded {
        min: StrategyId::Balanced,
        max: StrategyId::HighPerformance,
    },
);

// Or stop quality from flapping for the UI agent:
dcc.set_adaptation_mode(AgentId::Ui, AdaptationMode::Stable);
}

To return an agent to full autonomy, set it back to AdaptationMode::Learning.

Step 3 — (Optional) record and replay decisions

GORNA arbitration is deterministic (no RNG), so recording the strategy issued to each agent each tick and replaying it reproduces a session’s adaptation bit-for-bit — useful for QA, network lockstep, and bug reproduction.

#![allow(unused)]
fn main() {
// Start capturing per-tick decisions into a fresh trace.
dcc.start_decision_recording();

// … run the engine …

// Stop and take the captured trace (a `DecisionTrace`).
let trace = dcc.stop_decision_recording();

// Later: replay it. Each tick re-issues the recorded strategies in order,
// bypassing live fit and AdaptationMode, until the trace is exhausted.
dcc.replay_decisions(trace);

// Return to live arbitration at any point.
dcc.stop_replay();
}

recorded_decisions() returns a snapshot of the trace captured so far without stopping recording.

Step 4 — Verify it works

cargo test --workspace

With recording on, drive a few ticks, replay the captured trace, and assert the issued strategies match the original run. To confirm a mode took effect, read the agent’s reported current_strategy and check it respects the bound you set.

  • GORNA — the negotiation protocol and strategy fitting.
  • Add an agent — the agent whose adaptation you are controlling.