用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/suzbot/petri --skill test-world命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
基于 SOC 职业分类
正在显示 SKILL.md
| name | test-world |
| description | Create a test world with specific preconditions, when asking user to verify a behavior that's hard to observe naturally. |
| user-invocable | true |
| argument-hint | Structured world spec — read this skill's Caller Requirements before invoking |
| model | sonnet |
| context | fork |
| agent | general-purpose |
| allowed-tools | ["Read","Write","Bash","Glob","Grep"] |
The caller must read this section and build a structured argument before invoking this skill.
Specify all of the following in the skill argument:
Do not leave entity attributes for the skill to infer. If a vessel contains water, specify "item_type": "liquid", "color": "", "kind": "water". If a vessel contains berries, specify the exact color. The skill will translate this spec into a valid save file.
Test the workflow, not the data. For features that test a placement or creation flow, give the character the required know-how and let the user exercise the flow — do not pre-populate the data being tested. Pre-placed data only tests serialization, not the code path.
You are creating a test world save file so the user can verify specific game behaviors. You will be given a structured world spec as your argument.
Read internal/save/state.go for the complete SaveState struct and all serialization types. This is your source of truth for JSON field names and structure.
Also read internal/config/config.go for character/item symbols, spawn counts, and any relevant constants.
Check docs/game-mechanics.md for system interactions (e.g., hunger tiers, order interruption, idle activity triggers) before designing preconditions — this is faster than searching code and captures player-visible behavior that code comments may not.
Based on the test description, determine:
known_activities AND known_recipes. Check ActivityRegistry and RecipeRegistry for the activity's prerequisites.Use Bash to create: ~/.petri/worlds/world-test-<feature>/
{
"id": "world-test-<feature>",
"name": "world-test-<feature>",
"created_at": "<timestamp>",
"last_played_at": "<timestamp>",
"character_count": <n>,
"alive_count": <n>
}
Start from the recipe template below, then customize for the test scenario.
Stat semantics (IMPORTANT):
hunger: 0 = fully satisfied, 100 = starving to deaththirst: 0 = fully satisfied, 100 = dying of thirstenergy: 0 = exhausted, 100 = fully restedDefault stat levels for test worlds: hunger=0, thirst=0, energy=98. This saturates survival needs so characters focus on the target behavior. Override only when the test specifically requires a needy character (e.g., testing hunger-driven eating).
Key considerations:
version: 1 and set map_width: 60, map_height: 60talking_with_id: -1 for characters not in conversationItemSave struct in state.go. See templates below for common examples."x": N, "y": N fields (NOT nested "position": {"x": N, "y": N})"color": "" (not "blue") and "kind": "water" in both the stack contents and the varieties array — wrong color causes a nil-pointer crash on save. Extraction requires seed varieties pre-registered in varieties (e.g. {"item_type": "seed", "kind": "tall grass seed", ...}) — AddToVessel fails silently without them.Color, Pattern, Texture are strings in the save format (not integers):
"red", "blue", "brown", "white", "orange", "yellow", "purple", "tan", "pink", "black", "green", "pale_pink", "pale_yellow", "silver", "gray", "lavender""" (none), "spotted", "striped", "speckled""" (none), "smooth", "slimy", "waxy", "warty"Use this as the starting structure. Add/remove characters, items, features, and varieties as needed for the specific test. Read internal/save/state.go for any fields not shown here.
{
"version": 1,
"map_width": 60,
"map_height": 60,
"elapsed_game_time": 0,
"characters": [
{
"id": 1,
"name": "Kai",
"x": 30,
"y": 30,
"health": 100,
"hunger": 0,
"thirst": 0,
"energy": 98,
"mood": 50,
"talking_with_id": -1
Item template (loose edible):
{
"id": 1,
"x": 31,
"y": 30,
"item_type": "berry",
"color": "red",
"pattern": "",
"texture": "",
"edible": true,
"poisonous": false,
"healing": false,
"death_timer": 0
}
Growing plant template (mature, can reproduce):
{
"id": 2,
"x": 32,
"y": 30,
"item_type": "berry",
"color": "red",
"pattern": "",
"texture": "",
"edible": true,
"poisonous": false,
"healing": false,
"death_timer": 0,
"plant": {"is_growing": true, "spawn_timer": 0}
}
Sprout template (still maturing, NOT yet edible — edible must be false):
{
"id": 3,
"x": 33,
"y": 30,
"item_type": "berry",
"color": "red",
"pattern": "",
"texture": "",
"edible": false,
"poisonous": false,
"healing": false,
"death_timer": 0,
"plant": {"is_growing": true, "spawn_timer": 0, "is_sprout"
Vessel with contents (in inventory or on map). name is the display name, container holds stacks. Stack variety attributes must match an entry in the top-level varieties array:
{
"id": 10,
"x": 0,
"y": 0,
"name": "Hollow Gourd",
"item_type": "vessel",
"kind": "hollow gourd",
"color": "green",
"pattern": "",
"texture": "",
"edible": false,
"poisonous": false,
"healing": false,
"death_timer": 0,
"container": {
"capacity":
To put a vessel in a character's inventory, add it to the character's "inventory" array (same ItemSave format). Characters have 2 inventory slots.
Feature template (leaf pile for sleeping):
{
"id": 1,
"x": 35,
"y": 30,
"feature_type": 1
}
Order template (pre-assign to a character by setting assigned_to and matching assigned_order_id on the character):
{
"id": 1,
"activity_id": "gather",
"target_type": "stick",
"status": "assigned",
"assigned_to": 1
}
Order status values (IMPORTANT — must use exact strings):
"open" — available to be taken by any character"assigned" — currently being worked on (use this when pre-assigning to a character)"paused" — interrupted by character needs"completed" — finished (swept up by game loop)Construct template (fence):
{
"x": 30,
"y": 28,
"construct_type": "fence",
"kind": "fence",
"material": "stick",
"material_color": "brown",
"wall_role": ""
}
Construct template (hut wall):
{
"x": 30,
"y": 28,
"construct_type": "structure",
"kind": "hut",
"material": "stick",
"material_color": "brown",
"wall_role": "wall"
}
Construct template (hut door): Note passable: true — doors are walkable.
{
"x": 30,
"y": 28,
"construct_type": "structure",
"kind": "hut",
"material": "stick",
"material_color": "brown",
"wall_role": "door",
"passable": true
}
Wall roles: "wall" or "door". Visual symbols are computed at render time from adjacency (DD-42).
Construction mark template (pre-placed marking for fence or hut tiles, in marked_for_construction array):
{
"position": {"x": 30, "y": 28},
"line_id": 1,
"material": "",
"construct_kind": "hut",
"wall_role": "wall"
}
For hut marks: wall_role is "wall" or "door" (door = center-south tile of the 5×5 footprint). For fence marks: wall_role is "". Also set "construction_line_id" on the SaveState to the next available line ID (e.g., 2 if line_id 1 is used). Characters in the same hut footprint share the same line_id.
Unlisted entity types: If the spec requires entity types not covered by templates above, read internal/save/state.go for the struct definition and serialize accordingly.
Variety template:
{
"item_type": "berry",
"color": "red",
"pattern": "",
"texture": "",
"edible": true,
"poisonous": false,
"healing": false,
"kind": ""
}
After writing state.json, verify the file was actually created (e.g., ls the directory). Do NOT report to user until the file exists.
Tell the user:
go build -o petri ./cmd/petri && ./petri