Overview
A feature flag is a named, typed value you flip in the dashboard. A live server picks it up without a restart.Server Exports
Read every flag, refresh on demand, react to changes
Client Exports
Synchronous reads from replicated state
Runtimes
Your server holds the API key, so it receives every flag. A
server flag is never published to clients, and reads on the client behave exactly like a flag that does not exist — so a secret cannot reach a player by accident.
How values move
1
The server fetches
nocloud polls the configuration endpoint with the ETag it already holds.2
The server publishes
Only the
shared values are written to GlobalState under
nocloud_flags (configurable).3
Clients read locally
The game replicates the state bag on its own, so a client read is a local
lookup — no round trip, no request, safe inside a tick.
What costs a request
Nothing is fetched until a flag is read. A server whose players never read a
flag makes one request in its life — at the first start after installing, so
clients are not left reading an empty state bag.
Server-side reads serve from memory for
cache_ttl_seconds and go to the API when that has passed, so a read is usually free and never more than one request per window. They never start a background loop — a read refreshes itself.
The cache window bounds the polling loop too: a tick that lands on a configuration still inside it skips rather than spending a request to be told nothing changed. A read and a poll are the same fetch, so whichever happens first covers the other.
Why polling exists
Clients read replicated state, which the server can neither see nor refresh on demand. So a client that is reading says so: the flags are refetched everypolling.interval_ms from that point, and stop when the last such player disconnects or goes quiet.
A client unsubscribes itself after five minutes without a read and resubscribes on the next one, so a player who checked one flag on spawn does not hold the server to polling all session. Reading in a tick sends nothing — the signals are two empty events at the edges, and they never carry values.
Surviving a restart or an outage
The last values received are kept in resource key/value storage whenflags.persist_last_known is on (the default). A restart serves them straight away, and an unreachable API never empties them.
These values are marked stale until a fetch replaces them — exports.nocloud:AreFlagsStale() tells you which you are reading.
Configuration
See Configuration for every setting:enabled, cache_ttl_seconds, global_state_key, persist_last_known, and the polling block.
