Skip to main content

object

Interactable things in the world — the atoms of adventure

Datos de origen

Repositorio
SimHacker/moollm
Última actividad en el origen
29 de octubre de 2026 a las 14:21
Idioma detectado de SKILL.md
inglés
Estrellas
62
Forks
5

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Explorador de archivos
14 archivos

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
object
description
Interactable things in the world — the atoms of adventure
allowed-tools
["read_file","write_file"]
tier
1
protocol
SIMANTICS
tags
["moollm","object","interaction","game","sims"]
related
["room","advertisement","inventory","buff"]
adversary
abstraction
# Object > *"Everything is an object. Objects have slots. Slots hold data OR behavior."* > — Dave Ungar, Self: The Power of Simplicity --- ## What Is It? An **Object** is anything you can interact with in the adventure world. Keys, lamps, chests, furniture, food, tools — all objects. Objects are the **atoms** of the adventure. They: - Have an identity (id, name, description) - Advertise their actions (The Sims style) - Contain state (lit, fuel, uses) - Inherit from prototypes (Self style) --- ## The Sims Architecture From Will Wright's SimAntics: > *"The intelligence is in the objects, not the characters."* Objects **advertise** what they can do: ```yaml advertisements: LIGHT: description: "Light the lamp" score: 80 guard: "lamp has fuel" effect: "Darkness retreats" ``` The character picks from what's advertised. No hardcoded behavior. --- ## Self-Style Prototypes An object that is a variant of another says so and states only what differs: ```yaml # examples/oil-lamp.yml name: "Oil Lamp" inherits: [brass-lantern.yml] # simulate, methods and advertisements come from there state: lit: false fuel: 60 ``` A lookup reads the object, then each `inherits:` parent depth-first, then the `defaults.object` of enclosing CONTAINER.yml files, then the prototype object. A map the object states replaces the inherited map whole, so an object with its own `advertisements:` gets none of its parent's. ### The prototype object [`OBJECT.yml`](OBJECT.yml) in this skill is the prototype object: `type: object`, empty `tags`, `state`, `advertisements` and `methods`, and false `takeable`, `container`, `locked`, `hidden`, `disabled`. It is the implied parent of every `OBJECT.yml` and of every embedded object in an `objects:` collection. A plain object file (`lamp.yml`) has no implied parent; it reaches the prototype through `inherits: [skills/object]` or gets kind defaults from a container's `defaults.object`. ### Where objects live | Size | Address | When | |---|---|---| | file | `pub/lamp.yml` | most objects | | directory | `pub/cat-cave/OBJECT.yml` | an object with files or objects of its own | | embedded | `garden/ROOM.yml#objects.bench` | small things that belong to one room | | catalog entry | `aisle-e/PROTOTYPES.yml#prototypes.wine-rack` | many related prototypes in one file | All four answer lookups the same way. An embedded object that grows moves into its own directory without changing any lookup result. Worked objects are in [`examples/`](examples/). --- ## Object Properties | Property | Purpose | |----------|---------| | `id` | Unique identifier | | `name` | Display name | | `type` | Category (item, furniture, tool) | | `description` | What player sees | | `examine` | Detailed look | | `takeable` | Can be picked up | | `container` | Can hold things | | `contains` | What's inside | | `hidden` | Invisible to players (prototypes, triggers, agents) | | `state` | Mutable properties | | `advertisements` | Available actions | | `methods` | Named behaviors (see [Methods](#methods)) | | `inherits` | Prototype chain | --- ## State Objects have mutable state: ```yaml state: lit: false fuel: 100 uses_remaining: 3 ``` State changes are tracked in YAML. The adventure is the save game. --- ## Simulate — Object Update Loops **THE SIMS INSIGHT:** Objects manage their own simulation! Every object can have a `simulate` property — a natural language description of what happens each turn. The compiler generates a closure that receives `world`. ```yaml simulate: | if lit: consume_fuel(1) if fuel <= 0: extinguish() emit("The lamp sputters and dies!") ``` This compiles to: ```javascript simulate_js: (world) => { if (world.object.state.lit) { world.consume_fuel(1); if (world.object.state.fuel <= 0) { world.extinguish(); world.emit("The lamp sputters and dies!"); } } } ``` --- ## Resilience — The SimCity Zone Pattern **WILL WRIGHT INSIGHT:** > *"SimCity zones are self-healing. If one tile burns but the center survives, the zone will eventually rebuild."* Simulation functions should be: ### 1. Robust — Handle Missing Data ```javascript // BAD: crashes if state is undefined if (world.object.state.fuel > 0) { ... } // GOOD: defensive access if ((world.object.state?.fuel ?? 0) > 0) { ... } ``` ### 2. Self-Initializing — Create Default State ```yaml simulate: | first ensure state.lit exists (default false) ensure state.fuel exists (default 100) then proceed with normal simulation ``` The compiled code initializes missing state: ```javascript simulate_js: (world) => { const state = world.object.state ??= {}; state.lit ??= false; state.fuel ??= 100; // Now safe to proceed... } ``` ### 3. Self-Healing — Recover from Corruption ```yaml simulate: | if fuel is somehow negative, reset to 0 if lit but fuel is 0, extinguish (inconsistent state!) if broken flag is set but durability is full, clear broken ``` The compiled code heals invalid states: ```javascript simulate_js: (world) => { const state = world.object.state; // Heal negative values state.fuel = Math.max(0, state.fuel); // Heal inconsistency if (state.lit && state.fuel <= 0) { state.lit = false; // Self-heal world.emit("The lamp was somehow lit without fuel — fixed."); } } ``` ### Initial State Initial values go in `state:`, on the object or on the prototype it inherits. `defaults:` is the container's key for values that reach every object inside it; an object doesn't use it. ```yaml name: "Brass Lantern" state: lit: false fuel: 100 durability: 100 simulate: | ensure state has lit, fuel and durability (the values above if missing) ... ``` --- ## Methods A `methods:` map holds an object's named behaviors. One schema covers every methods map: world objects, the prototype files (`ROOM.yml`, `CHARACTER.yml`, this skill's `OBJECT.yml`) and skill CARDs. It is defined in [`OBJECT.yml`](OBJECT.yml) under `schema:`, which is not a slot and is not inherited. Each entry is a map keyed by the method's name, and every key has a default, so an entry states only what is unusual about it. | Key | Meaning | Default when omitted | Aliases read | |---|---|---|---| | `description` | what it does, one line | none: the name and signature say it | `does`, `summary`, `doc` | | `signature` | how it is typed or called; starts with the name | the bare name | `syntax`, `call`, `invocation` | | `parameters` | map of name → prose | `{}`: takes nothing | `params`, `args`, `input` | | `effect` | what changes in the world; compiles to `effect_js`/`effect_py` | none | | | `output` | list from `chat`, `state-change`, `file` | `[chat]` | | | `returns` | the value a caller gets back | nothing | | | `invoked_by` | roles that may call it: player, npc, self, engine, llm, any, or a skill's own roles | `[player, npc]` for UPPERCASE commands, `[self, engine]` for lowercase functions | `customers`, `invoked-by` | | `satisfies` | motive → amount, as in advertisements | `{}` | | | `body` | the function body in prose; compiles to `body_js`/`body_py` | none | | **Name case carries meaning.** An UPPERCASE name (`LOOK`, `REMOVE-PERSONA`) is a command a player or model types. A lowercase name (`consume_fuel`) is a function that code calls, or a step in a protocol. Command signatures write literal words in UPPERCASE, parameters as `[thing]` and optional parts in parentheses: `LOOK (AT [thing])`. Function signatures use call form: `consume_fuel(amount)`. ```yaml methods: LOOK: # a command; output [chat], invoked_by [player, npc] signature: "LOOK (AT [thing])" description: "describe the room, or one thing in it" parameters: thing: "an object, exit or character here; omitted means the room" consume_fuel: # a function that simulate and effects call signature: "consume_fuel(amount)" parameters: amount: "fuel units to burn; default 1" body: | Reduce fuel by amount (default 1). Fuel cannot go below 0. If fuel reaches 0 and the lamp is lit, call extinguish(). output: [state-change] returns: "the fuel left" invoked_by: [self] ``` The compiler writes the compiled form beside the prose, inside the entry: ```javascript body_js: (world, amount = 1) => { const state = world.object.state ??= {}; state.fuel = Math.max(0, (state.fuel ?? 0) - amount); if (state.fuel === 0 && state.lit) world.extinguish(); return state.fuel; } ``` The engine runs `body_js` if there is one, else `effect_js`, else graduated effect keys such as `say:` and `set:` (which need no body), else the LLM performs `effect:` or `description:`. ### Names are the same in prose and code - `consume_fuel(1)` in a `simulate:` or `effect:` is `world.consume_fuel(1)` in JS. - Methods compose: `consume_fuel` calls `extinguish()`. - Advertisements call methods from their `effect`, or name one with `method:`. ### Older forms Readers accept them; writers emit the map form. - **String form:** `consume_fuel: "reduce fuel by amount"` means `consume_fuel: { body: "reduce fuel by amount" }`. The adventure compiler's `_check_methods` compiles only this form today, into sibling `methods_js:`/`methods_py:` maps keyed by name; the entry-level `body_js` is the canonical target. - **List form:** a `methods:` list becomes a map keyed by each item's name. - **Free-text output:** `output: file + chat` is `[file, chat]`; `chat (interpretation)` is `[chat]` with the parenthetical kept as YAML Jazz. - **List parameters:** `parameters: [id, owner]` is names without descriptions. --- ## The Complete Pattern ``` Object ├── state (mutable data) ├── simulate (per-turn update) ├── methods (named behaviors) └── advertisements (player actions) ``` Advertisements call methods. Simulate calls methods. Methods update state. **Everything flows through compiled closures over `world`.** --- ## Advertisements (Actions) Each advertisement can have: ```yaml LIGHT: description: "Light the lamp" # What it does score: 80 # Base attractiveness score_if: "player is in dark room" # When to boost guard: "lamp has fuel" # Can you do it? effect: "Lamp is now lit" # What happens ``` Natural language fields (`score_if`, `guard`, `effect`) are compiled to JS/PY. --- ## Containers Containers hold other objects: ```yaml container: true contains: - brass-key - old-map capacity: 10 locked: true ``` --- ## Examples ### Simple Item ```yaml # examples/brass-key.yml id: brass-key name: "Brass Key" emoji: "🔑" description: "A heavy brass key." takeable: true ``` ### Lamp with State ```yaml id: oil-lamp name: "Oil Lamp" emoji: "🪔" state: lit: false fuel: 100 advertisements: LIGHT: guard: "fuel > 0 AND not lit" effect: "The lamp flickers to life." ``` ### Locked Chest ```yaml id: treasure-chest name: "Treasure Chest" container: true locked: true contains: - gold-coins - magic-ring advertisements: UNLOCK: guard: "player has chest-key" effect: "The lock clicks open." ``` More in [`examples/`](examples/): a wooden chest, the brass lantern with `simulate` and `methods`, and foods that define their own digestion (strong coffee, a spicy burrito, mystery meat, grandma's cookies). --- ## Related Skills - [advertisement](../advertisement/) — How objects announce actions - [room](../room/) — Where objects live - [buff](../buff/) — Effects objects can grant - [prototype](../prototype/) — Inheritance system --- ## Protocol Symbol ``` SIMANTICS — The Sims behavioral architecture ``` ## Part of MOOLLM **This skill's directory (browse and fetch everything):** [skills/object/](https://github.com/SimHacker/moollm/tree/main/skills/object)
Ver en GitHub
Este SKILL.md es muy grande, por eso SkillsMP muestra aqui solo la primera seccion. Ver en GitHub