ServicesBiome

Threshold Alerts

A population carries up to 16 alert bands - named thresholds with a below floor and/or an above ceiling and an optional free-form hook label your game logic can key on. When an authoritative read or a checkpoint advance finds a population inside a band it was not in before, a crossing fires: entered on the way in, cleared on the way out.

Declaring bands

The CLI has no band flags - bands are set on the population over HTTP, at creation (alert_bands on the create body) or later via PATCH (platform admin token; replaces the whole array). Captured live:

curl -X PATCH -H "Authorization: Bearer $SNUG_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"alert_bands":[{"name":"collapse","below":1000,"hook":"spawn_ranger_quest"}]}' \
  http://localhost:4000/api/v1/biomes/<biome_id>/populations/pop_deer
{
  "status": 200,
  "msg": "OK",
  "data": {
    "population_id": "...:pop_deer",
    "slug": "pop_deer",
    "carrying_capacity": 5000.0,
    "checkpoint_size": 4200.0,
    "alert_bands": [
      { "name": "collapse", "below": 1000.0, "above": null, "hook": "spawn_ranger_quest" }
    ]
  }
}

When crossings fire

Only two paths evaluate bands: the authoritative "now" state read (no at_virtual parameter) and a checkpoint advance. What-if reads with an explicit at_virtual never fire alerts, so projections and time-travel stay speculation-free. With the deer herd integrated down to ~892 against a below: 1000 band, advancing the checkpoint returned the crossing in the response:

{
  "band": "collapse",
  "direction": "entered",
  "population_id": "...:pop_deer",
  "size": 892.34,
  "below": 1000.0,
  "hook": "spawn_ranger_quest",
  "at_virtual": 48.0
}

Where alerts go

Every crossing fans out in-process to PubSub, the Timeline event log, and registered webhooks. subscribe (platform admin token) reports the channel names and can provision more:

snug --output json biome subscribe -b <biome_id> --include-websocket
{
  "channel": "biome.threshold.<biome_id>",
  "websocket_topic": "biome:<biome_id>:threshold",
  "registered": false
}
  • channel is the canonical PubSub channel crossings publish to; it exists without any subscribe call.
  • --include-websocket reports the WebSocket topic for realtime clients. The handshake and message protocol are in the API reference.
  • --channel <name> durably registers an extra PubSub channel of your choosing; future crossings fan out to it as well (registered: true).

The published payload is the alert object - the checkpoint alert shape above plus biome_id. See PubSub and WebSocket for consuming channels and topics, and Timeline for the persisted series.

On this page