Back to Marketplace
FREE
Scanned
Grow Business

Worldbuilding CMS for AI Agents

Provides AI agents with structured tools to create, manage, and query fictional worlds through entities, relationships, and semantic search

New skill
No reviews yet
New skill
πŸ€– Claude Code⚑ CursorπŸ’» Codex🦞 OpenClaw πŸ„ Windsurf
FREE

Free to install β€” no account needed

Copy the command below and paste into your agent.

Instant access β€’ No coding needed β€’ No account needed

What you get in 5 minutes

  • Full skill code ready to install
  • Works with 7 AI agents
  • Lifetime updates included
SecureBe the first

Description

# Worldbuilding CMS β€” Agent Skill Guide This document tells AI agents how to effectively use the worldbuilding model layer. Read this before interacting with a world. ## Quick Start ```ts import { WorldEngine } from "./src/index.js"; // Open a world using default built-in types const engine = new WorldEngine({ worldDir: "world" }); await engine.open(); // Create entities β€” only name and body are required await engine.create("character", { name: "Kira Solane", body: "A shipwright who discovered she can hear the ocean's memories.", tags: ["protagonist", "gifted"], species: "human", status: "alive", }); // Query, validate, close const chars = await engine.list("character"); const result = await engine.validate(); engine.close(); ``` ## Architecture You Need to Know ``` Agent (you) ↓ reads/writes via WorldEngine β”œβ”€β”€ DuckDBLayer β€” SQL queries over flat JSON files (read_json_auto) β”œβ”€β”€ FileStore β€” one JSON file per entity in world/<type-plural>/ β”œβ”€β”€ Validator β€” schema + referential integrity checks └── VectorIndex β€” semantic search (cosine similarity) ``` **Key principle:** Entities are flat JSON files in git. Every entity file is the single source of truth. DuckDB queries them in-place. The search index is disposable. ## Entity Model Every entity has these base fields: | Field | Type | Notes | |---|---|---| | `id` | string | Auto-generated from name via slugify, or pass custom | | `type` | string | Entity type name (e.g. "character", "planet") | | `name` | string | **Required.** Display name | | `body` | string | **Required.** Freeform prose lore β€” the main content | | `tags` | string[] | Defaults to `[]` | | `relations` | Relation[] | Typed references to other entities. Defaults to `[]` | | `metadata` | object | Arbitrary key-value data. Defaults to `{}` | | `created_at` | ISO 8601 | Auto-set | | `updated_at` | ISO 8601 | Auto-set on create and update | Plus type-specific fields (e.g. `species`, `faction_id` for characters). ### Built-in Types | Type | Directory | Key Fields | |---|---|---| | `character` | characters/ | title, species, status, faction_id, location_id | | `location` | locations/ | region, parent_location_id, climate, population | | `faction` | factions/ | motto, leader_id, headquarters_id, alignment | | `event` | events/ | date_in_world, location_id, participants, outcome | | `item` | items/ | item_type, owner_id, location_id, rarity, properties | | `lore` | lore/ | category, era, scope | ### Custom Types Define in `world.config.json`: ```json { "name": "My Universe", "types": { "planet": { "plural": "planets", "fields": { "system": { "type": "string" }, "classification": { "type": "string", "enum": ["terrestrial", "gas_giant"] }, "population": { "type": "integer", "minimum": 0 }, "parent_star_id": { "type": "string", "reference": true } } } } } ``` Custom types get the same base fields, validation, search indexing, and DuckDB querying as built-ins. Set `"builtInTypes": false` to use only your custom types. Load from config: ```ts const engine = await WorldEngine.fromConfig("./world.config.json", { worldDir: "./world", }); ``` ## CRUD Operations ### Create ```ts // Minimal β€” just name and body await engine.create("character", { name: "Elara Voss", body: "A wandering mage.", }); // Full β€” all optional fields await engine.create("character", { name: "Elara Voss", body: "A wandering mage from the Northern Reaches.", id: "custom-id", // optional, auto-slugified from name otherwise tags: ["mage", "wanderer"], relations: [{ target_id: "some-faction", target_type: "faction", relation: "member_of" }], metadata: { alignment: "chaotic good" }, species: "human", status: "alive", faction_id: "some-faction", }); ``` ### Read ```ts const entity = await engine.get("character", "elara-voss"); const allChars = await engine.list("character"); ``` ### Update ```ts await engine.update("character", "elara-voss", { status: "dead", body: "Updated lore text...", }); ``` ### Delete ```ts await engine.delete("character", "elara-voss"); ``` ## Querying ### SQL via DuckDB ```ts // WHERE clause on a type const mages = await engine.queryWhere("character", "faction_id = 'mages-guild'"); // Raw SQL β€” full DuckDB power const result = await engine.sql(` SELECT c.name, f.name as faction_name FROM read_json_auto('world/characters/*.json', union_by_name=true) c JOIN read_json_auto('world/factions/*.json', union_by_name=true) f ON c.faction_id = f.id `); ``` ### Semantic Search ```ts // Natural language query const results = await engine.semanticSearch("political tensions in the north"); // Filter by type const results = await engine.semanticSearch("magic system", { type: "lore", topK: 5 }); ``` **Important:** Call `await engine.reindex()` after bulk operations to rebuild the search index. Individual creates/updates automatically update it incrementally. ## Validation ```ts const result = await engine.validate(); if (!result.valid) { for (const err of result.errors) { console.log(`[${err.entityType}/${err.entityId}] ${err.message}`); } } ``` Validation checks: 1. **Schema conformance** β€” every entity matches its type's JSON Schema 2. **Referential integrity** β€” all `*_id` foreign keys and relation targets point to existing entities Validation runs automatically on every `create()` and `update()` call (schema only). Run `validate()` for a full integrity check across the entire world. ## Relations Relations are explicit typed edges between entities: ```ts await engine.create("character", { name: "Commander Vex", body: "...", faction_id: "iron-compact", // foreign key (validated) relations: [ { target_id: "iron-compact", target_type: "faction", relation: "leads" }, { target_id: "elara-voss", target_type: "character", relation: "rival_of" }, ], }); ``` **Foreign keys** (`faction_id`, `location_id`, etc.) are type-specific fields marked with `reference: true` in the schema. They are validated for existence. **Relations** are a generic edge list on every entity. The `relation` field is freeform β€” use whatever relationship names make sense for your world. ## File Layout ``` my-world/ world.config.json ← optional: defines custom types world/ characters/ elara-voss.json locations/ ashenvale.json factions/ iron-compact.json planets/ ← custom type directory kepler-442b.json .worldindex/ ← gitignored, regenerable vectors.json ``` ## Working With Git - Each entity is one file β†’ minimal merge conflicts - Branch = alternative world state (e.g. `timeline/war-of-ash`) - Meaningful diffs: changing a faction leader is a one-line change - Run `npm run validate` as a pre-commit hook - Run `npm run reindex` after switching branches ## Common Patterns ### Seeding a World See `examples/verdance/seed.ts` (built-in types) and `examples/the-lattice/seed.ts` (custom types) for complete examples. ### Cross-Entity Queries ```ts // Characters in a location's region const northern = await engine.queryWhere("character", `location_id IN ( SELECT id FROM read_json_auto('world/locations/*.json') WHERE region = 'Northern Reaches' )` ); ``` ### Bulk Operations ```ts // Create many entities, then reindex once for (const char of characters) { await engine.create("character", char); } await engine.reindex(); // rebuild search index once at the end ``` ## What NOT to Do - **Don't edit JSON files directly** β€” use the engine so validation runs - **Don't commit `.worldindex/`** β€” it's a derived artifact, regenerate with `npm run reindex` - **Don't rely on the search index for correctness** β€” it's for discovery; use DuckDB/SQL for precise queries - **Don't create circular foreign keys in a single batch** β€” create entities first, then update with references (see the Verdance seed script's faction leader pattern)

Preview in:

Security Status

Scanned

Passed automated security checks

Related AI Tools

More Grow Business tools you might like