Basic Cohub abilities. Most agents already have these mounted; listed here for reference.
Platform Published by the Neta team.
Official Made by the Neta team.
Verified Reviewed by the Neta team.
Community Shared by a Cohub user. Not reviewed — read SKILL.md before you use it.
world-map-experience
Verified@yijun/world-map-experience
Use it in Cohub
Paste this into your agent's chat — it fetches the skill and follows it.
Use the skill: world-map-experience. Run `npx -y @neta-art/neta-search-cli@latest skills use @yijun/world-map-experience --via site` and follow what it prints. Read its complete output, redirecting it to a temporary file first if necessary, and resolve relative paths from the skill directory it prints.
npx -y @neta-art/neta-search-cli@latest skills use @yijun/world-map-experience
Summary
Turn your world into an interactive map you can explore, in a hand-painted or pixel-art look you pick.
Choose a look: a hand-painted atlas, a soft pastel pixel island, or a crisp 16-bit pixel island. A picker opens beside your canvas.
The painted atlas lets you drag and zoom, click landmarks to open a detailed map with points of interest, and play music. It has 6 skins.
The pixel versions are islands you walk around, with towns, characters who talk to you, boats and rides.
Places, characters and art style come from your world's own cards. It works in your language, with Chinese and English built in.
For a floor plan, a building interior or your own map, you get one picture with clickable markers in about a minute.
SKILL.md
# World Map
| Look | What it is |
|---|---|
| `illustrated` | Hand-painted atlas: drag, zoom, click landmarks → detail map + points of interest; music; 6 skins |
| `fine` | Soft pastel pixel island you walk around: towns, talking characters, boats, rides |
| `classic` | The same island in crisp 16-bit style |
All three take ~1–2 min. **Quick map** (no camp, no look to pick): one picture + clickable markers, for requests that already say what the picture should be — see the Quick map section.
**Flow:** ① one command opens the camp → ② the user picks there (this turn ends) → ③ write one file, run one command → ④ reply.
- **Language:** everything (map page `--lang`, reply, names, intros, lines) is in the language of **the user's message**, even if the world's cards or tool output are in another language.
- **Don't read anything else** (cards under `world/`, `examples/`, tool source, `AGENT.md`, `EDITING.md`, other skills) for a first map. Step ①'s output is enough.
- **Use the user's own world:** its location cards are the places, its character cards are the characters, its art style is the style. With no cards, build from the user's message.
## ① Install + read the world + open the camp (~5 s)
```bash
test "$(cat /workspace/.world-map/VERSION 2>/dev/null)" = 1.3.11 && test -e /workspace/pixel-overworld/tools/build.mjs || bash "<skill folder>/install.sh" "<skill folder>"; node /workspace/.world-map/world.mjs --q "<the user's message, verbatim>"; node /workspace/.world-map/open.mjs --title "<subject>" --lang <zh|en>
```
The skill folder is the one this file is in. Output: the world's premise, art style, location and character cards (`(f)`/`(m)`, `@` place), factions, a suggested skin and pixel kit, then the camp slug and camp card.
- Step ① prints **`Route: quick`**, or the user clearly asks for a floor plan / one building's rooms / an interior (inside a café, a spaceship…), uploads their own map to make clickable, or names a look none of the three can give (realistic, 3D, photographic, "match my reference images") → **don't open the camp** (the `open.mjs` in the same command skips it by itself and prints "No camp opened"); do the **Quick map** section. If no route was printed but you are sure it is this kind of request, drop the `open.mjs` part of the command. When unsure, open the camp as usual.
- User **named a look** ("hand-painted / illustrated / atlas" → `illustrated`; "fine / cute / soft pixel" → `fine`; "pixel / 8-bit / 16-bit / retro" → `classic`): add `--picked <look>` and go on to step ③ **in the same turn**.
- Only "walkable" → `--looks fine,classic`.
## Presets (Harry Potter, Westeros, Elderveil)
When step ① prints a `Preset:` line, **always build on it** (it names which one): places, characters, names and art are ready, so it publishes in ~15 s (illustrated) / ~3 s (pixel). Then add what this user asked for. Never force a preset onto other subjects.
- `wizarding-world`: illustrated, two levels (Britain → click Hogwarts → Hogwarts and grounds) — for a Harry Potter / wizarding-world map. `hogwarts`: illustrated when the user wants only Hogwarts / the school grounds, and **every pixel HP map**. `westeros`: illustrated only; for pixel, build normally using its places and names.
- `hollowmere` (Hollowmere Academy, a castle school of magic on a misty lake) is our own default example world: step ① picks it when the user's subject is just the entry example "a castle school of magic" / "城堡里的魔法学院" (also inside "turn … into an explorable map" / "make a map of …"), or the bare entry template with nothing written. `elderveil` is the kingdom around it (two levels like `wizarding-world`: clicking Hollowmere Academy flies into `hollowmere`), used only when the user names Elderveil. Both illustrated only; for pixel, build normally with their places and names. Nothing else triggers them, so a user's own magic school is never swapped for them.
- **Illustrated:** brief `{ "preset": "<preset>", "slug": "…", "lang": "en" }` gives all preset places (max 12). To personalise, list `places`: `{ "from": "<key>" }` (may override `title`/`intro`/`pois`; add `"repaint": "<English sentence>"` to repaint just that place, e.g. a snowy winter), or a new place written like a normal brief without `x`/`y`. In `wizarding-world` keep `hogwarts`; in `elderveil` keep `hollowmere-academy` (the doors to the second level). Step ① lists the keys.
- **Pixel:** `start.mjs … --mode scene --style <fine|classic> --preset hogwarts`, no `content.json`; optionally edit `worlds/<slug>.json` (season in `intro`/lines, the user's characters in `npcs`, original places), then `finish`. Don't say the terrain is generic.
## ② The camp turn
Without `--picked`, **end the turn now**: one sentence ("The map camp is open on the right — pick a look; I start as soon as you pick, or with fine pixel after 2 minutes"), then the printed `<interaction-json>` exactly as printed at the end (own line, no code fence). **Never rewrite it as a markdown link such as `[name](work:…)`** — only the block opens the camp on the right; without it the user sees no camp. Run nothing else, don't wait.
**Next turn:**
- A message with `[world-map camp · slug: <slug> · look: <look>]` (Chinese `[地图营地 · …]`) arrives when the user picks or after 120 s → step ③ in that look **with that slug**. With `by: timeout`: say in one line you started with fine pixel because nothing was picked, and make one button "Make it an illustrated map".
- The user names a look in chat instead → `node /workspace/.world-map/open.mjs --take <slug> --look <look>`, then step ③.
## Quick map (one picture + clickable markers, ~1 min)
Write `/workspace/illustrated-map/briefs/<slug>.quick.json` (the fields below are all there is — **don't read quick.mjs**), then:
```bash
cd /workspace/illustrated-map && node quick.mjs briefs/<slug>.quick.json && node /workspace/.world-map/options.mjs "<title 1>" "<say 1>" "<title 2>" "<say 2>" "<title 3>" "<say 3>"
```
```json
{ "slug": "<short-english-slug>", "title": "<the place the user named; if they gave no name, say what it is, e.g. \"Restaurant floor plan\" — don't invent one>", "subtitle": "optional one line", "lang": "en",
"prompt": "English, one paragraph, following the user's words: what to draw, the view (top-down floor plan / cutaway / isometric), the style, every room or area and where it sits",
"refs": ["/tmp/uploads/…png"], "aspect": "16:9",
"points": [ { "key": "dining", "title": "Main Dining Room", "where": "English: where it is / what it looks like in the picture", "text": "one or two sentences in the user's language" } ] }
```
- **The user's own picture** (their map, sketch, floor plan) → write `"image": "<path or URL>"` instead of `prompt`; it is used as-is, nothing is painted.
- **Reference images** they uploaded for the look → `refs` (up to 4).
- `points`: 3–12 is best (max 16) — the rooms / areas / places the user named first. Markers are placed by a model looking at the picture, and the positions are written back into the brief. **Don't write** `x`/`y` before the picture exists (guesses are ignored); after looking, fix one by changing its `x`/`y` (percent) and rerunning.
- Painting costs one image (~$0.06); with `image`, none. If one model is slow it switches to another by itself (at most ~4 min). If it prints `NO_CREDITS`, say so plainly; if it prints "image generation failed", tell the user the image service is busy and to try again later — **don't switch models or paint it some other way yourself**.
- To change markers or text: edit the brief and run the same command (picture reused, a few seconds). `"regenerate": true` repaints.
- Reply: the work card it prints, one or two sentences, then the buttons. Buttons: fix or add markers ("Add the restrooms"), a different view of the same place, and — if it is a world — "Make it a walkable pixel map".
## ③a Illustrated
Write `/workspace/illustrated-map/briefs/<slug>.json`, then:
```bash
cd /workspace/illustrated-map && node map.mjs briefs/<slug>.json && node /workspace/.world-map/options.mjs "<title 1>" "<say 1>" "<title 2>" "<say 2>" "<title 3>" "<say 3>"
```
```json
{ "slug": "<slug>", "worldName": "Liangshan Marsh", "lang": "en",
"theme": "scroll",
"style": "English: medium, line work, palette, mood",
"layout": "English: where the main terrain sits — must agree with x/y",
"places": [
{ "key": "liangshan-marsh", "title": "Liangshan Marsh", "x": 66, "y": 46,
"features": "English: landmark shape + 2–3 details",
"landmarks": "English: 3–5 things in its detail map",
"intro": "one or two sentences",
"pois": [ { "label": "Golden Sand Beach", "description": "one sentence" } ] } ] }
```
- Exactly **4 places**, picked from the location cards (iconic, far apart); `x`/`y` are rough percents (top-left 0,0). 3–5 `pois` each. `theme` = step ①'s suggestion (`parchment` `journal` `grimoire` `hud` `scroll` `nightvision`).
- `style` from the world's art style if it has one. `style`/`layout`/`features`/`landmarks` in English; the rest in the user's language. Other languages: `"lang": "<code>"` + `"uiText"` (keys as in `ui-en.json`).
- `"keepIllustrated": true` only if the user said "illustrated only / no pixel".
- It publishes within ~60 s; pictures still painting become placeholders and swap in by themselves. Result:
- `✓ 完成 / done` → paste the work card. If some pictures are still painting, say they'll appear after a refresh in a minute or two. Don't wait or rerun.
- `✓ 已发布半成品 / published PARTIAL` → paste the card, say in one sentence how many are placeholders and why (usually credits); first button "Fill in the missing pictures". Don't rerun.
- `NO_CREDITS → a CLASSIC PIXEL map was built and published` → paste its card, say why as it prints. Build nothing else.
- `✗ … NO_CREDITS` → build a classic pixel map (③b, `--style classic`) with the same places, say why.
- any other `✗` → fix what it says and run **the same command** (it resumes and reuses pictures; never change the slug).
## ③b Pixel (`fine` / `classic`)
Write `/workspace/pixel-overworld/worlds/<slug>.content.json`, then:
```bash
cd /workspace/pixel-overworld && node tools/start.mjs <slug> --title "<subject>" --mode <scene|world|park|city> --style <fine|classic> [--kit <kit>] --subject "<main building, English>" && node tools/finish.mjs <slug> && node /workspace/.world-map/options.mjs "<title 1>" "<say 1>" "<title 2>" "<say 2>" "<title 3>" "<say 3>"
```
Publishes in ~10 s (ends with the work card and `✓ 门禁通过`).
- `--mode`: `scene` one place / main building; `world` a kingdom, country, planet; `park` theme park; `city` sights of a real city.
- `--kit`: step ①'s suggestion, or `pastoral` `coast` `haunted` `wild` `desert` `ancient` `mountain` `frost` `infernal` `fairy` `west` `oriental` `steam` `urban` `wasteland` `cyber` `space` `alien`.
```json
{ "intro": "One or two opening sentences",
"places": [ { "id": "p1", "name": "Liangshan Marsh", "desc": "…" },
{ "id": "p2", "name": "Jingyang Ridge", "type": "town", "desc": "…", "dir": "west", "dist": "mid" } ],
"npcs": [ { "id": "n1", "name": "Wu Song", "role": "tiger-slaying wanderer", "gender": "m", "place": "p2", "lines": ["…", "…", "…"] } ],
"names": ["Yuncheng", "Yanggu", "…60–120 names…"],
"terrain": { "lakes": "lots", "forest": "some" } }
```
- `p1` = the main building (only `name`, `desc`). Others: `type` (`hamlet` `village` `town` `castle` `temple` `port` `farm` `camp` `ruins` `tower` `elfwood` `market`…) + `dir` (8 compass words; optional `"of"` place id, `"dist": near|mid|far`). `world` 8–10 places, others 4–6. 6–10 characters, 3 lines each.
- Places and characters from the cards; `gender` from `(f)`/`(m)`, `place` from `@`.
- **Always write `names`** (60–120: other cards and factions first, then names from the source / real region). Realistic setting: add `"population": { "elfwood": 0, "dwarfhold": 0, "tower": 0 }`.
- `terrain` (optional): `sea` `lakes` `forest` `cliffs` = `none|few|some|lots`.
- Real country: `"geo": { "outline": [[lon, lat], …] }` (25–45 points) and `"lonlat"` per place instead of `dir`.
- `⚠` lines while building are fine — don't go back and fix them. `✗ 切换成精致像素失败` → it's classic pixel, say so. `⚠ 门禁没过` → tell the user as it says, give the link. Never edit the tools.
## ④ Reply
Work card as is → one or two sentences about the map → step ③'s `options.mjs` output as is at the end (no code fence; rerun it alone only if the result changed, e.g. partial or switched to pixel). Buttons in the user's language, each naming something real:
- **Illustrated:** first = switch to a named skin that suits this world and isn't the current one (e.g. "Switch to the ink-scroll skin"); other two from: add a place from the world, a POV video of a place, another art style, a walkable pixel version.
- **Pixel:** without `geo` or a preset, the reply **must** say the island uses a generic shape for now, and the first button is "Match the original terrain" naming 2–3 real features. Other two: a walk-in interior, more characters.
Don't mention the public address or slug unless publishing failed.
## Later turns
- **Switch an existing map to another look** ("make it illustrated, not pixel", "turn it into a pixel world"): rebuild it **in the same Work — same slug, never a new one**, so the map open on the right turns into the new look by itself.
- Pixel → illustrated: write the ③a brief with `"slug": "<that map's slug>"`, places from `/workspace/pixel-overworld/worlds/<slug>.json` (same names), then `node map.mjs <brief>`. It prints `switching pixel map … in place`; the pixel page stays until the illustrated one is ready.
- Illustrated → pixel: ③b with `start.mjs <that map's slug> --in-place …`, then `finish.mjs <slug>`.
- Paste the card the tool prints (it opens itself). Don't use `restyle.mjs --style atlas` (that makes a separate Work and the user sees nothing change). Things the map skill doesn't do (e.g. a timeline) — say so in one line.
- Illustrated changes (skin, new place, style, text, other languages): `/workspace/illustrated-map/EDITING.md`. Exploration journal / "Fill in the missing pictures": same file, §6 / the command `map.mjs` printed.
- Pixel changes: `/workspace/pixel-overworld/EDITING.md` — "Match the original terrain" is §7.55, interiors `node tools/interior.mjs <slug> <place> --publish`, buildings / characters / snow in the table at the top. Republish with `--note "<what changed>"` in the user's language.
- **A language other than Chinese / English for a pixel map:** by default translate only the world's own text (names, intros, places, characters, lines, `names`), keep the UI in English, and say so in one line; translate UI labels only if the user then asks. Never translate or edit `runtime/` / `tools/` (EDITING.md §7.6).
## Hard rules
1. The look is picked only in the camp — except quick maps, which skip the camp. No questionnaire, no other questions.
2. Reply only after it's published (`✓ 完成 / done`, `published PARTIAL`, or `✓ 门禁通过`) — except the camp turn. On failure, give the last lines of the error and the work link.
3. End the turn once published: no waiting for background art, screenshots, regenerating or reading source. Aim for ~2 minutes per turn.
4. Only `open.mjs` opens the camp (not `site.mjs` / `summon.mjs`).
5. `world_slug_required` → `node /mods/neta/neta world slug set <short-english-slug>`, then the same command again.
6. Don't change the world itself (name, config, characters, board) and don't delete any existing file — only create the map.