Game Mechanics

The math behind Ultima I Unity: how damage, defense, difficulty, the Mondain duel, shops and leveling are actually calculated.

These are the actual numbers our reproduction runs on. Every formula is tagged with where it comes from. RNG(a, b) means a random integer from a up to but not including b, clamped to 255.

Where the numbers come from

  • 1987 DOS remakeRecovered byte for byte from the original 1987 DOS executable OUT.EXE.
  • 1987 DOS remake (unverified)A formula once attributed to OUT.EXE that a deeper disassembly could NOT substantiate. Shown for comparison only.
  • Data Driven Gamer blogReconstructed from The Data Driven Gamer blog analysis of the original game.
  • Community guideSourced from community reference guides (gamercorner.net).
  • 1981 originalMatches the original 1981 Ultima I behaviour (community model; the executable has no explicit table).
  • Prototype designA design choice made for this reproduction, not a verified original value.
  • Community guide + designFood costs follow community reference guides; the time constants are a tuned design choice.

The toggles

Prototype design
  • Overworld Combat: 1981 Original or 1987 Remake (default 1987).
  • Dungeon Combat: 1981 Apple II or 1987 DOS (default 1987).
  • Weapon Availability: 1981 Original (shops sell the full town stock) or 1987 Remake (step-gated stock).
  • Spell Casting: Class Locked (1981, arcane spells stay Wizard-only) or Unrestricted (1987 remake, any class casts what it owns).
  • 1987 DOS Dungeon Armor Bug: optional toggle that reproduces the remake bug where worn armor gives no dungeon protection.
  • Space Docking: Precise (legacy pixel-perfect) or Assisted (a controller-friendly snap, an accessibility aid rather than an era setting).

Each toggle defaults to the behavior the prototype already used, so switching is opt-in. The 1981 sets are faithful transcriptions of the Apple II BASIC and community write-ups, not byte-exact executable dumps.

Overworld: player attacks

1981 original
hit if:  RND(20) + STR/5 + AGI/5 + WeaponPower  >  Defense
Defense = min(monster EXP + 10, 20)

damage = RND(WeaponPower + STR) + 1   (1 up to WeaponPower + STR)

WeaponPower = weapon catalog index (bare Hands = 0)

RND(20) is a fractional 0..20 roll. WeaponPower and the monster EXP table come from community reverse-engineering, not an in-executable table, so treating catalog index as "power" is a derived interpretation.

Compare to the original

1987 DOS remake1987 remake (default)

damage = RNG(2, STR + WeaponIndex * 8)

See the Damage and Defense sections for the DOS to-hit rolls.

Overworld: monster attacks

1981 original
hit if:  RND(15)^2  >  min((min(ArmorPower/5, 0.5) + 1.5) * AGI, 80)

damage = RND(monster EXP) + 1   (1 up to the creature EXP value)

ArmorPower = armor catalog index

RND(15) is a fractional 0..15 roll, squared so it skews low. Squaring makes agility a strong overworld defense in the 1981 model.

Compare to the original

1987 DOS remake1987 remake (default)

Overworld enemy damage uses OverworldMonsterData.RollDamage (see the Damage section).

Overworld: monster HP, EXP and gold

1981 original
HP by band (classic index I):
  Sea   (I 6-9)   RND(20*I - 80)  + 30
  Woods (I 10-14) RND(20*I - 180) + 30
  Land  (I 15-20) RND(10*I - 140) + 10
plus first-in-group time bonus:  RND(1)^2 * Time / 100

EXP reward = the creature EXP value
gold = 10 + RND(4 * EXP)

Spans reproduce the community write-up table (Ness 30-69, Thief 10-19, and so on). This port spawns single monsters, so every creature is treated as first-in-group; the group and successor-HP rules are not modeled.

Compare to the original

1987 DOS remake1987 remake (default)

HP scales with player level (GetScaledHP); EXP and gold come from the DOS tables in the Difficulty Scaling section.

Dungeon: player attacks

1981 original
hit if:  RND(Agility/4 + WeaponPower)  >  min(RND(MN + (MB-20)/3) + L, 20)

damage = RND(Strength/5 + WeaponPower*3) + Strength/5

L  = dungeon depth (1-based)
MN = monster number 1..5 on the level
MB = monster base = set*5 + 15

RND(n) here is the integer Apple II roll (0..n). WeaponPower is the weapon catalog index, a derived interpretation.

Compare to the original

1987 DOS remake1987 remake (default)

Player damage is the unified RNG(2, STR + WeaponIndex * 8) (see the Damage section).

Dungeon: monster attacks

1981 original
attack  = min(RND(10) + 3*L, 20)
defense = RND(Stamina/3) + 3*ArmorPower
monster hits if defense < 20 AND attack > defense

damage = RndLarge(MN * L^2) + 2*L

A defense roll of 20 or more is a guaranteed miss. With the Dungeon Armor Bug toggle on, ArmorPower is forced to 0 in both rule-sets, so worn armor stops helping underground. RndLarge composes two rolls for values above 254 and is not byte-exact.

Compare to the original

1987 DOS remake1987 remake (default)

Uses the DOS dungeon to-hit and damage rolls (see the Defense and Damage sections).

Dungeon: HP, EXP and gold

1981 original
spawn HP   = RndLarge(MN * L^2) + 10
respawn HP = RndLarge(2 * MN * L^2) + 15

kill EXP  = RndLarge(L * MN * 5) + L
kill gold = RndLarge(9 * L^2) + 9

Unlike the remake, 1981 EXP depends on which creature was slain, not just the depth, and the gold is far richer.

Compare to the original

1987 DOS remake1987 remake (default)

HP, EXP and gold scale with depth per the DOS tables (see the Difficulty Scaling section).

Weapon availability (1987 step-gate)

Community guide
Daggers to Rope & Spikes (1-4):  from the start
Sword, Great Sword (5-6):        at 1500+ steps
Bow, Amulet, Wand, Staff (7-10): at 3000+ steps
Triangle to Blaster (11-15):     never sold (steal or pond/pence drops only)

Steps count town and overworld moves only (dungeon moves are deliberately excluded). Under 1981 Original, shops sell whatever the town stock list holds, matching the prototype default. The step thresholds follow the gamercorner reference guide.