Custom enemies
Custom enemies are a clone-and-patch kind: you start from a vanilla enemy, change its stats/assets, and register it as a new definition. Confirmed
Author one
Section titled “Author one”The enemy kind is confirmed, so no experimental opt-in is needed.
from rsmm import sdk
with sdk.Mod("MyEnemies") as mod: mod.enemy( "Frost_Goblin", base="Goblins/Goblin_Warrior", # vanilla donor to clone name="Frost Goblin", # **fields override stat-block values on the clone )Equivalent declarative form:
[mod]id = "MyEnemies"
[[content]]kind = "enemy"id = "Frost_Goblin"base = "Goblins/Goblin_Warrior"name = "Frost Goblin"Mod.boss(...) takes the same shape. Bosses are not a separate class — they
are ordinary enemies tagged into the boss flag-list and gated by the boss-timer
controller.
Run ./rsmm apply to cook and register the definition.
How enemies spawn
Section titled “How enemies spawn”Spawning is selector-driven, not a direct “place enemy X” call. The chain:
flowchart LR
E["oCDtEnemyDefinition<br/>(one stat block)"] --> T["oCDtEnemyTribeDefinition<br/>(group / faction)"]
T --> S["Camp spawn selector<br/>(flag-list, tag-filtered)"]
C["oCDtEnemyCampTierDefinition<br/>(camp difficulty tier)"] --> S
S --> R["runtime spawn in a camp"]
An enemy reaches a run by being a member of a tribe, which a camp selector picks via tags/flags at the right difficulty tier. So registering a definition is necessary but not sufficient — something must select it.
Class map
Section titled “Class map”The full camp/enemy machinery, for when you need the internals:
| Class | UID | Library | Purpose |
|---|---|---|---|
oCDtEnemyDefinition |
0x176debb7 |
0x1414118c0 |
one enemy stat block |
oCDtEnemyTribeDefinition |
— | 0x141411200 |
tribe = group / faction |
oCDtEnemyCampTierDefinition |
0x176e18f8 |
0x141411560 |
difficulty tier of one camp |
oCDtEnemyCampDifficultyDefinition |
— | 0x141411710 |
global difficulty curve |
oCDtEnemyCampEntitySelectorToSpawnEntityCpntSettings |
0x16b7d175 |
— | per-camp spawn selector |
oCDtEnemyCampEntitySelectorToSpawnTribeEntrySettings |
0x16b81d80 |
— | one tribe entry inside a camp |
oCDtEnemyFlagListEntitySelectorToSpawnEntityCpntSettings |
0x17019bf9 |
— | tag-filtered enemy selector |
oCDtEnemyDefinition is fully registered (size 0x350, factory FUN_14030a190).
The runtime spawn primitive itself — the vftable[3] call that constructs an
entity at a position — is documented in Spawning.
