Skip to content

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.

json
[
  {
    "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:

jsx
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 ​

bash
npm run check
npm run dev

Open 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 ​

PropMeaning
itemIdLocal manifest item ID, such as village-sign.
propertiesSettings for this placement, merged with item defaults.
worldObjectThe host's object data for this placement.
renderModeworld, 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.

VibeLands Creator · Runtime API v2