AgentSkillsCN

tile-placement

为 Valkyrie MoM 制定系统的地砖布局方法。适用于设计地图布局、铺设连贯路径、设置多入口地砖,或确立命名规范时使用。

SKILL.md
--- frontmatter
name: tile-placement
description: Systematic tile placement methodology for Valkyrie MoM. Use when designing map layouts, placement chains, multi-entry tiles, or establishing naming conventions.

/tile-placement - Systematic Tile Placement

Methodology for placing tiles, tokens, and building the exploration chain in Mansions of Madness scenarios.

Standard Placement Chain

When a player explores a new area, a strict sequence of events fires. Each phase ALWAYS calls the next — never skip steps:

code
PlaceTile → PlaceDecoration → PlaceConnections → PlaceItems → PlacePeople → MoveOneSpace

Phase-by-Phase Breakdown

1. PlaceTile — Reveal the tile itself

code
upsert_event("EventOfficePlaceTile", {
  display: "false",
  buttons: "1",
  add: "TileOffice",
  event1: "EventOfficePlaceDecoration"
})

2. PlaceDecoration — Add walls, barriers, and terrain features

code
upsert_event("EventOfficePlaceDecoration", {
  display: "false",
  buttons: "1",
  add: "TokenWallOffice1 TokenWallOffice2",
  event1: "EventOfficePlaceConnections"
})

3. PlaceConnections — Place explore tokens leading to adjacent unrevealed areas

code
upsert_event("EventOfficePlaceConnections", {
  display: "false",
  buttons: "1",
  add: "TokenExploreToLibrary TokenExploreToCellar",
  event1: "EventOfficePlaceItems"
})

4. PlaceItems — Place search tokens and interactable objects

code
upsert_event("EventOfficePlaceItems", {
  display: "false",
  buttons: "1",
  add: "TokenSearchOffice TokenInteractDesk",
  event1: "EventOfficePlacePeople"
})

5. PlacePeople — Place NPCs, monster spawns, and other entities

code
upsert_event("EventOfficePlacePeople", {
  display: "false",
  buttons: "1",
  add: "SpawnOfficeGuard",
  event1: "EventOfficeMoveOneSpace"
})

6. MoveOneSpace — The investigating hero takes one step onto the new tile

code
upsert_event("EventOfficeMoveOneSpace", {
  display: "false",
  buttons: "0",
  operations: "moveOneSpace,=,1"
})

MoveOneSpace Pattern

The moveOneSpace variable is a shared convention:

  • Set moveOneSpace,=,1 at the end of every placement chain
  • Explore tokens that trigger placement should set their associated variable to 0 before the chain starts
  • The Valkyrie app reads moveOneSpace to animate the hero stepping onto the new tile

Additionally, in the MoveOneSpace event:

  • Set explore tokens to value 1 (marks them as "active/visible")
  • Set sight tokens to value 0 (marks them as "not yet seen")

Multiple Entry Points

When a tile can be reached from multiple directions, guard against double-placement.

Use vartests with a revealed flag. Remember the button mapping:

  • event1 = test FAILS
  • event2 = test PASSES
code
# Test: is officeRevealed == 0? (not yet revealed)
upsert_event("EventOfficeFromHallway", {
  display: "false",
  buttons: "2",
  vartests: "VarOperation:officeRevealed,==,0",
  event1: "EventOfficeAlreadyRevealed",  # FAILS: it's NOT 0, already revealed
  event2: "EventOfficePlaceTile"          # PASSES: it IS 0, place the tile
})

# The placement chain sets the flag
upsert_event("EventOfficePlaceTile", {
  display: "false",
  buttons: "1",
  operations: "officeRevealed,=,1",
  add: "TileOffice",
  event1: "EventOfficePlaceDecoration"
})

Conditional Token Placement

Use conditions on tokens to show/hide them based on game state:

code
upsert_token("TokenSearchSecretRoom", {
  type: "TokenSearch",
  xposition: "10",
  yposition: "3",
  conditions: "secretRoomFound,>=,1",
  buttons: "1",
  event1: "EventSearchSecret"
})

The token only appears on the map when secretRoomFound >= 1.

Naming Conventions

Consistent naming keeps complex scenarios manageable:

PatternExampleUse
Event<Room>PlaceTileEventOfficePlaceTileTile reveal event
Event<Room>PlaceDecorationEventOfficePlaceDecorationWall/barrier placement
Event<Room>PlaceConnectionsEventOfficePlaceConnectionsExplore token placement
Event<Room>PlaceItemsEventOfficePlaceItemsSearch/interact token placement
Event<Room>PlacePeopleEventOfficePlacePeopleNPC/monster placement
Event<Room>MoveOneSpaceEventOfficeMoveOneSpaceTerminal movement event
Tile<Room>TileOfficeTile component
TokenExplore<From>To<To>TokenExploreHallToOfficeExplore token
TokenSearch<Room>TokenSearchOfficeSearch token
TokenInteract<Object>TokenInteractDeskInteract token
T1_<Name> / T2_<Name>T1_Office / T2_LibraryTile group prefix
0_<Name> / 1_<Name>0_LoopInit / 1_LoopBodyLoop event prefix

Layout Tips

  • Start with 2-3 tiles visible; reveal others through exploration
  • Standard tile spacing is 7 units — use place_tile_relative for consistent positioning
  • Place explore tokens at tile edges facing the direction of the next tile
  • Use get_map_ascii frequently to verify spatial layout
  • Consider the camera: use mincam/maxcam events to control visible area
  • Hub-spoke layouts create a central nexus with branching paths
  • Linear layouts create a more directed narrative experience
  • L-shape layouts offer a good balance of exploration and direction