Building Types
Buildings provide interactive services and content within locations. Each building type offers specific functionality, from commerce and healing to quest distribution and cultivation.
Basic Buildings
Healer
Provides healing services to restore health and remove injuries:
{
kind: 'healer',
condition?: 'realm >= meridianOpening', // Optional availability
disabled?: 'injured == 0' // Optional disable condition
}
Cultivation Chamber
Allows meditation and qi cultivation:
{
kind: 'cultivation'
}
Manual Pavilion
Access to combat technique manuals:
{
kind: 'manual'
}
Crafting (Furnace Pagoda)
Alchemy and item crafting:
{
kind: 'crafting'
}
Treasure Vault
Banking and storage services:
{
kind: 'vault'
}
Material Compendium
Encyclopedia of crafting materials:
{
kind: 'compendium'
}
Mystical Region
Portal to special cultivation areas:
{
kind: 'mysticalRegion'
}
Expedition
Portal to expedition dungeons. Expedition buildings require a name matching an existing expedition tile pool (registered by the base game or via modAPI.actions.addExpeditionTiles).
{
kind: 'expedition';
name: string; // Expedition identifier (e.g. 'Tai Kong')
displayName?: Translatable; // Optional custom display name
teamCount: number; // Number of team members required
realm: Realm; // Realm tier for the expedition
}
Example:
{
kind: 'expedition',
name: 'Tai Kong', // Expedition identifier - must match the key used in addExpeditionTiles
displayName?: 'Tai Kong Expedition',
teamCount: 3, // Number of team member slots
realm: 'qiCondensation' // Minimum realm required to enter
}
The name field is the expedition identifier. It must match the expeditionName passed to api.actions.addExpeditionTiles(expeditionName, tiles) so that the tile pool is correctly associated with this building. See Expedition Tiles below for how to register tiles for a custom expedition.
Training Ground
Combat training and sparring:
{
kind: 'trainingGround'
}
Research (Vault of Infinite Reflections)
Research and experimentation facility:
{
kind: 'research'
}
Reforge Workshop
Item reforging and enhancement:
{
kind: 'reforge'
}
Furnace of Ten Thousand Flames
Advanced alchemy furnace for high-tier crafting:
{
kind: 'tenThousandFlames'
}
Commerce Buildings
Market
General marketplace with realm-specific inventory:
{
kind: 'market',
itemPool: {
bodyForging: [
{ name: 'Small Claw', stacks: 5 },
{ name: 'Healing Pill I', stacks: 3 },
{ name: 'Speed Room I', stacks: 1 }
],
meridianOpening: [...],
// ...other realms
},
reputationPool?: { // Optional reputation items
bodyForging: [
{
name: 'Spirit Core I',
stacks: 1,
reputation: 'respected', // Required reputation
valueModifier: 15 // Price multiplier
}
]
},
costMultiplier: 1.5, // Base price multiplier
refreshMonths: 3 // Inventory refresh period
}
Favour Exchange
Special shop using favour currency:
{
kind: 'favourExchange',
itemPool: { ... }, // Same as market
costMultiplier: 2.0,
refreshMonths: 1
}
Enchantment Shop
Shop for purchasing item enchantments:
{
kind: 'enchantmentShop',
costMultiplier: 1.5, // Base price multiplier
refreshMonths: 1, // Inventory refresh period
stockCount: 6 // Number of enchantments available at a time
}
Mission Buildings
Mission Hall
Sect missions with rewards:
{
kind: 'mission'
}
Missions defined at location level:
missions: [
{
realm: 'bodyForging',
rarity: 'mundane',
quest: 'ratascar_culling',
condition: '1'
}
]
Crafting Hall
Crafting-focused missions:
{
kind: 'craftingHall'
}
Crafting missions defined at location level:
crafting: [
{
realm: 'meridianOpening',
rarity: 'qitouched',
quest: 'pill_delivery',
condition: 'craftingSkill >= 50'
}
]
Request Board
Player-requested tasks:
{
kind: 'requestBoard',
requests: {
bodyForging: [
{
quest: 'herb_collection',
condition: '1',
rarity: 'mundane'
}
],
meridianOpening: [...],
// ...other realms
}
}
Resource Buildings
Herb Field
Herb gathering location:
{
kind: 'herbField',
condition?: 'farmingUnlocked == 1'
}
Yinying Mine
Mining for ores and gems:
{
kind: 'mine',
condition?: 'miningUnlocked == 1'
}
Special Buildings
Recipe Library
Access to crafting recipes:
{
kind: 'recipe',
recipePool: {
bodyForging: [
'recuperation_pill_recipe',
'iron_skin_pill_recipe',
'clothing_blank_recipe'
],
meridianOpening: [...],
// ...other realms
}
}
Library
Books and lore:
{
kind: 'library',
title: 'Ancient Archives',
categories: [
{
name: 'History',
condition: '1',
books: [
{
title: 'Rise of the Nine Mountains',
author: 'Elder Shou',
condition?: 'historyInterest == 1',
contents: 'Long ago, when the heavens...'
}
]
},
{
name: 'Cultivation Theory',
condition: 'realm >= meridianOpening',
books: [...]
}
]
}
House
Player housing:
{
kind: 'house',
houseDef: {
name: 'Heaven-Touched House',
description: 'Your rebuilt childhood home...',
background: homeImage,
screenEffect: 'dust',
qiDensity: 1000,
fixedRooms: [],
freeRooms: 3,
transportSeal: liangTiaoSeal
},
unlockCondition: 'houseRepaired == 1',
condition: 'houseRepaired == 1'
}
Compression Altar
Core compression service. Grants a temporary buff on use and a permanent breakthroughReward on the first compression at each altar.
{
kind: 'altar',
buff: {
name: 'Meditative Surge',
description: 'Your core has been compressed...',
canStack: true,
stats: {
power: {
value: 0.2,
stat: 'power',
scaling: 'stacks',
},
},
// ...other buff properties
},
// Optional: permanent stat rewards granted once per altar on first compression.
// These rewards persist through Core Formation breakthrough.
breakthroughReward?: {
// Combat stat increments — flat values or percentage of a stat.
// Example: { value: 0.03, stat: 'power' } = +3% of current power.
combatStats?: Partial<{ [key in CombatStatistic]: Scaling }>;
// Crafting stat increments — e.g. poolCostPercentage reduces qi costs.
craftingStats?: Partial<{ [key in CraftingStatistic]: Scaling }>;
};
}
breakthroughReward is optional. If omitted, compressing at the altar grants no permanent bonus. Each unique altar (identified by location name or house name) can grant its breakthroughReward once per playthrough. The same altar visited again provides only the temporary buff.
Available CombatStatistic keys include power, protection, critchance, critmult, speed, dr (damage resistance), accuracy, evasion, maxhp, barrierMitigation, barrierStrength, startingBarrier, weakness, armour, and block. Percentage scaling (e.g. +10% of current power) uses { value: 0.1, stat: 'power' }. Flat values use { value: 5, stat: undefined }.
Available CraftingStatistic keys include control, 流派强度 (technique intensity), critchance, critmult, successChanceBonus, poolCostPercentage, qualityBonus, and speed. poolCostPercentage with value 0.95 reduces qi pool costs to 95% of normal.
Guild
Guild headquarters:
{
kind: 'guild',
guild: 'Merchant Alliance',
position: 'topleft',
condition?: 'guildUnlocked == 1',
/** Token currency for this guild's shop. When set, the shop uses tokens instead
* of spirit stones and every rankShop item must declare a `tokenCost`. */
token?: Item,
}
Items sold in a token-based guild’s rank shop declare a fixed token price:
{
kind: 'rankShop',
tokenCost: 3, // Fixed price in the guild's token currency
// ...
}
Important: When a guild declares
token, every item in itsrankShopmust declaretokenCost. Items without it would be charged in spirit stones instead.
Custom Building
Fully customizable building with event steps:
{
kind: 'custom',
name: 'Mysterious Shop',
icon: shopIcon,
position: 'middleright', // Screen position
condition: 'mysteryUnlocked == 1',
eventSteps: [
{
kind: 'text',
text: 'You enter the mysterious shop...'
},
{
kind: 'choice',
choices: [
{
text: 'Browse wares',
children: [...]
},
{
text: 'Leave',
children: [
{ kind: 'exit' }
]
}
]
}
]
}
Position options for custom buildings:
'top','topleft','topright''belowtop','belowtopleft','belowtopright''middleleft','middle','middleright''bottom','bottomleft','bottomright'
Mod-Specific Buildings
Mod Building
A custom building that navigates to a registered mod screen. Use modBuilding alongside api.addScreen() to integrate fully custom UI into a location.
{
kind: 'modBuilding',
name: 'Mysterious Device', // Internal name (used as icon seed)
displayName?: 'Mysterious Device', // Optional display name (supports translation)
icon: myCustomIcon, // Building icon image
screen: 'myModScreen', // Key of screen registered via api.addScreen()
position: 'middleleft', // Position on the location screen
condition?: 'deviceUnlocked == 1', // Optional: when to show the building
disabled?: 'deviceBusy == 1' // Optional: when to disable the button
}
The screen field must match the key used when registering the screen with api.addScreen(). See Adding Screens for how to create and register mod screens.
// Register the screen
api.addScreen({
key: 'myModScreen',
component: MyModScreenComponent,
});
// Add the building to a location
window.modAPI.actions.addBuildings('Liang Tiao Village', [
{
kind: 'modBuilding',
name: 'Ancient Device',
icon: deviceIcon,
screen: 'myModScreen',
position: 'top',
condition: '1',
}
]);
Building Properties
Common Properties
All buildings support these optional fields:
{
kind: BuildingType, // Required building type
condition?: string, // When building is available
disabled?: string, // When building is disabled
offset?: { // Position adjustment
x: number,
y: number
}
}
Conditional Availability
Control when buildings appear:
{
kind: 'market',
condition: 'marketBuilt == 1 && realm >= meridianOpening',
// ...other properties
}
Disabled State
Temporarily disable buildings:
{
kind: 'healer',
disabled: 'injured == 0', // Disabled when not injured
}
Complete Example
export const myLocation: GameLocation = {
// ...basic properties
buildings: [
// Basic services
{ kind: 'healer' },
{ kind: 'crafting' },
// Market with reputation items
{
kind: 'market',
itemPool: {
bodyForging: [
{ name: 'Healing Pill I', stacks: 5 },
{ name: 'Small Claw', stacks: 10 }
]
},
reputationPool: {
bodyForging: [
{
name: 'Rare Manual',
stacks: 1,
reputation: 'exalted',
valueModifier: 10
}
]
},
costMultiplier: 1.8,
refreshMonths: 2
},
// Custom event building
{
kind: 'custom',
name: 'Elder\'s Residence',
icon: elderIcon,
position: 'top',
condition: 'elderQuestComplete == 1',
eventSteps: [
{
kind: 'speech',
character: 'Village Elder',
text: 'Welcome back, young cultivator...'
},
// ...more events
]
},
// Conditional library
{
kind: 'library',
condition: 'libraryUnlocked == 1',
title: 'Village Archives',
categories: [
{
name: 'Local History',
condition: '1',
books: [...]
}
]
},
// Mod screen building
{
kind: 'modBuilding',
name: 'Alchemist Workshop',
icon: workshopIcon,
screen: 'myAlchemistScreen',
position: 'middleright',
condition: 'workshopBuilt == 1',
}
]
};
Expedition Tiles
Expeditions use a tile-based dungeon generation system. Each tile has a kind (entrance, exit, combat, treasure, etc.) and defines connections to neighbouring tiles.
Tiles are registered via api.actions.addExpeditionTiles(expeditionName, tiles) and are keyed by the same expedition identifier used in the expedition building’s name field. An expedition building without any tiles registered will use the default game tiles.
Reading existing tiles:
// Inspect the tile pool for an existing expedition
const tilePool = window.modAPI.gameData.expeditionTiles['Tai Kong'];
const treasureTiles = tilePool.filter((t) => t.kind === 'treasure');
Registering tiles for a custom expedition:
// Register a new expedition with a custom treasure tile
window.modAPI.actions.addExpeditionTiles('Frozen Reach', [
{
kind: 'treasure',
name: 'Glacial Cache',
icon: 'mod://icons/ice.png',
bg: 'mod://backgrounds/iceBG.png',
description: 'A cache pulsing with cold qi.',
rarity: 'resplendent',
intro: [{ kind: 'text', text: 'You uncover a cache of frozen treasures.' }],
expeditionTiles: [],
edges: { left: [], right: [], top: [], bottom: [] },
tileConnections: [],
edgeConnections: [],
},
]);
Tile Kinds
All tile types share these base fields:
interface BaseTile {
name: string; // Display name
icon: string; // Icon path (use 'mod://' for mod assets)
bg: string; // Background image path
description: Translatable; // Shown when the tile is revealed
rarity: Rarity; // 'mundane' | 'qitouched' | 'empowered' | 'resplendent' | 'incandescent' | 'transcendent'
intro: EventStep[]; // Event steps shown when entering this tile
// Tile graph fields (required for generation)
expeditionTiles: ExpeditionTilePoint[]; // Named points inside this tile
edges: Record<ExpeditionDirection, ExpeditionTilePoint[]>; // Connections per direction
tileConnections: { src: string; dst: string }[]; // Named point links
edgeConnections: { tile: string; edge: string; direction: ExpeditionDirection }[];
}
entrance - Starting tile. Exactly one per expedition.
{ kind: 'entrance', /* ...BaseTile */ }
exit - Goal tile. Reaching this tile completes the expedition.
{ kind: 'exit', /* ...BaseTile */ }
extract - Grants extraction rewards (materials, items).
{ kind: 'extract', extractCount: 3, /* ...BaseTile */ }
combat - Triggers a combat encounter.
{
kind: 'combat',
modifier?: number, // Difficulty multiplier (default 1)
enemyCount?: number, // Number of enemies spawned
items?: { item: ItemDesc; count: number }[], // Guaranteed drops
/* ...BaseTile */
}
rest - Restores team health and removes debuffs.
{ kind: 'rest', baseRestore: 50, /* ...BaseTile */ }
treasure - Grants treasure room loot.
{ kind: 'treasure', /* ...BaseTile */ }
boss - Triggers a boss fight with scaled rewards.
{
kind: 'boss',
modifier?: number, // Difficulty multiplier
items?: { item: ItemDesc; count: number }[], // Guaranteed drops
/* ...BaseTile */
}
buff - Applies a positive buff to the team.
{ kind: 'buff', /* ...BaseTile */ }
debuff - Applies a negative debuff to the team.
{ kind: 'debuff', /* ...BaseTile */ }
challenge - High-difficulty combat with extra rewards.
{
kind: 'challenge',
modifier?: number,
items?: { item: ItemDesc; count: number }[],
/* ...BaseTile */
}
puzzle - A puzzle encounter, optionally with enemies.
{ kind: 'puzzle', enemies?: boolean, /* ...BaseTile */ }
boonBane - Random beneficial or harmful effect.
{ kind: 'boonBane', /* ...BaseTile */ }