Fire Emblem: The Sacred Stones
Intelligent Systems' third Fire Emblem for the Game Boy Advance, read through the fireemblem8u decompilation of its North American release.
On this page
Intelligent Systems developed Fire Emblem: The Sacred Stones for the Game Boy Advance. The code read here is the FireEmblemUniverse fireemblem8u decompilation, which builds the North American ROM.
Its forecast window shows one hit percentage, and the game rolls against it with the average of two random numbers1. Computed from the code, taking the two rolls as independent, a shown 80 hits 92.2% of the time and a shown 20 only 8.2%2. A critical hit rolls a single number3. A level-up rolls one number per stat, and rerolls up to twice when no stat rises4.
Mechanics
| Mechanic | Kind | How |
|---|---|---|
| Hit chance | Two rolls averaged | hit less avoid, against the average of two numbers from 0 to 99, so a shown 80 hits 92.2% of the time, computed with the two rolls taken as independent |
| Critical hit | Weapon and stats | the weapon's crit plus half the attacker's skill, less the defender's luck, on one roll; a critical triples the damage |
| Weapon triangle | Hit and damage | 15 hit and 1 damage each way, for swords, axes, and lances and for anima, light, and dark |
| Follow-up attack | Speed threshold | an attack speed 4 or more above the foe's strikes once more after both have attacked |
| Growth rate | A roll per stat · player units | each level rolls each of seven stats on the character's own percentage |
| Growth rate | Growth times levels · autoleveled enemies | one roll per stat on the class's growth times its levels, moved by up to an eighth |
| Permadeath | Per unit | a player unit that falls in combat is flagged dead, and chapter changes keep the flag; a phantom is erased |
| Damage formula | Attack minus defense, no roll | might, triangle, and strength less defense, tripled on a critical and held within 0–127 |
Every claim about this game, by concept (11)
References
- ^In the North American build, an attack hits when the displayed hit is greater than the average of two random numbers from 0 to 99, rounded down; each number scales a 16-bit
NextRN()by 100/65,536.Codefireemblem8uHow we know
68int NextRN_100(void) { 69 // take the next rn (range 0-0xFFFF) and convert it to a range 0-99 value 70 return NextRN() * 100 / 0x10000;
src/rng.c lines 68–70 at 04d1edb · upstream ↗ 89s8 Roll2RN(int threshold) { 90 int average = (NextRN_100() + NextRN_100()) / 2; ⋮ 92 return (threshold > average);
src/rng.c lines 89–93 at 04d1edb · upstream ↗ 1007 if (!(gBattleHitIterator->attributes & BATTLE_HIT_ATTR_SURESHOT)) { 1008 if (!BattleRoll2RN(gBattleStats.hitRate, TRUE)) { 1009 gBattleHitIterator->attributes |= BATTLE_HIT_ATTR_MISS;
src/bmbattle.c lines 1007–1011 at 04d1edb · upstream ↗ 879void BattleUpdateBattleStats(struct BattleUnit* attacker, struct BattleUnit* defender) { ⋮ 882 gBattleStats.hitRate = attacker->battleEffectiveHitRate;
src/bmbattle.c lines 879–882 at 04d1edb · upstream ↗ 260 PutNumberTwoChr(gUiTmScratchA + 0xA8 + 0x40, 2, gBattleActor.battleEffectiveHitRate);src/bksel.c line 260 at 04d1edb · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^Computed from the code, taking the two numbers as independent and evenly spread, a displayed hit connects times in 10,000 up to 50 and times above it, so a displayed 80 hits 92.2% of the time, 20 hits 8.2%, and 50 hits 50.5%.Codefireemblem8urevised
How we know
89s8 Roll2RN(int threshold) { 90 int average = (NextRN_100() + NextRN_100()) / 2; ⋮ 92 return (threshold > average);
src/rng.c lines 89–93 at 04d1edb · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Revised after a check by a second AI model, 2026-10-21.
- ^In the North American build, a unit's crit is its weapon's crit plus half its skill, plus 15 for classes with a crit bonus; the crit shown and rolled is that less the defender's luck, at least 0, and one random number from 0 to 99 below it triples the hit's damage.Codefireemblem8u
How we know
589 bu->battleCritRate = GetItemCrit(bu->weapon) + (bu->unit.skl / 2); ⋮ 591 if (UNIT_CATTRIBUTES(&bu->unit) & CA_CRITBONUS) 592 bu->battleCritRate += 15; ⋮ 596 bu->battleDodgeRate = bu->unit.lck;
src/bmbattle.c lines 588–597 at 04d1edb · upstream ↗ 612 attacker->battleEffectiveCritRate = attacker->battleCritRate - defender->battleDodgeRate; ⋮ 615 attacker->battleEffectiveCritRate = 0; ⋮ 617 if (attacker->battleEffectiveCritRate < 0) 618 attacker->battleEffectiveCritRate = 0;
src/bmbattle.c lines 612–618 at 04d1edb · upstream ↗ 85s8 Roll1RN(int threshold) { 86 return (threshold > NextRN_100());
src/rng.c lines 85–87 at 04d1edb · upstream ↗ 1030 if (BattleRoll1RN(gBattleStats.critRate, FALSE) == TRUE) { ⋮ 1038 gBattleHitIterator->attributes = gBattleHitIterator->attributes | BATTLE_HIT_ATTR_CRIT; 1039 gBattleStats.damage = gBattleStats.damage * 3;
src/bmbattle.c lines 1030–1039 at 04d1edb · upstream ↗ 883 gBattleStats.critRate = attacker->battleEffectiveCritRate;src/bmbattle.c line 883 at 04d1edb · upstream ↗ 243 critRate = gBattleActor.battleEffectiveCritRate;src/bksel.c line 243 at 04d1edb · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^In the North American build, a level-up rolls each of seven stats on the character's own growth rate, with one random number from 0 to 99; each full 100 of a rate is a sure point, and if no stat rises, the game rerolls the stats in order up to twice, stopping at the first that does.Codefireemblem8u
How we know
1227int GetStatIncrease(int growth) { ⋮ 1230 while (growth > 100) { 1231 result++; 1232 growth -= 100; ⋮ 1235 if (Roll1RN(growth)) 1236 result++;
src/bmbattle.c lines 1227–1238 at 04d1edb · upstream ↗ 1275 growthBonus = (bu->unit.state & US_GROWTH_BOOST) ? 5: 0; ⋮ 1278 bu->changeHP = GetStatIncrease(bu->unit.pCharacterData->growthHP + growthBonus); ⋮ 1281 bu->changePow = GetStatIncrease(bu->unit.pCharacterData->growthPow + growthBonus);
src/bmbattle.c lines 1275–1281 at 04d1edb · upstream ↗ 1299 if (statGainTotal == 0) { 1300 for (statGainTotal = 0; statGainTotal < 2; ++statGainTotal) { 1301 bu->changeHP = GetStatIncrease(bu->unit.pCharacterData->growthHP); ⋮ 1303 if (bu->changeHP) 1304 break;
src/bmbattle.c lines 1299–1304 at 04d1edb · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
Sources
Code
- FireEmblemUniverse contributors. 2026. “fireemblem8u: decompilation of Fire Emblem: The Sacred Stones.” FireEmblemUniverse. Commit 04d1edb. FireEmblemUniverse/fireemblem8u @ 04d1edb · licence, all uses