Posts for FatRatKnight

Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
I have re-optimized the ceiling clips in Stage 7. Removed delay between Stages 7 & 1. Inserted 16 frames delay between Stages 1 & 4. I am not looking forward to fixing item drops with a timing 16 frames out of sync on a stage where refills are extremely important. Hoping the speediness isn't exclusive to when we started Stage 4. But hey, an annoying frame rule in Stage 1 is resolved. Cheers.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
So, essentially... There are no publishers on this submission? Well, someone claim it! Confusion over, claim, claim, claim! ... I'm an editor, not a publisher. Someone publish, okay?
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
Exonym wrote:
At first glance of the new stage 6, would it not be wise to dash to the right wall earlier, like say... frame 45511. I don't know at this point how many bubble barrier invincibility hits have taken effect. The thought for me is that there is more ground here to dash right on, since when you go to the right on that small ledge you are mostly in the air. I dont know if that long ladder is the problem, since climbing it is slower than wallkicking obviously. Just a suggestion if it hasn't already been tried.
Sorry about responding to this particular suggestion so late, but now I am fully free of my sickness and can actually put decent effort into examining things. I actually did take a look at dashing on that strip there. Try #3 in this post. Yes, the ladder is in the way, but the walljump just below it lets us go up it part way at a high speed, and the wall above it is reachable from a bit lower than you'd expect. In fact, based on segment transitions, it's faster than my Try #2. The one flaw is my barrier doesn't hold up as well as I'd like, and I end up taking longer on the miniboss follow-up as a result. Mind, I was quickly putting together things in my attempts. As for whether there are optimizations to do there, I haven't gone over it carefully. But the suggestion is pretty good anyway, and probably should be taken if there's a way to make it work. My immediate concerns with the run is to finish re-optimizing the ceiling clips in Stage 7, then retry item manipulation in the following stages. There was something I've been meaning to look at anyway, and I mostly forgot about it until now.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
Okay, that first battle scared me away from trying to clear this game. I'm here taking another look and refining some plans. Plan revision: * Walk forward to battle * All characters hidden * Two kobolds act, instant turn end due to everyone hidden * Fodder kills, then moves to die to two kobolds * Everyone else kills kobolds * Remaining kobold walks forward, dies to attack of opportunity from Garon Not necessarily in that order. This should wrap up the battle in one turn, with the Kobolds getting perhaps 2 turns where everyone is hidden and 1 turn only to die to us. Enemy turns should be rather minimal. I can generate a bunch of stats and tell you what is feasible. The six stats use 4d6, discarding lowest die. The RNG resets to default every time you reroll, adjusted only by frame count, so spamming the Roll option will not give us new possibilities. This limits our freedom for what we can pull from the RNG, I'm not expecting 3 CON any time soon. As for important stats, STR means we can possibly favor dagger over Magic Missile. DEX has a whole pile of effects, both positive and negative. CON gives us HP, something we want none of. INT lets us die smarter, though we need 10 to even pick Wizard. WIS lets us die wiser. CHA lets us die charmingly. For sake of simulations, Garon and Wobby are always going to be present. Our two fodder are essentially protoplasm that we can mold in various ways, limited by RNG and a few racial and feat tweaks. We can generally assume any and all stats we need, just to see if the battle can work at all, then worry about whether we can create such characters.
######| Here's how combat start looks
#+----+ Numbers are kobolds, letters are us
#|54
#|213    Garon must be A or B
#|AB+--- Wobby must be C or D
-+CD|### So, four practical formations
    |###
Character tasks are as follows: Forward fodder must kill something, either by dagger or Magic Missile, then move into range of two readied Kobolds and move once more to trigger Attacks of Opportunity, to which we must die. Magic Missile is out of the question if we allow adjacent Kobolds to act first, and they're not dead yet, leaving the unlikely dagger as our only other option. Garon must attack, needs 14+ to hit a Kobold who didn't act yet, 15+ against one who already did. If our target is Kobold #3, that's around a corner, moving the range to 18+ or 19+. Additionally, after Garon acts, a Kobold must move to a spot diagonal from Garon, then die as they continue to move and take an attack; this roll needs 15+ to hit. Damage output is 1d6+0, and that needs to kill whatever HP we target. Back fodder must use Magic Missile. 1d4+1 should kill. Wobby must use Magic Missile. 1d4+1 should kill. The particulars depend on formation. If Garon is on B, this seriously tightens what must happen: Kobolds 1 and 4 must act first. Forward fodder must use dagger to slay Kobold 2, then do the die dance. Garon must act before Kobold 5, who must act while Kobold 4 is still alive. Garon will not be able to use an Attack of Opportunity against any other Kobold, not without moving a step first, and I'd rather manipulate than spend frames walking. With Garon on A, there's a lot more possibilities. Any pair of Kobolds other than 1 can be used to kill fodder, although Magic Missile is disallowed if either 1 or 2 got to act before the fodder. 3 can act first just fine, no AoO across corners. Garon can kill either Kobold #3 or #4 by opportunity, though #5 must remain alive long enough if #4 is the target. Magic Missile can't strike Kobold #3 from position D. Ideally, we keep it all in one round. However, it is possible that we can have someone act a bit too early, and we can just skip their turn. They can act in round 2, and skipping turns is very fast. The point is to ensure Kobolds do not get a single turn where any character is not hidden, other than the one instance where we abuse Attack of Opportunity on the Kobold's turn. Let's look at dice rolls: * A initiative * A "Can Hide" check (must be 6+) * A Hide check (if Garon, 14+; if protoplasm, 9 at lowest) * B initiative * B "Can Hide" check (must be 6+) * B Hide check (if Garon, 14+; if protoplasm, 9 at lowest) * C initiative * C "Can Hide" check (must be 6+) * C Hide check (if Wobby, 14+; if protoplasm, 9 at lowest) * D initiative * D "Can Hide" check (must be 6+) * D Hide check (if Wobby, 14+; if protoplasm, 9 at lowest) * Kobold 1 Initiative * Kobold 1 HP * Kobold 2 Initiative * Kobold 2 HP * Kobold 3 Initiative * Kobold 3 HP * Kobold 4 Initiative * Kobold 4 HP * Kobold 5 Initiative * Kobold 5 HP Just starting combat, and we can instantly trim out impossible cases. Initiative is complicated business. At least I can look at the Hide rolls and tell you what choices we've got. _9 - 20 DEX Lf. Halfling 13 - 12 DEX Lf. Halfling, 20 DEX Moon Elf 14 - 10 DEX Lf. Halfling, 18 DEX medium race 15 - _8 DEX Lf. Halfling, 16 DEX medium race 16 - _6 DEX Lf. Halfling, 14 DEX medium race 17 - 12 DEX medium race 20 - _6 DEX medium race Of course, the better the Hide roll, the more choices we have with DEX for whatever simulation of Initiative we need. Such simulations can also pick a weaker AC when it comes time to being hit. Now, if we're looking at dagger poke vs. Kobold, the lowest roll we can tolerate is 8, and of course I can inform what the possibilities are there as well. _8 - 20 DEX Lf. Halfling w/ Weapon Finesse vs. flatfooted _9 - 20 STR Half-Orc vs. flatfooted 12 - 20 DEX Lf. Halfling w/ Weapon Finesse vs. flatfooted Kobold #3 15 - 10 STR 19 - 10 STR vs. Kobold #3 (corner) 20 - Automatic hit As for damage, the most a Kobold Swordsman will have is 4 HP. +3 damage is all we need, so 16 STR can do it. The only failure case for damage is, after manipulating other stats, we can't get the needed Strength. In general, the Magic Missile is much more likely to get stuff done, and if so, makes STR meaningless, but if that isn't available thanks to an active adjacent kobold, we still have the dagger to test. Finally, our forward fodder needs to take a hit. Kobold Swordsman is very accurate, bestowed a +5 Attack for some reason. Thus, our range is something like: _2 - 4 DEX medium race (except we need our Hide to work) _5 - 10 DEX medium race 11 - 20 DEX Lf. Halfling Basically, it's an automatic hit at 11+. There's no reason to shuffle armor off Garon to the fodder, if you're going to bring that up. A low roll means we must have a lower Dexterity if we're going to pass the simulation, which can have conflict with Initiative and Hide and give us a failure from that. As for damage, here's the most CON we can have: 1 - _5 CON 2 - _7 CON 3 - _9 CON 4 - 11 CON 5 - 13 CON 6 - 15 CON Of note, it is a lot easier to manipulate 7 CON than it is to find 5. If we really need 1 HP, Moon Elf would be suggested to turn those 7s into 5s. Initiative probably just needs some serious simulation. Kobolds get +3, one from DEX and two because we walked into battle rather than menu-fight. If a Kobold gets to act, someone is not hidden, and does not die to Garon's Attack of Opportunity, we hit a fail case. Forward Fodder needs two Kobolds to die against, only one hit will merely be a KO instead. Ties are handled by giving control to the side opposite of whoever just took their turn. If no one acted yet, players get the first shot. On the same side, whoever is closer to the first slot. At least, that's what I can recall from memory. The game will not give an Initiative less than 1. I don't know the limits of the RNG. I do know that I am asking for a rather significant series of good dice rolls, all on the first battle, so whether a possible RNG state exists that clears all criteria would be nice to know. I need to double check the rolls of different actions. I recall physical attacks needing a d20 for hitting, dice for damage, and one more for the screams. Critical hits are not implemented. Magic Missile needs a roll for Arcane Spell Failure despite the lack of armor, and another for damage. I don't know if Kobolds use the RNG if they have no targets to go after (when everyone's hidden, there are no targets).
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
My advice for Climax: Search for your speed. Should be zero when holding still. Should be going up (by an unknown amount) when accelerating. It is almost certainly 2 bytes in size. If it's anything like the structures in the other two games, it will be in EWRAM. Use the Hex Editor and look in that area to see if there's a bunch of stats in that region that reasonably change based on your machine. If the positions are in the exact same spot in relation to the speed address, we probably have the same basic structure all over again, and can probably just copy the script with a single change in the PlAddr function. Oh, and probably a change in FetchInternalFrame as well. For calibrating the object size, just look at later stats in the Hex Editor. Find something that looks distinctly like position? The size is whatever difference in addresses of that position and yours. There are actually a few more changes from MV to GPL, as I forgot to use PlAddr in a few spots in the MV version. I recommend tinkering with the GPL script for convenience.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
No plans for Climax. I just happened to have GPL available at the time. Go ahead, encode and upload to YouTube. I have no confidence in creating videos myself. I really need to remember to note this in my uploads. I did measure my average speed when I was heading north along that major straight. Somewhere around 1530 km/h true speed. The precise timing of the rail damage is based on the frame you were on the offending terrain, not the frame you got onto it. The Side Attack momentum still carries through on the frame it is lost on the rail. I was carefully watching my position to make sure that I am on the rail for exactly one frame, so that my motion would immediately get me back off because of the speed decay of the Side Attack, with some adjustment in steering as needed. I did not attempt brake tapping. Initiating a Side Attack depends on controls: If it's double-tap, you need at least a blank frame without drifting to have it happen. If it's any other control, you instead need to steer that direction. At the rate I was doing Side Attacks, the double tap controls would take too long to help. Between L+R or the other controls, on the frame you initiate a Side Attack, it immediately impacts your position. Side Attacks override drifting, so the fact you need L+R to initiate it doesn't really matter as you can't drift on that frame anyway, keeping a control free for braking. I suppose the disadvantage with L+R for Side Attack is that you need steering to initiate Side Attack. Between left or right, the game prioritizes right. This means you can press left+right to avoid steering that frame and get a side attack to the right. Right side rails have a clear optimal pattern I can do. Left side rails, unfortunately, has only one possible control for the frame to go left, as even if you held right for a few frames before L+R, it will still trigger as a right Side Attack. For comparison, drift speed of Dragon Bird (used in first story mission) is 220 km/h. Repeating the first three frames of the Side Attack like I did is "drifting" at an average of 952 km/h.
Post subject: F-Zero: Grand Prix Legend
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
Here's a Story mission, Rick Wheeler #1, done in 16"87 to begin with. A script, which I ported readily enough from Maximum Velocity. I'm pretty sure the optimal controls would be to have Accelerate, Brakes, and Boost on separate buttons, and Side Attack for L+R, and not double-tap L or R. If there are real-time speedrunners wondering what I did on the rails, I don't think the variant I did is RTA viable. Not unless you can press left+right on the D-pad as well as L+R buttons at 20 to 30 Hz. Still, the basic idea is that the side attacks have an insane drifting speed, 1016 km/h on the first frame for the guy used in the first story mission. This decelerates at a rate of 64 km/h per frame, so the speed quickly diminishes. Taking damage on rails will cancel the side attack, so that the average speed remains very high. When I have time to rest and think about it, I can explain more. For now, here's a topic with a nice WIP.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
I just remembered Final Fantasy Legend. That game has an unusual RNG in which its effects can be seen in real-time almost trivially, and real-time runs essentially plan things based on a particularly static RNG. It's very consistent on console, put it in a GB and you get different results from putting it in a GBC due to some start-up timing differences. If you use the D-pad to change colors during start-up in GBC, delaying the BIOS will give yet more possible starting RNG outcomes, though of course the player will have a hard time predicting the results. I'm not sure what sort of RNG we'd get without BIOS emulation, but there's almost no chance Final Fantasy Legend will have the right RNG like on console without it. Progress is already going forward here, so I'm just handing over a data point to think about. Still, it seemed relevant to me.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
Some internal changes to my script. It's a little smarter about who exists and when a race is really started for recording mode. I ported the script for Grand Prix Legend. After finding new addresses, it turns out the machine stat offsets are basically the same. Actually, so many mechanics are similar enough that I don't really recall any serious changes I had to make to the script. Should feel nice and familiar on your way to GPL. (whoops, set Hex mode in there. Decimal mode is in there and should be implemented fine, just find MachineHUD_hex(PlayerSel) at line 713 and replace hex with dec.)
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
What I'm reporting is likely this: https://github.com/TASVideos/BizHawk/issues/867 I suspect there's something very wrong happening during garbage collection and tables with BizHawk 2.0 I have run this line: local c= 0; while true do local k= {c}; c= c+1; emu.frameadvance() end After thousands of frames (inconsistent time), BizHawk either crashes, or throws a lua exception at curious lines claiming a curious reason. I did not crash for these lines: (might happen, I could be unlucky) while true do local t={}; emu.frameadvance() end while true do local t={true}; emu.frameadvance() end local t,c= {},0; while true do t[1]= c; c= c+1; emu.frameadvance() end I also did not crash when repeatedly toggling this script: local t={}; for i=1,1000 do t[i]= {i,i-1} end; while true do emu.frameadvance() end If it matters, the errors I had while refining my scripts: LuaInterface.LuaScriptException: [string "main"]:-1: 'for' initial value must be a number LuaInterface.LuaScriptException: [string "main"]:-1928045675: attempt to call a table value LuaInterface.LuaScriptException: [string "main"]:1: attempt to index a nil value Note it was either the random error or a BizHawk crash, seemingly at random, and after a random time. I have yet to find line negative 1.9 billion in my script. Every one of these tests were made starting BizHawk 2.0, opening a ROM, running a movie, then running a script. No other action on my part was done.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
Unless I uploaded the wrong file, here's the glowy speed indicator when under hysteresis. I didn't want to design the script around finding the hysteresis triggering speed. I wanted to find the hysteresis flag itself, and work that into the script instead. Whatever the distinction, I hope it fulfills the change you wanted.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
One not-hex script coming right up. No idea if there's anything in there you want to stay hex, though. Thanks for letting me know about the video.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
JV has 48 acceleration during boost, best in the game. Once hysteresis kicks in, and assuming there aren't evil bad obstacles you're tripping over, speed will always fall to exactly 2363 as JV's maintenance during boost is -1. One frame of acceleration gets us to 2411, then our speed slips down again under hysteresis. JV's normal maximum is 2368, which is significantly slower than 2411, so braking to avoid hysteresis is right out. This is basically thanks to the extremely powerful acceleration moving us well past the usual maximum in a frame. And while we could hypothetically accelerate at 2368 speed, getting to 2416, this would only be the case if we weren't under hysteresis mode, and dropping our speed to 2320 just so we can reach 2416 two frames later is almost certainly not worth it. So let's just focus on chopping down the slow half of our hysteresis time and getting to our next cycle sooner. Dropping down to 2363 with one, two, or three frames of braking means we should only brake at 2376, 2389, or 2402 speeds. I'll just math out the average speeds for zero to three frames of braking: 2387.00 - No braking, cycle length 49 frames 2392.68 - 1 frame braking, cycle length 37 frames 2397.56 - 2 frames braking, cycle length 25 frames 2399.00 - 3 frames braking, cycle length 13 frames Well, the good news is that brake tapping has a more significant advantage here. Not counting drifting, it's even 0.5% faster at its best. There's room for error so that you're still at an advantage even if you brake a frame or two early. I'm not sure how RTA-viable it is, though. I hear you players can get crazy-good, so something like this might be within the realm of possibility. If you are able to add in the effort of braking in the middle of whatever crazy snaking you're doing, there is a chance it can save a bit of time. Problem is that over-braking for a single frame means you start the next cycle at less than top speed, which can ruin whatever savings you got with brake tapping to begin with. How consistently can you tap a button for exactly two frames? I'll give you an easy test: Training -> JV -> any track. Once the timer is running, start at 0 speed and tap A (unless you changed controls and made that B instead). 12 km/h is one frame. Jet Vermilion is done with its first gear in 8 frames, by the way, so if your speed exceeded 96 km/h, you went into the second gear's 6 km/h per frame acceleration. If you need a better feel, swap the A-B controls for a moment as a way to practice the feeling of trying the brake tapping, seeing where you accelerated to, before you go try boosting and brake tapping then (oh, don't forget to fix your controls back to normal by then). So during boosts, TAS would just get the 3 frame brakes and that's the end of the story. Well, almost, as there may be some tweaks in picking which frame braking to fit the remaining boost time. I would advise RTA to go for 2 frame brakes, as that requires 2.4 brake taps per second rather than a more frantic 4.6, any errors in timing is less painful, and the peak of 2 frame brakes is only minimally worse than the peak of 3 frame brakes. Even so, the precision needed to save even a frame is very high, I'll leave it to RTA players to decide if it's worth practicing. On a side note, if I'm throwing decimal around in this post, I really should just stick with decimal in my script. Sorry about the whole hexadecimal thing. Would you prefer my next script version goes with decimal values?
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
There are a number of things I did in my TAS that I don't really think to explain. What feels obvious enough to me doesn't necessarily mean it's obvious to basically anyone else (EDIT: or rather it's less obvious, but just doesn't come to mind). Indeed, the brake tapping is just to get a higher average speed. Thanks to hysteresis, the speed would otherwise vary as low as 0x70F up to 0x721, or 1807 to 1825. This averages to 1816 speed. Hitting the brakes at 0x720 means I avoid having the hysteresis kick in, and therefore my speed never falls below whatever amount one frame of braking would cause. This is enough to increase the average to 1818 speed. Essentially, if you keep up frame-perfect brake tapping for 908 solid frames, you will save 1 frame. Except you'd need more time than that, as you should also be drifting a bunch for higher true speed, so the amount of time saved by brake tapping is virtually nil, but is something I thought I may as well just do. Some machines would actually have reduced average speed if you try brake tapping with them. Jet Vermilion gets about 0.1% advantage at best doing frame-perfect brake tapping, which is really small. I momentarily stop brake tapping on the first curve, preferring a different method to slow down just before the hysteresis kicks in. When trying to steer beyond a tolerance, you slow down, and this friction is much smaller than Jet Vermilion's brakes. Naturally, I time my left presses for this, pushing against the tolerance whenever I needed its friction. Finally, as much as I would like to toggle the accelerator and use coasting friction instead of braking friction, this triggers the Blast Turn, dramatically adjusting momentum, and would kill any advantage in higher average speed by destroying your drifting. I've made no real attempts at manipulating CPU cars, other than the immediate moments before impact. I don't know a lot about them yet, other than they seem to have very consistent spawn points where they'll appear once you get to some magic spot, and of course your facing wouldn't sight them showing up out of thin air.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
Had a similar thought at one point, though at least it didn't take me long to realize the fallacy of trying to do Stage 6 before Stage 6. Been sick for the past few days, mostly sleeping it off, but I'm recovering well. Considering how little I could do, haven't had a chance at any sort of progress, but I should resume shortly. ThunderAxe wasn't reading my first line right. The situation that Exonym was pondering was that we need the star weapon for any sort of hope on the Stage 6 miniboss skip. Meaning star weapon before Stage 6. To get star weapon, we clear Stage 6, hence, Stage 6 before Stage 6. This should be a very obvious problem at this point, having it explained out like this, so I'm outlining the fallacy of this piece by stating it so. Unless I don't know the proper meaning of `fallacy', in which case, please enlighten me on the actual word I should use.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
Went back and did something different in Stage 7. Anyone got ideas on better ceiling clips? I was writing up stuff for the submission text, in case I ever finish this, so that I will have written stuff ready ahead of time. So, I realized an idea about the timing of our invincibility in Stage 7, and had some old memories that insisted we had to get invincible after the miniboss. Realizing just why after the miniboss was important, I also realize this reason is no longer valid thanks to skipping the miniboss, so now I pick an earlier spot to gain invincibility. Would be perfect if ceilings did not halt my ascension worse than what we had before. There is a visible hesitation at one of the ceilings now. Actually the whole ascent might need another look anyway. But hey, nice to catch any improvements before I get to the end. Sync is easy on 32-frame increments, but other than that, best hope you can get the item drops needed, and I chose to temporarily force the 32-frame sync by throwing away 8 frames. Don't do this for a final run.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
I took a look at Q5 briefly. When I landed, the Segment value jumped to something appropriate to an earlier part of the track, and after the wall impact, I floated straight to that earlier part. So I'm pretty certain these two values are important, though I'm not entirely certain why the jump selected that early segment. As for the exact memory address, it is independent of what track you select. Actually, it depends on whether you select Training (always first "slot") or Grand Prix (machine dependent). There are five machine slots, and the player is put into one of the first four based on what spot the machine starts each track in. Hot Violet starts in the front, all the way to the left, and is in the first slot. Jet Vermilion starts in the back, all the way to the right, and is in the fourth slot. As for how to read my style: EWRAM:12D60[Size=0xCC][Count=5] Machine data +9E,1u - Which split did you take on the track? +A2,1u - Lap segment EWRAM is the memory region. Personally, I prefer the full bus address, EWRAM is at 0x02000000, but BizHawk's design made it difficult to work that during DTC6. 0x12D60 is the base address. If you're looking at the machine put in the first slot, that's what you start from. If you want the second machine instead, add the Size component once, so the first stat of the second machine is over in 0x12E2C. Just add 0xCC again for each machine you go down. The Count is simply to let me know when I went too far and I'm looking at not-machine data. Finally, the +xx lines after is the offset you need to add to get the stat you want. If we wanted the first machine's "Lap segment" I marked, you'd take 0x12D60 (the address of the first stat for that machine), then add 0xA2 to that, and it will be address 0x12E02. If in Grand Prix, the Jet Vermilion is not the first machine. We're three spots down. 0x12D60 is the first stat of the first machine, we need to add 0xCC for each spot to get to our fourth machine. 0x12D60 + 0xCC * 3 gets us our first stat. But we don't want the first stat, we want some crazy stat of that machine. So we add +0x9E for which split, and +0xA2 for which segment. After all this addition, addresses 0x13062 and 0x13066 hold the stats we want. The ",1u" part of "+9E,1u" just specifies how many bytes and what mode makes most sense to read it. 1 is one byte. u is unsigned. It is my style of how I write out stat data. Sure, I can write it out like... 12DFE - Machine 1's track split 12ECA - Machine 2's track split 12F96 - Machine 3's track split 13062 - Machine 4's track split 1312E - Machine 5's track split ... But this style doesn't work with me for various reasons. Compactness, scripting, and my own intuition for a rather brief look at my reasons why.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
I've poked about in RAM Search for a bit, and there's only a pair of memory locations I find remotely sensible: EWRAM:12D60[Size=0xCC][Count=5] Machine data +9E,1u - Which split did you take on the track? +A2,1u - Lap segment I have managed to get a pair of situations between two states that... * My x,y coordinate is identical * My facing is identical * Speed and momentum are also identical * I got to this location in the same amount of frames Yet, collide into the wall, we fly off into a different direction. I checked for different EWRAM values. Throughout the entirety of EWRAM, two bytes are located in the input history block I identified earlier (A2C0, A2C1), one is part of the rather short player trail (12D81), and one I just identified as which split you took (12DFE). Only those four bytes are any different, and I highly doubt the former three have anything to do with it. After some careful searching in IWRAM, I ended up empty. Zero results. My search has found only one relevant byte that's different throughout the entirety of RAM. So my theory is this: Depending on what segment you're in, and which split the game thinks you're in, hitting a wall will adjust your momentum to go toward some magical spot. The game does a pretty good job at updating what segment you're in. It appears less vigilant in updating what split you're in. I was running my scripts and ramming the Jet Vermillion alongside a wall, and saw that my momentum after these rapid wall hits were getting steeper and steeper angles, until suddenly after some point it's all gentle again. Making a guess, there's some magic pixel the game wants you to go toward, and will change your momentum to go directly there after a wall hit. Once I spotted my segment address changed, that was when the angle got all gentle all of a sudden. The consequence of an incorrect split means that the magic pixel is on that split over there, so your momentum goes toward that. Even if it means shoving your machine through the wall to get there. I have noted this split value doesn't update when taking damage on the rail. While parts of the track default to putting you into split 0 where there are no splits taking place, this won't update on a rail. Whether there are any spots that have an erroneous split 1 destination is uncertain. Anyway, it is an interesting little bug. Whether it'll have any helpful conditions is another matter.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
Okay, more ghosty stuff with the script. This time I'm displaying recorded history of all machines. And thanks to saving straight to a text file, it is capable of letting you run a movie, then running a different one to compare. It will always save on script exit if possible, but if the script errors out because of some mistake on my part, it won't save. I am sort of hoping the script turns out to be useful stuff. I'd advise keeping the script on record mode if you're moving on to some parts of the run you haven't done yet, so the script will constantly update trails. If you're going back to retry something, make sure your best is done in record mode, then shut off the record mode and go back for changes. Alright, I'm now feeling as though the script is less basic and more sophisticated. Hope the trails are pretty enough. EDIT: 23"65 Wanted to see TBK's advice in action. Sorry, it's nowhere near the 600 speed, but 563 km/h ain't bad. I'm starting to wonder if I should track down the collision detection, and display that on the script. I suspect distance calcs, checking if you're too close to someone, and if so, just how much overlap there is. Possibly hit-circles or something.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
In terms of what the run aims to do, it does it well. Enjoyable to watch, and definitely has good feedback in terms of entertainment. If accepted, there's little doubt it's in Moons, possibly Stars. Acceptance itself is being contested on the grounds of which emulator is used, however. Hence, "if" accepted, not "when" accepted. There's a few points to bring up. Obsoletion. The run this TAS attempts to obsolete was done on Mupen. So is the TAS itself. In emulation quality, the two are similar. There is very strong pressure to ensure we're using the best emulator, and I'm almost completely certain obsoleting a BizHawk run with a Mupen run will never happen. We're attempting to obsolete a Mupen run, which is itself already obsoleted by an RTA run, with another Mupen run. This softens the impact, but as I understand it, the pressure to keep with the rules is still strong, and bending from it will give signals that we don't respect the rules ourselves. Precedent. Suppose I somehow manage to produce a good enough syncing and extremely optimized Jet Force Gemini, on Mupen. We have no prior run. This means we only have the standards the rules set. Mupen is below those standards, and I should expect that optimized TAS to go rejected in a heartbeat. Mupen runs trying to obsolete BizHawk runs should be rejected in half a heartbeat. In this case, we have a prior run with a low standard. Should we continue a precedent, allowing an aged standard to continue where today's standards wouldn't take it? Effort. A run like this takes a very long time to produce. Even if we have a team working on trying to copy the strats onto BizHawk, it's not something I'd expect to see in one week. We have a nice run on a sub-optimal emulator available here. Do we accept this run, knowing it flies against the rules, or reject it, and continue to present a slower run, still on this sub-optimal emulator and grandfathered into its position after new emulators are available, as our best for who knows how many more months? Integrity. Whatever the precedents, this does not mean we must follow them. New rules are set to encourage what we can truly see when things are done on console. I have seen the site as a whole pushing for emulator accuracy and console verification as an ideal. To accept a continuance of an obsolete emulation, when it was not asked for in the time window given, means we are not making this push, and that we do not strictly adhere to advancement of emulation accuracy. Community. TASVideos is its own community. There are many outside of TASVideos who like to produce their own TASes, and they don't necessarily know the best emulators to use. Stay with our rules, and the spread of information around the rejection of this run may help to encourage knowledge of better emulators to use. Allow this exception, and we will have one more impressive run to help encourage others to view our site, though possibly with slight confusion with our recommended emulators. I'm not sure whether to firmly say we should accept or reject, so I'm sort of going both ways. I'm bringing up a few points that come to mind, hopefully to strengthen the decision on this run, or at least make it easier to ask the right questions.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
Momentum-facing allowance. If you attempt to turn beyond that point, the steering fails for that frame, acceleration does not apply, and some extra friction is added. You can go beyond this allowance through methods other than steering, and it'll cause a similar slowdown. Note that The Stingray's allowance is above 90 degrees, but turning beyond 90 degrees will still cause a loss in speed despite staying within allowance. I have also noted the coasting friction (not holding the accelerator) and allowance friction (turning too sharp) are disabled while in the air. The "boost maintenance" friction still applies, if you're above your speed limit. ... Now I'm trying to count all possible frictions. Braking, coasting, turning allowance, boost maintenance, rail, dirt... On a side note, there are a few machines that can go 90 degrees, notably Wind Walker (90 exact) and The Stingray (112.5), but Hot Violet also has 90 degrees allowance. It's just much, much harder to get to that 90 degrees with Hot Violet due to the non-Blast Turn balance shifting momentum so fast. Our focus here will most likely be primarily on GP. Not sure about plans on the Championship circuit, though.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
I'm fine with PMs, though I generally prefer the questions get publicly asked, but I won't hold you to it. Ask away, through whatever method you want. Rapid bumps from a cheat? Well, that would explain that. At least we'll have a good excuse if we later can't replicate it.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
Nice to see a console speedrunner taking a look here and checking our progress. I'm guessing you tried my scripts to see what information I've been trying to expose. 4-5 seconds in, I was drifting right the whole time. The momentary turn to the right was to nudge my momentum into avoiding slamming into the wall, and the rightward drift was to keep enough distance from said wall. There probably is an extra bump I could take. Just that I didn't see any obviously good bumps I could take while deep in TASing. I didn't like the feeling of slowing down too much, yet that's probably what we need to do for one more good bump. That one bump just before the jump has an ideal CPU placement, one where it is very obvious the gain outweighs the minuscule cost, but I just didn't like the larger sorts of cost later. Good to get a praise, at least. Obviously, as a TAS, this won't impinge on the unassisted WR, but it does give indication how close you guys are to the limit. Once Memory comes back, I hope to see my opener beaten. I want to talk about drifts a bit, though you probably already know all about it, except maybe the exact numbers behind it. The drifts apply a constant speed to the left or right of whatever direction you're facing, which can add to or subtract from your momentum, depending on where your momentum is relative to facing. Jet Vermillion has the highest drift speed of 128 km/h, probably part of the reason it clears tracks so fast, yet it also has the worst momentum-facing allowance of 45 degrees. So let's have our JV speeding along at 595 km/h, and we're also drifting at this allowance. Our true speed is more like 691 km/h in this situation. If we could go the full 90 degrees, it would be 723 km/h. Let's just not snake on a straightaway, and get to our normal maximum rather than boosted maximum. Call 455 km/h our normal speed, and since we're not snaking, our 128 km/h drift is 90 degrees from our momentum. Our true speed is about 472 km/h. If we're 45 degrees, it just about 553 instead. Even if, snaking to the 45 degrees amount, we're 20 degrees away from where we need to actually go (our momentum is constantly trying to match our facing, causing arcs instead of straight lines, except in some circumstances involving wall hits, but that applies extra friction), that's still 519 km/h in the direction we want. Snaking looks effective at these quick numbers, and it clearly showed in practice. But you already know the power of drifting. This might still be an interesting read, getting details from someone who looked deeper into the game, I hope. On the scripting side, I was thinking about that track image underlay. 4096x4096 image, except cropped and rescaled to fit the window, centered on where you're at. That is a bit beyond what I am willing to do at the moment. I'll be working on more sophisticated position tracking functions, including having it persist between selecting a different movie (selecting a movie triggers core reboot. Core reboot will also reset the whole lua VM. This reset kills all lua variables I set up. Therefore I must use file I/O to have anything persist, such as old player positions from the movie you're trying to compare). The recording is for the sake of the script, not the movie files produced by BizHawk, so that comparisons of an older run are more convenient.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
Pawn Master, first lap in 24"21. This high precision took a while to get. Been trying out my script to get an idea of what is working right. The detection I'm using for determining whether machines have changed positions has a steep learning curve to understand what it's doing. The other parts that are working seem to help me make decisions on whether it's a good idea to take another bump. Anyway, I don't have plans on TASing this myself. I still want to give support, though.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
Try #1 Try #2 (best) Try #3 Oh, this routing isn't making things easy. There's a lot of things in there to test. I have spotted an enemy who remains existing while going to the miniboss. I suspect others already tried spiking it, but I would try my own charged spikeball just in case, and it's not even close when the spikeball hits the left edge of the screen. The miniboss fight is faster than other teams, at least, so I'm doing something right. I just don't like feeling there is something more right to do and I just haven't found it.