The MMX RNG is a repeating sequence of 43534 16-bit integers used for randomness in MMX-MMX6, MM7 and Rockman & Forte. The sequence starts with the hex value 0xD37 (3383) and uses the following function (in pseudo-code) to get the next RNG value in sequence:
function get_next_rng_value( current_rng )
next_rng_H = [floor( 3*current_rng/256 )] mod 256
next_rng_L = (next_rng_H+current_rng) mod 256
next_rng = next_rng_H*256 + next_rng_L
return next_rng
end
- "mod 256" means to take the value modulo 256; that is, to take the remainder upon dividing by 256.
- "floor( 3*current_rng/256 )" means to take the largest integer that is less than or equal to 3*current_rng/256.
For more information, see the following Lua script may be used to monitor and/or disassemble aspects of the RNG and how it is used:
An ASM version of the RNG subroutine as it appears in the Rockman X (J) ROM is shown at the bottom of this page.
RNG Addresses
For X-X3, the RNG is stored in the following address:
| Game | X | X2 | X3 |
|---|
| RNG Address | 0xBA6 | 0x9D6 | 0x9D6 |
About auto-calls to the RNG
In MMX-MMX3, the game auto-calls the RNG routine once per frame (usually) without using its value. So if a frame cycles the RNG more than once, then the RNG was used for something important. Note: The auto-call always occurs during the frame first before any other RNG calls. The documentation will not make reference to this auto-call (i.e. "first RNG value" refers to the first RNG call after the auto-call).
Dragging down a wall to create dust sprites will run the RNG once per dust sprite.
About boss actions
Boss actions are typically determined through two factors: The RNG value (
modulo some power of 2) and one of:
- Previous action (ex: Penguin, Eagle, Mandrill)
- Distance (ex: Armadillo, Octopus, Mammoth)
- Something else
Actions are typically given in the game code as tables. The exact form of the table in ROM varies per boss. For consistency purposes, the tables for transition between actions will be given in the following format (using Chill Penguin as an example):
RNG mod 16 01234567 89ABCDEF
Prev.Act. -----------------
0 (cubes) 02244444 44668888
2 (blizzard) 00244666 66668888
4 (slide) 00002246 68888888
6 (jump at) 00000002 22244688
8 (penguins) 00002222 22244668
A (stun) 02244444 44668888
The previous action is indicated on the left (with a short gloss for context). The top row is the RNG value modulo a power of 2 (usually 16 or 32), with A=10, B=11, etc. The table in the bottom right then indicates the number of the next action determined by the previous action and the RNG value. Action numbers always correspond to the value of the "action" address in RAM (0xE6A, 0xEAA, 0xF2A, etc., depending on the enemy slot used in RAM).
For distance-based Maverick bosses, the next action depends on the horizontal distance between the player and the boss (on either the left or the right), based on three intervals: Near (0-79 pixels), Mid (80-127 pixels) and Far (128 or more pixels). (Fortress bosses may have other types of distance determination, which may be both horizontal and vertical.)
Boss RNG subpages
Due to the size of the pages, the following information is split into multiple pages:
RNG subroutine in assembly language
The RNG subroutine as it appears in the Rockman X (J) ROM:
809a7f jsl $849086 [849086] A:0000
849086 php A:0000
849087 rep #$20 A:0000
849089 lda $0ba6 [860ba6] A:0000
84908c asl A:4cfa
84908d clc A:99f4
84908e adc $0ba6 [860ba6] A:99f4
849091 xba A:e6ee
849092 sep #$20 A:eee6
849094 sta $0ba7 [860ba7] A:eee6
849097 clc A:eee6
849098 adc $0ba6 [860ba6] A:eee6
84909b sta $0ba6 [860ba6] A:eee0
84909e plp A:eee0
84909f rtl A:eee0