Posts for FatRatKnight

Editor, Experienced Forum User, Published Author, Skilled player (1175)
Joined: 9/27/2008
Posts: 1085
It's still my intent to look through the Valley of Death for whether fairies are viable. I recommend doing some aesthetic polish while waiting for me, starting from when the raft is first used. Good to know a restart really is a complete reset. Only things persistent are things directly related to Link's progress. Anything you fix aesthetically is unlikely to break any attempts I make on the Valley of Death. EDIT: Yes... It is viable. Now I just need to see if we can trigger the encounter on the "road" to Valley of Death on the perfect timing and RNG. Incidentally, there were 17 RNG/gTimer pairs that allowed for zero delay following the road encounter, spawns the first two encounters that omit the west group, and spawns a west fairy somewhere in the Step Timer. 13 of them failed to spawn because none of the 6 prior groups de-spawned off screen, and 2 just flew straight to somewhere unreachable. There may be more possibilities if we allow delays after the road encounter, in chunks of 21 frames.
Editor, Experienced Forum User, Published Author, Skilled player (1175)
Joined: 9/27/2008
Posts: 1085
I spawn a second fairy in the Reflect Trek. I really should have looked if the rest of the trek goes fine, but I have other things I need to work on. So I manually tried the next few of my fairy spawn list for the first fairy on the way to town. Yes, much faster than my concept trial. I'll keep this, as delays appear particularly minimal. The entry I tried is the fifth one in the list, with 2 frames at cave and 2 frames at child. Well, 2 frames more delayed than your TAS, anyway. The next trap is dealt with by using a normal encounter. TAS-kill two enemies as well. The next step, then, is to figure out which RNGs and gTimers I can use that won't cause any delay to the next fairy spawn. At the point I leave town, I can spare 5 frames, with gTimer 15 down to gTimer 10. When I exit, if I leave later than gTimer 0, we're stuck waiting 21 frames for the next group. So, I constrain my search as such. I got this list:
gT=15 R[2]= 48
gT=15 R[2]= 50
gT=15 R[2]= 52
gT=15 R[2]= 54
gT=15 R[2]=113
gT=15 R[2]=115
gT=15 R[2]=117
gT=15 R[2]=119
gT=14 R[2]= 52
gT=14 R[2]= 53
gT=14 R[2]= 54
gT=14 R[2]= 55
gT=14 R[2]=112
gT=14 R[2]=113
gT=14 R[2]=114
gT=14 R[2]=115
gT=13 R[2]= 20
gT=13 R[2]= 21
gT=13 R[2]= 54
gT=13 R[2]= 55
gT=13 R[2]=114
gT=13 R[2]=115
gT=12 R[2]=  4
gT=12 R[2]= 21
gT=12 R[2]= 55
gT=12 R[2]= 65
gT=12 R[2]= 80
gT=12 R[2]= 99
gT=11 R[2]= 12
gT=11 R[2]= 38
gT=11 R[2]= 73
gT=11 R[2]= 99
gT=10 R[2]= 34
gT=10 R[2]= 55
gT=10 R[2]= 77
gT=10 R[2]= 88
All of these spawn an east fairy. I have not constrained for path, I will check those manually. Once I knew which numbers were available to me, I created a lua table to hold them, then tried some interesting scripting to find the possible frame delays. This is the script:
Language: lua

local PassTable={ [0]={[48]=true,[50]=true,[52]=true,[54]=true,[113]=true,[115]=true,[117]=true,[119]=true}, {[52]=true,[53]=true,[54]=true,[55]=true,[112]=true,[113]=true,[114]=true,[115]=true}, {[20]=true,[21]=true,[54]=true,[55]=true,[114]=true,[115]=true}, {[4]=true,[21]=true,[55]=true,[65]=true,[80]=true,[99]=true}, {[12]=true,[38]=true,[73]=true,[99]=true}, {[34]=true,[55]=true,[77]=true,[88]=true} } --***************************************************************************** local function RecursionOverhead(T,FrameLim,r2) --***************************************************************************** local RNG_main= {0xA5,r2*2} local Path= {} --************************************************************************* local function RecursiveScreenCheck(T,n,fl,r) --************************************************************************* --Yes, defining a function inside another. I say, lua is sure fun! if not T[n] then --This part is to terminate our recursive loop. local s= "" for i= 1, #Path do --Identify our frame delays. s= s .. " " .. Path[i] end local val= math.floor(r[2]/2) s= s .. " : " .. val if PassTable[FrameLim-fl][val] then s= s .. " PASS" end print(s) return end --Oh, we're not at the end. Calculate things, then. local RNG= {unpack(r)} --Preserve higher tier RNG RNG[1]= 0xA5 --Screen transitions reset R[1]. Roll(RNG,T[n]-1) --Pass however long it takes us to go. for i= 0, fl do Roll(RNG) --Every frame we delay, add a roll. Path[n]= i --Keep track of which screens have our delay RecursiveScreenCheck(T,n+1,fl-i,RNG) end end --Function RecursiveScreenCheck(T,1,FrameLim,RNG_main) end local Transitions= {453,705,705,367,370,1074,364} RecursionOverhead(Transitions,5,115)
Okay, complicated scripting aside, this thing's output? Well, all the passes are:
 2 0 0 0 0 1 0: 55
 0 0 0 1 1 0 1: 80
 0 0 1 0 1 0 1: 80
 0 1 0 0 3 0 0: 12
 0 2 1 0 1 0 0: 12
 0 0 1 0 0 1 2: 38
 2 0 0 0 0 0 2: 38
 0 0 1 1 0 1 1: 99
 1 2 0 0 0 0 2: 34
 0 0 1 0 1 1 2: 55
 0 1 1 0 2 1 0: 55
 2 1 0 0 0 2 0: 55
 0 1 0 2 0 0 2: 77
 0 1 1 0 2 0 1: 77
 0 2 0 1 0 0 2: 77
 0 4 0 0 0 0 1: 77
 0 1 0 0 0 2 2: 88
 2 0 0 0 1 2 0: 88
 2 0 1 2 0 0 0: 88
The single-digit numbers are the frame delays for each transition. The two-digit values on the right are R[2]. The script spat out all the fails, too, which I wanted to see in case there were mistakes. The passes look encouraging. Time to trim things down some more. There are multiple ways to get the same R[2] and gTimer pair, so it would be pointless to bother with these duplicates. My list is now this short:
gT=12 R[2]= 55
gT=12 R[2]= 80
gT=11 R[2]= 12
gT=11 R[2]= 38
gT=11 R[2]= 99
gT=10 R[2]= 34
gT=10 R[2]= 55
gT=10 R[2]= 77
gT=10 R[2]= 88
Small enough to manually check them all. I did a direct memory edit to skip some movie tweaking, then when I found one I liked, picked the set of delays that got me the RNG, and created the input file. I took 1 2 0 0 0 0 2, delaying town entry by 1 frame, its first screen exit by 2 frames, and delaying exiting the Reflect building by 2 frames. I was left with a gTimer of 10 and R[2] of 34. Sure enough, the run matched my memory edit, and I got a lovely fairy spawn. If the encounters after my movie don't behave, try delaying when you trigger the approaching encounter and see if that helps. You probably already know this at this point, but I figure it wouldn't hurt to have a reminder.
Editor, Experienced Forum User, Published Author, Skilled player (1175)
Joined: 9/27/2008
Posts: 1085
Make a movie file. Save-state anchored for convenience. Have the movie save the game somewhere in its input (preferably very soon in the movie). Load the movie. Edit one stat in RAM you know will be saved. Run the movie. Compare it to the non-edited save. Since the movie is doing the exact same thing with the exact same timing, there should be no differences in clock. And hopefully no other factors to speak of. The only difference really should be the direct edit in RAM you did, and the checksum. Pick a different stat, and the common changed bytes are probably related to checksum. ... Well, it's one bit of advice I can think of. Curious if it'll help in any way.
Editor, Experienced Forum User, Published Author, Skilled player (1175)
Joined: 9/27/2008
Posts: 1085
Didn't expect a post 14 minutes before my edit. We're not getting two fairies in a row during the Reflect Trek, as detailed in my edit, but at least we'll know further effort in looking isn't likely to help.
Editor, Experienced Forum User, Published Author, Skilled player (1175)
Joined: 9/27/2008
Posts: 1085
I spawn a fairy. I've also broken some of my own expectations of what constitutes as "good enough amount of information," as I seem to have a slot 5 spawn when my table only accounts for slots 0, 1, and 2, and I waited longer in the overworld for the fairy to get into position. Considering what I've seen, RNG and timer-wise, the run might still sync following the reset after P4. I'm guessing you want to see if I can spawn fairies at will when the lava entry for fairy spawn is FF, giving a theoretical 1/256 chance. EDIT: My search for two consecutive fairies is indicating that it is virtually impossible. After several searches of all 2688 combinations with different allowed enemy step counts, there is exactly one possible 3x east for the west fairy, and this is after 42 frames of delay following the prior fairy encounter. I've tried higher step counts, out to 6, and none of them maintain 3x east. Delays are infeasible for step counts above 3, as without the wait, the north or south group moves randomly. Adding a delay means they make a beeline to Link. To get 3x east: r[2]= 27 gTimer= 8; 42 delay No other RNG/gTimer pair works, every one of the other 2687 possibilities fail, at least in short enough delays. Basically, this means eat the next trap with a normal encounter. Fairy manipulation for two traps in a row is impossible, unless you somehow pull together that exact RNG/gTimer pair while still getting a fairy prior to that miracle. I can make a search, I have one idea to try to see if this miracle is even possible, but I lack optimism, expecting more than 99% chance my search claims it really is impossible, that the RNG simply can't be twisted that far. Okay, with that loss in mind, what about our east fairy going west, on our return trip? Even worse. We'll just say you are not getting two fairies in a row on our way back from town. Well, at least I'm able to detect a decisive failure. The entire RNG/gTimer space is telling us some bad news, and we are not getting more than 2 fairies for our 4 traps. My search could be spotty, but from what I'm seeing, that second fairy in a row will remain nothing more than a dream. That still leaves the lava manipulation. My next investigation leads there to figure out the viability of fairy skips there. I'll see if I can spawn a fairy or if the 1/256 chance is an illusion.
Editor, Experienced Forum User, Published Author, Skilled player (1175)
Joined: 9/27/2008
Posts: 1085
f072846 RNG Reset: r[2]=  0 gTimer=13
f074905 RNG Reset: r[2]= 98 gTimer= 0   1966
f076947 RNG Reset: r[2]=107 gTimer= 2   1930
Frame 72846, you're fresh from a game restart, which seems to force a static RNG (R[2] == 0) and global timer. At this point you'll only visit two screens and this limits your degrees of freedom. Number of RNG calls are 1966 to first transition and 1930 more to the second. Frame 78640, your trek past the bridge gives lots of spawns. Spawns made: * f78796 - Global timer. 1746 calls * f78904 - Step timer. 1849 calls (1f delay) * f79162 - Step timer. 2107 calls (2f delay) * f79305 - Global timer. 2250 calls You end up using a spawn from the step timer, but it looks like it could just as easily been from the global timer. The step timer gives more freedom, since you basically choose the frame to spawn it rather than the 21-frame global timer. Now, the requirements for a trap fairy skip are as follows: * Fairy must be generated * Formation must not exclude west group (south looks good, except the only formation with fairies have them east and west) * Random pathing must be appropriate to land where you need it when it is needed I will assume the enemies you kill in the various screens must be killed and can't be killed any faster. Global timer is 7 at the last screen transition. So of the 147 - 167 range, you're at 154 frames to first spawn. Area timer begins at 0x5C. Fairy spawns at the step timer can happen with minor variance, but I have detected a problem with where the step timer zeroes out in your run. A fairy has to travel 10 steps west, but the longest string of repeated steps my script was able to calculate was only 8. It's not just unfeasable to expect a fairy to travel there from the forest where the step spawn takes place, but likely completely impossible from RNG limitations (allowing for, say, one or two steps south in between all the west steps). So, the only spawn important, then, would be the global timer spawn. This happens on the desert, where spawns appear further away, but with a lower chance of a fairy. You can also wait several frames to spawn in a forest, but the increased distance to the trap makes things less likely than they already are, so I'll go for the desert spawn. We do have one problem with predicting movement: It's not the RNG alone that determines it, but also what slot the important fairy is generated in. There are eight slots, and the bottom slots are filled first. Regardless of which direction is omitted, the west position occupies the third available slot from the bottom. The groups that go off-screen before the next spawns will affect which slots are available when the fairy spawns, and therefore the directions it will go. Prediction of that will be more difficult. So, we have two screen transitions where the r[1] is reset. With well-defined constraints, I wrote up a script to give us likely candidates within 30 frames. What follows is my script output. t1 = Frames to delay on entering that cave t2 = Frames to delay on falling into that child rescue zone
t1 t2
00 12 r[2]= 57 gTimer=11 |^^^>^v<^v . ^>>>v>>vv . >^^^>^v<^|
00 19 r[2]=127 gTimer= 4 |^v<<^><<v . ^<>v><^vv . <^v<<^><<|
00 22 r[2]= 79 gTimer= 1 |>v>>^>^v> . v<v>v^<>< . v>v>>^>^v|
01 03 r[2]=105 gTimer=19 |><^>^<vvv . <^><<^>>< . v><^>^<vv|
02 02 r[2]= 64 gTimer=19 |>><v><<v^ . <vv><^vvv . v>><v><<v|
02 25 r[2]= 76 gTimer=17 |^<<><^>v> . <<<^<^<v> . >^<<><^>v|
03 13 r[2]= 79 gTimer= 7 |v>>^>^v>< . <v>v^<><> . >v>>^>^v>|
03 14 r[2]= 39 gTimer= 6 |><v<>><>v . ><<vv<<>v . ^><v<>><>|
03 15 r[2]= 19 gTimer= 5 |<><<>v<v< . v<v^vv>>^ . ^<><<>v<v|
04 23 r[2]=101 gTimer=17 |^>^vv^^v< . <>^v<^^>^ . >^>^vv^^v|
05 14 r[2]= 68 gTimer= 4 |>v>vv><>v . v<^>><><> . <>v>vv><>|
06 03 r[2]= 43 gTimer=14 |<<>>v<<^v . ^vvvvv<v< . ><<>>v<<^|
06 19 r[2]=  2 gTimer=19 |>>^v^vv<v . <v>^vv>^< . ^>>^v^vv<|
07 13 r[2]= 58 gTimer= 3 |>v^v><<^< . ^^^^v>v^v . ^>v^v><<^|
07 22 r[2]=109 gTimer=15 |<>v<v^<<v . ^^v>>^vv< . <<>v<v^<<|
08 05 r[2]= 99 gTimer=10 |^^><<>^>v . >>>vv>^<> . v^^><<>^>|
08 06 r[2]= 49 gTimer= 9 |v>^^vvv^v . >>><<>v^v . vv>^^vvv^|
11 16 r[2]= 72 gTimer=17 |v<vv^><<^ . ^<v>>>v>^ . >v<vv^><<|
11 19 r[2]=105 gTimer=14 |<^>^<vvvv . ^><<^>><v . ><^>^<vvv|
12 11 r[2]= 34 gTimer= 0 |<>>>><>>< . >><>v^v>^ . v<>>>><>>|
14 08 r[2]=112 gTimer= 1 |<<^^vvv<v . v><><>v<< . ><<^^vvv<|
16 08 r[2]=  2 gTimer=20 |>>^v^vv<v . <v>^vv>^< . ^>>^v^vv<|
16 10 r[2]= 64 gTimer=18 |>><v><<v^ . <vv><^vvv . v>><v><<v|
20 06 r[2]= 18 gTimer=18 |><v<vv^^> . ^vv>v>v^> . >><v<vv^^|
21 02 r[2]= 57 gTimer= 0 |>^^^>^v<^ . ^^>>>v>>v . <>^^^>^v<|
24 00 r[2]= 34 gTimer=20 |<>>>><>>< . >><>v^v>^ . v<>>>><>>|
28 02 r[2]= 47 gTimer=14 |<vvv<>v>v . ^<<^<<^<v . <<vvv<>v>|
29 00 r[2]= 39 gTimer=15 |><v<>><>v . ><<vv<<>v . ^><v<>><>|
r[2] and gTimer would be the RNG factors spit out by my current script when you enter the child rescue zone. The arrows are for whatever is put into slot 0, 1, or 2, which are the likeliest candidates for where our fairy is put into, and will tell us which directions that fairy will fly. We'll want something that largely stays put, except to go one or two steps south. I do have a more full table, where you intentionally delay in 21-frame chunks after the child rescue zone, and what the results of that are. The above table is for 0 to 30 frames of delay before the second transition without that 21-frame chunk delays after the second transition. I haven't checked out how good this table is right now, but I am optimistic, as the first entry in it checks out (but doesn't give a good flying path for our fairy).
Editor, Experienced Forum User, Published Author, Skilled player (1175)
Joined: 9/27/2008
Posts: 1085
Welcome the next script version. Snap, it just occurred to me... There are effectively 128 possibilities with the RNG every time it resets. And it resets every time you get into a side scrolling screen. The interaction with the global timer messes things up, however, bringing the total possibilities to 2688 upon screen entry. Still, that's a small enough number to be very encouraging. Seems important enough for the script to track this. For anything independent of the global timer, you have just the 128 possibilities. The more important spawning, on the other hand, does depend on the global timer, so that gets us stuck with the 2688. Still, I have an idea on the spawning. After the spawn, we still need to figure out the path our fairies will take. Wouldn't help one bit if, after spawning, they immediately leave the area and far away from the trap. There are six possible terrain types where things can spawn. There's a table for the chances of which group to spawn:
00 60 B0 D0  37.5% 31.3% 12.5% 18.8%  Grass
00 60 D0 F0  37.5% 43.8% 12.5%  6.3%  Desert
00 60 C0 E0  37.5% 37.5% 12.5% 12.5%  Forest
00 50 BB F0  31.3% 41.8% 20.7%  6.5%  Swamp
00 57 D7 F8  34.0% 50.0% 12.9%  3.1%  Grave
00 57 D7 FF  34.0% 50.0% 15.6%  0.4%  Lava
The group that contains fairies is the last group. I suspect the lava terrain has the 0.4% up there. A fairy spawn would be really interesting there, assuming there isn't something coded I didn't trip over. I also analyzed the group pathing. The overview is: * Only make new decision if Area Timer ($0012) is multiple of #$10 (16) * If it's a fairy, pick random direction * If the Area Timer is less than #$40 (00 10 20 30), pick random direction * If aligned "close enough" vertically or horizontally with player, approach * Otherwise, pick random direction The definition of "approach" seems to mess up when the group is just north or just south of Link, as being that close means they'll preferentially move west or east before moving north or south. The Area Timer resets when you enter a side-scrolling screen. Much earlier than when the first byte of RNG is reset, something like 37 frames, but in any case, that's when the timer resets. Since it is reset to a constant relative to when the RNG resets, it doesn't expand the 2688 possibilities. Whew, close one! Anyway, it is clear that not only do you need a fairy spawn, but it needs to fly in directions that will ultimately get it to the trap you want to skip at the right time. They fly randomly without respect of Link's position, unlike the other encounters, which makes them more difficult to time appropriately. It looks like I have all the information needed to make the prediction. Coming from the maze to get that Reflect spell looks plain chaotic with all the encounters popping up, but you only need one encounter coming back out from the town to the next trap. Only 2688 possibilities to test. One last thing. Generating encounters with the global timer while over grass resets the timer to 32. Generating while over forest or deserts reset the timer to 24. It's one more form of adjusting encounters in that long trip to Reflect.
Editor, Experienced Forum User, Published Author, Skilled player (1175)
Joined: 9/27/2008
Posts: 1085
I'm now poking at the RNG. So far, it looks like two things affect it: Frames passed, and the moment you enter a side-scrolling screen (world -> side or side -> side both trigger it). RNG is a standard shift RNG. It takes an XOR of bit #$02 in addresses $051A and $051B, and the result is shifted into $051A. The RNG is then extended to take up 9 bytes (051A - 0522), with each bit shifted out of the previous address going into the next. This happens once per frame in most cases. The nine bytes are for separate enemies and overworld monster pathing. The other time the RNG is affected is when entering any side scrolling screen. Theoretically, this means you can affect the RNG by adjusting which frame you enter the last side scrolling area. You can, of course, delay your exit to the world map, but you can also delay the moment you've last entered the side scrolling screen. Or last two times, as the effects of that time should still be present in $051B when overwriting $051A with #$A5. Basically any combination of screen delays might help. RNG is not adjusted when enemies "think", which is another usual thing games tend to do (no breakpoint trigger). So at least I won't have to worry about that if generating a predicting script. I've taken a look at the enemy spawn algorithm. If no one minds me dumping 77 lines of assembly, I'll post it here (ROM address 0002B3, including the .nes header). Two timers are used, each independently triggering a spawn. One is based on a global timer at $0500, and ticks down $0516 every time it hits zero. Once $0516 is zero, it will remain there until you're over spawning terrain, at which point stuff spawns and $0516 resets based on the terrain. The other timer is at $0026, which will always increment. When it overflows and returns to zero, a spawn may trigger. If you're not over terrain where a spawn will occur, $0026 just keeps running without triggering anything. What spawns and where they spawn is RNG based, of course. There are four possible groups, and four possible directions to omit an encounter. I can probably generate a predicting script, given some time, though it'll have to predict something about 671 RNG rolls away at times. The "what" depends on $051B and the terrain you're on, and the "where" depends on $051C and whether the 8 encounter slots are getting full. The global timer means that you essentially have a frame rule when leaving a side scrolling area to the world map, RNG-wise. Each frame you wait is a frame that global timer is passing anyway, and will trigger the spawn at exactly the same time, and thus the same RNG. The effect on the RNG when entering a side-scrolling area, however, should adjust the RNG differently when you exit to the world map out the other side. Seems you might have needed this info while on your prior run. Still, now we have some RNG info. If this has been looked into before, I must admit I'm not good at tracking down info over the internet.
Editor, Experienced Forum User, Published Author, Skilled player (1175)
Joined: 9/27/2008
Posts: 1085
I've taken a slightly closer look at the exits. I've got this much to say: Function at 07:CCB3 is what throws you at the "proper" coordinates in the world map. It uses a value at address 0748 to pick an overworld coordinates. 0748 appears to be set up when entering a town, palace, cave, or other such side-scrolling place. Whatever that value, exits can add as much as +3 to that, so there are up to four possible coordinates to choose from. It's a matter of finding an unintended exit. 6A00 (63 bytes) stores the Y coordinates, and 6A3F (63 bytes) has the X coordinates. Actually, there's a small amount of bit-packed information, and the coordinates take the lower 7 bits (Y) or lower 6 bits (X) of the bytes they occupy. So the actual ranges are 0-127 and 0-63. EDIT: Mind, I do see some special casing code for when one coordinate is 0. Actually, I probably should put together a bunch of notes rather than just looking at this and giving my general impressions of these exits. There are three worlds: The main zone you start in, the zone where the raft takes you, and then the combined zones of Death Mountain and the Maze. All transitions of these zones take place in the overworld, to my knowledge. All exits from side scrolling areas will never lead to a different zone, so to bypass the raft, you must get to Death Mountain then glitch an exit that leads to the Maze. Which world you're in is at address 0706. Currently trying to make scripts to help determine these exits at a glance rather than having to take them yourself. Problem is that the overworld coordinates aren't loaded at 6A00 until after you take an exit (of a palace or town, that is. The caves keep the overworld coordinates loaded). Anyway, it seems I'm getting pretty close to having something that should help speed up routing. I'll hand the script over once its ready. I probably should also hand over my WIP Zelda II HUD script, too. It's a mess, but it's my mess. EDIT2: I shall leave you with this. Assuming it's possible to abuse new exits, this should give you the information very quickly if the room, or even the area, is worth glitching. There's still some more things to dig up, but any progress might help, I should hope.
Editor, Experienced Forum User, Published Author, Skilled player (1175)
Joined: 9/27/2008
Posts: 1085
I've been working on a script to do cute things like calculate number of hits for each enemy for you. Been practicing the debugger a bit, but as fancy as such cute things may look, it's little more than convenience. Still, decided to check a few addresses relevant to finding out exits to each room. Results so far: 0561 appears to specify which room you're in 6A00[63 bytes] and 6A3F[63 bytes] holds list of world map destinations. (expecting 63 rooms) 6AFC[252? bytes] and later holds the list of room destinations. The upper six bits of each byte in 6AFC determines destination room; If this is 63, it is presumably an exit to world map. The lower two bits look like from what direction to enter the destination. The meaning of these lower two bits change if the destination is the world map. Obviously, there are more than 63 rooms in the entire game. Whatever these segments may be, part of loading these segments include storing the list of destinations here. I recall discussion about this sort of thing in the heavily glitched runs, though I'm not sure where precisely to look to get at the information. For now, I should sleep. I've been picking at the disassembly of this game for a bit while working on scripts. I've not seen anything exciting in terms of fairy glitching in palaces, at least, what few rooms I looked at. A small script, for some start into checking out the exits
Editor, Experienced Forum User, Published Author, Skilled player (1175)
Joined: 9/27/2008
Posts: 1085
Thanks. That is more like what I want to see. An estimate of how much will be different is good to see. And thanks for reminding me it isn't a difference involving exactly one glitch. I recall mention of the swordless challenge of the original Legend of Zelda, which is a difference of time of around 2 1/2 minutes from any%. But no one can deny the difference in content being major chunks of the run. Mainly, I'm less looking for difference in time, but rather content. Anyway, I hope to see a decision made and that there's no discouragement to produce an update to the published TAS. I didn't like what was happening in the discussion, so I made a post. If I helped clear anything up, great. If we're still in exactly the same spot, I can only say I made an attempt.
Editor, Experienced Forum User, Published Author, Skilled player (1175)
Joined: 9/27/2008
Posts: 1085
A) Skip an Encounter with wandering fairy B) Skip an Encounter with screen edge glitch Either way, the amount of content skipped is one encounter, for one instance of when the trick is used. There are multiple instances where we can use the wrong edge exit where the wandering fairy or monster won't let us viably skip the encounter. So, more instances of content is skipped. The result of the run minus this wrong edge exit will be around 45 minutes. How many seconds and minutes of differing content will we see as a result of the wrong edge exit? Okay, a few minutes will be subtracted. We can count that as differing content. How much will this impact the route? If you have to kill an extra enemy you didn't on another screen, that is probably a second or three of differing content. If you have to go down a different route for a segment, that might be a minute or two. Will you get to 20+ minutes of differing content, a large portion of the existing run's time? If not, I doubt judges will accept omission and inclusion of this glitch alone for separate categories. I want it in terms of differing content. While I will agree that there may be other sorts of viable reasons outside of this scope, my focus, right here and right now, is in that scope, and I do not wish to hear anything outside of it. Declaring something as a "warp" or "not warp" is actually outside this scope. Please, I ask that the argument stays within this scope I have outlined, and hope that the thoughts I inject to this discussion gets us to a conclusion more smoothly.
Editor, Experienced Forum User, Published Author, Skilled player (1175)
Joined: 9/27/2008
Posts: 1085
Fair enough. There just isn't enough a TASer can do that isn't already viable by RTA. I prefer honesty over trying to get a bad submission through, so I accept this. I didn't have high hopes when submitting this. But at least we can list this game as having a rejected and serious submission. Even the vault rejects this.
Editor, Experienced Forum User, Published Author, Skilled player (1175)
Joined: 9/27/2008
Posts: 1085
Samsara wrote:
Just one question on my end: How viable is this in real time? Could an RTA runner use this exact strategy and duplicate the run with ease or is this a TAS-only 3 minute wait?
Short answer: Everything up until the combat is trivial in RTA. Only the short combat will RTA have significant trouble replicating. There's enough leeway (nearly four seconds!) when the commands are still important to get the combat to start on the same day this TAS does it. I claim this because I just went out and ran FCEUX using keyboard and 100% speed, and checked when the latest I can press A to confirm sending a ship (latest is frame 2757, and this TAS does it in frame 2524). Not a lot of rehearsing, either. Long answer: Title screen: Technically before the run properly starts, but in case RTA wants to use TAS timing, hold start. Once the screen flips back to the presentation, it'll automatically move on to the difficulty select. B then start from there. Main screen: Move cursor to pile of gold. Hold A, and keep holding it. At the buy screen, hold down once the cursor finishes moving, for two transitions. Move cursor to buy Attack Cruiser A and hold A until you've confirmed the purchase. B to back out. Quickly select the fist. Quickly select buy. Hold A until you've noticed the messages about buying the hover tank. Move cursor to hangar button. Hold A until screen transition (you'll buy the tank and transition painlessly). Select prepare ship. Go to the ship screen. Move cursor right, to the destination selection. Hold A, and when the cursor stops moving, press down. Move cursor one to the right, hold A until command sent. Done. Waiting game, then finally the frantic combat. In a lot of cases, you can just hold A (or any other button, really) rather than mashing it, so even there you can waste zero frames in real-time in a lot of screens. The only frames lost, then, would be when waiting for the cursor to finish moving so that you can safely press down or up on the buttons that need it, and transitioning from one task to another. Four seconds leeway lets you be very wasteful on these frames. The only thing left that's remotely TAS-like, then, is the combat at the very tail end of this run. Pressing A as soon as the military update shows up, then doing fighting there. The tank controls are just horrible, and it's actually a small wonder to even win combat with exactly one tank, let alone do it reasonably quick. There is enough credits to get two tanks, but that likely delays you at least one game day. Then again, the combat is short enough to rehearse some steps to get it pretty fast. I am not aware of any significant RNG factors in this run. In terms of strategy, RTA can get it done on the same game day, no trouble. Winning the combat as quick as this TAS is another story.
Editor, Experienced Forum User, Published Author, Skilled player (1175)
Joined: 9/27/2008
Posts: 1085
The day counter runs on a timer. Screen transitions delay this timer. I can't show off all the screens without delaying completion. On the ship screen or main screen, there are frighteningly few things I can do with the cursor. However, I do have one "free" transition, in the fact I must go to a screen where I can select a different planet to then attack. This can either be the main screen or the colony stats screen. Both screens also have the option to attack, so I can show a few interesting numbers, I suppose. There's a few worthless options I can also attempt, calling up some messages to read while we wait. Mind, we still have to throw away 3 minutes of waiting. ... Eh, why not. Probably will make the run an order of magnitude more entertaining. Then again, 10 times the entertainment value of something like this is still probably not that much. I'll see what I can come up with, since I have some time to throw at it. EDIT: Oh, look. I have a v3. Same speed as before. However, I do different stuff this time around.
Editor, Experienced Forum User, Published Author, Skilled player (1175)
Joined: 9/27/2008
Posts: 1085
Dang it, why didn't I experiment with crashing my hover tank into the last defense structure? The attack is successful when all defenses are destroyed, regardless of the state of the attacker's armament. 14336 > 14264 I knew when I say "not likely", I'll be aware of an improvement in short time after I submit. Here's the improvement. Judges, I request replacement. EDIT: I recommend this one instead. Incidentally, the reason for hardest difficulty is that you otherwise just get kicked out to the difficulty select upon defeating the enemy. Hardly a respectable ending, though I suppose some consider it an "ending". Easy mode.
Editor, Experienced Forum User, Published Author, Skilled player (1175)
Joined: 9/27/2008
Posts: 1085
arandomgameTASer wrote:
what
My thoughts exactly when I was reviewing this run before submitting. Get out of my head.
Editor, Experienced Forum User, Published Author, Skilled player (1175)
Joined: 9/27/2008
Posts: 1085
The rightmost column shows the RNG value behind the item drop. On a lag frame, the RNG advances, as well as the "always running" timer, but the lagged timer doesn't advance. So overall, the column will advance upward, but its values also increment (lag timer subtracts from the calculated RNG value for the item drop). If you see a greyed out 49, 99, 149, 199, or 249, a lag frame will turn that into a 50, 100, 150, 200, or 250. According to my notes, that should get you a big weapon refill, along with one more lag increment. Two more lag increments, and it becomes an extra life instead. My script will recolor things for the changed values. Since numbers change as well as move, I may want an aesthetic change to the script. Namely, some kind of visual marker every 5th frame or so. Should help the eyes track a specific number you're thinking about. Lag is a pretty major factor, since just three of them can go from "no item drop" to "you just skipped the big weapon refill." It's not the only effect -- I believe some enemies end up affecting the RNG as well, so if something "thinks" just before your kill drops an item (by "just before", I mean 16 or fewer frames), that can mess up the RNG for the item drop, too. Destroying two enemies close together can also tweak the RNG like this. Anyway, now I'm thinking about an adjustment to the script. Give me a moment, and I'll have a new one up. This is to have markers every 5th frame, just to help track which frame that RNG value is coming up on. EDIT: User movie #33508220465369883 A bit different from what I thought, actually. Lag frames might not advance the RNG on the same frame of lag, but regardless, one timer does still advance while the other doesn't, and this shifts the calculated RNG up by one in most cases. Regardless, here's the updated script that should tell you when every 5th frame happens, assuming the RNG shifts every time.
Editor, Experienced Forum User, Published Author, Skilled player (1175)
Joined: 9/27/2008
Posts: 1085
User movie #33395645917665711 Okay, here's an updated script. Should fix an off-by-one somewhere in there. New colors, now that I took a look as to what, exactly, will drop with each value. Finally, I added in one more column that specifies number of frames until each of the next 20 item drops. The more I work on this script, though, the more it seems my optimism fades away. There are three factors that adjust the RNG. I can create a pretty good predictor if it were just one factor (such as number of RNG calls only). But there are three factors at play here. It wouldn't be so bad if these factors weren't so common. Lag is everywhere, and the game needs the RNG for several things, apparently. Even so, I ask that you test it out a bit and see if it provides any useful aid. Against this kind of effect the RNG has, there are limits to what I can script up. I have no idea how to predict when lag happens, after all.
Editor, Experienced Forum User, Published Author, Skilled player (1175)
Joined: 9/27/2008
Posts: 1085
User movie #33375453760541627 FCEUX script. The colors are what item will drop, and the numbers are the values behind whatever mechanism the game is using to figure out which item to drop. The numbers are going to be useful whenever there's lag, since you'll have an idea how many lag frames it'll take to shift it to some type of drop, or when it shifts back out of the desired drop. Values of 0, 50, 100, 150, 200, and 250 are the important spots when a drop becomes possible. The position is simply how many frames. The top-most number is the immediate value, the one below that is what it will be in one frame, the number after that in two frames, and so on. Well, now that I'm noticing some acknowledgement of my posts (even if I ended up making something that isn't working perfectly yet), I feel much more willing to ensure the scripts are doing what they're supposed to. I'll try the script under TASing conditions for a bit rather than glancing to see if it's doing what looks right. Oh, and to figure out the right instructions and documentation to make sure the scripts I'm giving are getting used right. It's a rather basic RNG tool. I'm not sure how much better I can have it predict things, but I might come up with other ideas. What makes things harder to predict is the lag does affect what drops come down. Hmm... EDIT: Alrighty, running the script with the TASEditor, hex editor, and all that fun stuff! A calculated 149 is giving an item. Well, that needs fixing. I assume I'm off by one, so lets try a bunch of memory edits. Would like to make sure I'm consistently off by one or if I have a carry somewhere that needs to be handled appropriately. Yes, this is a major error. Sorry about that mishap, I'll be working a bit to figure that mess out. EDIT2: Extent of what I can tell, my constant is off by one. Essentially, I need to turn my 8 into a 9. My constant for the sub calculation to get R2 is probably also off similarly. I do have a few thoughts about making the script smarter, such as keeping a comparison of the two timers and looking farther ahead for item drops. I'll have the idea for later, anyway.
Editor, Experienced Forum User, Published Author, Skilled player (1175)
Joined: 9/27/2008
Posts: 1085
I assumed BizHawk is the go-to emulator these days. Give me a moment to transplant the script to FCEUX. I've used a few features of BizHawk that FCEUX doesn't have (the memory domain thing, for example, and the canvas especially). In general, the right column of the BizHawk script is what you would want. The left column is in case you need to make plans involving destroying two enemies in close succession.
Editor, Experienced Forum User, Published Author, Skilled player (1175)
Joined: 9/27/2008
Posts: 1085
User movie #33370844597556344 A script I generated to assist in RNG related stuff. By no means is it perfect, but I did put something out for you all to try. If you're going to make an improvement, I'd like to see it with everything available to you.
Editor, Experienced Forum User, Published Author, Skilled player (1175)
Joined: 9/27/2008
Posts: 1085
There's little I can say that hasn't been said by now. The only major reason for my posting is in case you think I'm important. That said, glad to see my work, particularly the scripting, was put to use in this TAS (my touch was used in several other TASes, too). The results, naturally, are a treat to see, though I can spot a few things that you've mostly covered already in your submission text. The orb position at Greenwood's fire bridge looks like it could be easily more to the left, since you should be able to control its left-right position for 23 frames out of 24 while traveling vertical. If having it higher is the issue, I suspect holding up for 3 frames out of 4 when going down the first fire bridge might help, though by the time you get into position where the Light Arrow would help, it might have slid back to your position by then. In any case, we have a great improvement here. There are still more we can do to optimize this, but a game this long takes a fair while to complete as is. With the way the RNG works, it looks like we can catalogue each screen transition where it is important and track exactly where we can get the good GEM drops. But that's for the serious optimization analysis.
Editor, Experienced Forum User, Published Author, Skilled player (1175)
Joined: 9/27/2008
Posts: 1085
Hetfield90 wrote:
Maybe we can get someone with disassembly knowledge to help with RNG.
Fine, I'm pulling myself out of lurking for a bit...
Language: lua

local R1u= memory.read_u8 --My personal preference to rename related mem functions to something short. --Also, if emulator is different, we have one line to change for new function. local Thresholds= {2,3,8,10,14} local function ItemDropCalculation() --Pretend we did other stuff in this function local Calcs= (( 8 + R1u(0x00E6) --R2 + R1u(0x00E7) --R3 - R1u(0x009D) --Frame timer, affected by lag - R1u(0x00E5) --R1 )%255 + 1 + R1u(0x0092) --Frame timer, always runs )%256 Calcs= Calcs%50 --Game does divide routine, and uses modulo portion local v for i= 1, #Thresholds do if Calcs%50 < Thresholds[i] then v= i; break end end --Pretend we do more stuff here end
I've generated a little lua code after reading the item drop routine. This is simplified to the best of my ability. Basically, the game does a bunch of consecutive ADC and SBC. The function always enters with carry set, to my knowledge, and the way SBC are mixed in there makes me think it's better to see it as ADC (255 - var) instead of SBC var. The function also affects one byte of the RNG. If I'm understanding the RNG right, this change in the byte will only modify behaviors for 16 frames, then the upper bit of the modification finally gets shifted out and tossed away, with no impact on future numbers. Which means destroying an enemy will only affect item drops if another kill was made within 16 frames. With the way timers work, lag will affect the calculation. Since one timer always increments, and the other only increments when gameplay happens, this means that by intentionally triggering lag, you adjust the calculations. I'm not surprised this hasn't been console verified, considering what the timers do here. In any case, I got that bit from using FCEUX and disassembling certain parts, after setting breakpoints on anything that reads the RNG. Here's the disassembly:
  RNG function
0E:AE59 LDA $0540,X
0E:AE5C CMP #$04
0E:AE5E BNE $AE58    Esc
0E:AE60 LDA $002F
0E:AE62 BMI $AE58    Esc
0E:AE64 LDA $00E6    R2
0E:AE66 ADC $00E7    R3
0E:AE68 ADC $0000    #$59 (used for function call)
0E:AE6A SBC $009D    Frame timer (affected by lag)
0E:AE6C STA $00E6    Modify R2 right away
0E:AE6E ADC $0001    #$AE (used for function call)
0E:AE70 SBC $00E5    R1
0E:AE72 ADC $0092    Frame timer (always runs)
0E:AE74 STA $00E7    R3
0E:AE76 STA $0000
0E:AE78 LDA #$32     Decimal: 50
0E:AE7A STA $0001
0E:AE7C JSR $F207    Divide routine
0E:AE7F LDY #$04     Loop start
0E:AE81 LDA $0003      Temp (remainder portion of division)
0E:AE83 CMP $AF1B,Y    0E 0A 08 03 02
0E:AE86 BCC $AE8E      Checking which item to drop
0E:AE88 DEY
0E:AE89 BPL $AE83    Loop end
0E:AE8B JMP $F2C4    Stuff after this isn't too important
0E:AE8E LDA $AF20,Y  77 74 75 78 76 (obj ID?)
0E:AE91 JSR $EA98    I guess this spawns the object
0E:AE94 LDA #$00
0E:AE96 STA $0408,X
0E:AE99 STA $0420,X
0E:AE9C LDA $AF25,Y
0E:AE9F STA $0468,X
0E:AEA2 LDA #$FF
0E:AEA4 STA $0480,X
0E:AEA7 JSR $EA1E
0E:AEAA LDA #$B7
0E:AEAC STA $0300,X
0E:AEAF LDA #$CC
0E:AEB1 STA $0588,X
0E:AEB4 LDA #$AD
0E:AEB6 STA $05A0,X
0E:AEB9 RTS -----------------------------------------

  Divide routine
0F:F207 LDA #$00     Blank things out
0F:F209 STA $0002
0F:F20B STA $0003
0F:F20D LDA $0000    Temp 1
0F:F20F ORA $0001    Temp 2
0F:F211 BNE $F216    Forget it if it's 0/0
0F:F213 STA $0002    Set zero in $02 (again)
0F:F215 RTS -----------------------------------------
0F:F216 LDY #$08
0F:F218 ASL $0002
0F:F21A ROL $0000    Numerator
0F:F21C ROL $0003
0F:F21E SEC
0F:F21F LDA $0003
0F:F221 SBC $0001    Denominator
0F:F223 BCC $F229
0F:F225 STA $0003
0F:F227 INC $0002
0F:F229 DEY
0F:F22A BNE $F218
0F:F22C RTS -----------------------------------------
Post subject: Hey, IRC. Just dropping by long enough for this post.
Editor, Experienced Forum User, Published Author, Skilled player (1175)
Joined: 9/27/2008
Posts: 1085
Just a quick reminder: You can swing using a sword you're not a high enough level for. Just switch swords in mid-swing! Not useful for Zantetsu Sword, due to enemy defense being high enough that you're still only doing token damage, but the Spirit Sword should benefit when you start Magridd Castle. Won't cast Pheonix, so we still need that final level grind. Largely that I remember having formed this page, so... http://tasvideos.org/GameResources/SNES/SoulBlazer.html Thought I'd bring it up now, since there was no need of this trick in the earlier worlds, and so it would be easy to forget the trick exists when its use is coming up. If you can find use with this trick and the Zantetsu Sword, even better! I'm still loving those crazy steps. Amusing how an otherwise straight line can still be done with different animations without loss of time. Like the simultaneity when multiple lairs are involved. The strategies are nice to see, and the timing of Level 8 -> 9 to replace an herb was just grand. Although I expected the Critical Sword abuse, it's still a treat to actually see. Mostly posting for the trick reminder up there, just in case. But I thought I'd add in some encouragement while I'm here. So, I order you to be encouraged!