Spell Casting Mechanics - HoraceAndTheSpider/Bloodwych-68k GitHub Wiki
Spell casting mechanics
This page describes the SPS 439 player spell-casting path. The individual spell effects are documented separately under Spell Effects and Handlers.
A spell costs mana, and spending more or less mana adjusts its power. Whether it succeeds also depends on the champion: their class, level, equipment, practice with that spell, and how recently they last cast.
In the following, champions, wands, rings and spells match if their colour is identical.
Attempting to cast a selected spell reduces vitality by 4, to a minimum of 0, and sets the general action cooldown to 15. Neither of those two values changes the spell's success chance. The separate spell cooldown does affect it.
Spell table
SpellCost_DataTable begins at memory address $685E (SPS 439 file position $64DA). The difficulty values are the signed-quality penalties in the adjacent 32-byte difficulty table, not spell numbers.
| No. | Name | Profession | Cost value | Difficulty penalty |
|---|---|---|---|---|
| 1 | Armour | Serpent (green) | 1 | 14 |
| 2 | Terror | Chaos (yellow) | 2 | 15 |
| 3 | Vitalise | Dragon (red) | 2 | 14 |
| 4 | Beguile | Moon (blue) | 1 | 14 |
| 5 | Deflect | Chaos (yellow) | 1 | 13 |
| 6 | Magelock | Dragon (red) | 2 | 14 |
| 7 | Conceal | Moon (blue) | 2 | 14 |
| 8 | Warpower | Serpent (green) | 3 | 15 |
| 9 | Missile | Dragon (red) | 1 | 14 |
| 10 | Vanish | Moon (blue) | 3 | 15 |
| 11 | Paralyze | Serpent (green) | 2 | 14 |
| 12 | Alchemy | Chaos (yellow) | 5 | 18 |
| 13 | Confuse | Moon (blue) | 2 | 15 |
| 14 | Levitate | Serpent (green) | 2 | 15 |
| 15 | Antimage | Chaos (yellow) | 4 | 17 |
| 16 | Recharge | Dragon (red) | 5 | 16 |
| 17 | Trueview | Moon (blue) | 3 | 15 |
| 18 | Renew | Serpent (green) | 3 | 16 |
| 19 | Vivify | Chaos (yellow) | 7 | 36 |
| 20 | Dispell | Dragon (red) | 3 | 16 |
| 21 | Firepath | Dragon (red) | 4 | 17 |
| 22 | Illusion | Moon (blue) | 4 | 19 |
| 23 | Compass | Serpent (green) | 2 | 14 |
| 24 | Spelltap | Chaos (yellow) | 5 | 18 |
| 25 | Disrupt | Chaos (yellow) | 8 | 24 |
| 26 | Fireball | Dragon (red) | 3 | 16 |
| 27 | Wychwind | Moon (blue) | 7 | 22 |
| 28 | Arc Bolt | Serpent (green) | 4 | 16 |
| 29 | Formwall | Serpent (green) | 5 | 17 |
| 30 | Summon | Chaos (yellow) | 6 | 19 |
| 31 | Blaze | Dragon (red) | 6 | 18 |
| 32 | Mindrock | Moon (blue) | 4 | 16 |
The original list also includes these Extended Levels spells. They belong to BEXT43 and are not entries in the SPS 439 dispatch or cost tables above.
| No. | Name | Class |
|---|---|---|
| 33 | Protect | Ancient (pink) |
| 34 | Phaze | Ancient (pink) |
| 35 | Enhance | Ancient (pink) |
| 36 | Inferno | Ancient (pink) |
| 37 | Nullify | Ancient (pink) |
| 38 | Restore | Ancient (pink) |
| 39 | Spray | Ancient (pink) |
| 40 | Vortex | Ancient (pink) |
Mana cost and power adjustment
Without a matching charged ring, the initial mana cost is:
2 × (cost value + 1) + power adjustment cost
For example, spell 10 (Vanish) has a cost value of 3, so its base mana cost is
2 × (3 + 1) = 8.
The power adjustment is stored in champion byte $14. A negative adjustment
reduces the mana cost by that amount:
| Power adjustment | −3 | −2 | −1 | 0 |
|---|---|---|---|---|
| Mana adjustment | −3 | −2 | −1 | 0 |
| Vanish mana cost | 5 | 6 | 7 | 8 |
Positive adjustments cost progressively more mana, following this curve:
Byte $14 |
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Added mana | 0 | 3 | 6 | 10 | 15 | 21 | 28 | 36 | 45 | 55 | 66 | 78 | 91 | 105 |
For Vanish, a +1 power adjustment adds 3 mana, making the cost 11; +2 adds 6 mana, making it 14.
Mana used on a single spell cannot exceed 99. If the result reaches 100, the routine decrements byte $14 and recalculates until the cost is at most 99. A calculated zero is changed to one and byte $14 is incremented. Consequently the stored power adjustment may be normalised during costing.
A charged ring matching the spell profession makes the mana cost zero, resets byte $14 to zero, and spends one ring use. The ring is checked in either hand.
Practice
Each spell is practised individually. As a champion casts it successfully, practice improves their chance of succeeding with that spell again. The count belongs to that champion, not to the party or all champions together.
SPS 439 stores 32 counters for each of its 16 champion records: 512 bytes beginning at memory address $1694C. A successful dispatch increments only the caster's counter for the selected spell. Each counter saturates at $FF (255).
The practice contribution to casting quality follows one tiered curve:
Practice count X |
Contribution |
|---|---|
| 0–4 | X |
| 5–14 | 5 + floor((X - 5) / 2) |
| 15–34 | 10 + floor((X - 15) / 4) |
| 35–74 | 15 + floor((X - 35) / 8) |
| 75–154 | 20 + floor((X - 75) / 16) |
| 155–255 | 25 + floor((X - 155) / 32) |
The maximum practice contribution is therefore 28.
Casting success
The game combines the champion's bonuses and penalties into a casting-quality value, then adds a three-dice roll. A negative result means the spell fails.
The game builds a signed one-byte quality value from these terms:
quality = profession bonus
+ matching-wand fallback bonus
+ practice contribution
+ level contribution
+ signed power adjustment
- spell-cooldown penalty
+ Power Staff bonus
- spell difficulty penalty
The profession and level terms are:
| Champion profession | Bonus when spell matches | Level contribution |
|---|---|---|
| Warrior | +3 | 2 × floor(level / 4) |
| Wizard | +5 | 2 × level |
| Adventurer | +4 | 2 × floor(level / 2) |
| Cutpurse | +4 | 2 × floor(level / 4) |
If champion and spell professions do not match, holding the spell's matching wand supplies +3 instead of the profession bonus. Holding a Power Staff in either hand adds a separate +5.
The full spell cooldown is normally subtracted. Calculate_SpellCastingQuality repeats the champion/spell class comparison immediately before this subtraction, so a matching champion class halves the cooldown, rounding down; a matching wand alone does not. After quality has been calculated, cooldown rises by cost value + 5, to a maximum of 100.
Finally the routine adds three independent die rolls, each valued 1–6. The spell fails only when the resulting signed value is negative.
Further source details (SPS 439)
Champion spell state
The casting routine uses these bytes in the champion record:
| Offset | Meaning |
|---|---|
$07 |
Current vitality. Every accepted casting attempt removes 4, clamped at zero. |
$09 |
Current spell points. The calculated mana cost is removed before the success roll. |
$13 |
Selected spell index, 0–31; $FF means no spell is queued. |
$14 |
Signed spell-power adjustment. Non-negative values also select the extra-mana curve. |
$15 |
Spell cooldown. This penalises casting quality and rises after an affordable attempt. |
$1B |
General action cooldown. A casting attempt sets it to 15. |
The source routine beginning at adrCd004E8E validates the queued spell, charges its costs, calculates casting quality, dispatches one of 32 handlers, records practice, and clears the queued spell.
Casting sequence
For an ordinary player cast, SPS 439 performs the following operations:
- Reject
$FFin the selected-spell byte. Beguile is allowed to keep the communication interface open; other spells close it when necessary. - Remove 4 vitality, set the general action cooldown to 15, and clear the current worn-spell effect.
- Calculate the mana cost. If the champion lacks enough spell points, show the cost-too-high notice and stop.
- Remove the spell points, or consume one use from a matching ring.
- Calculate the signed casting-quality value.
- Increase spell cooldown by the spell's cost-table value plus 5, clamped to 100.
- Add a
3D6roll to casting quality. A negative signed result produces SPELL FAILED. - Apply an environmental target-cell check. A rejected target produces SPELL FIZZLED.
- Call the selected spell handler.
- Increment that champion's practice counter for that spell, saturating at
$FF, then clear the queued spell.
Vitality and the general action cooldown are therefore charged before the mana, failure, and fizzle checks. An affordable cast that reaches its handler earns practice even when the handler finds no applicable object or target and makes no change.