Bestiary & Enemy Design
Arx ships 41 NPC class folders. Underneath they are two script archetypes and one stat block with a dozen dials.
The roster
| Family | Classes |
|---|---|
| Vermin | rat, wrat, mice, bat, spider (base / baby / nasty) |
| Goblins | goblin base, goblin lord, goblin king, hanged goblin |
| Ratmen | ratman |
| Big bruisers | troll, golem, worm |
| Undead | zombie, mummy, liche, tortured corpse |
| Demonic / arcane | demon, gargoyle, snake woman, black thing, flying creature, ice dragon |
| Humans | human male, female, child, king, priest, ylside (via type) |
| Bosses | Akbaa phase 1, phase 2, Akbaa tentacle |
| Livestock & ambience | chicken, pig, dog, frog |
| Dev leftovers | test, tsu_test, goblin_test, sylib, y_mx |
Ambient animals matter more than they look: goblins carry a care_about_mice flag and will abandon their patrol to hunt a mouse, stacking their behaviour and restoring it afterwards. The world has a food chain running whether or not you are watching.
Two archetypes, not forty
Every NPC script pulls in one of two shared include sets:
main_animal— rats, bats, spiders. No speech, no faction, no calling for help, no door handling, no theft. Detection, attack, flee, go home.main_clever— goblins, ratmen, undead, humans. Adds speech with anti-repetition arbitration, faction membership,CALL_FOR_HELP, door opening with carried keys, reaction to being pickpocketed, and per-spell counterplay.
A "clever" NPC that hears you says something about it, walks over, tells its faction, and opens the door on the way. An "animal" just comes. That single fork is the entire difference between a monster and an inhabitant.
Verified stat blocks
Read from the SET_NPC_STAT blocks in each base script. Absorb is percent damage reduction; aim time is milliseconds between strikes; pain is the damage threshold below which no flinch animation plays.
| Enemy | Life | Dmg | ToHit | AC | Absorb | Aim | Pain | XP | Magic / Poison / Fire resist |
|---|---|---|---|---|---|---|---|---|---|
| Baby spider | 4 | 2 | 40 | 10 | 10 | 2000 | 1 | 10 | 1 / 100 / 1 |
| Rat | 5 | 2 | 40 | 0 | 10 | 1000 | 0 | 12 | 1 / 30 / 1 |
| Spider | 8 | 4 | 40 | 10 | 10 | 2000 | 1 | 20 | 1 / 100 / 1 |
| Wrat | 10 | 4 | 50 | 0 | 15 | 1000 | 0 | 28 | 1 / 40 / 2 |
| Goblin | 12 | 3 | 30 | 8 | 10 | 1000 | 1 | 40 | 10 / 10 / 1 |
| Goblin king | 22 | 6 | 30 | 10 | 10 | 10 | 1 | 70 | 10 / 10 / 1 |
| Goblin lord | 25 | 10 | 50 | 16 | 20 | 1000 | 4 | 70 | 10 / 10 / 1 |
| Ratman | 25 | 10 | 80 | 30 | 30 | 300 | 2 | 400 | 10 / 50 / 10 |
| Nasty spider | 30 | 10 | 40 | 20 | 30 | 2000 | 1 | — | 1 / 100 / 1 |
| Zombie | 35 | 12 | 20 | 6 | 30 | 2500 | 6 | 0 | 30 / 50 / 30 |
| Troll | 40 | 18 | 30 | 18 | 30 | 1000 | 10 | 100 | 1 / 10 / 1 |
| Mummy | 45 | 30 | 60 | 8 | 30 | 2000 | 4 | 250 | 50 / 80 / 50 |
| Golem | 70 | 20 | 10 | 50 | 80 | 3000 | 15 | 200 | 30 / 100 / 30 |
| Demon | 140 | 25 | 50 | 30 | 20 | 200 | 2 | 1000 | 20 / 40 / 90 |
Also carried per class: reach (rat −50, goblin 20, troll 30, demon 100), poison-on-hit (SET_POISONOUS — spider 2, nasty spider 20, ratman 10, zombie 2), and backstabskill (ratman 70; most others unset).
The four dials that actually differentiate enemies
1. Pain — the stagger economy. Damage below an enemy's pain value plays no hit reaction. Rat 0, goblin 1, ratman 2, goblin lord 4, zombie 6, troll 10, golem 15. So your per-hit damage decides whether you can chain-stagger something or whether it walks through your swings untroubled. A player with Strength 6 and a floor attack value of 1 cannot flinch anything above a rat. This is the most important enemy stat in the game and it is invisible to the player.
2. Absorb versus to-hit. The golem is the design statement: 80% damage absorb, AC 50, but to-hit 10 and a 3-second swing. It barely lands a blow and barely takes one — a puzzle disguised as a fight, solved by patience, positioning, or magic that ignores the melee exchange. The demon inverts it: 200 ms attacks, 100 reach, 140 life, and only 20% absorb — pure pressure.
3. Attack speed as the real threat. Compare aim times: zombie 2500 ms, golem 3000 ms, ratman 300 ms, demon 200 ms, goblin king 10 ms. Damage numbers understate the difference wildly — the mummy's 30 damage at 2000 ms is 15 DPS, while the ratman's 10 at 300 ms is 33.
4. Resistances as build counterplay. Fire is the near-universal weakness (rat, spider, troll, goblin all at 1) except where it is a total wall (demon 90). Poison is the reverse: spiders and golems at 100, undead at 50–80. Whether your build is fire, poison or steel changes which half of the bestiary is easy.
XP anomalies worth noticing
Zombies give zero XP — the line SET_XP_VALUE 120 sits commented out directly above SET_XP_VALUE 0. Summoned demons likewise have their XP zeroed. Both are anti-farming patches: Raise Dead and Summon Creature would otherwise be infinite XP taps. The fix is blunt but correct, and it means the undead are pure attrition with no progression reward — fight them only when you must.
The ratman's 400 XP against a troll's 100 (with 15 more life and nearly double the damage) says the designers priced difficulty of the encounter, not the stat block. A teleporting, poisonous, gold-stealing assassin that opens at 80 to-hit is worth more than a slow wall of meat.
Behavioural counterplay
- Cowardice escalation. An NPC flees when
life < cowardice. On each flee the value is halved (or decremented by 2), and once it drops below 3 it is set to 0 — the script comment reads "next time attack and fight to death". Enemies get braver every time you scare them off. Trolls, golems, demons, goblin lords and all undead start at 0 and never flee at all. - Confusability is a caster-level gate: Confuse only lands if caster level ≥ the value. Spider 1, troll 2, goblin 3, ratman 5, mummy 6, demon 8.
- Repel Undead flips undead into flee tactics; the liche ignores it below caster level 6.
- Harm, Life Drain and Mana Drain trigger a panic branch that sets the target's pain threshold to 20 (so it stops flinching) and makes it flee — unless the player is below 20 life, in which case it presses the attack. A drain spell is a rout tool, and the enemy smells blood if you are nearly dead.
- Noise accumulates: three distinct sound sources auto-detect the player; the same source is ignored for 2 seconds.
- Stealth thresholds in script: bumping into an NPC reveals you unless Stealth ≥ 80, and Stealth > 50 opens the pickpocket bag on contact.
- Ratman special attack: on a roll it turns invulnerable, casts Invisibility on itself, teleports to a marker or directly behind the player, and may throw a shuriken (only beyond 300 units) for up to 20 damage. It also steals gold on 25% of its strikes — recoverable from its corpse.
Assessment
The bestiary is wide in fiction and narrow in mechanism. Fourteen stat blocks, two AI archetypes and four meaningful dials produce enemies that feel distinct because the dials are tuned to opposite extremes rather than spread evenly — the golem and the demon are the same system pushed in opposite directions.
The gap: none of the four dials is legible. The player cannot see pain thresholds, absorb percentages, aim times or confusability, and the game never teaches that fire is the universal answer or that a drain spell routs. Enemy knowledge in Arx is acquired by dying, not by reading — defensible in 2002, and the reason the player curve is so much longer than the character curve.
Touchpoints
- → NPC AI & Behaviour: the shared behaviour stack, pathfinding and evade rolls all of these classes drive
- → Combat: absorb, AC and to-hit feed the same damage resolution as the player's
- → Magic & Runes: confusability, repel, and the drain-panic branch are per-spell counterplay authored per enemy
- → Stealth & Light: contact detection at Stealth 80, pickpocketing at 50
- → Economy & Items: per-class loot tables, goblin gold, ratman theft recovery
What breaks if you remove it
Nothing structural — but the fiction of a fortress shared by competing species is carried almost entirely by the roster's breadth and by the ambient animals. Cut the mice and the chickens and Arx becomes a monster closet.