Resource manifest
Declare a Vital.sandbox resource — its scripts, files, and dependencies — via manifest.yaml
Overview
Every resource in Vital.sandbox lives in its own folder under the server's resources/ directory, described by a single manifest.yaml at its root. The Resource Manager scans this directory on server startup, parses each manifest, and tracks the resulting metadata for the lifetime of the server.
Server builds read manifest.yaml directly from disk, validate it, resolve dependencies, and broadcast the resulting metadata to connected clients.
Client builds never read manifest.yaml — they receive an equivalent, pre-resolved manifest over the network from the server and register it locally.
Where resources live
- Folder = resource — each resource is a folder named after it, e.g.
resources/inventory/. - Fixed filename — the manifest must be named exactly
manifest.yamland sit at the folder's root. - Folder name is the reference — it becomes the resource's
refand is used everywhere the resource is addressed.
resources/
└── inventory/
├── manifest.yaml
├── client.lua
├── client2.lua
└── assets/
└── ...Script and file paths declared in the manifest are resolved relative to this folder.
Resource
Naming conventions:
- must not be empty
- must pass filesystem path sanitization (no path traversal or unsafe path characters)
- must contain only alphanumeric characters or underscores (
_) — no spaces, dots, or slashes
Restarting resource
- Restarting reloads the manifest, then compares old vs. new script hashes, file hashes, and dependency lists, reporting exactly what was added, modified, or deleted before stopping and re-starting the resource.
- This makes it possible to see at a glance whether a restart picked up the change you expected.
Reconnecting / late-joining clients
- On peer join, the server broadcasts the full asset manifest, then sends a
resource:startedpacket for every currently running resource, in the order they were originally started. - This lets a client that connects mid-session receive every active resource without a full server restart.
Manifest
Full example showing every supported top-level key:
name: "My Resource"
author: "YourName"
version: "1.0.0"
dependencies:
- "inventory"
scripts:
- { src: "client.lua", type: "client" }
- { src: "client2.lua", type: "client" }
- { src: "shared/*.lua", type: "shared" }
- { src: "server.lua", type: "server" }
files:
- "assets/**"Only scripts is mandatory.
- A manifest with no
scriptskey, or wherescriptsisn't a list, is rejected outright and the resource is skipped during scan. name,author,version,files, anddependenciesare all optional.
| Key | Type | Required | Default | Description |
|---|---|---|---|---|
name | string | No | ref | Display name for the resource Falls back to resource's reference if omitted |
author | string | No | "" | Free-text author/credit string - not validated |
version | string | No | "" | Free-text version string - not validated |
scripts | list<string> | Yes | None | List of script entries to compile and execute for this resource |
files | list<string> | No | [] | Glob patterns for non-script assets (models, textures, sounds, etc) |
dependencies | list<string> | No | [] | Names of other resources that must be running before this one starts |
Scripts
Each entry in scripts is a map with two required fields:
scripts:
- { src: "client.lua", type: "client" }Invalid or unmatched entries fail the whole manifest.
- A script entry missing
srcortypeis a hard error — the manifest fails to parse. typemust be exactly"shared","server", or"client"— anything else is rejected.- A
srcpattern that matches zero files is rejected — there's no "optional" script.
| Field | Type | Description |
|---|---|---|
src | string | Path or glob pattern to a .lua script, relative to the resource folderExpanded against the filesystem at load time; a pattern that matches nothing is an error |
type | string | One of the below script types: • "shared" - Loaded and executed on server and client both• "server" - Loaded and executed on server only• "client" - Loaded and executed on client only |
Files
A flat list of glob patterns for non-script assets — models, textures, sounds, config, anything the resource needs to ship.
Like scripts, each pattern is expanded on disk; a pattern matching nothing produces an error and the whole manifest fails.
Files are hashed at parse time.
- Changes after every restart can be detected as per Resource section.
- Models declared under
filesare additionally auto-detected and loaded as part of resource startup.
files:
- "assets/**"
- "models/*.glb"
- "config.json"Dependencies
A list of other resource names that must be running before this resource starts.
Resource Manager resolves the full dependency graph recursively and starts dependencies in the correct order before starting the resource itself.
| Rule | Behaviour |
|---|---|
invalid-name | Any dependency name failing the naming conventions is rejected with an error |
self-dependency | A resource cannot list itself as a dependency - rejected outright |
missing dependency | If a listed dependency isn't a known resource, resolution fails and the resource does not start |
circular-dependency | Detected via a recursion stack; a cycle (e.g. A → B → A) aborts the start with the full chain reported |
already-running | Dependencies already running are skipped - they are not restarted |