Skip to content

fog.fbs โ€” the fog-of-war mask

Source: modules/Descent.Vtt.Protocol/schemas/fog.fbs at build time. 4 line(s) withheld โ€” internal regions exist in the source and are removed by the scrubbing pipeline; that they exist is public, their content is not.

// ADR-092 clause 3's out-of-band fog mask message.
//
// Read schemas/README.md first; its three rules are assumed here.
//
// **Why this is not on the snapshot.** Q-010 fixes a packed chunk at 16 KiB.
// Riding the tick-driven snapshot, one chunk alone is ~320 KiB/s per viewer at
// Q-001's 20Hz โ€” more than fifty times the entire transform payload it would be
// attached to. Its cadence is already governed separately by the
// Q-068โ€ฆQ-071 ladder, so bundling it would silently re-couple two cadences ยง5.3
// deliberately separates.
//
// **The filter here is different in kind from the snapshot's.** A snapshot
// filter answers "may this viewer see this entity". A mask *is* the disclosure:
// the question is which party's explored set this viewer belongs to, and the
// answer is never "all of them merged". ADR-091 clause 6 is the constraint โ€” a
// mask set exists for a party that receives one, and per-viewer masks were
// rejected because fifty independent masks were never affordable at any tier.
namespace Descent.Vtt.Protocol;
/// One chunk of fog, as a single party is permitted to see it.
///
/// The bytes are Q-010's packed form **as persisted** โ€” `VISIBLE` already
/// stripped, per ADR-035 โ€” so a host cannot store what it was handed and
/// resurrect a stale lit set.
table FogChunk {
/// Cell coordinates of the chunk's origin corner.
origin_x: int32;
origin_y: int32;
/// Q-010's packed chunk: 256x256 cells at 2 bits each, 16 KiB.
///
/// A vector rather than a fixed-size struct because FlatBuffers has no
/// fixed-length byte array outside a struct, and a 16 KiB struct would be
/// copied by value at every accessor.
packed: [ubyte];
}
/// What one viewer is sent when their party's fog advances.
///
/// **Event-driven on the mask cadence, not the tick.** The Q-068โ€ฆQ-071 ladder
/// decides when a party's mask advances; this message follows that and not
/// Q-001. A viewer whose party has not advanced receives nothing rather than a
/// repeat of what they already hold.
table FogUpdate {
/// ยง9.6: every packet carries this.
protocol_version: uint32;
/// The tick the mask was computed for.
///
/// Distinct from the snapshot's `transform_tick` and routinely behind it: the
/// tick is pipelined, geometry is dispatched fire-and-forget and consumed a
/// tick later. A client gates rendering on the older of the two, which is what
/// `PerViewerSnapshot.disclosure_tick` carries.
mask_tick: int64;
/// The chunks this viewer's party is permitted to hold.
///
/// **Already filtered**, and the filter is party membership rather than
/// entity entitlement. A viewer belonging to no party with an observer
/// receives an empty vector โ€” never another party's mask, and never a merge.
chunks: [FogChunk];
}
root_type FogUpdate;
/// Identifies a fog buffer on disk or in a capture.
file_identifier "DVF1";