ContainerCostMeter
What each container this worker leases is actually costing it, measured rather than guessed: the NetworkTick time spent on its entities, the replication bytes they put on the wire, and the owner state a gateway has to relay for them.
Nebula · Packages/com.1by3.nebula/Runtime/Worker/ContainerCostMeter.cspublic sealed class ContainerCostMeterWhat each container this worker leases is actually costing it, measured rather than guessed: the NetworkTick time spent on its entities, the replication bytes they put on the wire, and the owner state a gateway has to relay for them. The numbers go out with the worker's telemetry document (WorkerTelemetry) as one row per container and end up in ContainerCost.
The accumulators live on Container itself, so the hot paths (once per authoritative entity per tick) add to a field instead of hashing a container id. The meter keeps the list of containers it has touched since the last sample so it can clear exactly those. Nothing here allocates once the world is warm.
Design record: docs/cost-telemetry.md. The attribution is exact for what it covers and covers only what a container's own entities caused: the rest of a tick (physics, the interest pass, the publish loop, the engine's own frame work) belongs to no container and is deliberately left out.
Fields
MinTicksPerSample
public const int MinTicksPerSample = 10;The fewest simulated ticks a window must hold to be a reading. A window with fewer is not closed: its counts carry into the next one and Latest keeps the previous reading. The first telemetry beat after a worker starts can hold a single tick that spawned everything the worker was handed; read on its own, that one tick says the container costs more than a whole tick budget, which the orchestrator publishes as "at capacity" and the gateway refuses joins on (docs/cost-telemetry.md D13).
Properties
Latest
public IReadOnlyDictionary<string, Rate> Latest { get; }The latest sample, by container id ("" for entities in no container). Replaced by Sample.
Ticks
public int Ticks { get; }Simulated ticks counted into the current window.
Methods
CountTick
public void CountTick();One simulated tick has begun; called from the worker's tick so a sample can be per tick.
AddSimulation
public void AddSimulation(Container container, long stopwatchTicks);Charge stopwatchTicks of NetworkTick time to container.
AddReplication
public void AddReplication(Container container, long bytes);Charge bytes of worker-to-gateway replication to container.
AddGateway
public void AddGateway(Container container, long bytes);Charge bytes of per-client relay traffic (owner state) to container.
Sample
public void Sample(float now);Turn everything counted since the window opened into per-tick and per-second rates in Latest, and start a new window. now is a monotonic clock in seconds; the first call only establishes the baseline. A window with fewer than MinTicksPerSample ticks stays open (see there). Main thread, outside the tick.
Of
public Rate Of(string containerId);The sample for a container id, or all zeroes when it has not been measured yet.
Nested types
Rate
public struct RateOne container's costs since the last sample, as the telemetry document reports them.
Fields
TickMs
public float TickMs;Milliseconds of NetworkTick per simulated tick.
BytesOutPerSec
public long BytesOutPerSec;Bytes per second of world state, netvars and sync state, counted once per receiving gateway.
GatewayBytesPerSec
public long GatewayBytesPerSec;Bytes per second of owner state (one client each, relayed by its gateway).