1 2
7 8 9 10
hellagels
He/Him
Experienced player (771)
Joined: 2/1/2011
Posts: 83
Location: Guangdong, China
Flameberger wrote:
If I understand correctly, any event that has random elements will affect it. In my RTA strats I shoot the snake with a lemon (which gets randomly deflected up or down) to get a better pattern. Sometimes the options for how you can manipulate it are a bit limited.
I don't think so. Boss' pattern can be changed by shooting red orbs to its body, but the cause is not red orbs' random elements. You can try shoot the snake's body with Model Fx' regular bullet, snake's pattern can change, too.
Current projects: Castlevania - Order of Ecclesia (NDS)
Active player (250)
Joined: 3/30/2015
Posts: 49
hellagels wrote:
Flameberger wrote:
If I understand correctly, any event that has random elements will affect it. In my RTA strats I shoot the snake with a lemon (which gets randomly deflected up or down) to get a better pattern. Sometimes the options for how you can manipulate it are a bit limited.
I don't think so. Boss' pattern can be changed by shooting red orbs to its body, but the cause is not red orbs' random elements. You can try shoot the snake's body with Model Fx' regular bullet, snake's pattern can change, too.
Haven't checked with Fx shots, but when orbit (or other charge shots) hit the snake they create the same kind of spark that you see when you shoot a wall with a lemon. It's only visible for one frame though. http://imgur.com/a/DxKIu#0 These images show that frame, the second image was captured after firing the charge 1 frame later than for the first image. One of the sparks has a different shape. Edit: Just checked Fx against an enemy with the same lemon deflecting properties (The roller on the miniboss in Lurerre's stage) and the same spark is visible, with the shape being different depending on the frame the shot was fired.
And all should cry, Beware! Beware! His flashing eyes, his floating hair! http://www.twitch.tv/flameberger
ALAKTORN
He/Him
Former player
Joined: 10/19/2009
Posts: 2527
Location: Italy
I’m working on a Lua script to help a bit with RNG manipulation guys. The RNG formula is: xnew = (214013 xold + 2531011) % 231
ALAKTORN
He/Him
Former player
Joined: 10/19/2009
Posts: 2527
Location: Italy
OK so for now I have this, it’s pretty shitty but I’m not sure how the display should be made to improve it, I need feedback. http://tasvideos.org/userfiles/info/21849958098105961 Link updated to latest version. It might only work on the USA version of the game because I’m using the USA RNG address. If you want to make it work on JPN/EUR you’ll have to find the RNG address on that version and edit the “readRNG()” line of the script with your address. Like the description says it prints in the Lua window log the current RNG value and writes in parentheses how many steps it has advanced from the previous value. Most of the time the game just advances the RNG 1 step, it does so every frame actually which makes it pretty messy. Any kind of RNG manipulation you can do gets added on top of that every-frame 1 step advance, it seems. I’ve only found the RNG to not advance during the pause screen. Edit: found out loading a new area throws a “couldn’t calculate” (-1) error in the current script. I’ll look into that when I get the time. /// Looks like each area has its own “reset value”. A-1: 1627459585 A-2: 1627463682 A-3: 1627467779 A-4: 1627471876 B-1: 1644302341 B-2: 1644306438 B-3: 1644310535 B-4: 1644314632 C-1: 1661145097 C-2: 1661149194 C-3: 1661153291 D-1: 1677987855 D-2: 1677991952 D-3: 1677996049 D-4: 1678000146 D-5: 1678004243 E-1: 1694830612 E-2: 1694834709 E-3: 1694838806 E-4: 1694842903 E-5: 1694847000 E-6: 1694851097 E-7: 1694855194 E-8: 1694859291 F-1: 1711673372 F-2: 1711677469 F-3: 1711681566 F-4: 1711685663 F-5: 1711689760 G-1: 1728516129 G-2: 1728520226 G-3: 1728524323 G-4: 1728528420 G-5: 1728532517 H-1: 1745358886 H-2: 1745362983 H-3: 1745367080 H-4: 1745371177 I-1: 1762201642 I-2: 1762205739 I-3: 1762209836 I-4: 1762213933 I-5: 1762218030 J-1: 1779044399 J-2: 1779048496 J-3: 1779052593 J-4: 1779056690 J-5: 1779060787 K-1: 1795887156 K-2: 1795891253 K-3: 1795895350 K-4: 1795899447 L-1: 1812729913 L-2: 1812734010 L-3: 1812738107 L-4: 1812742204 M-1: 1829572669 M-2: 1829576766 M-3: 1829580863 N-1: 1846415424 O-1: 1863258177 O-2: 1863262274 X-1: 2014318659 X-2: 2014322756 X-3: 2014326853 Transerver rooms: 2047938630 Boss rooms: 2047942727 (Boss rush only I believe) Edit2: this is the RNG address in the JPN version: 0x02108790 /// EUR: 0x0210AD98 /// USA: 0x02108B90
Fortranm
He/Him
Editor, Experienced player (878)
Joined: 10/19/2013
Posts: 1121
Does the emulator support switching slot2 roms in movie files yet? Yes, I'm talking about the MMZ3&4 bosses in MMZX.
ALAKTORN
He/Him
Former player
Joined: 10/19/2009
Posts: 2527
Location: Italy
New RNG Lua script is here: http://tasvideos.org/userfiles/info/21849958098105961 Updated to latest. Added an experimental automated ROM version detection system. Compatible with USA, JPN, and EUR. Also added an input toggle for 3 different modes (as suggested by Flameberger), it defaults to key “D”, but you can change it to whatever you want, it’s the very first function in the script (writing “tab” makes it work with the Tab key). The current mode is written on the bottom screen. The modes are: Complete, Moderate, and Nothing. Complete writes all advances, Moderate only those bigger than 1 step, Nothing writes none. Feedback, error reports, feature requests and such all appreciated. Thanks to my friend STL for coding help, and to Flameberger for his feature suggestion. Edit:
Elpis TK31 in 2009 wrote:
Something I discovered that may be useful, is that you can hit the airplane boss by shooting the Double Charge Shot at a wierd angle, the pink stuff around the charge shot will deflect and if done properly it connects, enabling you to take him down in 3 turns instead of 4!
*facepalms*
ALAKTORN
He/Him
Former player
Joined: 10/19/2009
Posts: 2527
Location: Italy
Fortranm wrote:
Does the emulator support switching slot2 roms in movie files yet? Yes, I'm talking about the MMZ3&4 bosses in MMZX.
DeSmuME 0.9.11 is gonna come out soon, so you might wanna look into that before it’s too late. Updated the RNG Lua, just some bug fixes. http://tasvideos.org/userfiles/info/21849958098105961 I may start TASing this game soon enough. Edit: to get over small walls with X, walljumping for 1 frame is faster than dashattack-walljumping it when it’s possible to do so. 2 frames is already slower (unless maybe you have perfect position and can start dashing right after). /// This may be irrelevant now that I found the new delay dash technique.
ALAKTORN
He/Him
Former player
Joined: 10/19/2009
Posts: 2527
Location: Italy
After trying for a while a couple of things, I finally found a way to save 1 frame in the first area in the game. Since for dashjumping you don’t need to dash on the same frame you jump in this game, you can abuse this by delaying the dash to 2 or 3 frames after walljumping, allowing for slower speed while jumping away from the wall and top speed when moving forward again. Made an encode of my A-1 improvement TAS: https://www.youtube.com/watch?v=8SUp0LFt_2s Sadly wasn’t able to manipulate any life up drops… I wish I knew how drops work in this game. I’m expecting to save 1 more frame in the A-2 walljump, then I’ll probably go a while before any improvements… don’t remember exactly how it goes. Edit: TAS’d up to Giga Aspis, saved 1 frame at the walljump as expected. Cutscene trigger isn’t perfect but even with perfect subpixel entry it wouldn’t save a frame at this point.
ALAKTORN
He/Him
Former player
Joined: 10/19/2009
Posts: 2527
Location: Italy
Giga Aspis manipulation is a fucking mess. I can see why Moth gave up here. Anyway, as expected I’m 2 frames ahead at the start of the boss. I’ve been trying to optimize it while cheating the RNG for optimal pattern, but even then the results aren’t at all satisfying. Best fight so far is an on-screen kill that takes 1216 frames from 1st movement to the lag frame that reloads your position after the boss fight. 634f if we count from 1st movement to 0 boss HP, which I think is almost 100 frames ahead than the published TAS, but that’s a bad way to count. Edit: The published TAS takes 1277 frames, so mine is 61 frames faster. I didn’t expect such a big cut at all to be honest. https://www.youtube.com/watch?v=qRV4I6D6PAM My fight gets a late spit at the start, so that I can do full attack combo loops without wasting time up until the second to last hit (3 frames lost to hit), then gets an early dive to get the kill with the boss as low to the ground as possible. Many frames are actually wasted to wait for the boss to come down here, but it still results faster to wait for it. Edit: Missing the early cycle on the first hit cost the published TAS 41 frames. I’m not even sure what I should go for for an optimal fight. I hate this boss. Hmm, the published TAS lost frames in every attack except for the second to last one… 1f, 41f, then stuff like 3-4f each and 7f on the last hit. The fact that it has 2 fewer lag frames bothers me though. Edit: Lol this sucks, I’m 1 frame away from hitting the boss with an early spit. Edit2: 8 frames lost on the last hit in my on-screen kill. So 3+8 = 11 frames away from perfect? The explosion I got with the head grounded seems to be perfect itself, don’t know why. 17406, 17576–17976 17434, 17604–18004 Boss 0 HP, explosion sprite appears – lag frame / position updated after kill 17406, 17574–17976 17434, 17602–18004 Boss 0 HP, player pixels updated – lag frame / position updated after kill Healing HP at a transerver: 14 14 – 1 HP 14 18 – 2 HPs 14 22 – 3 HPs 1 HP makes no change, each subsequent one appears to add 4 frames.
Editor, Expert player (2073)
Joined: 6/15/2005
Posts: 3282
ALAKTORN wrote:
Sadly wasn’t able to manipulate any life up drops… I wish I knew how drops work in this game.
Is there any currently-known basis for how the RNG is used by the game? My guess is that since it is a LCG, the higher half (upper 16 bits of a 32-bit RNG) is used. Your script seems to indicate that the RNG is 31 bits instead (% 2147483648). Shouldn't it be 32 (% 4294967296)?
ALAKTORN
He/Him
Former player
Joined: 10/19/2009
Posts: 2527
Location: Italy
I hoped you’d come in and lend a hand.
FractalFusion wrote:
Is there any currently-known basis for how the RNG is used by the game? My guess is that since it is a LCG, the higher half (upper 16 bits of a 32-bit RNG) is used.
No idea how it works. I only know that it resets to predetermined values in certain areas, and I know how to manipulate it, nothing else (other than the formula itself).
FractalFusion wrote:
Your script seems to indicate that the RNG is 31 bits instead (% 2147483648). Shouldn't it be 32 (% 4294967296)?
I’m pretty sure it’s 31. Numbers bigger than 2^31 get cut off. Edit: Tried starting the fight with an early dive, have to take 3 HP damage to not lose time. Then I lost 3 frames in one of the attacks I think, so that alone makes it tie with my on-screen win, but it doesn’t even work because I couldn’t get a quick enough dive at the end. Starting with an early spit is 1 frame away from being able to hit, and a late dive loses way too many frames on the 2nd hit already.
HHS
Active player (286)
Joined: 10/8/2006
Posts: 356
Sorry, didn't notice this thread until now. The RNG formula, as you probably already know, is a(n) = (a(n-1) * 0x343fd + 0x269ec3) & 0x7fffffff. When a value is needed, bits 16-30 are used. For item drops, it works very much like in Mega Man X. It takes the 8 lower bits of a value from the RNG, and there are 8 different drop distributions, which are listed at 0x20ddcfc as a list of tables of 8 halfwords each, giving the rate for each type of item (the range of values that cause this item to be dropped). So, for example, for distribution 5, the first value is 32, thus covering values 0-31, the second value is 12, covering values 32-43 and so on. The 8 entries in each distribution correspond to, in this order: small health, large health, small crystal, large crystal, small ammo, large ammo, extra life, nothing.
ALAKTORN
He/Him
Former player
Joined: 10/19/2009
Posts: 2527
Location: Italy
Damn. Thanks for the help. At first glance I’m confused about a few things, though.
HHS wrote:
When a value is needed, bits 16-30 are used.
That sounds ridiculous. That’s even less than 1 byte. You make a 4 bytes RNG just to use the last 5 bits of it? Actually not even last, 31 isn’t used. Also when you mention drops, you say it takes the first byte basically (which sounds wrong…). So that’s different to what you said before; when are bits 16–30 actually used?
HHS wrote:
So, for example, for distribution 5, the first value is 32, thus covering values 0-31, the second value is 12, covering values 32-43 and so on.
I also don’t understand this. I take it distribution 5 is “small ammo”, but what are the values about? Edit:
HHS wrote:
which are listed at 0x20ddcfc as a list of tables of 8 halfwords each, giving the rate for each type of item (the range of values that cause this item to be dropped).
I just looked at this address and don’t get any of this either. That address starts off as 0000 0000 for me.
HHS
Active player (286)
Joined: 10/8/2006
Posts: 356
Bits 16 to 30 would be 15 bits, not 5, according to established mathematics. So it takes the lower 8 of those bits to decide a drop, in other words it takes bits 16 to 23, and uses this to determine which item to drop, by using the rates listed in one of the 8 tables. Which distribution to use depends on the type of enemy that was killed. So, we have the following mappings between the random value and the dropped item: Distribution #0: never drop anything Distribution #1: 0x00-0x3f small health 0x40-0x5f large health 0x60-0x7f small ammo 0x80-0x8f large ammo 0x90-0xff nothing Distribution #2: 0x00-0x3f small crystal 0x40-0x5f large crystal 0x60-0x7f small ammo 0x80-0x8f large ammo 0x90-0xff nothing Distribution #3: 0x00-0x3f small health 0x40-0x5f large health 0x60-0x9f small crystal 0xa0-0xbf large crystal 0xc0-0xff nothing Distribution #4: 0x00-0x37 small health 0x38-0x6f small crystal 0x70-0xa7 small ammo 0xa8-0xff nothing Distribution #5: 0x00-0x1f small health 0x20-0x2b large health 0x2c-0x4b small crystal 0x4c-0x57 large crystal 0x58-0x77 small ammo 0x78-0x83 large ammo 0x84 extra life 0x85-0xff nothing Distribution #6: 0x00-0x3f small health 0x40-0x54 large health 0x55-0x94 small crystal 0x95-0xa9 large crystal 0xaa-0xe9 small ammo 0xea-0xfe large ammo 0xff extra life Distribution #7: always drop extra life
ALAKTORN
He/Him
Former player
Joined: 10/19/2009
Posts: 2527
Location: Italy
16–23 bits would be the 3rd byte, or the last bit of the 2nd byte plus almost the entirety of the 3rd byte? If the latter that’s fucking weird and I don’t even know how I’d be able to calculate anything around it. If the “distribution” as you call it depends on the enemy, it’s basically what I called a “table of item drops”… and I’ve only ever found 2 of them in the game. The hell do those other ones come from? #0 makes sense, some enemies never drop anything, but all others except for #4 (drop list B as I call it) and #5 (drop list A) don’t appear in the game as far as I know. #7 is particularly strange. What are those about? How did you figure this stuff out, btw?
Joined: 4/13/2009
Posts: 431
ALAKTORN wrote:
16–23 bits would be the 3rd byte, or the last bit of the 2nd byte plus almost the entirety of the 3rd byte?
Bits 16-23 is the 3rd byte unless we're using the unconventional belief that the first bit is bit 1.
ALAKTORN
He/Him
Former player
Joined: 10/19/2009
Posts: 2527
Location: Italy
EEssentia wrote:
ALAKTORN wrote:
16–23 bits would be the 3rd byte, or the last bit of the 2nd byte plus almost the entirety of the 3rd byte?
Bits 16-23 is the 3rd byte unless we're using the unconventional belief that the first bit is bit 1.
Thanks. It just hit me but I don’t think this makes sense. If it only takes bits 16–23 for drops, wouldn’t that mean that any RNG number lower than 2^16 would result in the same drop every time? Because bits 16–23 are all 0?
Joined: 4/13/2009
Posts: 431
Yes, but I'm guessing the chances of that happening are pretty slim because we're adding and multiplying pretty big numbers.
ALAKTORN
He/Him
Former player
Joined: 10/19/2009
Posts: 2527
Location: Italy
EEssentia wrote:
Yes, but I'm guessing the chances of that happening are pretty slim because we're adding and multiplying pretty big numbers.
But I’ve dumped the item drop from cheating the RNG to 0 up to 23k, and it goes through the items in sequential order. ( http://pastebin.com/acExBvgT ) Edit: I’ve tested advancing the RNG in my dump that gives a life up (such as 259 or 1114), and checked the 3rd byte in the resulting number, but it still doesn’t match up with any life up in any distribution posted by HHS. I’m confused.
HHS
Active player (286)
Joined: 10/8/2006
Posts: 356
Ah, but it will advance the RNG once first. Every time it needs a random number, it advances the RNG, in addition to advancing it on every frame. So that needs to be taken into account. If you want to look at the code, it is as 0x2032728 (thumb mode). As for how I figured it out, I have an emulator with data breakpoints, but it hasn't been released to the public yet...
ALAKTORN
He/Him
Former player
Joined: 10/19/2009
Posts: 2527
Location: Italy
HHS wrote:
Ah, but it will advance the RNG once first. Every time it needs a random number, it advances the RNG, in addition to advancing it on every frame. So that needs to be taken into account.
Right, I thought I considered that by just advancing 1 step but that’s not what happens when you kill an enemy. In the intro I’m seeing 7 steps for the flying enemy thing, and randomly > 11 for the rotating blade… That makes it more complicated.
HHS wrote:
If you want to look at the code, it is as 0x2032728 (thumb mode).
I don’t think I can understand that.
HHS wrote:
As for how I figured it out, I have an emulator with data breakpoints, but it hasn't been released to the public yet...
Huh… would probably be nice to have for the AWDS TAS. Not that I know much about using breakpoints.
AntyMew
It/Its
Encoder, Player (35)
Joined: 10/22/2014
Posts: 425
HHS wrote:
As for how I figured it out, I have an emulator with data breakpoints, but it hasn't been released to the public yet...
no$gba debugger has breakpoints too
Just a Mew! 〜 It/She ΘΔ 〜
ALAKTORN
He/Him
Former player
Joined: 10/19/2009
Posts: 2527
Location: Italy
ALAKTORN wrote:
HHS wrote:
Ah, but it will advance the RNG once first. Every time it needs a random number, it advances the RNG, in addition to advancing it on every frame. So that needs to be taken into account.
Right, I thought I considered that by just advancing 1 step but that’s not what happens when you kill an enemy. In the intro I’m seeing 7 steps for the flying enemy thing, and randomly > 11 for the rotating blade… That makes it more complicated.
So I’m doing tests now. Freezing the RNG to 1114 always drops a Life Up, so even with those random advances from that enemy, the drop is consistent. It’s always 7 steps on the other enemy, so I tried advancing 1114 7 steps: 146014667. In hexadecimal this is 0x8B401CB. Based on HHS’s distribution #5, I’m looking for a 0x84 in the 3rd byte, here. I did it for all the steps, and none of them had 0x84, except for one: 2 steps = 1384400292, 0x528445A4. Bingo? So basically the item drop is the first thing that’s determined out of the RNG, I have no idea what the extra 5 steps (or even 10+ with the rotating blade enemy) are about, nor do I really care. (Also tested 1683597101 and 501745596, both have 0x84 3rd byte after 2 steps.) Now I need a way to put this into a Lua so that I can manipulate drops with ease.
ALAKTORN
He/Him
Former player
Joined: 10/19/2009
Posts: 2527
Location: Italy
ALAKTORN wrote:
Now I need a way to put this into a Lua so that I can manipulate drops with ease.
Done that but I don’t like my implementation. Mainly the fact that I have to use a bitwise operator.
Language: Lua

function getThirdByte(iRNG) iRNG = RNGSteps(iRNG, 2) return bit.band(iRNG, 0xFF0000) end a = readRNG() function findItem() c = 0x840000 b = readRNG() thirdbyte = getThirdByte(b) if thirdbyte == c then print(a .. " to " .. b .. " is " .. getNumSteps(a, b, 10000) .. " steps") end end
Editor, Expert player (2073)
Joined: 6/15/2005
Posts: 3282
ALAKTORN wrote:
Done that but I don’t like my implementation. Mainly the fact that I have to use a bitwise operator.
Language: Lua

function getThirdByte(iRNG) iRNG = RNGSteps(iRNG, 2) return bit.band(iRNG, 0xFF0000) end a = readRNG() function findItem() c = 0x840000 b = readRNG() thirdbyte = getThirdByte(b) if thirdbyte == c then print(a .. " to " .. b .. " is " .. getNumSteps(a, b, 10000) .. " steps") end end
Instead of bit.band, maybe use math.floor(iRNG/0x10000)%0x100. This gets the third byte as an actual byte, and not as an 8-bit number times 0x10000. Then you write c=0x84 instead of c=0x840000. By the way, there is nothing inherently wrong about bitwise operators. I'd use them if it is convenient. Only thing is, bitwise operators should never be used on numbers that have more than 32 bits (2^32 or greater).
1 2
7 8 9 10