Submission #2590: Acmlm's NES Dragon Warrior in 17:47.74

Nintendo Entertainment System
baseline
FCEUX 2.0.4
64170
60.0988138974405
1614
Unknown
Dragon Warrior (U) (PRG0).nes
Submitted by Acmlm on 2/28/2010 5:44:58 PM
Submission Comments
"!" is back again, in my first submission since 2006!
  • Recorded with FCEUX 2.0.4 (also syncs in 2.1.2, with new PPU)
  • Fastest time to reach the ending
  • Uses death as shortcut
  • (A lot of) Luck manipulation

Improvements

  • Metal slimes: 172 frames
  • Goldman: 30 frames
  • Death after keys: 12 frames
  • Axe Knight: 140 frames
  • Death after harp: 38 frames
  • Dragonlord: 838 frames
  • Rest: 28 frames
Total: 1258 frames (20.97 seconds)

New changes (outside of luck manipulation)

I switched the ROM from PRG1 to PRG0, the only signifiant change is the shorter text when enemies attack ("Thy Hits" instead of "Thy Hit Points"), saving a few frames each time. (it happens 4 times in the whole run, so it's still less than 1 second total)
The Dragonlord's first form is no longer put to sleep. Instead, he feels the pain and desperately tries to stop !'s magic TAS powers, but realizes too late that Stopspell is completely worthless against that ... This is slightly slower, but saves MP to use Hurt one more time against the second form and avoid most of the long manipulation delays.

About the luck manipulation

$0094-$0095 are used for random values, and change when:
  • Something in game needs a random value (enemy encounter, damage, etc.)
  • Player input is read
Player input is usually read once per frame when used (waiting input), or not at all otherwise (text, moving between tiles), but one exception is when pausing on the map, where the input is read in a loop (until Start is pressed again), randomizing 86-87 times per frame (about 86.6 average, alternating in a way that's hard to predict).
I've been able to predict every random result in advance (encounters, enemy HP, damage, dodging, even enemy moves), except for the pausing (see above), so it made the battles much easier to manipulate. The only thing I still couldn't improve much was for avoiding battles, but it'd be a whole other story if the movie input could work by CPU cycles instead of frames ... with midframe unpausing, I could cut anywhere into the last frame's 86-87, giving much better control without wasting time and saving at least a few more seconds.
I once again pushed it farther for the Dragonlord fight, as ! took some advice from P (the Monopoly player!) and bruteforced the whole battle to find the best manipulation delays. This alone helped a lot, since my first attempt at the new strategy (manipulating hits one by one) was 10 seconds slower!
In the making of the run, I used a custom built FCEUX with a few small changes to lua:
  • readpc() to get the current PC register
  • readsp() to read the stack pointer (so I could get the return address)
  • memory.register called the function even when the memory write didn't change the value
Then I had a script that counted how many times the randomizer was called per frame and where it was called from, and showed a few variables like $0094-0095 (random), $004F (used for timing) and the X/Y position.
I've even done a (unfinished) disassembly of the ROM last year, hoping to find glitches or at least something useful for a new run ... and while I did find quite a few things I didn't know about, most of it was only good for better luck manipulation, so that's most of the improvements here.

adelikat: Accepting as an improvement to the published movie.
Aktan: Processing
Last Edited by adelikat on 11/29/2022 12:19 AM
Page History Latest diff List referrers