Skip to main content

Entities

Entities are Dreamlab's fundamental game objects—similar to Unity GameObjects or Godot Nodes.
They

  • own a Transform (position / rotation / scale / z-layer)
  • can nest to form a hierarchy
  • gain behavior through attached Behavior scripts
  • sync automatically when placed under the shared world root

Entities are usually added from the editor's right-click menu:

Spawn entity menu

1. Quick start - spawning by script

Create a brand-new entity

// Spawn an Empty into the shared world root
const pivot = this.game.world.spawn({
name: "Pivot",
type: Empty,
transform: { position: { x: 4, y: 1 } },
});

Clone a prefab at runtime

// “Crate” lives under prefabs/
// cloneInto returns the new instance
const crate = this.game.prefabs._.Crate.cloneInto(this.game.world, {
name: "Crate." + crypto.randomUUID(),
authority: this.game.network.self, // I control this crate
});
crate.pos.set(2, 0);

cloneInto() duplicates the entity (plus all children & behaviors) and registers it in the target root.


2. Core concepts

FeatureWhat / Why
RootsDecide where an entity exists. See the Scenes & Roots page.
BehaviorsAdd logic to the entity. See the Behaviors page.
AuthorityPeer that owns simulation authority → entity.authority or takeAuthority().
EventsPub-sub events such as EntityDestroyed, EntityChildSpawned.
ValuesStrong-typed, optionally replicated props. See the Synced Values and Adapters page.
Transform APIentity.transform or shortcuts entity.pos, entity.z.

Accessing entities by name

root._.<Name> gives you a quick reference to any direct child under a root:

const cam = this.game.local._.Camera; // generic Entity

The proxy returns an untyped Entity, so if you want type-specific methods (e.g. Camera.zoom), cast it:

// get the local camera with full IntelliSense
const cam = this.game.local._.Camera.cast(Camera);

cam.zoom = 2; // Camera-only API

Dot-path chains work for grandchildren too:

// Prefab » Player » Health
const health = this.game.prefabs._.Player._.Health.cast(RichText);
health.text = "HP: 100";

Names with spaces or symbols- If the entity's name isn't a valid JavaScript identifier (contains spaces, hyphens, etc.) use bracket access:

// Entity is literally named “My Entity”
const ent = this.game.world._["My Entity"];

The lookup throws if the child name is wrong, so check your spelling against the scene graph panel.


3. Entity catalog (common types)

note

This table is a quick reference—open the editor for the full, up-to-date list.

General

EntityPurpose
AudioSourcePlay sounds (optionally positional).
CameraViewport controller—see the Camera page.
CharacterControllerCapsule collider with built-in movement checks.
ClickableEmits a signal when clicked.
ColliderBasic physics collider.
ComplexColliderPolygon collider formed by 3 + child empties.
EmptyTransform only—good for markers, parents, manager scripts.
RichTextDraw PIXI rich text in-world.
RigidbodySimulated physics body; attach one or more colliders.
TilemapCreate Tilemaps using a predefined tileset

Sprites

EntityPurpose
AnimatedSpriteJSON spritesheet playback with speed / frame control
SpriteDraw a single image
TilingSpriteSprite that tiles its texture

UI

EntityPurpose
UILayerFull-screen DOM tree—ideal for HUDs
UIPanelDOM tree fixed in world space (nameplates, signs, etc.)

Graphics

EntityPurpose
RawPixiAdvanced: draw via PIXI Graphics API
ColoredSquareSolid-color rectangle
ColoredPolygonSolid-color regular polygon

4. Common entity events

Dreamlab uses events for entity lifecycle—subscribe with entity.on(Event, handler).

EventFires when…
EntitySpawnedthe entity is first created (constructor done)
EntityDestroyedthe entity is about to be removed
EntityChildSpawneda direct child is added
EntityDescendantDestroyedany level of descendant gets destroyed
EntityRenamedentity.name changes
EntityReparentedentity.parent changes
EntityEnableChangedthe effective enabled state toggles

5 · Entities

note

This is a quick reference—open the editor for the full, up-to-date entity list.

🔊 AudioSource

Howler.js under the hood—handles both UI SFX and positional audio.

ValuePurpose
clipPath to OGG / MP3 / WAV.
volume0 … 1
loopLoop forever.
minRangeDistance (m) before attenuation starts.
maxRangeMax audible distance; -1 = infinite.
falloff0 … 1 how quickly volume drops off.
streamStream large music tracks vs. preloading.
const sfx = this.entity.cast(AudioSource);
sfx.clip = "res://sfx/hit.ogg";
sfx.play();

🎥 Camera

Reference

Detailed documentation is available on the Camera page.

The Camera is a local-only entity that controls what the player sees.

Key valuePurpose / default
active (bool)When true, becomes the current viewport. Only one Camera can be active at a time.
zoom (number)1 = 1 unit ≈ 1 metre on screen. Higher zooms in.
smooth (seconds)How long interpolation takes to catch up to the real transform. 0 = no smoothing.
lockAspectRatioLock vertical / horizontal FOV, e.g. [16, 9].
scaleFilterMode"nearest" or "linear"—overrides PIXI scale mode for crystal-clear pixel-art.

🚶 CharacterController

Reference

Detailed documentation is available on the Physics page.

Kinematic platformer-style movement.

APIDescription
.isGrounded (getter)true when touching the ground.
.correctedPositionPosition after resolving collisions.
.teleport = trueSkip collision check on the next frame.
const ctrl = this.entity.cast(CharacterController);

if (ctrl.isGrounded && this.inputs.getKey("Space")) {
ctrl.pos.y += 3; // jump impulse
ctrl.teleport = true; // skip one collision frame
}

👆 Clickable

Creates an invisible hit-box that turns any entity into a UI button or trigger.

Value / getterDetails
activeDisable to ignore cursor & clicks.
shape"Rectangle" (default) or "Circle".
width / heightRectangle size in metres. (Only when shape = "Rectangle")
radius / innerRadiusOuter & inner radii for ring-style targets. (Only when shape = "Circle")
clicked (getter)true while the mouse button is held down over the entity.
hover (getter)true when the cursor is inside the bounds.

Note — Clickable automatically changes the game canvas cursor to a pointer when any active Clickable is under the mouse.


🧱 Collider

Reference

Detailed documentation is available on the Physics page.

A Collider is a shape the physics engine can query.
Attach to a Rigidbody or leave loose as a static trigger.

Key valuePurpose
shape"Rectangle" | "Circle" (capsule WIP)
isSensortrue → overlap events only; no collisions.
massUsed only if parented to a Rigidbody.

🧱 ComplexCollider

Reference

Detailed documentation is available on the Physics page.

A concave (multi-polygon) collider built from its children’s positions.
Perfect for arbitrary terrain outlines.

ValuePurpose
isSensorTrigger only, no physical response.
massUsed if parented to a Rigidbody.

How it works

  1. Sorts direct children (Child.0, Child.1, …).
  2. Runs poly-decomp to split into convex pieces.
  3. Creates one Rapier collider per piece (auto-updates on transform / re-parent).

Tip: Keep the child points roughly in order (clockwise or CCW) for best results.


📦 Empty

An entity with only a Transform.
Use it as a pivot, folder, or to attach scripts that don't need graphics / physics.


🔡 RichText

Renders a PIXI Text with full CSS-like styling.

ValueDetails
textPlain string or BBCode (coming soon).
fontFamilyAny web-safe or imported font (async-loads on first use).
fontSizeIn pixels. Remaps to metres via entity scale.
fontStyle"normal" | "italic"|"oblique"`.
fontWeight"bold" or numeric 100900.
align"left", "center", "right" (auto-sets anchor).
colorFill colour.
strokeToggle outline; reveals strokeColor, strokeWidth, strokeJoin.
scaleFilterMode"default" → inherit Camera; otherwise "nearest" / "linear".
const label = this.game.local._.ui.spawn({ name: "label", type: RichText });
label.text = "FPS: 60";
label.fontSize = 24;
label.color = "#00ff00";
label.stroke = true;
label.strokeColor = "black";

⚙️ Rigidbody

Reference

Detailed documentation is available on the Physics page.

Creates a Rapier RigidBody and re-parents all child Colliders automatically.

ValueDescription
type"dynamic" (default) or "fixed".

🗺️ Tilemap

Reference

Detailed documentation is available on the Tilemap page.

A grid of palette IDs rendered via an atlas. Great for terrains & dungeons.

Handy methodWhat it does
setTile(x, y, paletteId?)Draw / erase a cell (undefined = erase)
getTile(x, y)Return TileData or undefined.
getTileAtPoint(worldPos)Ray-cast the cursor to a tile.
clearTiles()Erase everything.
tiles() (generator)Iterate { x, y, tile } of filled cells.

🖼️ AnimatedSprite

Plays frames from JSON spritesheets or chops a grid into frames on the fly.

ValueDetails
jsonSpritesheetPath to .json exported by Aseprite / TexturePacker.
spritesheetPlain PNG; sliced by frameDimensions.
speedFrames per second (default 0.1).
startFrame/endFrameClamp playback range; endFrame = -1 ➜ to last frame.
loopWhen false, stops on last frame.
const anim = this.entity.cast(AnimatedSprite);
anim.spritesheet = "res://run.png";
anim.frameDimensions.set(128, 128);
anim.speed = 0.2;

🖼️ Sprite

Draw a single texture, with optional letter-box preserve-aspect.

ValuePurpose
textureImage path. Empty ⇒ white 1 × 1 pixel.
width / heightTarget size in metres.
preserveAspectRatiotrue ⇒ maintains original proportions (letterbox).
tint / alphaStandard PIXI tint & transparency.

🖼️ TilingSprite

Repeats a texture infinitely—ideal for parallax backdrops, water, conveyor belts…

ValueDetails
textureTile image.
tilePositionScroll offset—animate for parallax.
tileScalePer-axis scaling before fit into entity width/height.
tileRotationRotation of the pattern in radians.
width / heightDrawn size in metres.
tint / alphaStandard PIXI properties.
const water = this.game.local._.MyTilingSprite.cast(TilingSprite);
water.onFrame = () => water.tilePosition.x += 0.02; // gentle flow

🎨 UILayer

Reference

Detailed documentation is available on the User Interface page.

Full-screen DOM overlay—great for HUDs, menus, or drag-and-drop editors.

  • Lives in its own Shadow DOM to avoid CSS bleed.
  • Pointer-events are disabled by default; enable per-element.
  • dom → ShadowRoot, element → root <div> inside the layer.

Position & scale follow the canvas, not the world.


🎨 UIPanel

DOM anchored to an entity in world space (nameplates, shop signs, speech bubbles).

FeatureHow it works
Screen lockRe-projects each frame via Camera.worldToScreen().
Transform awareHonors entity position/rotation/scale (plus Camera zoom).
Shadow DOMSame isolation as UILayer.

🖌️ RawPixi

Reference

Detailed documentation is available on the Rendering with Pixi page.

Low-level access to PIXI—attach your own Graphics / Sprite objects.

const raw = this.game.local.spawn({ name: "graphic", type: RawPixi });

// Draw a circle each frame
raw.onFrame = function () {
if (!this.container) return;
const g = this.container.getChildAt(0) as PIXI.Graphics ?? new PIXI.Graphics();
if (!g.parent) this.container.addChild(g);

g.clear().circle(0, 0, 0.5).fill("hotpink");
};

RawGraphics is an alias kept for legacy scenes; new projects should use RawPixi.


🟩 ColoredSquare

Simplest possible PIXI rectangle.

ValueDetails
width / heightSize in metres
colorFill colour
tintTint multiplier
const box = this.game.world.spawn({ name: "square", type: ColoredSquare });
box.width = 5;
box.height = 0.5;
box.color = "#ffffff";

🟢 ColoredPolygon

Draws a filled n-gon directly in PIXI. Great for quick proto art or hit flashes.

ValueDetails
sides3 – 1000 edges.
width / heightSize in metres (scales with entity transform).
colorFill colour (#rrggbb, rgba(), or CSS name).
tintPost-multiply tint (palette swaps / hit-flash).
const poly = this.game.local.spawn({ name: "hexagon", type: ColoredPolygon });
poly.sides = 6; // hexagon
poly.width = poly.height = 2;
poly.color = "#ffcc00";
poly.tint = "#ff8800";