MadROM Builder's Compendium

A code-driven reference that summarizes builder access levels, creation tools, and flag definitions directly from the MadROM source tree.

Overview

This compendium draws its data straight from the MadROM C sources so that builders always work with the canonical rules used by the game server. Command availability is sourced from the global command table, trust level macros, and the corresponding handler implementations, while flag and type listings mirror the live tables in tables.c and supporting headers.

The trust ladder comes from interp.h and merc.h, the builder tooling summaries cite their command implementations (for example, population.c, generate.c, flag.c, and act_wiz.c), and every flag table reproduces the constants maintained in tables.c. No legacy markdown was consulted—everything you see here is regenerated from the current code.

Access levels & trust

The MadROM trust macros map to numeric levels derived from MAX_LEVEL = 100 and the immortal/hero thresholds. These macros are referenced throughout the command table to gate builder tools.

MacroLevelDescription
ML100Implementor
L199Creator
L298Supreme Being
L397Deity
L496God
L595Immortal
L694Demigod
L793Angel
L892Avatar
IM93LEVEL_IMMORTAL (Angel)
HE91LEVEL_HERO (Hero)

The macros above are defined alongside MAX_LEVEL, LEVEL_IMMORTAL, and LEVEL_HERO in merc.h and documented in interp.h.【F:src/interp.h†L1-L14】【F:src/merc.h†L146-L169】

Builder command reference

The table below lists the most frequently used building tools, their minimum trust requirements, and a short description taken directly from the handler source. Levels are shown using the same macros that the command table uses.

CommandRequired levelWhat it doesImplementation
populate L4 (96) Spawns 1–20 template mobs into the current room, using an explicit theme when provided, otherwise preferring the default theme before falling back to a random (unweighted) pick; requires trust 100 before doing any work.【F:src/interp.c†L75-L76】【F:src/population.c†L156-L207】 population.c
generatearea L4 (96) Builds a themed 50-room grid (33700–33749) from predefined templates after validating the theme argument and listing available options.【F:src/interp.c†L75-L76】【F:src/generate.c†L130-L182】 generate.c
flag L2 (98) Provides syntax to toggle mob, player, object, and room flags with optional +, -, or = modes; enforces scope-specific flag tables before applying the change.【F:src/interp.c†L337-L338】【F:src/flag.c†L90-L203】 flag.c
vnum L4 (96) Searches loaded indices for mobs, objects, or skills by name and prints their vnums so builders can reference assets quickly.【F:src/interp.c†L407-L408】【F:src/act_wiz.c†L3046-L3094】 act_wiz.c
olist L5 (95) Lists objects in the current area with optional filters (weapons, armor, food, keys, etc.), showing counts, weights, costs, and type-specific values.【F:src/interp.c†L393-L394】【F:src/act_wiz.c†L3449-L3518】 act_wiz.c
mlist L5 (95) Enumerates area mobiles and can focus on clerics, mages, or mobprog-enabled entries while reporting alignment, kill counts, and armor values.【F:src/interp.c†L390-L392】【F:src/act_wiz.c†L3585-L3646】 act_wiz.c
rlist L5 (95) Displays rooms in the current area with heal/mana rates and supports swim/noswim filters for aquatic checks.【F:src/interp.c†L400-L402】【F:src/act_wiz.c†L3646-L3696】 act_wiz.c
alist L5 (95) Prints all loaded areas with their vnum ranges and filenames—handy for seeing what ranges are already in use.【F:src/interp.c†L390-L393】【F:src/act_wiz.c†L3716-L3740】 act_wiz.c
load L4 (96) Loads mobs or objects into the room via load mob <vnum> or load obj <vnum> <level>; relays syntax if arguments are missing.【F:src/interp.c†L355-L356】【F:src/act_wiz.c†L4751-L4781】 act_wiz.c
clone L5 (95) Duplicates the targeted mobile or object, recursively copying contents and broadcasting creation events to the room and Wiznet.【F:src/interp.c†L408-L409】【F:src/act_wiz.c†L4638-L4713】 act_wiz.c
string L5 (95) Edits descriptions and titles on mobiles or objects with explicit syntax for each editable field, guarding against PC-only changes where appropriate.【F:src/interp.c†L404-L405】【F:src/act_wiz.c†L6264-L6332】 act_wiz.c

Flag reference

Each table below mirrors the live flag definitions in tables.c. The “Builder Settable” column reports the boolean stored in the table (for commands such as flag) so you can see which bits are protected in-game.

Legacy guide discrepancies: docs/madozy.txt stops before newer bits that appear in tables.c. Notable gaps include smart/prestige/nowander in the act flags, the gore offense flag, and the wood/silver/iron immunity/resistance/vulnerability bits. Keep these differences in mind when reconciling builds against the classic guide.

Mob act flags
NameBit / ConstantBuilder Settable
npcANo
sentinelBYes
scavengerCYes
smartDYes
unusedACT_UNUSEDYes
aggressiveFYes
stay_areaGYes
wimpyHYes
petIYes
trainJYes
practiceKYes
holylightNNo
undeadOYes
clericQYes
mageRYes
thiefSYes
warriorTYes
noalignUYes
nopurgeVYes
healeraaYes
gainbbYes
update_alwaysccYes
nowanderddYes

Source: tables.c act_flags array.【F:src/tables.c†L59-L84】

Player flags
NameBit / ConstantBuilder Settable
plr0No
autoassistCNo
autoexitDNo
autolootENo
autosacFNo
autogoldGNo
autosplitHNo
autohappyINo
autogrumpyJNo
showdefenseKNo
exactMNo
holylightNNo
wizinvisONo
can_lootPNo
nosummonQNo
nofollowRNo
colorSNo
wiznetTNo
afkUYes
tribeVNo
logWNo
denyXNo
freezeYNo
thiefZYes
killeraaYes
arenabbYes
spectateccYes
autotitleddNo
testeeYes

Source: tables.c plr_flags array.【F:src/tables.c†L86-L117】

Affect & combat flags
NameBit / ConstantBuilder Settable
blindAYes
invisibleBYes
detect_evilCYes
detect_invisDYes
detect_magicEYes
detect_hiddenFYes
talonGYes
sanctuaryHYes
faerie_fireIYes
infraredJYes
curseKYes
protect_goodLYes
poisonMYes
protectNYes
paralysisOYes
sneakPYes
hideQYes
sleepRYes
charmSYes
flyingTYes
pass_doorUYes
hasteVYes
calmWYes
plagueXYes
weakenYYes
dark_visionZYes
berserkaaYes
swimbbYes
regenerationccYes
lethargyddYes

See also affect2_flags, off_flags, and imm_flags in the same section of tables.c for extended effects, attack assists, and damage immunities.【F:src/tables.c†L119-L213】

Additional combat, aggression, and form flags

The following tables list auxiliary combat toggles that builders can apply to mobiles.

TableHighlights
off_flagsOffensive moves such as backstab, trip, and assist behaviours.【F:src/tables.c†L162-L185】
imm_flagsDamage and effect immunities including fire, poison, silver, and iron.【F:src/tables.c†L188-L212】
aggr_flagsAggression selectors by class, race, or temperament (e.g., mage, good, psycho).【F:src/tables.c†L215-L240】
form_flags & part_flagsCreature body types and anatomy for dismemberment and behaviour logic.【F:src/tables.c†L241-L288】
Communication, room, exit, and object flags
TablePurpose
comm_flagsPlayer channel and messaging toggles (quiet, noargue, notecho, etc.).【F:src/tables.c†L289-L325】
room_flagsEnvironmental properties such as dark, private, and arena flag markers.【F:src/tables.c†L326-L347】
room_aff_flagsAmbient room effects like smoke and bloody.【F:src/tables.c†L348-L357】
exit_flagsDoor state bits (door, closed, locked, pickproof, etc.).【F:src/tables.c†L360-L372】
extra_flagsObject properties such as glow, nodrop, ancient, and elite.【F:src/tables.c†L373-L397】
wear_flagsWear locations including offhand, twohands, and belt slots.【F:src/tables.c†L398-L417】
weapon_flagsWeapon specializations such as flaming, vampiric, and twohands.【F:src/tables.c†L418-L427】
rest_flagsRace/class alignment restrictions for resting objects.【F:src/tables.c†L428-L447】
food_flags, portal_flagsFood side-effects and portal behaviours (e.g., randomarea, nocurse).【F:src/tables.c†L448-L470】
Item and sector types
NameBit / ConstantBuilder Settable
lightITEM_LIGHTYes
scrollITEM_SCROLLYes
wandITEM_WANDYes
staffITEM_STAFFYes
weaponITEM_WEAPONYes
treasureITEM_TREASUREYes
armorITEM_ARMORYes
potionITEM_POTIONYes
clothingITEM_CLOTHINGYes
furnitureITEM_FURNITUREYes
trashITEM_TRASHYes
containerITEM_CONTAINERYes
drinkITEM_DRINK_CONYes
keyITEM_KEYYes
foodITEM_FOODYes
moneyITEM_MONEYYes
boatITEM_BOATYes
npccorpseITEM_CORPSE_NPCYes
pccorpseITEM_CORPSE_PCNo
fountainITEM_FOUNTAINYes
pillITEM_PILLYes
protectITEM_PROTECTNo
mapITEM_MAPYes
jukeboxITEM_JUKEBOXYes
portalITEM_PORTALYes
explosiveITEM_EXPLOSIVEYes
liquidITEM_LIQUIDYes
red_mineITEM_RED_MINENo
blue_mineITEM_BLUE_MINENo
charmITEM_CHARMYes
jeweleryITEM_JEWELRYYes
reagentITEM_REAGENTYes
trophyITEM_TROPHYYes
travelITEM_TRAVELNo

The same source block contains sector_types, sex_types, size_types, and qs_table, which are reproduced for convenience below.【F:src/tables.c†L471-L548】

Sector / demographicConstantSettable
insideSECT_INSIDEYes
citySECT_CITYYes
fieldSECT_FIELDYes
forestSECT_FORESTYes
hillsSECT_HILLSYes
mountainSECT_MOUNTAINYes
water_swimSECT_WATER_SWIMYes
water_noswimSECT_WATER_NOSWIMYes
airSECT_AIRYes
desertSECT_DESERTYes
water_floodedSECT_WATER_FLOODEDYes
fireSECT_FIREYes
lavaSECT_LAVAYes
voidSECT_VOIDYes
eunuchSEX_NEUTRALYes
maleSEX_MALEYes
femaleSEX_FEMALEYes
randomSEX_RANDOMYes
tinySIZE_TINYYes
smallSIZE_SMALLYes
mediumSIZE_MEDIUMYes
largeSIZE_LARGEYes
hugeSIZE_HUGEYes
giantSIZE_GIANTYes
hitPC_QS_HITYes
manaPC_QS_MANAYes
movesPC_QS_MOVESYes
hungerPC_QS_HUNGERYes
thirstPC_QS_THIRSTYes
expPC_QS_EXPYes

Source: tables.c item, sector, sex, size, and quick-stat tables.【F:src/tables.c†L488-L548】

ROM object value reference

Use this table to decode the five Value slots found on every object in the ROM engine. Match the object’s type to learn what each field controls when you audit resets or review builder submissions.

Item typeValue1Value2Value3Value4Value5
LIGHTUnused slot (always 0).Unused slot (always 0).Hours of light remaining (0 = dead, 999 = infinite).Unused slot.Unused slot.
SCROLLSpell level the scroll casts at.Spell slot #1 (spell number).Spell slot #2 (spell number or 0).Spell slot #3 (spell number or 0).Unused slot.
WANDSpell level the wand casts at.Maximum charges the wand can hold.Current charges remaining.Spell number cast by the wand.Unused slot.
STAFFSpell level the staff casts at.Maximum charges the staff can hold.Current charges remaining.Spell number triggered by the staff.Unused slot.
WEAPONWeapon class (sword, axe, etc.).Number of damage dice.Size of each damage die.Damage type / attack verb.Weapon flags (flaming, frost, two-handed, etc.).
TREASUREUnused slot.Unused slot.Unused slot.Unused slot.Unused slot.
ARMORArmor vs. pierce.Armor vs. bash.Armor vs. slash.Armor vs. magic.Unused slot.
POTIONSpell level the potion casts at.Spell slot #1 (spell number).Spell slot #2 (spell number or 0).Spell slot #3 (spell number or 0).Unused slot.
CLOTHINGUnused slot (cosmetic clothing uses affects instead).Unused slot.Unused slot.Unused slot.Unused slot.
FURNITUREMaximum occupants.Maximum weight it can support.Furniture flags (sit, rest, sleep, stand, etc.).Healing bonus (hp gained per tick).Mana bonus (mana gained per tick).
TRASHUnused slot.Unused slot.Unused slot.Unused slot.Unused slot.
CONTAINERCapacity (total weight it can hold).Container flags (closeable, pickproof, etc.).Key vnum (0 if none).Weight multiplier for carried contents.Unused slot.
DRINK-CONLiquid capacity (maximum units).Current quantity of liquid.Liquid type number.Poison flag (0 = safe, non-zero = poisoned).Unused slot.
KEYUnused slot.Unused slot.Unused slot.Unused slot.Unused slot.
FOODHours of nourishment provided (1 also flags poison).Unused slot.Unused slot.Unused slot.Unused slot.
MONEYGold value (coins in the pile).Unused slot.Unused slot.Unused slot.Unused slot.
BOATUnused slot.Unused slot.Unused slot.Unused slot.Unused slot.
CORPSE_NPCDecay timer (minutes before the corpse crumbles).Reserved for corpse metadata.Reserved for corpse metadata.Reserved for corpse metadata.Killer level (used for random drops).
FOUNTAINUnused slot.Unused slot.Liquid type dispensed.Unused slot.Unused slot.
PILLSpell level the pill casts at.Spell slot #1 (spell number).Spell slot #2 (spell number or 0).Spell slot #3 (spell number or 0).Unused slot.
PROTECTReserved for protection logic.Reserved for protection logic.Reserved for protection logic.Reserved for protection logic.Reserved for protection logic.
MAPMap visibility flag (1 = usable map).Unused slot.Unused slot.Unused slot.Unused slot.
SINGINGCurrent lyric line index (-1 means idle).Current song number.Queued song #1.Queued song #2.Queued song #3.
PORTALDestination room vnum.Gate flags (closed, pass proof, random, etc.).Exit flags applied when stepping through.Charges remaining before the portal collapses.Key vnum required if locked (0 if none).
EXPLOSIVESpell level the explosive triggers at.Spell slot #1 (spell number).Spell slot #2 (spell number or 0).Spell slot #3 (spell number or 0).Unused slot.
LIQUIDReserved for liquid objects.Reserved for liquid objects.Reserved for liquid objects.Reserved for liquid objects.Reserved for liquid objects.
CHAOS_FOODRandom chaos effect selector.Reserved for chaos food behaviour.Reserved for chaos food behaviour.Reserved for chaos food behaviour.Reserved for chaos food behaviour.
FOOD_BAD_BREATHHours of nourishment (bad breath variant).Unused slot.Unused slot.Unused slot.Unused slot.

Source: unified ROM value schema surfaced on the MadWeb items page.【F:madweb/items.php†L122-L215】

Builder playbooks

Practical guardrails gathered from the retired stand-alone builder notes. Use these when auditing new content or coaching other staff between full code dives.

Item balance limits

Use these caps when reviewing gear for parity with the modern combat math. They reflect the preserved madozy.doc/objstats.doc guidance plus the current Ancient tier behaviour.

Level caps & principles

  • Player-usable items top out at level 91 and should stay within five levels of the resetting mob unless a story exception applies.
  • Reserve maximum values for lore-heavy rares and ensure extended descriptions and materials match the theme so destruction logic stays believable.

Weapons

  • Average damage ≈ 5 + \lfloor level / 10 \rfloor × 5. Trim dice when stacking hit/dam or other affects and mark glow/hum at the +6 ceiling.
  • floor × 5. Trim dice when stacking hit/dam or other affects and mark glow/hum at the +6 ceiling.
  • Keep weights near 3–20 lbs. and prices below 1,000 gold under level 50 or 2,000 overall.

Armor

  • No bonus: physical AC ≤ level / 3, magic AC ≤ level / 8.
  • With bonuses: physical AC ≤ level / 4, magic AC ≤ level / 10. Enforce glow/hum on max hit/dam sets.

Containers, lights & food

  • Perpetual lights begin at level 20; endless drink containers wait until level 65.
  • Container capacity scales 100 lbs (levels 1–10) → 150 (11–15) → 200 (16–25) → 500 (26+).
  • Food values stay between 10 and 50.

Scrolls, potions & pills

  • Item level ≥ spell base class level. Spell level ≤ min(item level + 10, item level × 1.4).
  • Shop costs for spells above level 50 run at least 1.25× homemade scroll/potion prices.

Area file string hygiene

Keep an eye on tilde terminators whenever you hand-edit #OBJECTS or #ROOMS blocks. The loader stops reading each keyword, long description, or extra description the moment it hits a bare ~ on its own line, then expects the very next character to belong to the following field.

  • Never leave a trailing ~ or extra punctuation on the same line as the sentinel. Doing so makes the parser treat the stray character as the start of the next record, which desynchronises the area stream and corrupts everything that follows.
  • If you need a literal tilde in the description text, escape it in the editor (for example with \~) or replace it with another glyph—do not rely on the raw delimiter.
  • When you clean up errant sentinels, follow the object layout used in area/voxmad.are: description lines flow normally, then a blank line, then a single ~ line before the next field begins.

Reference: the shared fread_string helper stops at the first ~ it encounters while loading area strings, so any stray delimiter halts the read early and shifts the file pointer into the wrong place.【F:src/ssm.c†L436-L478】【F:area/voxmad.are†L446-L471】

Wands & staves

  • Share the same level constraints as consumables.
  • Charge caps: 1 (levels 1–15), 2 (16–25), 3 (26–40), 4 (41–60), 6 (61–91). Limit marquee spells accordingly.

Bonus ceilings

  • HP/Mana/Move: choose mana or hit points per item; bracket caps: 0 (1–10), +15 (11–25), +20 (26–40), +35 (41–60), +40 (61–84), +50 (85–91). Subtract five when stacking extra affects.
  • Hitroll or damroll: maxes from +0 (levels 1–9) through +6 (90–91); reduce other bonuses by one per +2 stacked and enforce glow/hum on +6 armor.
  • Attributes: total stat boosts peak at +2 (1–10), +4 (11–25), +5 (26–50), +6 (51+); lower ceilings when mixing with hp/mana or hit/dam bonuses.
  • Saves: best-in-slot stays at −5 for level 71+ pieces and scales down one step per bracket.

Ancient tier rolls

  • Eligible gear between levels 30–91 can auto-upgrade: Elite (30–59, 10%), Runic (60–89, 5%), Ancient (90–91, 1%).
  • Use ancients <tier> <vnum> to force a tier; the game validates eligibility before cloning.
  • Armor/lights gain +20–120 split bonuses by tier; weapons receive flat dice bumps (+5/+5 → +25/+25).

Enchanting reference

  • Failure chance starts at 25% (clamped 5–95). Caster level removes up to 50 (armor) or 75 (weapon) points; glow adds 4, hum adds 3, extra affects add 20/25.
  • Catastrophic failure steps bonuses down instead of vaporising items, but +5 or higher bonuses spike failure quickly because of quadratic penalties.

Sources: Rebuilt objstats.doc guidance combined with the current enchant and Ancient tier logic in docs/gameplay_systems.html.

Achievement configuration

Each achievement lives on a single pipe-delimited line inside config/achievements.txt:

<id>|<name>|<description>|<criteria>|<threshold>|<points>
id
Lowercase identifier used internally; keep stable.
name
Player-facing title shown in help and UI.
description
Short summary surfaced in achievement listings.
criteria
One of kill_count, death_count, level, exploration_completions, all_stats_maxed, language_skill:<language>, prestige_kill:<mob>, or prestige:<identifier>.
threshold
Numeric requirement for the tracked stat (often 1 for prestige kills and boolean checks).
points
Score granted when unlocked.

Exploration milestones

Use exploration_completions to reward fully explored areas. Set the threshold to the number of distinct 100% completions required.

Physical perfection

all_stats_maxed ignores the threshold beyond confirming it is at least one. Leave the value at 1 for boolean checks.

Language mastery

Configure language_skill:<language> with the keyword accepted by the language command (for example jedi or msl). Characters unlock the achievement once the tracked proficiency reaches the threshold.

Prestige encounters

prestige_kill:<mob> normalises the supplied mob name (lowercase, punctuation removed, prefixed with prestige_) so it matches the stored counter. For non-kill counters, fall back to prestige:<identifier> and supply the exact key.

Reload the definitions with a reboot or copyover after editing. Characters keep retired achievements flagged as legacy.

Critter invasion sizing

Two numbers control an invasion’s cadence: the route array length and the wave_count. Each route entry spawns one mob per wave, and the wave count dictates how many full cycles fire before shutdown.

Want ten waves of thirty NPCs? Create thirty route entries (duplicates allowed when sharing paths), point the group at that array, and set wave_count to 10. The scheduler respawns the next wave after the configured delay until the count reaches zero.

static const CRITTER_ROUTE thirty_raider_routes[] = {
  {"b0", "Follow path B", 9615, 9616, 9620},
  {"b1", "Follow path B", 9615, 9616, 9620},
  /* add twenty-eight more entries */
};

static const CRITTER_GROUP critter_groups[] = {
  {"thirty_raiders", "Thirty Raiders", "Recommended levels 30-40", 35,
   thirty_raider_routes,
   sizeof thirty_raider_routes / sizeof thirty_raider_routes[0],
   10},
  /* existing groups follow */
};

Result: each wave spawns thirty mobs, waits for the respawn delay, and repeats ten times before the system shuts down.

Skill & spell availability

Use the interactive matrix to cross-check class access, earliest levels, and race-only perks without diving into tables.c. Filter by class or ability type, and expand the race primer for innate bonuses.

Data generated from the live skill table; the embedded view shows the refresh timestamp.

Bit constant quick reference

The single-letter (and double-letter) bit macros are defined in the builder section of merc.h. Use this chart when you need the numeric value for manual flag editing or when checking masks in logs.

MacroValue
A1
B2
C4
D8
E16
F32
G64
H128
I256
J512
K1024
L2048
M4096
N8192
O16384
P32768
Q65536
R131072
S262144
T524288
U1048576
V2097152
W4194304
X8388608
Y16777216
Z33554432
aa67108864
bb134217728
cc268435456
dd536870912
ee1073741824

Source: merc.h “values of interest to area builders” section.【F:src/merc.h†L660-L710】

Wiznet channels

These toggles help builders subscribe to the appropriate server events. Each entry shows the Wiznet flag and the minimum level macro allowed to enable it.

ToggleFlagMinimum Level Macro
onWIZ_ONIM
bugsWIZ_BUGSL3
ticksWIZ_TICKSIM
loginsWIZ_LOGINSIM
sitesWIZ_SITESL4
linksWIZ_LINKSL7
newbiesWIZ_NEWBIEIM
spamWIZ_SPAML5
deathsWIZ_DEATHSIM
resetsWIZ_RESETSL4
mobdeathsWIZ_MOBDEATHSL4
flagsWIZ_FLAGSL2
penaltiesWIZ_PENALTIESL5
saccingWIZ_SACCINGL5
levelsWIZ_LEVELSIM
loadWIZ_LOADL4
restoreWIZ_RESTOREL4
snoopsWIZ_SNOOPSL5
switchesWIZ_SWITCHESL5
secureWIZ_SECUREL7
illegalWIZ_ILLEGALL5
debugWIZ_DEBUGL1
spellsWIZ_SPELLSL5
arenaWIZ_ARENAL3
cloneWIZ_CLONEL5

Source: wiznet_table in const.c.【F:src/const.c†L24-L64】