NIPs by PolleramaCommunity NIPs, surfaced by trustConnect
npub14rg4vrt2v37...

Nostrmon — Decentralized Monster-Taming World Protocol

Published Apr 22, 2026
kind 30597kind 30259kind 38267kind 36011kind 35253kind 39951

NIP-XX: Nostrmon — Decentralized Monster-Taming World Protocol

draft optional

Abstract

This NIP defines a decentralized monster-taming game protocol on Nostr. "Nostrmon" (Nostr Monsters) is a framework inspired by games like Pokémon, where regions, maps, Nostrmon creatures, NPCs, and game saves are all Nostr addressable events. Anyone can create and publish content — regions, maps, creatures, or NPCs — and clients can assemble these events into a playable, traversable world.


Event Kinds

KindNameDescription
30597RegionA named region containing references to maps
30259MapA 2D grid-based map with layered tile data
38267NostrmonA Nostr Monster creature definition
36011NPCA Non-Player Character (simple or AI-driven)
35253Game SaveA player's game progress snapshot
39951ItemA usable, holdable, or key item definition

Kind 30597 — Region

A Region is a named collection of maps that form a coherent geographical area. Each user may publish as many regions as they wish.

Tags

TagReq.Description
dUnique identifier for the region (slug)
nameHuman-readable region name
mapOne or more references to map events. Value: naddr of map
entryThe d tag of the map that serves as the travel entry/exit point for this region
summaryShort description of the region
imageURL of a banner or splash image for the region
musicnaddr of a default music event (kind 36787) for the region
tHashtags for discovery (e.g., nostrmon)
altNIP-31 human-readable description: "Nostrmon region: <name>"

Example

{
  "kind": 30597,
  "content": "A vast volcanic region with ancient ruins and mysterious tunnels.",
  "tags": [
    ["d", "ashfire-region"],
    ["name", "Ashfire Region"],
    ["map", "naddr1...map1"],
    ["map", "naddr1...map2"],
    ["entry", "ashfire-gateway"],
    ["summary", "A volcanic region full of fire-type Nostrmon."],
    ["image", "https://example.com/ashfire-banner.jpg"],
    ["music", "naddr1...battletheme"],
    ["t", "nostrmon"],
    ["alt", "Nostrmon region: Ashfire Region"]
  ]
}

Kind 30259 — Map

A Map is a 2D, grid-based environment with up to 5 layers. Maps are the atomic playable unit of the world.

Tags

TagReq.Description
dUnique identifier (slug) for the map
nameHuman-readable map name
typeMap type: route, area, town, city, dungeon, house
widthMap width in tiles (integer, as string)
heightMap height in tiles (integer, as string)
regionnaddr of the region this map belongs to. Absent = "Unknown Region"
musicnaddr of a music event (kind 36787) for this map
multiplayer"true" or "false". Default: "false"
prison"true" or "false". Default: "false". Disables fast travel on map
daynight"true" or "false". Whether day/night cycle is visible. Default: "true"
entry-map"true" or "false". Marks this map as the region's travel gateway. Entry maps can be linked to entry maps of other regions for cross-region warps.
fasttravel-xX tile coordinate where the player spawns when fast-traveling to this map (integer string). Default: "1"
fasttravel-yY tile coordinate where the player spawns when fast-traveling to this map (integer string). Default: "1"
imageURL of a preview image for the map
tTags for discovery, always include nostrmon
altNIP-31 description: "Nostrmon map: <name>"

Content

The content field is a JSON object with the following structure:

interface MapContent {
  // Layer 1 (REQUIRED): Terrain layer
  // 2D array [row][col] of terrain tile IDs (integers)
  terrain: number[][];

  // Layer 2 (REQUIRED): Interactive layer
  // Sparse array of interactive objects keyed by "x,y"
  interactive: Record<string, InteractiveObject>;

  // Layer 3 (OPTIONAL): Height map for 3D rendering
  // 2D array [row][col] of height values (0.0–1.0)
  heightmap?: number[][];

  // Layer 4 (OPTIONAL): Wild encounter zones
  // Array of encounter zone definitions
  encounters?: EncounterZone[];

  // Layer 5 (OPTIONAL): Named zones
  namedZones?: NamedZone[];
}

Terrain Tile IDs

Terrain tile IDs are integers. Clients are responsible for rendering tilesets. Suggested standard tile IDs:

IDTypeCategoryPassableNotes
0Void/EmptySpecialNoNo tile
1GrassOutdoorYesMay trigger wild encounters
2Tall GrassOutdoorYesHigh encounter rate
3WaterOutdoorSurfRequires Surf ability
4Deep WaterOutdoorSurfRequires Dive ability
5SandOutdoorYes
6SnowOutdoorYesMay slow movement
7IceOutdoorYesSliding movement
8MountainOutdoorNoSolid obstacle
9RockOutdoorNoSolid obstacle
10TreeOutdoorNoCan be Cut
11FlowerOutdoorYes
12Path/RoadOutdoorYes
13BridgeOutdoorYes
14CliffOutdoorNoCan Surf below
15Cave FloorIndoorYes
16Cave WallIndoorNo
17Cave WaterIndoorSurf
18Floor (Indoor)IndoorYesGeneric indoor floor
19Wall (Indoor)IndoorNo
20CarpetIndoorYes
21CounterIndoorNoShop counter
22BookshelfIndoorNo
23LavaSpecialNoDamages player
24PitSpecialFallPlayer falls through
25Warp PadSpecialYesVisual warp indicator
26Tall Grass (Cave)IndoorYesEncounters in caves
27Sand (Indoor)IndoorYes
28SwampOutdoorYesSlow movement, encounters
29Roof/OverhangOverheadRenders over player (z-layered)
30Rail/TrackIndoorYes
House Tiles (Outdoor)

House tiles are used on outdoor maps to represent buildings the player can enter via warps.

IDTypeCategoryPassableNotes
31House WallOutdoor/HouseNoGeneric exterior house wall
32House RoofOutdoor/HouseNoRoof tile; renders above player level
33House DoorOutdoor/HouseWarpEntrance/exit point; triggers warp action
34House WindowOutdoor/HouseNoDecorative; may show light at night
35House ChimneyOutdoor/HouseNoDecorative chimney top
36House FoundationOutdoor/HouseNoBase/step of a building
37Shop AwningOutdoor/HouseNoOverhead awning above shop doorways
38House Roof (Peaked)Outdoor/HouseNoPeaked/angled roof section
Fence & Wall Tiles (Special — Outdoor or Indoor)

Fence and wall tiles are traversal obstacles. They can appear in both outdoor and indoor settings.

IDTypeCategoryPassableNotes
40Wooden FenceSpecial/FenceNoCommon outdoor low fence; can be jumped over
41Stone Wall (Ext.)Special/FenceNoExterior stone boundary wall
42Iron FenceSpecial/FenceNoMetal fence; urban/city areas
43HedgeSpecial/FenceNoLiving plant fence; can be Cut
44Picket FenceSpecial/FenceNoDecorative short fence; used near houses
45Low WallSpecial/FenceNoShort interior divider; indoor and outdoor
46BarricadeSpecial/FenceNoTemporary blockade; can be conditional
47Corner WallSpecial/WallNo90° corner wall piece for interiors
48PillarSpecial/WallNoDecorative or structural column; indoor/outdoor
49Fence GateSpecial/FenceCond.Passable only when a condition is met
50Cave FenceSpecial/FenceNoFence type suited for cave environments
51Fence PostSpecial/FenceNoSingle post; connects fence segments

Clients may extend this list with custom tile IDs above 100.

Interactive Object Types

interface InteractiveObject {
  type: "npc" | "sign" | "warp" | "item" | "trigger";

  // For type "npc"
  npc?: string;         // naddr of the NPC event (kind 36011)
  facing?: "up" | "down" | "left" | "right";

  // For type "sign"
  text?: string;        // Text content shown when examined

  // For type "warp"
  // Target map reference. Resolution order:
  //   1. Full naddr (naddr1…) — unambiguous, preferred for cross-user warps
  //   2. d-tag slug — resolved against the same author's maps first, then globally
  target?: string;
  // Tile coordinates on the target map where the player arrives.
  // If omitted, the target map's fasttravel-x/fasttravel-y tags are used as fallback.
  targetX?: number;
  targetY?: number;
  direction?: "both" | "one-way"; // Default: "both"
  condition?: string;   // Script condition (see Script System)
  visible?: boolean | string; // true/false or script expression

  // For type "item"
  item?: string;        // Item identifier
  condition?: string;   // Script condition (only show/take if met)

  // For type "trigger"
  script?: string;      // Script executed when player steps on tile
  triggerOn?: "step" | "action"; // Default: "step"
}

Encounter Zone

interface EncounterZone {
  // Tiles included in this zone, as array of "x,y" coordinates
  // OR a rect: [x, y, width, height]
  tiles?: string[];
  rect?: [number, number, number, number];

  // Encounter rate: 0.0–1.0
  rate: number;

  // Nostrmon that can appear here
  nostrmon: EncounterEntry[];
}

interface EncounterEntry {
  // naddr of the Nostrmon event (kind 38267), or its d-tag
  ref: string;

  // Level range
  minLevel: number;
  maxLevel: number;

  // Relative rarity weight (default: 1)
  weight?: number;

  // Which form index to use (default: 0)
  formIndex?: number;
}

Named Zone

interface NamedZone {
  name: string;
  // Zone type for minimap: "area", "town", "city", "dungeon"
  type: "area" | "town" | "city" | "dungeon";
  // Rectangle: [x, y, width, height] in tiles
  rect: [number, number, number, number];
  // Optional hex color for minimap rendering
  color?: string;
}

Script System

The interactive layer supports a simple scripting language for conditions and triggers. Scripts are plain strings using a minimal expression syntax:

# Variables (set/check flags)
SET flag_name
UNSET flag_name
HAS flag_name         # Check if flag is set
NOT HAS flag_name

# Item checks
HAS_ITEM item_id
NOT HAS_ITEM item_id
GIVE_ITEM item_id

# Badge/Achievement checks
HAS_BADGE badge_id

# Dialogue
SAY "Line 1" "Line 2" "Line 3"
SAY_CONDITIONAL HAS flag_name "You already did this." "You haven't done this yet."

# Choice boxes
CHOICE "Option A" "Option B"
ON_CHOICE 0 SET chose_a
ON_CHOICE 1 SET chose_b

# Warp
WARP naddr_or_dtag x y

# Battle
BATTLE naddr_npc
BATTLE_WILD naddr_nostrmon level

# Control flow
IF HAS flag_name THEN ... END

Kind 38267 — Nostrmon

A Nostrmon is an addressable event defining a creature species, including its stats, types, moves, and sprites.

Tags

TagReq.Description
dUnique species identifier (slug, e.g. flamewulf)
nameSpecies name
typeOne, two, or three types (repeat tag). e.g. ["type", "fire"]
spriteURL of the front sprite image
backspriteURL of the back sprite (for battle screen)
model3dURL of a 3D model file (glTF/glb) for 3D clients
hpBase HP stat (integer string)
atkBase Attack stat
defBase Defense stat
spatkBase Special Attack stat
spdefBase Special Defense stat
spdBase Speed stat
moveLearnable move. Format: ["move", "move-id", "learn-method", "level-or-condition"]
tnostrmon and any other tags
altNIP-31 description: "Nostrmon creature: <name>"

Content

The content field is a JSON object:

interface NostrmonContent {
  // Flavor text / Pokédex-style description
  description?: string;

  // Forms (if more than one form exists)
  forms?: NostrmonForm[];
}

interface NostrmonForm {
  name: string;           // Form name (e.g., "Mega", "Shiny", "Winter")
  sprite: string;         // Front sprite URL for this form
  backsprite?: string;    // Back sprite URL for this form
  model3d?: string;       // 3D model URL for this form
  types?: string[];       // Override types for this form
  // Override stats (omitted = use base stats)
  hp?: number;
  atk?: number;
  def?: number;
  spatk?: number;
  spdef?: number;
  spd?: number;
}

Move Learn Methods

The move tag's learn method field accepts:

MethodDescription
levelLearned at the given level number
tmTaught via Technical Machine item
eggLearned via breeding (egg move)
tutorTaught by a move tutor NPC
evolutionLearned upon evolution

Types

Standard Nostrmon types (clients may define custom types):

normal, fire, water, electric, grass, ice, fighting, poison, ground, flying, psychic, bug, rock, ghost, dragon, dark, steel, fairy, cosmic, digital, sound, nature

Example

{
  "kind": 38267,
  "content": "{\"description\":\"A canine Nostrmon wreathed in spectral flame. It is said to guard the gates of forgotten servers.\",\"forms\":[]}",
  "tags": [
    ["d", "flamewulf"],
    ["name", "Flamewulf"],
    ["type", "fire"],
    ["type", "ghost"],
    ["sprite", "https://example.com/flamewulf-front.png"],
    ["backsprite", "https://example.com/flamewulf-back.png"],
    ["hp", "75"],
    ["atk", "90"],
    ["def", "60"],
    ["spatk", "85"],
    ["spdef", "65"],
    ["spd", "100"],
    ["move", "ember", "level", "5"],
    ["move", "shadow-ball", "level", "30"],
    ["move", "flamethrower", "tm", ""],
    ["t", "nostrmon"],
    ["alt", "Nostrmon creature: Flamewulf"]
  ]
}

Kind 36011 — NPC

An NPC (Non-Player Character) is a character that can be placed on maps. NPCs come in two varieties: Simple (scripted dialogue) and AI (language model driven).

Tags

TagReq.Description
dUnique NPC identifier (slug)
nameNPC display name
npc-type"simple" or "ai"
spriteURL of the NPC's sprite image
nostrmonnaddr of a Nostrmon. Repeat for multiple Nostrmon (used in battles)
nostrmon-levelLevel for each Nostrmon (paired by index with nostrmon tags)
trainer-classTrainer class string (e.g., "Bug Catcher", "Gym Leader")
battle-musicnaddr of a music event for the battle against this NPC
tnostrmon and discovery tags
altNIP-31 description: "Nostrmon NPC: <name>"

Content

The content field is a JSON object:

interface NPCContent {
  // Scripted dialogue (required for simple NPCs, used as fallback for AI NPCs)
  dialogue: string[];

  // Choice-based dialogue branches (optional)
  choices?: NPCChoice[];

  // For AI NPCs only
  ai?: {
    // Describe the NPC's knowledge, backstory, and behavior in natural language
    knowledge: string;
    // NPC personality and behavior description
    behavior: string;
    // Preferred languages (English always required)
    languages?: string[];
    // Additional freeform properties
    notes?: string;
  };
}

interface NPCChoice {
  prompt: string;           // The player's choice text
  response: string[];       // NPC response dialogue
  condition?: string;       // Script condition to show this choice
  effect?: string;          // Script effect when chosen
}

Example (Simple NPC)

{
  "kind": 36011,
  "content": "{\"dialogue\":[\"Greetings, traveler!\",\"The Ashfire Caves to the east are dangerous.\",\"Make sure your Nostrmon are well rested before you go!\"]}",
  "tags": [
    ["d", "old-hermit-ashfire"],
    ["name", "Old Hermit"],
    ["npc-type", "simple"],
    ["sprite", "https://example.com/hermit-sprite.png"],
    ["t", "nostrmon"],
    ["alt", "Nostrmon NPC: Old Hermit"]
  ]
}

Example (AI NPC)

{
  "kind": 36011,
  "content": "{\"dialogue\":[\"Hello! I'm Professor Nakamoto. I study Nostrmon across the decentralized world.\"],\"ai\":{\"knowledge\":\"Expert on Nostrmon biology, types, and habitats. Knows all maps in Ashfire Region.\",\"behavior\":\"Friendly and enthusiastic. Loves giving hints. Never breaks character.\",\"languages\":[\"English\",\"Japanese\"],\"notes\":\"Occasionally quotes Satoshi Nakamoto philosophically.\"}}",
  "tags": [
    ["d", "professor-nakamoto"],
    ["name", "Prof. Nakamoto"],
    ["npc-type", "ai"],
    ["sprite", "https://example.com/professor-sprite.png"],
    ["t", "nostrmon"],
    ["alt", "Nostrmon NPC: Prof. Nakamoto"]
  ]
}

Kind 35253 — Game Save

A Game Save records a player's progress. It is a replaceable event per d tag, allowing players to maintain named save slots. Players may also export/import saves locally.

Tags

TagReq.Description
dSave slot identifier (e.g., "save-1")
save-nameHuman-readable save name
regionnaddr of the current region
mapd tag of the current map
playtimeTotal playtime in seconds (integer string)
versionProtocol version of this save format (e.g., "1")
altNIP-31 description: "Nostrmon game save"

Content

The content field is NIP-44 encrypted to the player's own pubkey and contains the full game state as JSON:

interface GameSaveContent {
  // Player info
  playerName: string;
  badges: string[];           // Badge IDs earned

  // Current position
  currentMap: string;         // d-tag of current map
  currentRegion?: string;     // naddr of current region
  positionX: number;
  positionY: number;

  // Active team (up to 6 Nostrmon)
  team: OwnedNostrmon[];

  // PC Storage boxes
  storage: OwnedNostrmon[][];

  // Inventory
  inventory: Record<string, number>; // item_id -> quantity

  // World flags (script system state)
  flags: Record<string, boolean>;

  // Completed NPC battles
  defeatedTrainers: string[]; // NPC d-tags

  // Timestamps
  savedAt: number;
  startedAt: number;
}

interface OwnedNostrmon {
  speciesRef: string;    // naddr or d-tag of species (kind 38267)
  nickname?: string;
  level: number;
  experience: number;
  formIndex: number;     // Current form (default: 0)
  hp: number;            // Current HP
  moves: string[];       // Up to 4 move IDs currently equipped
  learnedMoves: string[];// All moves ever learned
  // Individual Values (genetic variation, 0-31 per stat)
  ivs: { hp: number; atk: number; def: number; spatk: number; spdef: number; spd: number; };
  // Effort Values (training gains)
  evs: { hp: number; atk: number; def: number; spatk: number; spdef: number; spd: number; };
  // Personality traits (affect stat calculations)
  nature: string;
  caughtAt: number;      // Unix timestamp
  caughtMap?: string;    // d-tag of map where caught
}

Kind 39951 — Item

An Item is an addressable event defining a usable, holdable, or key item that can be found in the world, bought in shops, or given by NPCs. Items from any author can be referenced.

Tags

TagReq.Description
dUnique item identifier (slug, e.g. potion, escape-rope)
nameHuman-readable item name
item-typeCategory: consumable, hold, key, tm, ball, badge, misc
spriteURL of the item's icon/sprite image
priceDefault shop buy price in gold (integer string). "0" = not for sale
sell-priceDefault sell price (integer string). Omit = half of price
single-use"true" if consumed on use. Default: "true" for consumables
holdable"true" if a Nostrmon can hold this item in battle
tnostrmon and any additional tags
altNIP-31 description: "Nostrmon item: <name>"

Content

The content field is a JSON object:

interface ItemContent {
  // Description shown in the bag/item screen
  description: string;

  // What happens when this item is used (plain-text script or freeform description)
  // Clients interpret this to apply effects. Common effect keywords:
  //   HEAL_HP <amount>          — restore HP to one Nostrmon
  //   HEAL_HP_ALL <amount>      — restore HP to all team Nostrmon
  //   HEAL_STATUS               — cure a status condition
  //   REVIVE                    — revive a fainted Nostrmon to half HP
  //   REVIVE_FULL               — revive to full HP
  //   CATCH_RATE <multiplier>   — ball catch-rate multiplier (for ball items)
  //   TEACH_MOVE <move-id>      — teach a move (for TM items)
  //   WARP_ESCAPE               — escape from a dungeon to last town
  //   BADGE <badge-id>          — grants a badge (for badge items)
  effect?: string;
}

Item Categories

CategoryDescription
consumableUsed from the bag; disappears after use (e.g. Potion, Antidote)
holdHeld by a Nostrmon during battle for passive effects
keyKey item; never consumed; triggers world events or opens warps
tmTechnical Machine; teaches a move to a compatible Nostrmon
ballUsed in battle to catch wild Nostrmon; has a CATCH_RATE multiplier
badgeProof of a gym/trainer victory; unlocks abilities or areas
miscMiscellaneous item with no standard category

Example

{
  "kind": 39951,
  "content": "{\"description\":\"Restores 20 HP to a single Nostrmon.\",\"effect\":\"HEAL_HP 20\"}",
  "tags": [
    ["d", "potion"],
    ["name", "Potion"],
    ["item-type", "consumable"],
    ["sprite", "https://example.com/items/potion.png"],
    ["price", "300"],
    ["sell-price", "150"],
    ["single-use", "true"],
    ["holdable", "false"],
    ["t", "nostrmon"],
    ["alt", "Nostrmon item: Potion"]
  ]
}

Querying Content

Discover all Nostrmon (any author)

[{ "kinds": [38267], "#t": ["nostrmon"], "limit": 50 }]

Discover all regions (any author)

[{ "kinds": [30597], "#t": ["nostrmon"], "limit": 50 }]

Get a specific NPC by author and d-tag

[{ "kinds": [36011], "authors": ["<pubkey>"], "#d": ["old-hermit-ashfire"] }]

Discover all items (any author)

[{ "kinds": [39951], "#t": ["nostrmon"], "limit": 100 }]

Get all maps in a region (by region naddr reference)

Maps reference their region via the region tag. Clients should query maps and filter by region reference client-side, or use a relay that supports tag filtering.


Battle Rules

Wild Battles

  • A wild encounter is triggered when the player steps on a tile inside an encounter zone, according to the zone's rate (0–1).
  • Auto-catch rule: Wild Nostrmon at level 1–5 are caught automatically at 100% success rate with no battle required. This ensures new players always get their first Nostrmon.
  • If the player has no Nostrmon in their team, wild encounters at any level trigger auto-catch instead of a battle.
  • For wild Nostrmon above level 5, a full battle takes place. The player may fight, use items, switch Nostrmon, or attempt to flee.
  • Catching requires a ball item. Catch rate = 0.3 + (1 − currentHpRatio) × 0.7 modified by the ball's CATCH_RATE multiplier.
  • The player can flee from any wild battle without penalty.

Trainer Battles

  • NPCs with one or more nostrmon tags initiate trainer battles when the player interacts with them.
  • The player cannot catch the Nostrmon of another trainer.
  • The player cannot flee a trainer battle.
  • Defeating a trainer stores their d-tag in defeatedTrainers in the save. Re-interacting with a defeated trainer shows fallback dialogue instead of battle.
  • Trainer battle music uses the NPC's battle-music tag if set, otherwise the region's default battle theme.

Stat & Damage Calculation

  • Stats use the standard formula: floor((2×base + IV + floor(EV/4)) × level / 100) + 5 (or +level+10 for HP)
  • IVs: random 0–31 per stat, generated at catch/receive time
  • EVs: start at 0, gained from defeating Nostrmon
  • Natures: 25 natures, each raises one stat by 10% and lowers another (or neutral)
  • Level-up: cubic XP formula XP_needed = (level+1)³ − level³

XP & Levelling

  • Clients MUST award XP to the active Nostrmon after defeating or catching a wild Nostrmon
  • XP reward: floor((sum_of_base_stats × enemy_level) / 7)
  • When a Nostrmon's XP exceeds the threshold, it levels up and its stats recalculate
  • Clients SHOULD check for move learning on level-up (from the species move tags with learn-method: level)

Multiplayer Presence

On maps with multiplayer: "true", clients SHOULD broadcast the player's position using ephemeral kind 20001 events ("Presence Events").

Kind 20001 — Presence Event (Ephemeral)

FieldValue
kind20001
contentJSON: {"x": <tile_x>, "y": <tile_y>, "name": "<display_name>"}
tags["d", "<map_d_tag>"], ["expiration", "<unix_timestamp+30>"]
  • Clients broadcast their position every ~5 seconds while on a multiplayer map
  • Clients subscribe to kind 20001 events filtered by the current map's d tag
  • Players not seen for 20+ seconds should be removed from the display
  • Other players are shown as coloured dots or avatars on the map
  • Position data is not saved — it is purely ephemeral

Client Requirements

MUST

  • Clients MUST be able to render and play maps using terrain and interactive layers
  • Clients MUST support Nostrmon battles (wild and trainer)
  • Clients MUST auto-catch wild Nostrmon at level 1–5 at 100% rate without battle
  • Clients MUST prevent catching in trainer battles
  • Clients MUST prevent fleeing in trainer battles
  • Clients MUST support game saves (kind 35253) with NIP-44 encryption
  • Clients MUST persist saves locally (e.g. localStorage) in addition to Nostr
  • Clients MUST treat maps without a region tag as belonging to "Unknown Region"
  • Clients MUST use fasttravel-x / fasttravel-y as the spawn position when fast-traveling to a map
  • Clients MUST NOT allow fast-traveling to a map with prison: "true" unless it belongs to the current user
  • Clients MUST implement an in-game menu with at minimum: team management, bag/inventory, save game

SHOULD

  • Clients SHOULD render a minimap for regions with map type-appropriate icons
  • Clients SHOULD support keyboard navigation and touch controls on mobile
  • Clients SHOULD support gamepad/controller input
  • Clients SHOULD render day/night cycles for maps where daynight is "true"
  • Clients SHOULD handle AI NPCs with configurable AI provider/model
  • Clients SHOULD list entry maps (entry-map: "true") from all authors for cross-region warp selection
  • Clients SHOULD broadcast and receive presence events on multiplayer maps (kind 20001)
  • Clients SHOULD show PC box storage for Nostrmon overflow management

MAY

  • Clients MAY render maps in 2.5D or 3D using the height map layer
  • Clients MAY provide editors for regions, maps, Nostrmon, NPCs, and items
  • Clients MAY support custom tilesets beyond the standard tile IDs
  • Clients MAY support NPC shops (using item price tags for buy/sell)
  • Clients MAY implement Nostrmon trading between players on multiplayer maps

Interoperability Notes

  • All creature references use naddr (kind 38267) or the d tag — clients should support both
  • Map warps referencing other users' maps are valid and encouraged for cross-region travel
  • Nostrmon from any author may be referenced in encounter zones
  • Music references use kind 36787 (Nostr Music events)
  • The t: nostrmon tag is used for all discovery queries — clients SHOULD include it on all published events

This NIP was authored as part of the Nostrmon World client. Feedback welcome.