On this page
  1. How it works
  2. Implementations
  3. Consequences
  4. History
  5. Related
  6. Games
  7. References
  8. Sources

A random number generator (RNG) produces the numbers a game rolls with. The C standard defines rand as computing “a sequence of pseudo-random integers”, and srand as seeding it so that the same seed repeats the sequence1. The five games in the table use three designs: a linear congruential generator, a fixed table walked by a counter, and bytes stirred by a hardware timer.

  • FormulaDragon Warrior (1986). Battle rolls come from one generator, and reading the controller stirs it too.2,3,4Yoshi's Cookie (1992). One byte stepped as 5x + 17 mod 256, so it repeats every 256 steps.5,6Golden Sun (2001). The C standard's example constants, 1103515245 and 12345, with bits 8 to 23 as the result.7Pokémon Emerald (2004). The ISO C example generator, returning the top 16 bits.8,9
  • Fixed tableFinal Fantasy (1987). Battle rolls come from a fixed table, so they repeat every 256 draws.10,11,12,13,14Wolfenstein 3D (1992). One index walks a 256-byte table, the same table Doom uses, reset to 0 for demos and seeded from the clock otherwise.15,16Doom (1993). One 256-byte table walked by two indices, one for play and one for the wipe, sounds, and screens.17,18,19,20
  • Hardware-stirredPokémon Red and Blue (1996). The hardware divider added to one byte and subtracted from another every frame.21,22Pokémon Crystal (2000). Red and Blue's divider-stirred generator, returning the other byte.23
  • Shift registerAsteroids (1979). A 16-bit shift register stepped on each call.24
  • Stepped counterMetroid (1986). A byte that steps by 25 every frame, through all 256 values.25
  • ROM as tablePac-Man (1980). A pointer stepped by 5p + 1 mod 8192 reads the game's own ROM as its table.26

#How it works

A linear congruential generator (LCG) keeps a state x, steps it as x←(ax+c)modm, and hands out its high bits. A table generator keeps an index into a fixed list of bytes. A hardware-stirred generator adds a free-running counter into its state, so each result depends on the exact moment of the call.

LCG:       x = (a * x + c) mod m;   return the high bits of x      # Dragon Warrior, Emerald
table:     i = i + 1;               return TABLE[i mod 256]         # Final Fantasy
hardware:  s = s + timer + carry;   return s                       # Red/Blue, Crystal

A game then scales the number to the range it needs. Final Fantasy’s RandAX maps a byte r to lo+⌊r(hi−lo+1)/256⌋12. Emerald takes a remainder, as in Random() % 100 + 1 for accuracy27. Red and Blue compare the byte with a threshold directly28.

DesignStateOutputVaried by
Dragon WarriorLCG, s←771s+129(mod216)216 bits2the high byte2every call, including each controller read3
Final Fantasy256-byte tables10,13an 8-bit index per stream10,14the table’s byte10calls only10
Red and Bluehardware-stirred212 bytes21hRandomAdd21the divider at each call; a call every frame21
Crystalhardware-stirred232 bytes23hRandomSub23the divider at each call; a call every frame23
EmeraldLCG, x←1103515245x+24691(mod232)832 bits8the top 16 bits8a timer seed at the player’s naming screen; a call every frame9

#Implementations

#Dragon Warrior

UpdateRandNum steps a 16-bit state as s←771s+129(mod216)2, and battle code reads its high byte2. The 65,536 states split into two cycles of 32,7684, and over each cycle every high byte appears exactly 128 times4. Because the high byte is uniform, a probe that runs a routine once for every state measures its exact odds; the atlas measured Dragon Warrior’s run and damage routines that way4,29.

The controller routine steps the generator on every read3. Ryan8bit’s guide adds that an idle menu runs it 60 times a second, so a command’s outcome depends on when it is chosen3.

#Final Fantasy

Final Fantasy uses tables, not a formula. BattleRNG returns the next byte of a 256-byte table, indexed by a counter that wraps, so battle draws repeat every 256 calls10. That table holds $00 twice and never $9511. Disch’s comment assumes the table is a permutation, and the doubled $00 shows in the ROM: one swing at crit chance 1 crits 4 times in 256 rather than 311,30.

A second table, lut_RNG, holds every byte once13. BattleStepRNG walks it for encounter checks, reversing direction on some passes, and a battle counter indexes it to pick formations14,31. Over a full pass of 256 draws, each rate set against these tables is therefore exact13,31.

#Pokémon Red and Blue

Random_ adds the hardware divider register rDIV to hRandomAdd with carry and subtracts it from hRandomSub with borrow21. The VBlank handler calls it once a frame, and Random returns hRandomAdd21. The divider counts on its own, so the bytes depend on the exact cycle of each call as well as on the frame count21. A wild encounter reads both bytes directly, one to decide the fight and the other to pick the slot32,33.

In a link battle, BattleRandom instead reads the first 9 bytes of a 10-byte list that both Game Boys hold, then regenerates them as x←5x+1(mod256)22.

#Pokémon Crystal

Crystal keeps the generator but returns hRandomSub, and pret’s comment gives the divider’s rate as 16,384 Hz23. The link-battle list carries over23.

#Pokémon Emerald

Emerald’s Random is a 32-bit LCG, x←1103515245x+24691(mod232)8, returning the top 16 bits8. pret’s comment traces the multiplier to the C standard’s example rand8. That example steps x←1103515245x+1234534, so Emerald keeps the multiplier and changes the increment34,8.

The retail game seeds the generator only when the player’s naming screen closes; the clock-based seed at power-on is compiled only into pret’s BUGFIX build9. After loading a save the state starts from 0, and the VBlank handler steps it once a frame9. Every session therefore walks the same sequence from the same start; only the number of steps before a roll changes its result9.

Pokémon FireRed and LeafGreen roll wild encounters on a generator of their own, x←1103515245x+12345, seeded at a new game35. Its increment is the C standard example’s, where Emerald’s Random uses 2469134,8.

#Consequences

The whole state is a few bytes, and every roll follows from it. Where input timing steps the generator, as in Dragon Warrior, a player’s timing picks the outcome3. Where the state starts from a fixed value, as in Emerald after a load, the player’s timing picks a place in a known sequence9.

#History

Games

GameYearHowNote
Dragon Warrior1986Formulabattle rolls come from one generator, and reading the controller stirs it too
Yoshi's Cookie1992Formulaone byte stepped as 5x + 17 mod 256, so it repeats every 256 steps
Golden Sun2001Formulathe C standard's example constants, 1103515245 and 12345, with bits 8 to 23 as the result
Pokémon Emerald2004Formulathe ISO C example generator, returning the top 16 bits
Final Fantasy1987Fixed tablebattle rolls come from a fixed table, so they repeat every 256 draws
Wolfenstein 3D1992Fixed tableone index walks a 256-byte table, the same table Doom uses, reset to 0 for demos and seeded from the clock otherwise
Doom1993Fixed tableone 256-byte table walked by two indices, one for play and one for the wipe, sounds, and screens
Pokémon Red and Blue1996Hardware-stirredthe hardware divider added to one byte and subtracted from another every frame
Pokémon Crystal2000Hardware-stirredRed and Blue's divider-stirred generator, returning the other byte
Asteroids1979Shift registera 16-bit shift register stepped on each call
Metroid1986Stepped countera byte that steps by 25 every frame, through all 256 values
Pac-Man1980ROM as tablea pointer stepped by 5p + 1 mod 8192 reads the game's own ROM as its table
Every claim about this mechanic, by game (37)
Asteroids 1979Asteroids' random routine (77B5) shifts a 16-bit register left one bit and sets the new low bit to the old bit 14 exclusive-or the old bit 0, turning an all-zero register into 1; it returns the low byte.Code
Pac-Man 1980A frightened ghost picks a random direction from random_2a23, which steps a pointer as p←(5p+1)mod8192 and returns the byte at that address, so the game's own first 8 KB of ROM serve as the random table. The direction is the low 2 bits; a reversal or a wall sends it on to try the next one.Code
Dragon Warrior 1986UpdateRandNum steps a 16-bit state as s←771s+129(mod65536), and battle code reads its high byte, RandNumUB.Code
GetJoypadStatus steps the generator each time it reads the controller.Code
Computed from the generator's update, its 65,536 states form two cycles of 32,768, and over each cycle the high byte takes every value exactly 128 times.Code
Metroid 1986The main loop calls RandomNumbers once per frame, after the frame's work; it adds 5 to RandomNumber1 five times, 25 in all, so the byte steps through all 256 values every 256 frames.Code
When an enemy dies, a RandomNumber1 below 16 drops nothing; otherwise its low 3 bits pick from ItemDropTbl, which holds a missile at 0 and 3, energy at 1, 4, and 6, and $89 at 2, 5, and 7.Code
The Legend of Zelda 1986Outside the special cases, a drop happens only when the dead monster's slot's byte of Random is below its group's rate: $50, $98, $68, and $68, or 80, 152, 104, and 104 in 256.Code
Final Fantasy 1987BattleRNG returns the next byte of a 256-byte table, indexed by a counter (btl_rngstate) that wraps, so battle draws repeat every 256 calls.Code
BattleRNG's table holds $00 twice and never $95, so a battle draw is never $95.Code
RandAX scales a table byte r into a range: lo+⌊r(hi−lo+1)/256⌋.Code
lut_RNG, the 256-byte table at $F100, holds every byte from $00 to $FF exactly once.Code
BattleStepRNG returns lut_RNG[i] for a counter i that steps by 1 per call; each time it wraps to 0, a sign byte gains $A0, and its top bit sets the direction of the next pass.Code
Wolfenstein 3D 1992Wolfenstein 3D's random numbers come from rndtable, a fixed table of 256 bytes: US_RndT adds 1 to one index, wraps it at 256, and returns that entry, and the file's comment calls it "John Carmack's table driven pseudo-random number generator". SetupGameLevel sets the index to 0 for each level of a demo being played or recorded, and otherwise to the low byte of DX from DOS's get-time call (int 21h, function 2Ch), the hundredths of a second, 0 to 99 (the atlas's reading of the DOS call).Code
Doom's rndtable holds the same 256 values in the same order as Wolfenstein 3D's (compared entry by entry, computed); Doom walks it with two indices (prndindex for P_Random, rndindex for M_Random), where Wolfenstein 3D uses one (rndindex).Code
Yoshi's Cookie 1992Yoshi's Cookie keeps its random number generator in one byte, $0424, and steps it as x←5x+17mod256, written out in place at each call site, so the sequence runs through all 256 values before it repeats.Verified
The power-on code sets the generator to $C3.Verified
Each stage's board comes from the generator: it picks the stage's kinds of cookie, then fills the board from the bottom left, row by row, redrawing any cookie that matches the one to its left or the one below.Verified
A cookie kind is a generator step mod 5, drawn again while it equals the previous pick; the previous pick is reset to 0 at each stage's start, so the first kind picked is never kind 0.Verified
With n kinds in play, a cookie's kind is the list entry at the count of generator steps with bit 7 set among n − 1 steps, so the middle kinds of the list come up more often than the ends.Verified
Doom 1993Doom's random numbers come from rndtable, a fixed table of 256 bytes, walked by two indices: each call to P_Random or M_Random adds 1 to its own index, wraps it at 256, and returns that table entry.Code
Doom's play code (weapon damage, aim spread, pain) rolls P_Random, and M_Random serves the rest: the screen wipe, sound pitch, intermission animations, and the status bar.Code
G_InitNew resets both of Doom's random indices to 0, and it runs when a new game starts, when a saved game loads, when a demo starts playing, and when the command line starts a game directly (a warp or autostart, or a net game).Code
Doom's rndtable is not a permutation: its 256 entries hold 166 distinct values, 101 of them once, 45 twice, 16 three times, 3 four times, and 1 five times; the value 145 appears 5 times and the value 0 twice.Code
Pokémon Red and Blue 1996Random_ adds the hardware divider register rDIV to the byte hRandomAdd with carry and subtracts it from hRandomSub with borrow; the VBlank handler calls it every frame, and Random returns hRandomAdd.Code
BattleRandom calls Random outside link battles; in a link battle both Game Boys read the first 9 bytes of a shared 10-byte list in turn, and after the ninth read those 9 are each replaced by 5x+1mod256; the tenth byte is never read.Code
Pokémon Crystal 2000Crystal's Random is Red and Blue's generator, adding the divider register (with carry) to hRandomAdd and subtracting it (with borrow) from hRandomSub, but it returns hRandomSub where Red and Blue's Random returns hRandomAdd; pret's comment says the divider counts at 16,384 Hz.Code
Golden Sun 2001Golden Sun's RPGRandom is a linear congruential generator, x←1103515245x+12345(mod232) (0x41C64E6D and 0x3039; the state sRPGRNGState is a 32-bit unsigned int on the GBA), returning state >> 8 as an unsigned short: bits 8 to 23 of the state. RPGRandom2 scales one result to 0 to 99, as RPGRandom × 100 >> 16 (computed). These are the constants of the C standard's example rand, which returns bits 16 to 30 instead. Pokémon Emerald's Random keeps the multiplier but adds 24691 and returns the top 16 bits; pret's random.h defines a second step, ISO_RANDOMIZE2, with Golden Sun's 12345.Code
Fire Emblem: The Binding Blade 2002The Binding Blade hits when the displayed hit is greater than the average of two random numbers, rounded down; each number divides a 16-bit NextRN() by 655, so it runs from 0 to 100, and 100 comes from only 36 of the 65,536 values.Code
Metroid Fusion 2002When a dying sprite's countdown ends, SpriteDying sets its pose to 0x5B (the decompilers' SPRITE_POSE_TURNING_INTO_X) unless it is a secondary sprite, and an enemy's AI (Choot's, for one) runs XParasiteInit in that pose. The X it becomes takes its color from a number from 1 to 1024, made from the low 2 bits of gSpriteRandomNumber and the 8-bit frame counter, against three weights in that sprite's row of sPrimarySpriteStats: the top red-weight values give red and the next green-weight values green, each only when its weight is above 0, and everything left below the green bound gives yellow, whatever the yellow weight is, unless it is 0, which deletes the X instead. A would-be green X turns yellow when missiles are full and energy isn't, or Samus has no missiles yet; a would-be yellow X turns green when energy is full and missiles aren't. An X from a core X is green when gSpriteRandomNumber is below 5 or that energy test holds, and otherwise yellow; an X placed in a room is yellow. All of this applies only to an X whose sprite property is SSP_X_ABSORBABLE_BY_SAMUS: one marked SSP_X_UNABSORBABLE_BY_SAMUS, or the unnamed SSP_UNKNOWN_40, is always yellow, and any other property deletes the X.Code
Fire Emblem: The Sacred Stones 2004In 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.Code
Pokémon Emerald 2004Emerald's Random is a linear congruential generator, x←1103515245x+24691(mod232), returning the top 16 bits; pret's comment traces the multiplier to the example rand in the ISO C standard.Code
Emerald seeds Random from a hardware timer only when the player's naming screen closes, which also sets the trainer ID; the seeding from the real-time clock at power-on is compiled only into pret's BUGFIX build, so after loading a save the generator starts from 0, and the VBlank handler steps it once a frame outside link, Frontier, and recorded battles.Code
Pokémon FireRed and LeafGreen 2004FireRed and LeafGreen roll encounters on their own generator, x←1103515245x+12345, seeded at a new game; a check passes when its value mod 1,600 is below 16 times the area's rate, cut to 80% on a bike, plus 16/200 of a buff to which every failed check adds the area's rate, reset by a battle or a Repel.Code
Pokémon Platinum 2008Platinum's BattleScript_CalcCatchShakes keeps Emerald's capture math: the same a=⌊⌊Cm/10⌋(3M−2H)/3M⌋, the same status bonuses (×2 for sleep or freeze; ×15/10 for poison, bad poison, burn, or paralysis), a catch at once when a is 255 or more, and otherwise the threshold b=⌊1048560/⌊16711680/a⌋⌋ with up to four 16-bit rolls, each below b a shake, and the Master Ball's shakes set to four after the draw. The two square roots run on the DS hardware square-root unit (CP_SetSqrt32) instead of Emerald's GBA BIOS call, and both games roll with the same generator, multiplier 1,103,515,245 and increment 24,691, keeping the top 16 bits. A Pal Park battle or the catching tutorial always catches.Code
generalThe C standard defines rand as computing "a sequence of pseudo-random integers", and srand as starting a new sequence from a seed, so that the same seed repeats the same sequence.Publisher
The standard's example rand steps x←1103515245x+12345 and returns ⌊x/65536⌋mod32768.Publisher

References

  1. ^The C standard defines rand as computing "a sequence of pseudo-random integers", and srand as starting a new sequence from a seed, so that the same seed repeats the same sequence.PublisherC99 draft N1256
    How we know
    The rand function computes a sequence of pseudo-random integers in the range 0 to RAND_MAX.
    §7.20.2.1, p. 312 · archived copy ↗
    If srand is then called with the same seed value, the sequence of pseudo-random numbers shall be repeated.
    §7.20.2.2, p. 312 · archived copy ↗

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Checked by a second AI model, 2026-10-27.

    In the claim ledger

  2. ^ abcdefUpdateRandNum steps a 16-bit state as s←771s+129(mod65536), and battle code reads its high byte, RandNumUB.Codenmikstas/dragon-warrior-disassembly · Ryan8bit, DW Formulas
    How we know
    668UpdateRandNum:
    ⋮
    673LC563:  ASL RandNumLB           ;
    674LC565:  ROL RandNumUB           ;
    ⋮
    687LC57C:  ADC #$81                ;
    
    source_files/Bank03.asm lines 668–692 at ebe6a13 · upstream ↗
    $9495 = $9495 * 771 + 0x81
    III.A, Common algorithms · archived copy ↗

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  3. ^ abcdeGetJoypadStatus steps the generator each time it reads the controller.Codenmikstas/dragon-warrior-disassembly · Ryan8bit, DW Formulas
    How we know
    805GetJoypadStatus:
    ⋮
    807LC60A:  PHA                     ;Prepare to update the random number by first saving registers 
    ⋮
    811LC60E:  JSR UpdateRandNum       ;($C55B)Get random number.
    
    source_files/Bank03.asm lines 805–811 at ebe6a13 · upstream ↗
    If you sit by idly while waiting to make a command, the random generator is run 60 times per second.
    IV, Frequently Asked Questions · archived copy ↗

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  4. ^ abcdComputed from the generator's update, its 65,536 states form two cycles of 32,768, and over each cycle the high byte takes every value exactly 128 times.Codenmikstas/dragon-warrior-disassembly · Ryan8bit, DW Formulasrevised
    How we know
    ASL RandNumLB ROL RandNumUB CLC ADC RandNumLB … ADC #$81
    source_files/Bank03.asm#L668-L692 · upstream ↗
    This makes 32,768 possibilities.
    III.A, Common algorithms · archived copy ↗

    Measured by a script in MesenCE 2.2.1 (build 4b8a196), on . It fails if the result disagrees with the claim.

    Checked against the evidence by its author, an AI model, 2026-10-25.

    Checked by a second AI model, 2026-10-21.

    Revised after a check by a second AI model, 2026-10-25.

    In the claim ledger

  5. ^Yoshi's Cookie keeps its random number generator in one byte, $0424, and steps it as x←5x+17mod256, written out in place at each call site, so the sequence runs through all 256 values before it repeats.Verified“Yoshi's Cookie (USA)”
    How we know

    In the cartridge (“Yoshi's Cookie (USA)”): fixed bank $C923-$C938, the setup menu's step: lda $0424, asl, asl, clc, adc $0424, clc, adc #$11, sta $0424, then a far call to the menu itself; bank 2 $9FA4-$9FE3, the same step in the kind picker. We don't reproduce the bytes.

    Measured by a script in MesenCE 2.2.1 (build 4b8a196), on Yoshi's Cookie (USA) (SHA-1 b19b67e59dd6…). It fails if the result disagrees with the claim.

    The numbers come from the run; its author, an AI model, checked the script measures what the claim says, 2026-10-25.

    Checked by a second AI model, 2026-10-25.

    In the claim ledger

  6. ^The power-on code sets the generator to $C3.Verified“Yoshi's Cookie (USA)”
    How we know

    In the cartridge (“Yoshi's Cookie (USA)”): fixed bank $C0E4: lda #$C3, sta $0424. We don't reproduce the bytes.

    Measured by a script in MesenCE 2.2.1 (build 4b8a196), on Yoshi's Cookie (USA) (SHA-1 b19b67e59dd6…). It fails if the result disagrees with the claim.

    The numbers come from the run; its author, an AI model, checked the script measures what the claim says, 2026-10-25.

    Checked by a second AI model, 2026-10-25.

    In the claim ledger

  7. ^Golden Sun's RPGRandom is a linear congruential generator, x←1103515245x+12345(mod232) (0x41C64E6D and 0x3039; the state sRPGRNGState is a 32-bit unsigned int on the GBA), returning state >> 8 as an unsigned short: bits 8 to 23 of the state. RPGRandom2 scales one result to 0 to 99, as RPGRandom × 100 >> 16 (computed). These are the constants of the C standard's example rand, which returns bits 16 to 30 instead. Pokémon Emerald's Random keeps the multiplier but adds 24691 and returns the top 16 bits; pret's random.h defines a second step, ISO_RANDOMIZE2, with Golden Sun's 12345.CodeCoaltergeist/goldensun-decomp · C99 draft N1256 · pret/pokeemerald
    How we know
    3extern unsigned int sRPGRNGState;
    ⋮
    5unsigned short RPGRandom(void) {
    6    unsigned int state = sRPGRNGState * 0x41c64e6d + 0x3039;
    7    sRPGRNGState = state;
    8    return state >> 8;
    ⋮
    12unsigned short RPGRandom2(void) {
    13    extern int RPGRandom_i(void) __asm__("RPGRandom");
    14    return RPGRandom_i() * 0x64 >> 16;
    
    src/rpg/random.c lines 3–15 at 2e5c504 · upstream ↗
    next = next * 1103515245 + 12345; return (unsigned int)(next/65536) % 32768;
    §7.20.2.2 ¶5, p. 312 · archived copy ↗
    11u16 Random(void)
    ⋮
    13    gRngValue = ISO_RANDOMIZE1(gRngValue);
    14    sRandCount++;
    15    return gRngValue >> 16;
    
    src/random.c lines 11–16 at 731ad5b · upstream ↗
    14// The number 1103515245 comes from the example implementation of rand and srand
    15// in the ISO C standard.
    16#define ISO_RANDOMIZE1(val) (1103515245 * (val) + 24691)
    17#define ISO_RANDOMIZE2(val) (1103515245 * (val) + 12345)
    
    include/random.h lines 14–17 at 731ad5b · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-27.

    In the claim ledger

  8. ^ abcdefghiEmerald's Random is a linear congruential generator, x←1103515245x+24691(mod232), returning the top 16 bits; pret's comment traces the multiplier to the example rand in the ISO C standard.Codepret/pokeemerald
    How we know
    8COMMON_DATA u32 gRngValue = 0;
    ⋮
    11u16 Random(void)
    ⋮
    13    gRngValue = ISO_RANDOMIZE1(gRngValue);
    14    sRandCount++;
    15    return gRngValue >> 16;
    
    src/random.c lines 8–16 at 731ad5b · upstream ↗
    14// The number 1103515245 comes from the example implementation of rand and srand
    15// in the ISO C standard.
    16#define ISO_RANDOMIZE1(val) (1103515245 * (val) + 24691)
    17#define ISO_RANDOMIZE2(val) (1103515245 * (val) + 12345)
    
    include/random.h lines 14–17 at 731ad5b · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  9. ^ abcdefEmerald seeds Random from a hardware timer only when the player's naming screen closes, which also sets the trainer ID; the seeding from the real-time clock at power-on is compiled only into pret's BUGFIX build, so after loading a save the generator starts from 0, and the VBlank handler steps it once a frame outside link, Frontier, and recorded battles.Codepret/pokeemerald
    How we know
    108#ifdef BUGFIX
    109    SeedRngWithRtc(); // see comment at SeedRngWithRtc definition below
    
    src/main.c lines 108–110 at 731ad5b · upstream ↗
    208void SeedRngAndSetTrainerId(void)
    ⋮
    210    u16 val = REG_TM1CNT_L;
    211    SeedRng(val);
    ⋮
    228// FRLG commented this out to remove RTC, however Emerald didn't undo this!
    229#ifdef BUGFIX
    
    src/main.c lines 208–236 at 731ad5b · upstream ↗
    365    if (!gMain.inBattle || !(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_FRONTIER | BATTLE_TYPE_RECORDED)))
    366        Random();
    
    src/main.c lines 365–366 at 731ad5b · upstream ↗
    700        if (sNamingScreen->templateNum == NAMING_SCREEN_PLAYER)
    701            SeedRngAndSetTrainerId();
    
    src/naming_screen.c lines 700–701 at 731ad5b · upstream ↗
    8COMMON_DATA u32 gRngValue = 0;
    
    src/random.c line 8 at 731ad5b · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  10. ^ abcdefBattleRNG returns the next byte of a 256-byte table, indexed by a counter (btl_rngstate) that wraps, so battle draws repeat every 256 calls.CodeDisch, FF1 disassembly
    How we know
    13817BattleRNG:
    13818    LDX btl_rngstate
    13819    INC btl_rngstate
    13820    LDA @Scramble_lut, X
    13821    RTS
    
    Final Fantasy Disassembly/bank_0F.asm lines 13817–13824 at cbb87d3 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  11. ^ abcBattleRNG's table holds $00 twice and never $95, so a battle draw is never $95.Code“Final Fantasy (USA)” · Disch, FF1 disassembly
    How we know

    In the cartridge (“Final Fantasy (USA)”): bank $0F $FCF1-$FDF0, the table; `$00` sits at positions 97 and 110. We don't reproduce the bytes.

    13811;;    IMPORTANT NOTE!!!!  ChaosDeath in bank B assumes that calling this routine 256 times consecutively will
    ⋮
    13823  @Scramble_lut:
    13824    .INCBIN "bin/0F_FCF1_rngtable.bin"
    
    Final Fantasy Disassembly/bank_0F.asm lines 13811–13824 at cbb87d3 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  12. ^ abRandAX scales a table byte r into a range: lo+⌊r(hi−lo+1)/256⌋.CodeDisch, FF1 disassembly
    How we know
    5893    TXA
    ⋮
    5895    SBC $68AF       ; subtract to get the range.
    ⋮
    5898    JSR BattleRNG_L
    5899    LDX $68B6
    5900    JSR MultiplyXA  ; random()*range
    ⋮
    5902    TXA             ; drop the low 8 bits, put high 8 bits in A  (effectively:  divide by 256)
    
    Final Fantasy Disassembly/bank_0C.asm lines 5888–5905 at cbb87d3 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  13. ^ abcdlut_RNG, the 256-byte table at $F100, holds every byte from $00 to $FF exactly once.Code“Final Fantasy (USA)” · Disch, FF1 disassembly
    How we know

    In the cartridge (“Final Fantasy (USA)”): bank $0F $F100-$F1FF, lut_RNG. We don't reproduce the bytes.

    11326;;  RNG scrambling lookup table  [$F100 :: 0x3F110]
    ⋮
    11328;;    This table is $100 bytes in size, and simply consists of every number
    ⋮
    11333lut_RNG:
    11334    .INCBIN "bin/0F_F100_rngtable.bin"
    
    Final Fantasy Disassembly/bank_0F.asm lines 11326–11334 at cbb87d3 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  14. ^ abcBattleStepRNG returns lut_RNG[i] for a counter i that steps by 1 per call; each time it wraps to 0, a sign byte gains $A0, and its top bit sets the direction of the next pass.CodeDisch, FF1 disassembly
    How we know
    1315;;    Random numbers are generated by stepping through a RNG LUT.  Once it
    1316;;  cycles through the entire LUT, it cycles through it again -- potentially
    1317;;  in a reversed direction.  Which direction it's going depends on battlestep_sign.
    ⋮
    1323BattleStepRNG:
    1324    BIT battlestep_sign    ; see if sign indicates a decrement
    1325    BMI @Negative
    ⋮
    1339    ADC #$A0
    1340    STA battlestep_sign
    ⋮
    1343    LDX battlestep         ; put battlestep in X
    1344    LDA lut_RNG, X         ; use it to get a random number from the LUT
    
    Final Fantasy Disassembly/bank_0F.asm lines 1315–1345 at cbb87d3 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  15. ^Wolfenstein 3D's random numbers come from rndtable, a fixed table of 256 bytes: US_RndT adds 1 to one index, wraps it at 256, and returns that entry, and the file's comment calls it "John Carmack's table driven pseudo-random number generator". SetupGameLevel sets the index to 0 for each level of a demo being played or recorded, and otherwise to the low byte of DX from DOS's get-time call (int 21h, function 2Ch), the hundredths of a second, 0 to 99 (the atlas's reading of the DOS call).Codeid-Software/wolf3d
    How we know
    4;	Assembly portion of the User Mgr. This is just John Carmack's table
    5;		driven pseudo-random number generator, and we put it in the User Mgr
    6;		because we couldn't figure out where it should go
    
    WOLFSRC/ID_US_A.ASM lines 4–6 at 0516778 · upstream ↗
    19rndtable db    0,   8, 109, 220, 222, 241, 149, 107,  75, 248, 254, 140,  16,  66
    
    WOLFSRC/ID_US_A.ASM line 19 at 0516778 · upstream ↗
    60	mov	ax,[randomize]
    61	or	ax,ax
    62	jne	@@timeit		;if randomize is true, really random
    ⋮
    64	mov	dx,0			;set to a definite value
    65	jmp	@@setit
    ⋮
    67@@timeit:
    68	mov	ah,2ch
    69	int	21h			;GetSystemTime
    70	and	dx,0ffh
    ⋮
    72@@setit:
    73	mov	[es:rndindex],dx
    
    WOLFSRC/ID_US_A.ASM lines 60–73 at 0516778 · upstream ↗
    85PROC	US_RndT
    86	public	US_RndT
    ⋮
    88	mov	ax,SEG rndtable
    89	mov	es,ax
    90	mov	bx,[es:rndindex]
    91	inc	bx
    92	and	bx,0ffh
    93	mov	[es:rndindex],bx
    94	mov	al,[es:rndtable+BX]
    95	xor	ah,ah
    96	ret
    
    WOLFSRC/ID_US_A.ASM lines 85–96 at 0516778 · upstream ↗
    642	if (demoplayback || demorecord)
    643		US_InitRndT (false);
    644	else
    
    WOLFSRC/WL_GAME.C lines 641–644 at 0516778 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  16. ^Doom's rndtable holds the same 256 values in the same order as Wolfenstein 3D's (compared entry by entry, computed); Doom walks it with two indices (prndindex for P_Random, rndindex for M_Random), where Wolfenstein 3D uses one (rndindex).Codeid-Software/wolf3d · id-Software/DOOM
    How we know
    19rndtable db    0,   8, 109, 220, 222, 241, 149, 107,  75, 248, 254, 140,  16,  66
    20	db   74,  21, 211,  47,  80, 242, 154,  27, 205, 128, 161,  89,  77,  36
    
    WOLFSRC/ID_US_A.ASM lines 19–20 at 0516778 · upstream ↗
    37	db  120, 163, 236, 249
    
    WOLFSRC/ID_US_A.ASM line 37 at 0516778 · upstream ↗
    17rndindex	dw	?
    
    WOLFSRC/ID_US_A.ASM line 17 at 0516778 · upstream ↗
    31unsigned char rndtable[256] = {
    32    0,   8, 109, 220, 222, 241, 149, 107,  75, 248, 254, 140,  16,  66 ,
    33    74,  21, 211,  47,  80, 242, 154,  27, 205, 128, 161,  89,  77,  36 ,
    
    linuxdoom-1.10/m_random.c lines 31–33 at a77dfb9 · upstream ↗
    50    120, 163, 236, 249
    
    linuxdoom-1.10/m_random.c lines 50–51 at a77dfb9 · upstream ↗
    53int	rndindex = 0;
    54int	prndindex = 0;
    ⋮
    56// Which one is deterministic?
    57int P_Random (void)
    ⋮
    59    prndindex = (prndindex+1)&0xff;
    60    return rndtable[prndindex];
    ⋮
    63int M_Random (void)
    ⋮
    65    rndindex = (rndindex+1)&0xff;
    66    return rndtable[rndindex];
    
    linuxdoom-1.10/m_random.c lines 53–67 at a77dfb9 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  17. ^Doom's random numbers come from rndtable, a fixed table of 256 bytes, walked by two indices: each call to P_Random or M_Random adds 1 to its own index, wraps it at 256, and returns that table entry.Codeid-Software/DOOM
    How we know
    31unsigned char rndtable[256] = {
    32    0,   8, 109, 220, 222, 241, 149, 107,  75, 248, 254, 140,  16,  66 ,
    
    linuxdoom-1.10/m_random.c lines 31–32 at a77dfb9 · upstream ↗
    53int	rndindex = 0;
    54int	prndindex = 0;
    ⋮
    56// Which one is deterministic?
    57int P_Random (void)
    ⋮
    59    prndindex = (prndindex+1)&0xff;
    60    return rndtable[prndindex];
    ⋮
    63int M_Random (void)
    ⋮
    65    rndindex = (rndindex+1)&0xff;
    66    return rndtable[rndindex];
    
    linuxdoom-1.10/m_random.c lines 53–67 at a77dfb9 · 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 claim ledger

  18. ^Doom's play code (weapon damage, aim spread, pain) rolls P_Random, and M_Random serves the rest: the screen wipe, sound pitch, intermission animations, and the status bar.Codeid-Software/DOOM
    How we know
    633    damage = 5*(P_Random ()%3+1);
    634    angle = mo->angle;
    ⋮
    637	angle += (P_Random()-P_Random())<<18;
    
    linuxdoom-1.10/p_pspr.c lines 633–637 at a77dfb9 · upstream ↗
    894    if ( (P_Random () < target->info->painchance)
    
    linuxdoom-1.10/p_inter.c line 894 at a77dfb9 · upstream ↗
    159    y[0] = -(M_Random()%16);
    
    linuxdoom-1.10/f_wipe.c line 159 at a77dfb9 · upstream ↗
    326  // hacks to vary the sfx pitches
    ⋮
    330    pitch += 8 - (M_Random()&15);
    
    linuxdoom-1.10/s_sound.c lines 326–330 at a77dfb9 · upstream ↗
    523	    a->nexttic = bcnt + 1 + (M_Random()%a->period);
    
    linuxdoom-1.10/wi_stuff.c line 523 at a77dfb9 · upstream ↗
    992    st_randomnumber = M_Random();
    
    linuxdoom-1.10/st_stuff.c line 992 at a77dfb9 · 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 claim ledger

  19. ^G_InitNew resets both of Doom's random indices to 0, and it runs when a new game starts, when a saved game loads, when a demo starts playing, and when the command line starts a game directly (a warp or autostart, or a net game).Codeid-Software/DOOMrevised
    How we know
    69void M_ClearRandom (void)
    ⋮
    71    rndindex = prndindex = 0;
    
    linuxdoom-1.10/m_random.c lines 69–72 at a77dfb9 · upstream ↗
    1414    M_ClearRandom (); 
    
    linuxdoom-1.10/g_game.c line 1414 at a77dfb9 · upstream ↗
    1345void G_DoNewGame (void) 
    ⋮
    1356    G_InitNew (d_skill, d_episode, d_map); 
    
    linuxdoom-1.10/g_game.c lines 1345–1356 at a77dfb9 · upstream ↗
    1226    // load a base level 
    1227    G_InitNew (gameskill, gameepisode, gamemap); 
    
    linuxdoom-1.10/g_game.c lines 1226–1227 at a77dfb9 · upstream ↗
    1613    // don't spend a lot of time in loadlevel 
    1614    precache = false;
    1615    G_InitNew (skill, episode, map); 
    
    linuxdoom-1.10/g_game.c lines 1613–1615 at a77dfb9 · upstream ↗
    1161    if ( gameaction != ga_loadgame )
    ⋮
    1163	if (autostart || netgame)
    1164	    G_InitNew (startskill, startepisode, startmap);
    
    linuxdoom-1.10/d_main.c lines 1161–1164 at a77dfb9 · 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 claim ledger

  20. ^Doom's rndtable is not a permutation: its 256 entries hold 166 distinct values, 101 of them once, 45 twice, 16 three times, 3 four times, and 1 five times; the value 145 appears 5 times and the value 0 twice.Codeid-Software/DOOMrevised
    How we know
    31unsigned char rndtable[256] = {
    ⋮
    50    120, 163, 236, 249
    
    linuxdoom-1.10/m_random.c lines 31–51 at a77dfb9 · 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 claim ledger

  21. ^ abcdefghRandom_ adds the hardware divider register rDIV to the byte hRandomAdd with carry and subtracts it from hRandomSub with borrow; the VBlank handler calls it every frame, and Random returns hRandomAdd.Codepret/pokered
    How we know
    1Random_::
    2; Generate a random 16-bit value.
    3	ldh a, [rDIV]
    4	ld b, a
    5	ldh a, [hRandomAdd]
    6	adc b
    7	ldh [hRandomAdd], a
    8	ldh a, [rDIV]
    9	ld b, a
    10	ldh a, [hRandomSub]
    11	sbc b
    12	ldh [hRandomSub], a
    
    engine/math/random.asm lines 1–13 at af51989 · upstream ↗
    1Random::
    2; Return a random number in a.
    3; For battles, use BattleRandom.
    ⋮
    7	farcall Random_
    8	ldh a, [hRandomAdd]
    
    home/random.asm lines 1–8 at af51989 · upstream ↗
    37	call Random
    
    home/vblank.asm line 37 at af51989 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  22. ^ abBattleRandom calls Random outside link battles; in a link battle both Game Boys read the first 9 bytes of a shared 10-byte list in turn, and after the ninth read those 9 are each replaced by 5x+1mod256; the tenth byte is never read.Codepret/pokeredrevised
    How we know
    6543BattleRandom:
    6544; Link battles use a shared PRNG.
    ⋮
    6546	ld a, [wLinkState]
    6547	cp LINK_STATE_BATTLING
    6548	jp nz, Random
    ⋮
    6557	inc a
    ⋮
    6572; if we picked the last seed, we need to recalculate the nine seeds
    ⋮
    6586; multiply by 5
    6587	add a
    6588	add a
    6589	add c
    6590; add 1
    ⋮
    
    engine/battle/core.asm lines 6543–6599 at af51989 · upstream ↗
    19DEF SERIAL_RNS_LENGTH         EQU 10
    
    constants/serial_constants.asm line 19 at af51989 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Revised after a check by a second AI model, 2026-10-21: The link RNG uses only 9 of its 10 bytes.

    In the claim ledger

  23. ^ abcdefgCrystal's Random is Red and Blue's generator, adding the divider register (with carry) to hRandomAdd and subtracting it (with borrow) from hRandomSub, but it returns hRandomSub where Red and Blue's Random returns hRandomAdd; pret's comment says the divider counts at 16,384 Hz.Codepret/pokecrystal · pret/pokered
    How we know
    1Random::
    ⋮
    7; The divider is a register that increments at a rate of 16384Hz.
    ⋮
    16	ldh a, [rDIV]
    17	ld b, a
    18	ldh a, [hRandomAdd]
    19	adc b
    20	ldh [hRandomAdd], a
    ⋮
    22	ldh a, [rDIV]
    23	ld b, a
    24	ldh a, [hRandomSub]
    25	sbc b
    26	ldh [hRandomSub], a
    ⋮
    
    home/random.asm lines 1–29 at 97187cd · upstream ↗
    1Random_::
    ⋮
    3	ldh a, [rDIV]
    4	ld b, a
    5	ldh a, [hRandomAdd]
    6	adc b
    7	ldh [hRandomAdd], a
    8	ldh a, [rDIV]
    9	ld b, a
    10	ldh a, [hRandomSub]
    11	sbc b
    12	ldh [hRandomSub], a
    13	ret
    
    engine/math/random.asm lines 1–13 at af51989 · upstream ↗
    1Random::
    ⋮
    7	farcall Random_
    8	ldh a, [hRandomAdd]
    
    home/random.asm lines 1–12 at af51989 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-25.

    Checked by a second AI model, 2026-10-21.

    Checked by a second AI model, 2026-10-25.

    In the claim ledger

  24. ^Asteroids' random routine (77B5) shifts a 16-bit register left one bit and sets the new low bit to the old bit 14 exclusive-or the old bit 0, turning an all-zero register into 1; it returns the low byte.CodeComputer Archeology, Asteroids
    How we know
    ASL $5F ; {ram.rndValue} ROL $60 ; {ram.$60} BPL $77BD ; {} INC $5F ; {ram.rndValue} LDA $5F ; {ram.rndValue} BIT $77D1 ; {} BEQ $77C8 ; {} EOR #$01 STA $5F ; {ram.rndValue} ORA $60 ; {ram.$60} BNE $77CE ; {} INC $5F ; {ram.rndValue} …
    content/Arcade/Asteroids/Code.md#L1977-L1991 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  25. ^The main loop calls RandomNumbers once per frame, after the frame's work; it adds 5 to RandomNumber1 five times, 25 in all, so the byte steps through all 256 values every 256 frames.Codenmikstas/metroid-disassembly · “Metroid (USA)”
    How we know
    34RandomNumbers:
    ⋮
    37LC002:  LDX #$05                ;
    38LC004:* LDA RandomNumber1       ;
    39LC006:  CLC                     ;
    40LC007:  ADC #$05                ;
    41LC009:  STA RandomNumber1       ;2E is increased by #$19 every frame and
    ⋮
    46LC012:  DEX                     ;
    47LC013:  BNE -                   ;
    
    Source_Files/Bank07.asm lines 34–47 at 4270d57 · upstream ↗
    170WaitNMIEnd:
    ⋮
    176LC0D3:* JSR RandomNumbers       ;($C000)Update pseudo random numbers.
    177LC0D6:  JMP MainLoop            ;($C0BC)Jump to top of subroutine.
    
    Source_Files/Bank07.asm lines 170–177 at 4270d57 · upstream ↗

    In the cartridge (“Metroid (USA)”): bank 7 $C000. We don't reproduce the bytes.

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  26. ^A frightened ghost picks a random direction from random_2a23, which steps a pointer as p←(5p+1)mod8192 and returns the byte at that address, so the game's own first 8 KB of ROM serve as the random table. The direction is the low 2 bits; a reversal or a wall sends it on to try the next one.Codemburkley/pacman-crevised
    How we know
    12227/*  Generates a random number by reading a byte from a randomised ROM address 
    ⋮
    12246    RND_VAL_PTR = (RND_VAL_PTR * 5 + 1) & 0x1fff;
    12247    return MEM[RND_VAL_PTR];
    
    pacman.c lines 12227–12247 at 3277e56 · upstream ↗
    11905XYPOS randomDirection_291e (XYPOS hl, uint8_t *orientation)
    ⋮
    11921    BEST_ORIENTATION_FOUND = random_2a23() & 3;
    ⋮
    11942        /* Prohibit ghosts from doing u-turns */
    ⋮
    11952            /* Ensure this direction is not into a wall */
    ⋮
    11980        BEST_ORIENTATION_FOUND = (BEST_ORIENTATION_FOUND + 1) & 3;
    
    pacman.c lines 11905–11980 at 3277e56 · 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 claim ledger

  27. ^Cmd_accuracycheck combines the attacker's accuracy stage and the target's evasion stage into one stage, multiplies the move's accuracy in percent by that stage's ratio, and misses when a roll from 1 to 100 exceeds the result, so a 100% move at even stages never misses.Codepret/pokeemerald
    How we know
    1128        if (gBattleMons[gBattlerTarget].status2 & STATUS2_FORESIGHT)
    ⋮
    1136            buff = acc + DEFAULT_STAT_STAGE - gBattleMons[gBattlerTarget].statStages[STAT_EVASION];
    ⋮
    1149        calc = sAccuracyStageRatios[buff].dividend * moveAcc;
    1150        calc /= sAccuracyStageRatios[buff].divisor;
    ⋮
    1175        // final calculation
    1176        if ((Random() % 100 + 1) > calc)
    
    src/battle_script_commands.c lines 1128–1176 at 731ad5b · upstream ↗
    588static const struct StatFractions sAccuracyStageRatios[] =
    ⋮
    590    { 33, 100}, // -6
    ⋮
    596    {  1,   1}, //  0
    ⋮
    602    {  3,   1}, // +6
    
    src/battle_script_commands.c lines 588–603 at 731ad5b · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  28. ^MoveHitTest lands a move when a random byte is below its accuracy byte, so even a 100% move misses 1 time in 256.Codepret/pokered
    How we know
    5322; if the random number generated is greater than or equal to the scaled accuracy, the move misses
    5323; note that this means that even the highest accuracy is still just a 255/256 chance, not 100%
    5324	call BattleRandom
    5325	cp b
    5326	jr nc, .moveMissed
    
    engine/battle/core.asm lines 5321–5327 at af51989 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  29. ^Measured in the ROM over all 65,536 generator states, with Agility 40 against a defense byte of 40, the hero escapes 87.70% of the time from the first group, 81.64% from the second, 75.20% from the third, and 50.20% from the fourth; the hero takes the first turn 87.70% of the time.Verified“Dragon Warrior (USA) (Rev 1)” · nmikstas/dragon-warrior-disassembly
    How we know

    In the cartridge (“Dragon Warrior (USA) (Rev 1)”): bank 3 $EE91-$EEFC, TryRun through CalcNextOdds, the code the probe calls. We don't reproduce the bytes.

    LDA RandNumUB AND #$7F … LDA EnBaseDef … JSR WordMultiply … LDA DisplayedAgi … SBC GenWord42LB LDA MultRsltUB SBC GenWord42UB
    source_files/Bank03.asm#L8256-L8325 · upstream ↗

    Measured by a script in MesenCE 2.2.1 (build 4b8a196), on Dragon Warrior (USA) (Rev 1) (SHA-1 66809063b828…). It fails if the result disagrees with the claim.

    The numbers come from the run; its author, an AI model, checked the script measures what the claim says, 2026-10-25.

    Checked by a second AI model, 2026-10-21.

    Checked by a second AI model, 2026-10-25.

    In the claim ledger

  30. ^Measured in the ROM over all 256 battle-RNG states, one swing with base damage 20, hit rate 10, and crit chance 1 against evade 6 and absorb 4 hits 221 times and is critical 4 times; with the attacker in Dark it hits 170 times, and against a sleeping defender 216 times.Verified“Final Fantasy (USA)” · Disch, FF1 disassembly
    How we know

    In the cartridge (“Final Fantasy (USA)”): bank $0C $A68C-$A8D3, the math of DoPhysicalAttack the probe runs, skipping the animation at $A775-$A7C8. We don't reproduce the bytes.

    4310    STA math_hitchance
    ⋮
    4319    AND #AIL_DARK
    4320    BEQ :+
    4321      LDA math_hitchance
    4322      SEC
    4323      SBC #40
    4324      STA math_hitchance
    ⋮
    4327    AND #AIL_DARK
    4328    BEQ :+
    4329      LDA math_hitchance
    ⋮
    4332      STA math_hitchance
    ⋮
    4364    AND #AIL_STUN | AIL_SLEEP
    ⋮
    
    Final Fantasy Disassembly/bank_0C.asm lines 4307–4591 at cbb87d3 · upstream ↗

    Measured by a script in MesenCE 2.2.1 (build 4b8a196), on Final Fantasy (USA) (SHA-1 e8f34d935760…). It fails if the result disagrees with the claim.

    The numbers come from the run; its author, an AI model, checked the script measures what the claim says, 2026-10-25.

    Checked by a second AI model, 2026-10-21.

    Checked by a second AI model, 2026-10-25.

    In the claim ledger

  31. ^ abGetBattleFormation picks one of the area's 8 formations by indexing lut_RNG with a counter that rises by 1 per battle; the low 6 bits select formations 0–3 with 12 chances in 64 each, 4 and 5 with 6, 6 with 3, and 7 with 1.CodeDisch, FF1 disassembly
    How we know
    1293    INC battlecounter    ; increment the battle counter
    1294    LDX battlecounter    ; and put it in X
    1295    LDA lut_RNG, X       ; use it as seed to get a random number
    ⋮
    1297    AND #$3F                    ; drop the 2 high bits of the random number
    1298    TAX                         ; and put in X
    1299    LDY lut_FormationWeight, X  ; use that to index the formation weight LUT to know which formation to use
    
    Final Fantasy Disassembly/bank_0F.asm lines 1293–1299 at cbb87d3 · upstream ↗
    1357lut_FormationWeight:
    1358  .BYTE 0,0,0,0,0,0, 0,0,0,0,0,0    ; 12/64 chance of formation 0
    ⋮
    1365  .BYTE 7                           ;  1/64
    
    Final Fantasy Disassembly/bank_0F.asm lines 1357–1365 at cbb87d3 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  32. ^On each step in grass or water, TryDoWildEncounter starts a wild battle when the byte hRandomAdd is below the map's encounter rate, out of 256; Route 1's grass rate is 25.Codepret/pokered
    How we know
    26; determine if wild pokemon can appear in the half-block we're standing in
    ⋮
    32	ld a, [wGrassRate]
    33	jr z, .CanEncounter
    ⋮
    37	jr z, .CanEncounter
    ⋮
    47	ld a, [wGrassRate]
    48.CanEncounter
    49; compare encounter chance with a random number to determine if there will be an encounter
    50	ld b, a
    51	ldh a, [hRandomAdd]
    52	cp b
    53	jr nc, .CantEncounter2
    
    engine/battle/wild_encounters.asm lines 26–53 at af51989 · upstream ↗
    1Route1WildMons:
    2	def_grass_wildmons 25 ; encounter rate
    
    data/wild/maps/Route1.asm lines 1–2 at af51989 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  33. ^The byte hRandomSub then picks one of the map's 10 slots, which have 51, 51, 39, 25, 25, 25, 13, 13, 11, and 3 chances in 256.Codepret/pokered
    How we know
    54	ldh a, [hRandomSub]
    55	ld b, a
    56	ld hl, WildMonEncounterSlotChances
    
    engine/battle/wild_encounters.asm lines 54–62 at af51989 · upstream ↗
    17	wild_chance 51 ; 51/256 = 19.9% chance of slot 0
    ⋮
    26	wild_chance  3 ;  3/256 =  1.2% chance of slot 9
    
    data/wild/probabilities.asm lines 11–28 at af51989 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  34. ^ abcdThe standard's example rand steps x←1103515245x+12345 and returns ⌊x/65536⌋mod32768.PublisherC99 draft N1256
    How we know
    next = next * 1103515245 + 12345; return (unsigned int)(next/65536) % 32768;
    §7.20.2.2 ¶5, p. 312 · archived copy ↗

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Checked by a second AI model, 2026-10-27.

    In the claim ledger

  35. ^FireRed and LeafGreen roll encounters on their own generator, x←1103515245x+12345, seeded at a new game; a check passes when its value mod 1,600 is below 16 times the area's rate, cut to 80% on a bike, plus 16/200 of a buff to which every failed check adds the area's rate, reset by a battle or a Repel.Codepret/pokefireredrevised
    How we know
    20#define MAX_ENCOUNTER_RATE 1600
    
    src/wild_encounter.c line 20 at ce6406d · upstream ↗
    304    if (WildEncounterRandom() % MAX_ENCOUNTER_RATE < encounterRate)
    ⋮
    311    encounterRate *= 16;
    312    if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_MACH_BIKE | PLAYER_AVATAR_FLAG_ACRO_BIKE))
    313        encounterRate = encounterRate * 80 / 100;
    314    encounterRate += sWildEncounterData.encounterRateBuff * 16 / 200;
    
    src/wild_encounter.c lines 302–314 at ce6406d · upstream ↗
    372            if (DoWildEncounterRateTest(gWildMonHeaders[headerId].landMonsInfo->encounterRate, FALSE) != TRUE)
    ⋮
    374                AddToWildEncounterRateBuff(gWildMonHeaders[headerId].landMonsInfo->encounterRate);
    
    src/wild_encounter.c lines 372–374 at ce6406d · upstream ↗
    667static u16 WildEncounterRandom(void)
    ⋮
    669    sWildEncounterData.rngState = ISO_RANDOMIZE2(sWildEncounterData.rngState);
    670    return sWildEncounterData.rngState >> 16;
    
    src/wild_encounter.c lines 667–671 at ce6406d · upstream ↗
    18#define RAND_MULT 1103515245
    ⋮
    20#define ISO_RANDOMIZE2(val)(RAND_MULT * (val) + 12345)
    
    include/random.h lines 18–20 at ce6406d · upstream ↗
    778static void AddToWildEncounterRateBuff(u8 encounterRate)
    ⋮
    780    if (VarGet(VAR_REPEL_STEP_COUNT) == 0)
    781        sWildEncounterData.encounterRateBuff += encounterRate;
    782    else
    783        sWildEncounterData.encounterRateBuff = 0;
    
    src/wild_encounter.c lines 778–784 at ce6406d · upstream ↗
    103    SeedWildEncounterRng(Random());
    
    src/new_game.c line 103 at ce6406d · 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 claim ledger

Sources

Code

Primary

  • JTC1/SC22/WG14, ISO/IEC. 2007. “ISO/IEC 9899:TC3, Committee Draft WG14/N1256 (C99 with Technical Corrigenda 1–3).” ISO/IEC JTC1/SC22/WG14. original · archived · licence, all uses

Secondary