Spawn props and objects
Spawn meshes from the game's object catalog, move, scale and remove them, and clean them up per virtual world.
A prop is a static mesh from the game’s object catalog (a barrel, a fence, a whole house) that the server spawns and every nearby client builds, late joiners included. Use props for arenas, barricades, decoration and build modes.
const at = player.position;const barrel = Prop.spawn("barrel_a", new Vector3(at.x + 2, at.y, at.z));console.log(`spawned ${barrel}`);That is a barrel two metres east of the player, with default rotation, scale and physics, in the global virtual world.
Spawn a prop
Section titled “Spawn a prop”Prop.spawn takes the model,
then optional positional arguments:
const crate = Prop.spawn( "objects/manmade/barrels/barrel_a.cgf", // model: full path or file stem new Vector3(1024, 512, 40), // position new Vector3(0, 0, 90), // rotation: Euler degrees, or a Quaternion 1.5, // scale, 0.01 to 100 "rigid", // physics: "static", "rigid" or "none" player.virtualWorld, // virtual world);- Model. A full catalog path or its file stem (
barrel_a). A stem shared by several meshes resolves to the first, so use the full path when it matters. The catalog has about 8,500 meshes and the server cannot list them; the client’s World Builder browses it and shows each path. - Your own mesh. A
.cgfa resource ships in itsstream/objects/kcdc/<resource>/folder is named by its full path,objects/kcdc/<resource>/chair.cgf. A player whose game does not have the file yet sees the prop as soon as it arrives. See Custom assets. - Rotation. A
Vector3is Euler angles in degrees, butQuaternion.fromEulerandQuaternion.fromAxisAngletake radians. Mixing the two is the usual cause of a strange angle. See Positions, rotations and vectors (Z is up). - Facing the player. The default gamemode’s
src/server/place.tshas aninFrontOfhelper returning a position and a yaw-only quaternion.
After spawning, prop.model is the full path, prop.modelName the stem and
prop.modelGroup its browsing bucket (manmade/structures, or
kcdc/<resource> for a streamed mesh).
| Physics | Behaviour |
|---|---|
static (default) |
Collides, never moves. |
rigid |
Falls and can be pushed. |
none |
No collision: decoration you can walk through. |
Move or change a prop
Section titled “Move or change a prop”position and rotation are writable, and assigning moves the prop on every
client. physics and scale are writable too, but assigning either
rebuilds the prop everywhere: fine for an editor, not every tick. scale
is clamped into 0.01 to 100. model is read-only; to change the mesh,
destroy the prop and spawn another.
const prop = Prop.getById(42);if (prop) { prop.position = new Vector3(prop.position.x, prop.position.y, prop.position.z + 1); prop.scale = 2; // rebuilds it everywhere}Remove props
Section titled “Remove props”const barrel = Prop.spawn("barrel_a", player.position);
Prop.all(); // every live prop, any virtual world, any resourceProp.getById(barrel.id); // one prop, or nullbarrel.destroy(); // just this oneProp.destroyAll(3); // every prop in virtual world 3; returns the countProp.destroyAll(); // every prop on the serverProp.all() takes no virtual world; filter with
Prop.all().filter((p) => p.virtualWorld === world).
Clean up when your resource stops
Section titled “Clean up when your resource stops”Stopping or reloading a resource does not despawn its props, and
Prop.destroyAll() removes other resources’ props too. Track your own ids:
const RESOURCE = "my-mode";const mine = new Set<number>();
export function place(model: string, at: Vector3, world: number): Prop { const prop = Prop.spawn(model, at, undefined, undefined, undefined, world); mine.add(prop.id); return prop;}
Events.on("resourceStop", (name) => { if (name !== RESOURCE) return; for (const id of mine) Prop.getById(id)?.destroy(); mine.clear();});React to events
Section titled “React to events”| Event | Arguments | When |
|---|---|---|
propSpawn |
prop |
Right after a prop is created and replicated, by any resource or command. |
propDestroy |
prop |
While a prop is despawned. The handle still reads model and position. |
destroyAll raises propDestroy once per prop.
When a call fails
Section titled “When a call fails”| Call | Fails when | Result |
|---|---|---|
Prop.spawn |
The model is not in the catalog, and no running resource streams it. | Throws. Catch it when the name came from a player. |
Prop.spawn |
The physics word is not one of the three. | Check the word yourself before calling, as the gamemode does. |
Prop.spawn, prop.scale |
Scale outside 0.01 to 100. |
Clamped, not refused. |
There is no count limit. Every prop is geometry each nearby client builds, so budget them.
Related
Section titled “Related”- Let players place objects, a client preview before the server spawns
- Build a placement mode, the full build-mode tutorial
- Virtual worlds, how worlds partition what players see
- Raycasts and nearby entities, to find the ground before placing
- Custom assets, to ship meshes of your own
- Prop reference