Post subject: Final Fantasy with nesbot
Ambassador, Experienced player (709)
Joined: 7/17/2004
Posts: 985
Location: The FLOATING CASTLE
I heard from DwangoAC about how he and Feasel tried to get the NESbot to play the Final Fantasy TAS at AGDQ. I think it should be possible to get NESbot playing FF but not by simply playing the run as is. Well, there is a 1/256 chance that it would work. Main problem is that the battle RNG counter is located in the SRAM. So it is preserved when you turn the console power off and there is no other way to clear it. But if we can figure out what it is, it would not be difficult to tweak the run to compensate. It would just be a matter of tweaking some frames in the first encounter. The load time for the encounter varies based on the number of enemies by an easily predictable one frame per enemy (the TAS shaves a few frames by considering this). You would also need to make sure not to get ambushed, a low probability in most cases. You could figure out that value by getting into a random encounter and recording what happens. There are only 256 possibilities so it should only be necessary to record a few actions. Basically, whether the fight was ambush/preemptive/normal and then which party member attacks or gets attacked first for how much damage. When being attacked you can't distinguish between multiple enemies of the same type but it should be enough to get the party member and the damage. So to figure out that RNG value you wouldn't necessarily need an input file but it would make it simpler. The encounter mechanism does get reset with power cycle (a long-known fact that makes the classic Kyzoku trick work for example). So it would be possible to make an input file that gets into the random fight and just holds down the A button. That will have any living party members fight. They'll all attack the first enemy and if it dies then later party members will waste their attacks that turn. But eventually over a few rounds you will either win the battle or die. You don't need to record every action from start to end, just enough to know where the RNG started. Determinism can tell you where it ends. The counter only changes in battle so once the battle is over you don't need to rush to turn off the power. Now you know the counter value so you tweak the actual TAS input to compensate and the bot should sync. Another problem is that you do need to press the start button at exactly the right time when the game boots up. If you miss by even a frame you will throw off the much more random NPC movement. This could be very annoying because the desync may not be noticable for a while unless you pay very close attention to NPC movement. That RNG engine does reset on power cycle, so you can just start again and if the battles have been syncing you can figure out the current battle RNG pretty easily. Finally, the soft resets in the current run are going to cause desyncs unless the bot can handle the timing perfectly. Problem is that soft resets won't restart that NPC RNG system. But the earlier versions of the run don't use soft resets and with a little effort I could make a version that doesn't use them. I made an FM2 that adapts the current run to start with a saved game present instead of the standard blank SRAM start by starting from a savestate and then cycling power. I changed it to pick 'start' instead of 'continue' at the beginning (a one-frame optimization in the TAS) and hacked the battle RNG to start at 0. That was enough to sync all the way through. I haven't looked in to how hard it would actually be to adapt to different starting battle RNG values. I just need to use lua to analyze all 256 possibilities and make sure it gets synced after the first battle. Obviously it would be awesome to show this on console. Besides being an iconic game, the luck manipulation makes a TAS on this game look totally unreal. If anyone wants to work on this let me know.
Skilled player (1416)
Joined: 10/27/2004
Posts: 1978
Location: Making an escape
What about doing some surgery to pop the battery out?
A hundred years from now, they will gaze upon my work and marvel at my skills but never know my name. And that will be good enough for me.
Ambassador, Experienced player (709)
Joined: 7/17/2004
Posts: 985
Location: The FLOATING CASTLE
If that zeroes out the SRAM then it would work. That would get you started though you would only have one try to sync after each power cycle. Could be good enough.
Skilled player (1741)
Joined: 9/17/2009
Posts: 4981
Location: ̶C̶a̶n̶a̶d̶a̶ "Kanatah"
You could do something like FractalFusion talked about on the Wheel of Fortune submission.
Ambassador, Experienced player (709)
Joined: 7/17/2004
Posts: 985
Location: The FLOATING CASTLE
My plan is sort of the opposite of FractalFusion's. His run starts with a 'dirty' state and he described how to spend an hour and a half to set it up from starting at a 'clean' state. My run starts from a 'clean' state but the SRAM makes it so that you need to deal with starting from a 'dirty' state on an actual cartridge. Even if I plan on setting up that clean state I need to deal with that initial dirty state. The situation is different because WoF has no save battery so you can start from a known point with a power cycle. The starting state you need to reach and the setup process are more complicated there but it is possible to reach from that known starting point. Here there is no way to reach a known starting point without either Ferret's save battery idea or inferring the current value from the the game somehow.
Editor, Player (69)
Joined: 1/18/2008
Posts: 663
TheAxeMan wrote:
I heard from DwangoAC about how he and Feasel tried to get the NESbot to play the Final Fantasy TAS at AGDQ
Technically not the NESbot, it was my bot. But I think NESbot could handle this game also. ---- Already went through this. I tested this well before dwangoAC, and we've been discussing this for a while.
Ferret Warlord wrote:
What about doing some surgery to pop the battery out?
Doesn't work...at least not that alone. And sometimes the SRAM will save state for quite a long time without battery; need to overwrite it. ---- Actual RNG is in WRAM, is it not? And it is not initialized either. My initial idea was to modify a Game Genie to host some code to clear WRAM and SRAM, then enable the game ROM and start executing from that. Then we were talking about just clearing WRAM, so I thought of using a simple cart swap, and I forgot anything might be in SRAM. So now I am back to the former idea - which sucks but is really not modifying the console, it's emulator compensation and setting up a known state. I'll work on various things if I can get any of: NROM donor cart, game genie donor, FF cart (I have two but I need to make an SRAM delete circuit so I don't take them apart), 72-pin connector so I can make an SRAM erase circuit
true on twitch - lsnes windows builds 20230425 - the date this site is buried
Editor, Emulator Coder, Site Developer
Joined: 5/11/2011
Posts: 1108
Location: Murka
The Battle RNG state is a single byte at CPU $688A, which is in the cart's battery-backed ram. Game Genie donor seems like the simplest way to go; just need to dig up one of those documents that lists what the mmio ports on the Game Genie actually do (I saw it somewhere once...)
Ambassador, Experienced player (709)
Joined: 7/17/2004
Posts: 985
Location: The FLOATING CASTLE
I agree, the game genie is a great idea. You still need to fix the run to pick 'start' in the beginning. And the soft resets are still going to be a problem.
Editor, Player (69)
Joined: 1/18/2008
Posts: 663
I would only use the game genie as a convenient carrier, and solder up ROM and MCU directly to pins as necessary... Re: pick "start" what do you mean? I can always hit the button at the correct time. Re: soft resets, not all the runs use them. And the ones that do, timing shouldn't be an issue as it will hit the button at the exact time (or require some delay if a "no modification" rule is in place and an actuator is used). My new bot will support hitting reset in hardware and the movie file.
true on twitch - lsnes windows builds 20230425 - the date this site is buried
Editor, Emulator Coder, Site Developer
Joined: 5/11/2011
Posts: 1108
Location: Murka
True wrote:
I would only use the game genie as a convenient carrier, and solder up ROM and MCU directly to pins as necessary...
I don't think any special modification would be required? Just replace the GG's 4KiB mask rom with a flashable one, and flash a few lines of code into it:
on_reset:
    sei
    lda #initial_value
    sta $688a
    ; now do whatever the GG normally does to switch to "game mode"

Edit: I am of course assuming that the 4xxx:7fff range of the real cart's addresses are visible while the GG is active. This might not be true.
Ambassador, Experienced player (709)
Joined: 7/17/2004
Posts: 985
Location: The FLOATING CASTLE
True wrote:
Re: pick "start" what do you mean? I can always hit the button at the correct time.
I am talking about 'start' vs 'continue' at the beginning of the game. In earlier runs I picked 'start' but at least in the most recent run I pick 'continue' because it saves a frame. It works in the TAS because the TAS starts with no save data. On a real cartridge there is still save data even if you zero out the battle RNG so you'll continue from the last save unless you pick 'start'. Hitting down for one frame just before the second start button press will change it.
True wrote:
Re: soft resets, not all the runs use them. And the ones that do, timing shouldn't be an issue as it will hit the button at the exact time (or require some delay if a "no modification" rule is in place and an actuator is used). My new bot will support hitting reset in hardware and the movie file.
Nice, that should do the trick if it works.
Demon_Lord
He/Him
Joined: 2/20/2011
Posts: 80
Location: Chicoutimi, Qc, Canada
I don't know shit about how the SRAM is accessed, but can't the Game Genie be used to set that SRAM random counter to a specific value, then shut down the system, remove the GG and simply play the game with the now-deterministic value?
Editor, Player (69)
Joined: 1/18/2008
Posts: 663
TheAxeMan wrote:
True wrote:
Re: pick "start" what do you mean? I can always hit the button at the correct time.
I am talking about 'start' vs 'continue' at the beginning of the game. In earlier runs I picked 'start' but at least in the most recent run I pick 'continue' because it saves a frame. It works in the TAS because the TAS starts with no save data. On a real cartridge there is still save data even if you zero out the battle RNG so you'll continue from the last save unless you pick 'start'. Hitting down for one frame just before the second start button press will change it.
There would be no saved game on console either...
natt wrote:
I don't think any special modification would be required? Just replace the GG's 4KiB mask rom
Seems like a special modification to me. I haven't taken apart GG, is it SMD? Does it have an external mask ROM? I need one to work on. My code would init all RAM to match emulator, init SRAM / cart RAM to initial values expected by emulator for blank SRAM (0x00? 0xFF?), disable the ROM and enable the game ROM and jump to that.
Demon Lord wrote:
I don't know shit about how the SRAM is accessed, but can't the Game Genie be used to set that SRAM random counter to a specific value, then shut down the system, remove the GG and simply play the game with the now-deterministic value?
Not sure. But then I'd have to take out the cart, put it in and hope it boots properly on the first try otherwise I repeat the process again...and I have to hope nothing decayed / changed in the console between powerups.
true on twitch - lsnes windows builds 20230425 - the date this site is buried
Editor, Emulator Coder, Site Developer
Joined: 5/11/2011
Posts: 1108
Location: Murka
Here's a board shot of a GG: http://bootgod.dyndns.org:7777/profile.php?id=597 If you're willing to replace the boot rom, we could easily make one that resets all internal and external ram and io ports to known values, including manually setting a particular ram initial state to match fceux or for things like wheel of fortune. One could also set initial mapper state for many mappers.(Having looked up the GG specs and how it handles the switch to game mode, I can now confidently say that this is doable.)