Miscellaneous Item Types
Several item types in AFNM use only the base ItemBase interface without additional fields or mechanics. These items rely on their name, description, rarity, and realm to convey their purpose.
Simple Item Types
Breakthrough Items
export interface BreakthroughItem extends ItemBase {
kind: 'breakthrough';
// No additional fields
}
Purpose: Required consumables for realm advancement Usage: Consumed during cultivation breakthroughs
Token Items
export interface TokenItem extends ItemBase {
kind: 'token';
// No additional fields
}
Purpose: Currency or exchange items Usage: Trade, quests, or special vendors
Trophy Items
export interface TrophyItem extends ItemBase {
kind: 'trophy';
hint: string; // Hint about how to earn
achievementID: string; // Achievement system link
}
Purpose: Achievement rewards and collectibles Usage: Display accomplishments, unlock achievements
Treasure Items
export interface TreasureItem extends ItemBase {
kind: 'treasure';
isCollectible?: boolean; // Optional collection tracking
}
Purpose: Valuable items from enemies or exploration Usage: Selling, crafting materials, or collections
Upgrade Items
export interface UpgradeItem extends ItemBase {
kind: 'upgrade';
// No additional fields
}
Purpose: Equipment enhancement materials Usage: Improve existing items’ stats or quality
Flare Items
export interface FlareItem extends ItemBase {
kind: 'flare';
// No additional fields
}
Purpose: Used to explore the mine Usage: Spendable resource
Recuperation Items
export interface RecuperationItem extends ItemBase {
kind: 'recuperation';
// No additional fields
}
Purpose: Healing/recovery consumables Usage: Restore health between combats
Elixir Items
export interface ElixirItem extends ItemBase {
kind: 'elixir';
qi: number; // Amount of qi restored
}
Purpose: Qi restoration consumables Usage: Replenish qi during cultivation
Transport Seal Items
export interface TransportSealItem extends ItemBase {
kind: 'transport_seal';
destination: string; // Location identifier
}
Purpose: Fast travel consumables Usage: Teleport to specific locations
Life Essence Items
Life essence items are cultivation resources tied to the life system. Each essence levels up as the player invests in it, granting new buffs and techniques at each threshold.
export interface LifeEssenceItem extends ItemBase {
kind: 'life_essence';
thresholds: {
level: number; // Level at which this threshold activates
buffs: Buff[]; // Buffs granted permanently at this level
techniques: Technique[]; // Techniques unlocked at this level
}[];
}
Fields:
thresholds— ordered list of level milestones. Each threshold fires once when the essence reaches that level, permanently applying the listed buffs and unlocking the listed techniques.
Example:
export const myEssence: LifeEssenceItem = {
kind: 'life_essence',
name: 'Ember Essence',
description: 'A concentrated fragment of living flame, warm to the touch.',
icon: emberIcon,
stacks: 1,
rarity: 'empowered',
realm: 'bodyForging',
thresholds: [
{
level: 1,
buffs: [hearthwardBuff],
techniques: [],
},
{
level: 5,
buffs: [],
techniques: [flameTouchTechnique],
},
],
};
Device Items
Device items are functional farm objects. When placed, they operate automatically based on their deviceEffects.
export interface DeviceItem extends ItemBase {
kind: 'device';
deviceEffects: Array<{
type: 'harvester' | 'growthBoost' | 'yieldBoost' | 'universalSoil';
harvestInterval?: number; // For 'harvester': days between auto-harvests
boostAmount?: number; // For 'growthBoost'/'yieldBoost': fractional boost (e.g. 0.25 = 25%)
soilConditions?: string[]; // For 'universalSoil': soil condition IDs to provide
}>;
}
Effect types:
harvester— automatically collects mature plants everyharvestIntervaldaysgrowthBoost— speeds up plant growth byboostAmountyieldBoost— increases harvest yield byboostAmountuniversalSoil— provides the listed soil conditions to all plants in the plot
Example:
export const autoHarvester: DeviceItem = {
kind: 'device',
name: 'Spirit Harvester',
description: 'Golden blades hum as they collect mature essence from nearby plants.',
icon: harvesterIcon,
stacks: 1,
rarity: 'resplendent',
realm: 'bodyForging',
valueTier: 2,
deviceEffects: [{ type: 'harvester', harvestInterval: 30 }],
};
Ore Extractor Items
Ore extractors are automated mining devices that can be installed into vein chambers inside mines. Once installed, an extractor bores into the vein each month and delivers ore to the mine screen automatically, without requiring the player to revisit the chamber. They are differentiated from standard device items (which operate on house farms) by the dedicated ore_extractor kind and are primarily used in the delve/mine system rather than house building.
export interface OreExtractorItem extends ItemBase {
kind: 'ore_extractor';
/** Ores mined per month once installed in a vein chamber. Fractional amounts accumulate. */
extractionSpeed: number;
}
Fields:
kind— Always'ore_extractor'extractionSpeed— Number of ore units mined per month. Fractional values accumulate over time; e.g., an extractor yielding 0.5 ore/month delivers 1 ore after two months.
Ore extractors are offered to the player via the oreExtractor event step. The event step presents the player with a choice of all compatible extractors in their inventory, filtered by vein realm. Higher extractor grades (resplendent base, incandescent +, transcendent S) multiply the base extraction rate for that realm.
The three standard grades are defined in src/data/items/oreExtractor/oreExtractors.ts:
// Resplendent base grade — e.g. Ore Extractor (Qi Condensation) yields 0.50 ore/month
export const oreExtractorMap: Record<Realm, OreExtractorItem>
// Incandescent + grade — 1.5x base rate
export const oreExtractorMapPlus: Record<Realm, OreExtractorItem>
// Transcendent S grade — 2.0x base rate
export const oreExtractorMapS: Record<Realm, OreExtractorItem>
Register a custom extractor recipe with window.modAPI.actions.addRecipe, targeting one of the three ore extractor item names from oreExtractorList as the output.
Manual Items
Manual items contain a full combat style: a set of named stances each containing an ordered list of technique names. When the player reads a manual, they gain access to all stances defined within it.
export interface ManualItem extends ItemBase {
kind: 'manual';
style: ManualStyle;
}
interface ManualStyle {
name: string; // Style name (usually matches the manual's display name)
stances: ManualStance[];
}
interface ManualStance {
name: string; // Stance name shown to the player
stance: string[]; // Ordered list of technique names in this stance
stanceRule?: StoredRule; // Optional auto-switch rule (see below)
}
Stance rules control automatic stance switching during combat. Without a rule, the stance is always available for the player to select manually. With a rule, the game may switch stances automatically based on combat state.
Rule Types
Opener
Places the technique at a fixed position at the start of combat:
stanceRule: {
kind: 'opener',
position: 0, // 0-indexed position in the opener sequence
}
Rotation
Cycles through techniques at a fixed position each round:
stanceRule: {
kind: 'rotation',
position: 0, // 0-indexed position in the rotation cycle
}
Conditional
Evaluates one or more conditions to decide whether to use this stance. Supports complex multi-condition logic with AND/OR grouping:
stanceRule: {
kind: 'conditional',
blocks: [
{
// AND group: all conditions in a block must be true
conditions: [
{ condition: 'Health', check: '<', value: 50 },
{ condition: 'Iron Shell', check: '>=', value: 3 },
],
},
],
rootOperator: 'AND', // 'AND' or 'OR' — how blocks combine
maxCount: 5, // Optional: max uses per combat (unlimited if omitted)
}
Available condition names:
| Condition | Meaning |
|---|---|
Health | Player HP percentage (0–100) |
Enemy Health | Enemy HP percentage (0–100) |
Toxicity | Player toxicity percentage |
Barrier | Player barrier percentage |
Qi Droplets | Player qi droplet count |
Missing Qi Droplets | Player missing qi droplets |
Round | Current combat round number (1-based; 0 before round 1) |
Weapon Boost, Fist Boost, etc. | Element boost percentages |
Weakest <group> | HP percentage of lowest-health entity in a guardian group |
Average <group> | Average HP percentage of a guardian group |
Target: <buff> | Stack count of a debuff on the enemy |
Flag: <name> | Value of a global flag |
Trigger: <name> | Value of a trigger flag |
(Any) <buff> | Whether any instance of a multi-instance buff meets the condition |
Percent-based conditions (Health, Toxicity, Barrier, Enemy Health, element boosts, guardian groups) display a % suffix in the UI. All other conditions compare raw values.
Condition operators: <' >, <=, >=, ==, !=`
For realm-specific buffs (pillar shard buffs, condensation art buffs, persistent month-buffs), the condition picker in-game surfaces them automatically once you have unlocked the relevant content. You can target them by name in conditions exactly as you would a technique-generated buff.
Expression-based conditions — use round as a variable to gate round-specific behaviour:
// Switch stance at round 5 or later
{ condition: 'Round', check: '>=', value: 5 }
Example:
export const ironFistManual: ManualItem = {
kind: 'manual',
name: 'Iron Fist Canon',
description: 'A worn manual dense with diagrams of striking postures.',
icon: fistManualIcon,
stacks: 1,
rarity: 'empowered',
realm: 'bodyForging',
style: {
name: 'Iron Fist',
stances: [
{
name: 'Crushing Advance',
stance: ['Iron Strike', 'Bone Crack', 'Iron Guard', 'Smashing Blow'],
},
{
name: 'Defensive Hold',
stance: ['Iron Guard', 'Iron Guard', 'Iron Strike', 'Bone Crack'],
stanceRule: {
kind: 'conditional',
blocks: [
{
conditions: [
{ condition: 'Iron Shell', check: '<', value: 3 },
],
},
],
rootOperator: 'AND',
},
},
{
name: 'Counter Stance',
stance: ['Iron Strike', 'Iron Strike', 'Iron Guard', 'Iron Guard'],
stanceRule: {
kind: 'conditional',
blocks: [
{
conditions: [
{ condition: 'Round', check: '>=', value: 5 },
{ condition: 'Health', check: '>=', value: 75 },
],
},
],
rootOperator: 'AND',
maxCount: 3, // Use at most 3 times per combat
},
},
],
},
};
Techniques referenced in stance arrays must already exist in the game (either from the base game or registered by your mod). Register a manual with:
window.modAPI.actions.addManual(ironFistManual);
Common Properties
All these items inherit from ItemBase:
kind: The item type identifiername: Display namedescription: Flavor text and usage hintsicon: Visual representationstacks: Stack sizerarity: Item quality tierrealm: Associated cultivation realmvalueTier?: Optional economic value indicator
Implementation Example
// Simple breakthrough item
export const meridianNeedle: BreakthroughItem = {
kind: 'breakthrough',
name: 'Meridian Cleansing Needle',
description: 'Clears impurities from meridians during breakthrough.',
icon: needleIcon,
stacks: 1,
rarity: 'qitouched',
realm: 'meridianOpening'
};
// Trophy with achievement link
export const bossDefeatTrophy: TrophyItem = {
kind: 'trophy',
name: 'Demon Lord\'s Crown',
description: 'Proof of defeating the Demon Lord.',
icon: crownIcon,
stacks: 1,
rarity: 'resplendent',
realm: 'coreFormation',
hint: 'Defeat the Demon Lord in single combat',
achievementID: 'ACH_DEMON_LORD'
};
// Collectible treasure
export const ancientCoin: TreasureItem = {
kind: 'treasure',
name: 'Ancient Spirit Coin',
description: 'Currency from a lost cultivation empire.',
icon: coinIcon,
stacks: 99,
rarity: 'mundane',
realm: 'any',
isCollectible: true
};
// Qi restoration elixir
export const minorQiElixir: ElixirItem = {
kind: 'elixir',
name: 'Minor Qi Elixir',
description: 'Restores a small amount of qi.',
icon: elixirIcon,
stacks: 10,
rarity: 'mundane',
realm: 'bodyForging',
qi: 50 // Restores 50 qi
};
// Transport seal for fast travel
export const marketSeal: TransportSealItem = {
kind: 'transport_seal',
name: 'Market District Seal',
description: 'Instantly transports you to the Market District.',
icon: sealIcon,
stacks: 1,
rarity: 'mundane',
realm: 'any',
destination: 'market_district'
};
Design Notes
These item types are intentionally simple:
- No complex mechanics: Functionality comes from game systems, not item properties
- Flexible usage: Can be repurposed for various game features
- Easy to extend: New items just need base properties
- Clear purpose: Name and description convey all necessary information
For items requiring special mechanics or additional data, use the more complex item types like pill, technique, artefact, etc.