occluder.fbs — the disclosed occluder set
Source: modules/Descent.Vtt.Protocol/schemas/occluder.fbs at build time. 12 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.
// The disclosed occluder set — walls, on the wire (§9.2, ADR-034).//// Read schemas/README.md first; its three rules are assumed here.//// **Why occluders travel at all, when visibility does not.** ADR-034 makes line of sight// strictly server-authoritative and the client's fog a *presentation* of the authoritative// mask. That does not make geometry itself secret: §9.2 puts "own-entity movement prediction// and collision preview over geometry the acting client has been disclosed" explicitly IN// scope. A client needs walls to predict a move that will not walk through one; it does not// get them in order to compute what it can see.//// **The set is per viewer and it is a subset, always.** §9.2: entities the server has not// disclosed are "absent from the client's data set entirely; they are never// present-but-culled, because a culling shader is one patched line away from being// disabled". The same rule governs this message — an undisclosed wall is not sent with a// flag, it is not sent. That is what keeps the client's A* a *preview* rather than an answer.//// **A secret door is the case that decides the shape of this file.** If the server sent// every wall and let the client hide some, a player could read the concealed geometry out of// their own memory. So the filter runs server-side, before the encode, and this schema has// no field a client could use to reconstruct what was withheld — no total count, no// identifiers with gaps, no bounding box of the full set.
namespace Descent.Vtt.Protocol;
/// One wall segment, in raw fixed-point (i32.16), exactly as ADR-017 requires.////// A **struct** rather than a table: it is four fixed scalars with no optional member, so/// the vector below is a flat inline run of 16-byte records with no vtable and no offset/// indirection per element. A table here would cost a vtable lookup per wall on a path that/// reads every wall on every disclosure change.////// The ordinates are Q16.16 and never floating point, so both hosts agree bit-exactly —/// neither ever sees an f32.struct OccluderSegment { ax: int32; ay: int32; bx: int32; by: int32;}
/// Server -> client. The occluder set this viewer is permitted to hold.////// **Whole-set replacement, never a delta.** Walls change when a map is authored or a door/// opens — rarely, and never at tick cadence — so the bandwidth argument for a delta does not/// arise. What does arise is the correctness argument against one: a delta stream over a/// *filtered* set has to express "this wall left your set", and whether it left because it/// was deleted or because it stopped being disclosed is precisely the distinction that leaks./// Replacing the set says nothing about why it changed.table OccluderSync { /// §9.6: every packet carries this, field id 0. protocol_version: uint32;
/// Monotonic per room. Lets a client discard a sync that lost a race with a newer one. /// /// **Not a tick.** Occluders are not tick-driven and pinning them to the tick sequence /// would imply a cadence they do not have. It orders two syncs against each other and /// nothing else. revision: int64;
/// The disclosed walls. **Empty is a legitimate answer** meaning "you have been disclosed /// no geometry", and a client must treat it as such rather than as a failed load. segments: [OccluderSegment];}
root_type OccluderSync;
/// Identifies an occluder buffer on disk or in a capture.file_identifier "DVO1";