Add a placeable object
This example adds a configurable sign to the editor. The host saves each placement and handles selection, movement, rotation, and duplication.
Start from vibelands create my-signs --template props-pack, install its dependencies, and keep its generated project setup.
1. Declare the item
Replace the manifest's editorItems array with this value. Keep the other manifest fields, including entries.client.
[
{
"id": "village-sign",
"label": "Village Sign",
"category": "Props",
"properties": { "color": "#7ad7ff", "height": 2 },
"propertySchema": {
"type": "object",
"properties": {
"color": { "type": "string", "title": "Color" },
"height": { "type": "number", "title": "Height", "minimum": 1, "maximum": 4 }
}
}
}
]id connects the manifest to your renderer. Keep it stable after people have placed the item. The saved preset is mod:my-signs:village-sign when your mod ID is my-signs.
2. Draw it in the client entry
Replace the client entry selected by entries.client with:
import { defineModClient } from '@vibelands/mod-sdk/client';
function VillageSign({ properties }) {
const height = Number(properties.height ?? 2);
return (
<group>
<mesh position={[0, height / 2, 0]}>
<boxGeometry args={[0.12, height, 0.12]} />
<meshStandardMaterial color="#6b4933" />
</mesh>
<mesh position={[0, height - 0.25, 0]}>
<boxGeometry args={[1.4, 0.5, 0.12]} />
<meshStandardMaterial color={properties.color ?? '#7ad7ff'} />
</mesh>
</group>
);
}
export default defineModClient({
objectRenderers: { 'village-sign': VillageSign },
});The host applies the placed object's world transform. Draw in local coordinates: y = 0 is the base of this model. Do not apply the world position a second time. This example is visual only; a mesh alone does not add a blocking collider. See editorItems for collider declarations.
3. Preview and place
npm run check
npm run devOpen the printed preview link, then choose Add → Props → Village Sign. Place two signs and edit their properties separately. Rejoin the same preview world to check the saved placements.
Renderer inputs
| Prop | Meaning |
|---|---|
itemId | Local manifest item ID, such as village-sign. |
properties | Settings for this placement, merged with item defaults. |
worldObject | The host's object data for this placement. |
renderMode | world, ghost, or library. |
A renderer is also used for placement previews and library thumbnails. Run interaction, audio, or other gameplay effects only in world mode. Keep React hooks unconditional; gate the work inside the effect or callback.
When to use a WorldLayer
Use objectRenderers for things people place and save. Use WorldLayer for world-wide effects or rendering runtime entities supplied by a server mod. Both surfaces can be registered by the same mod.
Next: Build a world or Client API.