Timing rules for the game changed after I submitted this run, so the time should be +5 seconds or so. I'll get around to redoing this run with proper time someday.
Well I'm two years late, but thanks to covid I've got nothing but free time, so I recorded a tutorial video
I've been playing around with the RNG routines. It looks like the routine itself is at $8151, and its calculation depends on the values of $8A, $8B, and $3D0-$407. It looks like $8B is always offset from $8A by 0x17 mod 0x36 in normal gameplay, so its effect on RNG calculation can be effectively ignored. $8C appears to be where the result is saved, but doesn't actually influence the generation itself. I haven't seen anything with $8F - not sure why. The RNG reset routine is at $813E. Here's some Python code I threw together that computes the RNG values:
It looks like this routine is called at least twice per enemy spawn. Some spawns will call it more, such as the tricycle kid, which I think does a third call to figure out how far to move.
As for the top and front loader differences, I think it has to do with the PPU state. The NES dev wiki goes into detail; in particular, [quote]The Reset button on the Control Deck resets the PPU only on the front-loading NES (NES-001). On top-loaders (Famicom, NES-101), the Reset button resets only the CPU.[/quote] The wiki also gives some sample code to make sure that 29658 cycles have passed since power on; Paperboy does this at $8057:
[quote] 00:8057:20 3E 81 JSR initialize_RNG 00:805A:20 51 81 JSR get_RNG 00:805D:AD 02 20 LDA PPU_STATUS = #$00 00:8060:10 F8 BPL $805A 00:8062:AD 02 20 LDA PPU_STATUS = #$00 00:8065:10 FB BPL $8062 [/quote]
On BizHawk, the RNG routine is called 317 times as the game first starts. My guess would be that because the top loader doesn't reset the PPU, the get_RNG routine gets called a randomish number of times compared to the front loader? But I would expect that the routines should end up synced eventually anyway. I don't have any NES hardware so I can't test anything.
I've been working on a Lua script for FCEUX that can play through days and count the number of frames and lag frames to see if I can find some better RNG starting states. I've made some simplifications: rather than try to dodge obstacles, I just periodically save a state, and if I ever crash, I load the last state and just change the player's x position randomly to see if I can bypass the obstacle. It's not perfect, but it's easy. I'm also not throwing any newspapers; instead I just manually mark all houses as delivered at the end. It seems like it's necessary to finish each day with a dog, and right now I'm not sure where the enemy type is stored, so that will need more work. I'm also ignoring the orbs. But if this all works, hopefully I can just have it grind through different RNG states until it finds a good one.
Very cool. Concerning the RNG differences between console revisions, I know Gyre and Feasel talked about how RNG is affected in their run of Final Fantasy at AGDQ, which you can watch here: . What's weird is they found that the memory was consistent at boot with the top loaders, while you found that resetting the top loader changes the RNG every time. Nice find!