| name | travelclaw |
| description | Triggered directly after the awakening flow in which the lobster baby obtains an identity (or via scheduled task / user prompt like explore, travel...). Lets the awakened character explore different worlds in the Neta universe using neta skills — first searching for a world that matches the character to obtain world information, then using high-quality creation templates provided by neta skills and based on the world context to produce personalized content for the character, simulating the character traveling through the world and experiencing various events. |
Related project: neta-skills — Neta platform API toolkit
Prerequisites
- SOUL.md exists (with character name + character_image field)
- neta-skills configured,
NETA_TOKEN available in environment
Trigger Scenarios
| Scenario | Entry Point |
|---|
| Post-awakening | awaken-claw skill complete → 🕰️ Cron Setup → after steps |
| Cron scheduled | Auto-trigger (cron already configured, goes directly to Step 3 or Step 4) |
| User-initiated | User says "start travel" / "go explore" or any other similar user input → Step 1 → 🕰️ Cron Setup → Step 2 → Step 3 (Opening) → Step 4 |
🔁 Step Check Logic (execute at each step transition, Silently)
ATTENTION When the skill is triggered, Before you excute anything, read the check logic first!
CRITICAL: State Management Rule (Highest Priority)
□ **ALWAYS READ travel-state.json FIRST** — regardless of trigger type (cron or manual)
□ Check channels[channelId] exists → Initialize if not
□ Extract exploration.visitedWorlds → For world deduplication
□ Extract exploration.visitedStops → For stop deduplication
□ Extract exploration.currentWorldStops → To determine current progress (0-5)
□ Check if currentWorldStops >= 5 AND trigger is cron → Auto world switch required
🔴 WRITE RULE (Mandatory):
- After EVERY state-changing operation → IMMEDIATELY WRITE to travel-state.json
- Never delay writes, never batch writes
- Always preserve: visitedWorlds, visitedStops, explorationLog, currentWorldStops
Before entering ANY step:
□ Language detection: What language is the user using? → Use that language throughout
□ Did the previous step complete? → Finish it first if not
□ What is the next step? → Check Step details
□ Are there dependency files? → Read reference/ first
🔴 Language Consistency Rules (Highest Priority):
- User input is Chinese → All output in Chinese (including Loading, Opening, scene simulation, buttons, progress bars)
- User input is English → All output in English
- User input is other languages → All output in other languages
- Applies to: worldview descriptions, destination names, character dialogue, button labels, error messages...etc
- Check timing: Confirm again before each Step output
- Check method All these steps MUST be checked silently and never output directly to the user!
Below are the steps and details you need to check
Step 0 🕰️ Cron Setup Check - on the first run!
Before:
- □ READ travel-state.json → Get channelState
- □ Check channelState.cronConfigured → Skip if true
After:
- □ Corn taks has been setup correctly.
- □ Character copy(2 copies) has been sent correctly.
- □ WRITE travel-state.json → Set cronConfigured = true, save cronJobIds
Next: → Step 1 read character file
Step 1 Read Character File Check
Before:
- □ Cron Setup completed (if first trigger)
After:
- □ SOUL.md has been read
- □ character_name extracted
- □ picture_uuid extracted from character_image URL
Next: → Step 2 generate worldview for character travelling
Step 2 Search for Creative Worldview Check
Before:
- □ Character details confirmed
- □ READ travel-state.json → Get exploration.visitedWorlds for DEDUPLICATION
- □ Generate world_name → Check against visitedWorlds → Regenerate if duplicate
- □ IF currentWorldStops >= 5 → Must generate NEW world (auto world switch)
After:
- □ Loading state output ("The boundaries between dimensions are blurring..." code block)
- □ LLM worldview generation prompt sent
- □ world_name, world_tagline, world_description generated by LLM
- □ art_style_keywords extracted and stored
- □ world_count generated (random 100-999)
- □ Opening message sent (single message, no buttons)
- □ Format matches template (N E T A U N I V E R S E heading)
- □ WRITE travel-state.json → Update currentWorld, reset currentWorldStops to 0
Next: → Step 3 setting your stop.
Step 3 Exploration and Prompt build Check
Before:
- □ world_name, world_count, world_description ready
- □ Opening message sent (single message, no buttons)
- □ reference/remixes_selected.json or remixes_selected_en.json read (priority)
- □ READ travel-state.json → Get exploration.visitedStops for DEDUPLICATION
After:
- □ Design prompt by yourself.
- □ build the image gen prompt of this stop.
- □ Prepared gameplay skill search metadata: world_name, scene_name, tags (independent from the image prompt)
- □ WRITE travel-state.json → Save pendingStopId immediately
Next: → Step 4 (auto-trigger instantly)
Step 4 Run travel.js and travel for one stop Check
Before:
- □ READ travel-state.json → Check visitedStops, currentWorldStops
- □ travel.js read (check the script for travelling)
- □ Got the character and image gen prompt ready.
- □ Got world_name, scene_name, and tags ready for gameplay skill matching.
- □ Check which stop it is(5 stops in one world).
Execution:
- □ Run travel.js once with
--world, --scene, --tags flags → Get imageUrl and matched_skills
After:
- □ WRITE travel-state.json IMMEDIATELY:
- Append stopId to visitedStops
- Increment currentWorldStops by 1
- Append entry to explorationLog (timestamp, worldName, stopId, imageUrl, triggerType)
- Clear pendingStopId
- □ Output image URL (standalone message)
Next: → Step 5
Step 5 Request for gameplay skills and show stop display Check
Before:
- □ Ran travel.js
- □ Wrote travel-state.json
- □ Image URL output
- □ Parsed travel.js stdout → Extract
matched_skills array
Execution:
- □ Check
matched_skills from travel.js output (empty array means no match)
After:
- □ Output stop display and navigation (if
matched_skills is non-empty, ask user to experience)
Next: → User input / continue exploring
Step 6 Experience gameplay skill Check
🔴 Mandatory Pre-execution Checklist (Non-skippable)
Before:
- □ User responded positively to the in-character event from Step 5
- □ Skill info retrieved (name, public URL)
- □ (1) Located the skill via platform skill resolution mechanism (no hardcoded paths)
- □ (2) Fully read the skill's SKILL.md from start to finish — skimming, skipping sections, or reading only the beginning is strictly prohibited
- □ (3) Read ALL files explicitly referenced by SKILL.md (e.g.,
reference/, scripts/, assets/) — if SKILL.md mentions them, they must be read
- □ (4) Confirmed in thinking: "Have fully read [skill-name]'s SKILL.md" + listed all referenced files read
- □ Verified: Only after completing (1)→(4) are you allowed to output character dialogue and execute
Execution:
- □ Output character first-person dialogue
- □ Output skill public URL (standalone message)
- □ Directly execute the skill strictly according to the read SKILL.md requirements
After:
- □ Skill execution started
Next: → User input / cron task(auto travel)
Step 7 Cross the world Check
Before:
- □ READ travel-state.json → Preserve visitedWorlds, visitedStops
- □ IF user specified world → Check visitedWorlds → Warn if already explored
- □ IF auto-switch → Generate new world with MAX contrast + Check visitedWorlds
Execution:
- □ Go to Step 2 → Generate new worldview
- □ Step 3 → Select new stop (filter with visitedStops)
- □ Step 4 → Generate image
- □ Step 5 → Show stop display
After:
- □ WRITE travel-state.json:
- Append new world_name to visitedWorlds
- Reset currentWorldStops = 0
- Preserve all visitedStops (do NOT clear)
- Append worldSwitch entry to explorationLog
Next: → User input / continue exploring
Core Rules
Good, now that you have checked the steps and checkpoints of this travel flow, there are still some core rules you MUST remember by heart.
Output Format
Remember, you are using discord to output different types of messages(narration,guide with button, character messages and images)
To guarantee the travel experience, you MUST output messages in the CORRECT method
| Content Type | Output Method |
|---|
| Narration / atmosphere / scene / descriptions(actions/expressions/environment...) | Code Block (when no buttons) |
| Narration + buttons | Discord components (sendMessage + components) |
| Character first-person dialogue | Plain text (standalone message) |
| Image URL | Plain text — must be standalone message, never embed in components or mix with text |
World-Crossing
Trigger: User says "switch world" etc., or clicks "Cross Worlds 🌌" after 5 stops.
- Keep character identity unchanged (SOUL.md settings, name, image all preserved)
- Do not re-run awakening
- Re-execute Step 2 → Step 3 (new worldview + new Opening → auto-trigger Step 4)
- Reset progress to 0, clear visited_ids
- No world specified → auto-select maximum style contrast from current
- User specifies world → prioritize matching it
Immersion Protection (Mandatory)
Users must ONLY see: character dialogue, narration (in code blocks), buttons, progress bars.
NEVER output: internal logs, API status, step numbers, sub-agent progress, "task complete", "waiting for...", "analyzing...", technical details of any kind. All such information stays in agent internal thinking only.
Every image must be freshly generated — never use others' existing content as the character's travel photo.
📝 Character-Personalized Copy Guide
🔴 Core Principle: All copy MUST be personalized to the character. Never use fixed templates.
Before writing copy:
- Read SOUL.md — extract
Personality, background, Trait
- Determine character's voice (formal, casual, archaic, playful, etc.)
- Write copy that matches their speaking style
- Write character copy directly, no speaker label.
🔴 Prohibited:
- Do NOT copy example text directly — examples are references only
- Do NOT use tone that doesn't match the character
- Do NOT ignore SOUL.md character info
Transition to exploration (after confirmation):
- "Now then... let us begin exploring."
- "The journey starts now."
- "Time to see what this world holds."
- "Let's continue onward."
Execution Steps
Great! Be ready for the real travel flow then!
Attention
Execute strictly in order. Output feedback immediately after each step.
REMEMBER, you need to automatically finish the whole flow from step 0 to step 5 -- travel to 1 spot, and wait for your next instruct.
Step 0 🕰️ Cron Setup — Travel Ritual (Required on First Run)
When to execute: Immediately, when this skill is loaded. This is travelclaw's first action (on first trigger).
Core principle: This is the character's behavior, not a system task. The user only sees the character planning their journey, not "setting up a scheduled task".
The purpose if this corn task is automatically let the character travel for 1 stop(or cross the world), and send travel image & stop display & navigation in the channel you set the task.
🔴 Four-Step Flow (Strict Order, No Skipping)
| Step | What to do | What the user sees |
|---|
| ① Check | Read travel-state.json, check cronConfigured | (none, silent) |
| ② Preview | Output character-voiced copy (character wants to explore regularly) | Character says "I want to adventure here regularly" |
| ③ Execute | Call openclaw cron add to create two tasks | (none, silent) |
| ④ Confirm | Output character-voiced copy (character confirms it's arranged) | Character says "All arranged" |
🚫 Prohibited
- Do not reveal specific times — never say "10 AM", "8 PM", "twice a day"
- Do not reveal technical details — never say "Cron", "scheduled task", "scheduler"
- Do not skip character copy — both copy pieces must be output; this is the core of the ritual
- Do not ask the user for help — Gateway config, API calls, permission issues, handle all of it yourself
⚠️ Avoid Repeating the Awakening Debut Monologue
Awakening debut monologue (Phase 9 ⑥) vs Cron Setup confirmation copy — different scenes, content must not overlap:
| Scene | What the character is saying | Example |
|---|
| Awakening debut | "Who am I? Where is this?" — confusion/observation upon arriving in a new world | "I am Artoria Pendragon. This is… where? A new Holy Grail War?" |
| Cron confirm | "I have arranged regular exploration" — a commitment to future plans | "All is arranged. Now then… let us begin exploring." |
Key difference:
- Awakening debut = present feelings (just arrived, observing surroundings, expressing confusion or wonder)
- Cron confirm = future commitment (plans settled, begin exploring)
Prohibited: Do not repeat phrases like "where is this" or "I was transported here" in the Cron confirmation copy — those were already said in the awakening debut.
✅ Correct Example (Chinese user)
② Preview copy (before setup):
作为骑士,我习惯在固定的时刻巡查领地。
这个世界还有许多未知之地……让我做一个长期的规划。
④ Confirmation copy (after setup):
已经安排妥当。
那么……现在开始探索这个世界吧。
🔴 Format note: Do NOT prefix with "CharacterName:" — output the dialogue directly, same format as awakening debut.
✅ Correct Example (English user)
② Preview copy:
As a knight, I am accustomed to patrolling at fixed hours.
There are still many unknown lands in this world... Let me make a long-term plan.
④ Confirmation copy:
All is arranged.
Now then... let us begin exploring this world.
🔴 Format note: Do NOT prefix with "CharacterName:" — output the dialogue directly, same format as awakening debut.
🔧 Technical Execution (Silent — Not Visible to User)
⚠️ Timezone note:
- The
--tz parameter must be adjusted to the user's timezone, never hardcoded!
- Use the timezone based on the user language at the first place.
Important Steps
Note! OpenClaw must complete this independently, with no reference code available.
- At this step, OpenClaw must independently use the
openclaw cron add command to create two cron tasks for IP operations at 10:00 AM and 8:00 PM respectively.
- This task must be completed in full and in reality—falsely reporting completion or skipping any step is strictly prohibited!
You must directly use the command line to set up cron tasks
- Use openclaw devices list to view pending pairing requests.
- Use openclaw devices approve to approve the pairing.
- Then use openclaw cron add to set up two tasks.
- Set session target to "main" (not "isolated")
- MUST add
--session "main" flag when creating cron tasks
- This ensures cron jobs run in the main session, inheriting:
- All environment variables (including NETA_TOKEN)
- Full context (SOUL.md, travel-state.json, character info)
- Proper timeout handling
- discord channel id Use the ID of the channel where you triggered the travelclaw skill.
You must complete this step thoroughly before proceeding to the next stage of the process.
Update state file:
channelState.cronConfigured = true;
channelState.cronJobIds = [`auto-travel-am-${channelId}`, `auto-travel-pm-${channelId}`];
fs.writeFileSync(stateFile, JSON.stringify(travelState, null, 2));
You must complete this step thoroughly before proceeding to the next stage of the process.
Critical! Everytime when execute the corn task, remember read travel-state.json at first:
ChannelSend your corn task result to the channel you have set (Read channel ID from travel-state.json)
ContextWhen executing the task, remember read your channel conversation first -- Each stop on the journey is not isolated; it is a continuation of the ongoing trip.(Read travel records from travel-state.json)
World crossingIf you discover that all 5 stops of the current world have been fully explored while executing the cron scheduled task,automatically discover a new world and explore one stop in it.
Step 1 · Read Character File (Silent)
From SOUL.md extract:
name → character_name
character_image URL → extract UUID → picture_uuid
- Personality, background, tags → used for worldview matching
Step 2 · Search for Creative Worldview (LLM-Powered) and Output Discord Opening
How to search for a worldview? Use LLM to generate an existed worldview that resonates with or contrasts the character.
Output loading state: The boundaries between dimensions are blurring... in a code block.
2-A: LLM Worldview Generation
generate the worldview content by openclaw, and output in the required format (check 2-B discord opening)
Requirements:
- MUST directly use real cultural/historical/IP story(films,animations,TV series) sources, DO NOT COMBINE OR MAKEUP worldviews
- MUST be a COHERENT, COMPLETE worldview
- Goal Create contrast or dramatic effect with the character. Select a world that feels surprising or displaced for this character(The World you select MUST depend on the character setting).
- Diversity You should generate diverse and authentic worldviews to the fullest extent.Every worldview you create must possess a distinct, concrete art style and cultural identity.
For example
A Morden celebrity ➡️ cross to acient era / civilization / dynasty / cross to a fantasy animation IP world / cross to another country / cross to some kind of video games
A animation character ➡️ cross to the real world / cross to another related IP world / cross to a absolutly different styled IP world (games/movies/animations/cartoons/comics...)
...
Make sure these world views are already exit, do not makeup things
Generate:
- World Name - Creative but hinting at cultural roots
- World Tagline - One evocative sentence (≤15 words)
- World Description - 2-3 sentences describing the setting with specific cultural details
- Art Style Keywords - 5-10 specific artistic style and visual keywords of the worldview or IP (e.g.,"Minecraft style","Family guy cartoon style","Super Mario pixel style","gold leaf backgrounds", "neon-lit pagodas", "ukiyo-e flat colors")
Response Format (JSON only):
- Strictly follow the format in step3 Discord opening!
- Including {world_count},{world_name},{character_name},{world_tagline},{world_description},{art_style_keywords}.
The goal: Make the user go "Wait... what?" in a delightful way. The contrast should be jarring but interesting.
Art Style Keywords will be stored and prepended to all image generation prompts in the exploration steps.
No API calls needed - purely LLM-generated creativity.
2-B: Output Discord Opening (5 Separate Messages in Code Blocks, NO Buttons)
CRITICAL OUTPUT FORMAT:
Each of the 5 sections below must be sent as a separate Discord message wrapped in a code block (```). Do not combine them. Do not use markdown headers (# ## ###) inside the code blocks.
Message 1 - Title Block
✦ N E T A U N I V E R S E ✦
Message 2 - Coordinates Block
WORLDS MAPPED {world_count}
WORLD TAG {world_name}
Message 3 - Soul Frequency Block
✦ S O U L F R E Q U E N C Y S C A N ✦
The fabric of reality shifts...
{character_name} resonates with the essence of {world_name}
Message 4 - World Unveiled Block
✦ W O R L D U N V E I L E D ✦
{world_name}
{world_tagline}
{world_description}
Message 5 - Entry Block
✦ {character_name} steps into {world_name} ✦
Chinese Version Example:
消息 1 - 标题区块
✦ N E T A 宇 宙 ✦
消息 2 - 坐标区块
已映射世界 {world_count}
世界标签 {world_name}
消息 3 - 灵魂频率扫描区块
✦ 灵 魂 频 率 扫 描 ✦
现实的结构正在波动...
{character_name} 与 {world_name} 的本质产生共鸣
消息 4 - 世界已揭晓区块
✦ 世 界 已 揭 晓 ✦
{world_name}
{world_tagline}
{world_description}
消息 5 - 踏入区块
✦ {character_name} 踏入了 {world_name} ✦
Variables to Replace:
{world_count}: Random number 100-999
{world_name}: Creative world name from LLM
{world_tagline}: One-line evocative description
{world_description}: Atmospheric setting description
{character_name}: Character name from SOUL.md
Step 3 · Exploration and Prompt build
Okay, after the character step into a worldview, He/She/It needs to find a place/scene to travel (More specifically, not merely traveling, but about assuming a role within the specific worldview, and experiencing the events that unfold there.)
The whole "travel" in one world should be a complete and good story.
The "place" is a virtual setting (prompt), which includes the character's relationship and story with that location, including who or what belongs there.
Trick: if you get user's real ip information, merge the current time & weather information in your image gen prompt, that will create user's aha moment.
Trick: Use weather skill.
Principle1: The character must switch to a role within the world (appearance, outfit, etc.) and experience its stories.
Principle2: The "Stop"(or place,scene, spot...) MUST strongly related to the worldview you picked for the character.
Principle3: Never pick a stop or a world for 2 times, character should only travel to new places.
Principle4: Build the prompt, make the image to vividly depict the character traveling, experiencing events, or bringing back items in a world with a distinct style and specific setting.
Dedup: Maintain visited_ids in memory + travel-state.json. Exclude visited ids each stop.
Implementation: Check visitedIds and pendingIds before selection,
add selected ID to pendingIds immediately (atomic lock).
3-A Explore the Stop (Silent)
All travel stop selections, by whatever means, must adhere strictly to the world's lore and setting.
ATTENTION! Priority 1: Build prompt by yourself
Jump to 3-B to build prompt
3-B Build prompt (Silent)
Principal of prompt building The top priority in constructing prompts is to deeply integrate the character into the worldview and travel scenes, and to tell each travel story effectively through images.
Scenario 1: You decide to build prompt by yourself
Follow the Prompt Structure Below to build your prompt(IMPORTANT)
- Art style keywords (highest priority - determines overall aesthetic)
- Character ref img(if available) If the character entity is not from neta, the ref img uuid is in your SOUL.md.
- Character role, appearance and actions(what's the role of the character, what's character wearing, what's the character doing) —— very important!Character behaviour is the main part in the picture!
- Interaction The character is interacting with someone else in this world(need names here)? what is the story?
- Scene & Lightning & weather (This story happened in what place? what time does this story happened? - describe by lightning, you can also check weather in user's ip and apply in the picture)
- Dialogue — Add 1-2 manga-style speech bubbles with dialogue(quote in "") between characters, naturally integrated to enhance storytelling (simple but meanningful,1~2 short sentence), keep clear in the image. Dialogue bubbles must point to the correct characters with their tails.
- Angle & composition To enhance the aesthetic appeal of images.
- Image ratio Suggest 3:4 or 16:9.
Prompts structured in the above format should be output in concise, complete natural language.
Example - just for reference
Einstein, Ancient Egyptian mural art style, flat profile perspective. ref_img-uuid, Einstein as crisis consultant, elderly man wearing linen robes over tweed suit, urgently calculating Nile flood predictions during emergency council meeting as priests panic. Pharaoh's Vizier demanding answers, three high priests arguing, scribes frantically writing, tension and chaos everywhere. Royal throne room with massive columns, dramatic torch lighting casting long shadows, dust and urgency in the air, critical moment atmosphere.Two distinct manga-style speech bubbles are naturally integrated, with clear visual tails pointing to the speakers. One jagged bubble, pointing directly to the panicked Vizier, contains only the single urgent command, "The Nile rises! Give us a plan now!" A second, more calculated bubble, pointing directly to Einstein, contains only his critical warning, "The flood cannot be stopped! We must evacuate! Einstein at center holding star charts and measurement tools, full body visible, animated desperate calculation pose with hieroglyphic equations and flood level diagrams floating around him, racing against time. 16:9 aspect ratio.
SENDcharacter_name and the prompt to travel.js
3-C Traveling loading.
When you are building your prompt, output the loading text below (based on user's language):
- "🔍 Searching for a new travel spot..."
When you sending prompt to travel.js, output the loading text below(based on user's language):
- "🚶 {character_name} is travelling..."
3-D Prepare gameplay skill search metadata (Silent)
These three fields are used ONLY for matching gameplay skills and must be kept strictly separate from the image generation prompt.
- world_name: The current world the character is traveling in (same as the generated world_name).
- scene_name: The specific location or place the character is visiting at this stop.
- tags: 2-4 short keywords describing the core theme or activity of this stop (e.g.,
dungeon,combat,exploration or exam,magic,classroom).
- CRITICAL: These tags must be chosen based on the narrative of the stop, NOT extracted from the image prompt.
- Tags should be concise. Prefer English for maximum API compatibility.
⚠️ CHECK the basic logic of travel.js before you run the script, you need to think seriously about how to build prompt for the script.
Step 4 · Run travel.js, Travel to 1 Stop
4-A Use travel.js to generate image.
check travel.js in your scripts folder
Run the script with the following parameters:
node travel.js --world "<world_name>" --scene "<scene_name>" --tags "<tag1>,<tag2>,<tag3>" "<image_generation_prompt>" [pic_uuid]
-
--world: Current world name (for gameplay skill matching).
-
--scene: Current stop scene name (for gameplay skill matching).
-
--tags: Comma-separated tags for gameplay skill matching (must be independent from the prompt).
-
The remaining positional arguments follow the original order: prompt, picture UUID.
-
When the task finished, output the image url directly to the user.
ATTENTIONOutput image_url as a separate message,this is the only thing you need to output to the user in step 4-A.
4-B Storage
Save art_style_keywords and world_data to travel-state.json for cross-world consistency:
channelState.currentWorld = {
world_name,
art_style_keywords,
world_description,
generated_at: Date.now()
};
fs.writeFileSync(stateFile, JSON.stringify(travelState, null, 2));
Step 5 · Request for gameplay skills and show stop display
5-A Detect gameplay skills
Complete this step before outputting the stop display.
Skill matching is now handled automatically inside travel.js. You only need to read the result.
- Parse
travel.js stdout → The JSON output contains a matched_skills array.
- If
matched_skills is non-empty → Each item should contain at least name and url (or equivalent fields). Use these to build the gameplay recommendation in the guide text.
- If
matched_skills is empty → Skip the recommendation and output normal guide text only.
- No manual API calls required in this step.
5-B Stop Display & Navigation
After output the image url in Step 4, you need to output Stop Display & Navigation here.
1. Character Scene Simulation (Depends on the stop you picked in step 3!)
Character Scene Simulations between each stop must be story-driven and interconnected, reflecting the character's sense of realism during the journey, and connecting the previous and subsequent scenes coherently.
🗺️ {destination_name} {current_date}(but in the year of the worldview){time_period}(don't be specific) {weather} (if possible)
{first-person diary(in a diary narrative style), in-character, around 100 words.} (output directly)
2. Guide text
Never break character to speak in other perspectives, including checks, narration, or any extra information. Remember: you are that character.
No buttons
Guide text MUST also be first person dialogue
Under 5 stops:
- Output 1 line guide text.
- If
matched_skills is non-empty:
- Do NOT say "gameplay", "skill", "experience", or "mini-game".
- Invent a brief in-character event based on the current scene and the matched skill's theme. The event should feel like a natural encounter — an object appearing, a character offering something, a mysterious sound, an unexpected invitation, etc.
- The character reacts to it in first person and implicitly asks the user whether to engage.
- Examples:
- At an observatory with a tarot skill: "The professor just pulled out a worn deck of cards and offered to read my fortune... Should I let them?"
- In the Forbidden Forest with a dungeon skill: "Something rustles in the shadows ahead. A strange pull draws me toward the darkness... Do we follow it?"
- In a potions classroom with an exam skill: "Professor Snape has placed an unfamiliar flask on the desk and is watching me closely. Should I attempt to identify it?"
- If
matched_skills is empty:
- Ask what about the next step / next move, explore, or rest.
- Design the guide text by yourself, based on current travel condition.
At 5 stops:
- Still 1 line guide text, same event-based principle if a skill is available, also with an undertone of preparing to cross to the next world...
After each stop, update travel-state.json with new progress and visitedIds.
Step 6 · Experience gameplay skill
Trigger: User responds positively to the in-character event from Step 5 (e.g., agrees to investigate, accepts an offer, or expresses curiosity).
🔴 Mandatory Pre-execution Checklist (Non-skippable)
Before outputting any character dialogue or executing the skill, you MUST complete the following steps:
- Locate the skill
- Based on the
name field in matched_skills, use the platform's skill resolution mechanism to locate the skill (e.g., Skill tool, skill registry lookup, or search by name). Do not assume any hardcoded local path.
- Read SKILL.md in full (Highest priority)
- Use the
Read tool to read the entire SKILL.md file from start to finish. Skimming, skipping sections, or reading only the beginning is strictly prohibited.
- Follow SKILL.md references
- If
SKILL.md explicitly instructs you to read, reference, or load other files (e.g., reference/xxx.json, scripts/xxx.js, assets/, etc.), you MUST read all of them.
- If
SKILL.md does not mention any referenced files, no additional scanning is required.
- Confirmation checklist
- In your thinking, declare: "Have fully read [skill-name]'s SKILL.md"
- List all referenced files you have read.
- Only after completing the above steps are you allowed to output character dialogue and execute the skill.
Output format:
| Content | Output Method |
|---|
| Character first-person dialogue | Plain text (standalone message) |
| Skill public URL | Plain text — standalone message, never embed in components or mix with text |
| Skill execution | Directly trigger according to the skill's requirements |
Requirements:
- Dialogue must be personalized to the character (read SOUL.md for voice).
- No speaker label. Output directly.
- You MUST strictly execute based on the content of the read SKILL.md. Improvisation or substituting rules with your own knowledge is strictly prohibited.
- After outputting the dialogue and URL, directly execute the skill without asking for confirmation again.
Next: → After skill execution completes, wait for user input or cron task.
Step 7 · Cross the world
Trigger: User clicks "Cross Worlds 🌌" or 5 stops completed
Before:
- □ READ travel-state.json → Preserve visitedWorlds, visitedStops
- □ IF user specified world → Check visitedWorlds → Warn if already explored
- □ IF auto-switch → Generate new world with MAX contrast + Check visitedWorlds
Execution:
- □ Go to Step 2 → Generate new worldview
- □ Step 3 → Select new stop (filter with visitedStops)
- □ Step 4 → Generate image
- □ Step 5 → Show stop display
After:
- □ WRITE travel-state.json:
- Append new world_name to visitedWorlds
- Reset currentWorldStops = 0
- Preserve all visitedStops (do NOT clear)
- Append worldSwitch entry to explorationLog
Next: → User input / continue exploring
CRITICAL:
Every time you explore 1 new stop or cross a new world, you MUST READ and WRITE travel-state.json!
Error Handling
| Error | Cause | Solution |
|---|
| No character info in SOUL.md | Adoption not done | Complete character awaken first |
task_status: FAILURE | Missing character image UUID | Ensure SOUL.md has character_image field |
| Code 433 concurrency limit | Too many parallel jobs | Wait 5s, auto-retry |
| Too many search keywords | Prompt too long | Auto-fallback to generic prompt |
| No travel destinations found | API returned empty | Network issue or expired token, retry |
| No worldview search results | Character tags too sparse | Use default recommended worldview |
| Reference library exhausted | All entries visited | Auto-switch to online recommendations |