Skip to content

The scene and visibility sets ​

You'll learn: how anything gets drawn, and how to hide information from some players. You'll need this when: you create anything visible, or your game has secrets.

Status: Built (headless, and in the plots dev stack, whose page draws plot entities, cuboid and glTF models and mesh terrain): the scene, components, visibility sets, interest management and the binary snapshots. Not in the live world yet.

If others should see it, it's in the scene ​

The scene is a set of entities with components, replicated to every viewer who's allowed to see them. Nothing replicates unless you write it here.

ts
import { scene } from "@inventery/host";

const torch = scene.create({
  Transform: { pos: [10, 65, 4] },
  Model: { asset: "models/torch.glb" },
  Light: { color: "#ffaa44", intensity: 2, range: 8 },
  Emitter: { particles: "inventery:flame", rate: 4 },
});

scene.setComponent(torch, "Light", { color: "#ff4400", intensity: 4, range: 10 });  // replace one component
scene.setComponent(torch, "Emitter", null);                                          // remove one
scene.remove(torch);

Components are plain data: Transform, Model, Pose, Material, Light, Emitter, AudioSource, Nametag, Collider, Controller, Velocity, Billboard, Lifetime, Custom. See Components.

One lighting. Everything the world draws is lit by the same world lighting as the blocks around it: your entities, cuboid models, glTF meshes and props, mesh terrain and dropped items get the sky light and block light at their position, the time of day, face shading and fog. A mesh in a dark cave is dark, and a torch lights it. Light components are dynamic lights on top.

Visibility sets ​

Every entity (and sound) has a set saying who receives it:

SetWho sees it
"public" (default)everyone: this lobby, and onlookers whose lobby it is (and everyone, if it's the featured lobby)
"lobby"the players in this lobby
{ players: [id, ...] }just those players
"serverOnly"nobody: the server keeps it (a hidden marker your code uses)
ts
// Among Us: only the impostor sees the vent markers
scene.create({ Transform: { pos: ventPos }, Model: { asset: "models/vent_glow.glb" } },
             { visibility: { players: [impostor] } });

// Horror: the scare is only for its target
audio.play("sfx/whisper.ogg", { at: hallway, to: { players: [target] } });
scene.setVisibility(ghost, { players: [target] });

The room filters by set before encoding anything for a viewer. A hacked client can't reveal what it was never sent: this is also your wallhack protection.

One limit: sets hide information, not the place. What someone saw from outside must be what they walk into. Hide the impostor's role, not the building.

Children inherit ​

ts
const ship = scene.create({ Transform: { pos: [0, 80, 0] }, Model: { asset: "models/ship.glb" } });
const flag = scene.create({ Transform: { pos: [0, 4, 0] }, Model: { asset: "models/flag.glb" } }, { parent: ship });

A child's Transform is relative to its parent, and it inherits the parent's visibility.

Shared entities ​

At plot level, { shared: true } puts an entity in the shared base, seen by every lobby:

ts
// plot level: a leaderboard every lobby and every passer-by sees
scene.create({ Transform: { pos: [16, 70, 0] }, Billboard: { text: "Top: Ana (12 wins)", size: 2 } }, { shared: true });

What isn't the scene ​

Reaches onlookers?Use for
sceneyes (public parts)anything visible or audible in the world
ui.*no: per playerHUDs, scoreboards, menus
network.send (channels)no: the lobby's players onlygame logic messages
Custom componentreplicated, drawn by no onedata your client code reads (client code is In progress)

The lint warns when a channel or client code looks like it's carrying visuals.

Rates and detail outside ​

The zones around a player's monument plot: inside, the near ring of about 2 chunks, and far

Players inside get the scene at your tick rate. Onlookers near the plot (about 2 chunks) get it at 10 Hz with simpler poses; far ones at 2 Hz, transforms only. Low-end devices fall back to LODs, impostors, then average colours. Your plot always shows; it just shows simpler.

Next ​

Content tiers.