Understand the SDK
Mods use the public SDK contract apiVersion 2.
A mod is a small package that adds a feature to a world. A world can enable several mods, and the same mod can be used in several worlds with different settings.
Four parts to understand
| Part | Its job | Example |
|---|---|---|
| Manifest | Declare files, permissions, settings, and editor items | “This mod provides a lantern and needs audio.” |
| Client | Draw objects, play audio, display UI, and send player requests | Draw a chest and request that it opens when clicked. |
| Server | Validate requests and own shared gameplay | Check distance, then mark the chest as opened. |
| World | Hold terrain, placed objects, and enabled mod settings | A village with your lanterns and a treasure activity. |
The host is the VibeLands game that runs your mod. It supplies terrain, networking, the editor, physics, and storage through the SDK.
Choose visual or gameplay
| Visual mod · Tier A | Gameplay mod · Tier B | |
|---|---|---|
| Code | Client | Client and server |
| Use for | Scenery, models, ambient effects | Shared interactions, scores, persistent progress |
| Shared state | Derive visual placement from the world seed | Server writes; clients receive updates |
| Start command | vibelands create my-scenery | vibelands create my-game --tier B |
A placeable decorative object can be Tier A: the host editor saves its placement. Tier B is needed when your own code changes shared gameplay. A visual effect generated by a client is not automatically a saved world object.
Project structure
my-mod/
├── vibelands-mod.json # identity, entries, permissions, settings
├── client/ # React and React Three Fiber components
├── server/ # Tier B gameplay hooks and tests
├── shared/ # generated message types, when configured
├── assets/ # optional models, textures, audio
├── review-metadata.json # listing and reviewer information
└── package.json # dependencies and development commandsThe manifest's entries fields select the actual entry files. Creator templates supply the files needed by the selected feature; every directory above is not required.
SDK imports
| Import | Use it in | What it provides |
|---|---|---|
@vibelands/mod-sdk/client | Client components | Hooks, rendering registration, UI, assets |
@vibelands/mod-sdk | Server entry | defineModServer, context types, shared helpers |
@vibelands/mod-sdk/physics | Client components | Collider components and replicated body rendering |
@vibelands/mod-sdk/shared | Shared code | Contracts, validation, deterministic helpers |
@vibelands/mod-sdk/testing | Tests | A headless world and controllable clock |
Keep the Creator and SDK versions generated together by the CLI. API version 2 in the manifest is the runtime contract version; it is different from the npm package version. API v3 is a tooling draft, not a loadable manifest.
A multiplayer action, step by step
- The client sends a request such as
openChestwith an entity ID. - The host checks declared message shape and rate limits.
- Your server handler checks the player, distance, and chest state.
- The server changes the mod's shared state.
- Clients read the updated state and redraw.
Use messages for requests and notifications. Use replicated state for what is true now, so a player joining later sees the current result. Use storage for what must survive a restart.
Where code runs
You edit local source files. Creator checks and uploads them to a hosted build. The game loads that build in a private preview world. Public server mods run in isolated workers. You do not need to run the VibeLands server locally.
Client components share the host's React, Three.js, and React Three Fiber. Use the generated build setup so these libraries are shared correctly. Import host features through the SDK; imports from @vibelands/client, @vibelands/server, and @vibelands/shared fail Creator checks.
What a mod can change
Each mod owns its runtime entities, storage, and messages. Permissions grant specific host services; they do not grant arbitrary access to another mod, the database, or the renderer. World entity queries return read-only snapshots.
The host cleans up mod timers and entities when the mod stops. Your code must also clean up custom resources and handle rejected calls.