Editor, Experienced Forum User, Published Author, Skilled player
(1197)
Joined: 9/27/2008
Posts: 1085
I'm going to make a few observations for RTA to consider.
Steering. I have noted that the car's momentum shifts slightly faster based on how different your facing and momentum is. This means you will turn faster if you oversteer then quickly correct it after the turn. It becomes less important the better your tires are. It doesn't seem too tricky to oversteer a bit in RTA conditions, if you think you need a little tighter cornering.
Car choice. Well, it affects the letters in some way, as instead of looking to maximize letters for P1 to collect, you're maximizing letters for other players. I've chosen yellow car to aid in luck manipulation, although I'm not entirely sure it was needed. Also, it does affect when CPUs can cheat their letters -- Instead of races 2,3,4, it could be races 1,3,4 if you pick P2. In any case, you would need the Four Score for P3 and P4.
Speed. I've already told you all you needed to know, and we already came up with a motor plan that maximizes this even before we knew of the steps of 4. I suppose the only thing then is finding spots to nitro that doesn't coincide with a zipper, as the two together hits the speed cap.
That is a pretty good run, though. My suggestions probably won't save much time or luck frustration, but if you want to put in the extra effort, they're thoughts to consider. I probably should look over my run and start constructing some notes.
Race 1: Right at the very start, I hop on that hill at only 102 speed, when eight more frames of acceleration gets me 104. Of course, eight frames means I'm not past that hill, and it would take 200 frames to make up for losing about 800 distance units with an extra 4 speed. Actually, it's a bit more optimistic than that, but I don't think the hop takes more than a second or two.
Race 2: This is where I get a bunch o' letters. Nothing of note, aside from tricky manipulation that would inconvenience anyone trying to improve race 1. Silver Motor has a tight need, so any awkward collections done here were necessary.
Race 4: Just a reminder to anyone improving earlier races, this is another tricky letter manipulation spot.
Race 5: I'm focusing on that cruddy jump spot before that turn for this note. First lap, I get the nitro. Second lap, I use zipper twice. First lap, I pretty cleanly take that hairpin, but that's because I have less zipper speed, and dropped the motor down to 112 speed on top of that. Second lap, I basically thought 'forget it' and took the outside wall without bothering to try slowing down after the second zipper, or skipping said zipper a second time. It's an inconveniently placed boost, that's for sure. I actually do have time to stack a nitro on top of that second lap jump (well, I do need to waste a frame or two...), so taking the speed to a further extreme is possible. Not sure if that would be a good answer for tightening up our money route, but it's possible. This one jump, I tell you...
Race 6: Our last tricky letter manipulation zone. Manipulate the two "random" letters to be I, and all others are different. Fail, and you delay car upgrade by two races minimum. This reminder is my only note for this race, for now.
Editor, Experienced Forum User, Published Author, Skilled player
(1197)
Joined: 9/27/2008
Posts: 1085
Well, it does help to know about some details of speed. The steps of 4 is one thing. The cap of 252 from the sum of motor, nitro, and zipper is another thing. As for the two hidden nitros, the CPU actually does pick one of them up, so if you're not first there, you miss it. I haven't stumbled over other hidden goodies myself, so I'm wondering if these hidden pick-ups are a mistake.
Alright! Criticism! Now to either explain myself or confirm the problem!
Wide turn in race 5: The first lap, I had a nitro to pick up. This means avoiding a second zipper right before the jump. On the second lap, my excuse is that I hit the second zipper. So, I just hug the outer wall for "free" steering despite being in mid-air at the time. Mind, being at the outer wall is, rest assured, not taking that corner tightly, so it's certainly worth a few tests to see if slowing down the jump is worth it.
Missed zippers for nitros:
Race 10, the zipper I miss for a nitro is very close to another zipper I do hit, and is itself not exactly an ideal position to drive to. It's a small number of frames loss, likely less than 15 based on some quick calculations (I have zipper speed for 18 frames before that second zipper), but one to consider anyway.
Race 14, I spend every nitro I had. Skipping a nitro means not getting its 30-ish frames of savings, and those zippers are pretty close together. There are four nitros, grouped in two pairs, that I pick up, and not picking one up probably means not picking the other. By my count, two ideal nitros beat one ideal zipper, and these zippers are among the least ideal due to being grouped so close together. That said, it may be worth checking if the CPU avoids the first pair of nitros for me to take on the second lap, as I don't need to spend them all that rapidly. This is simply not a race where I can skimp on picking up nitros, as I end with 0, and it's rather difficult to end with -1.
Race 15, that money bag on that corner just before going under the bridge? Considering how tight I can take that corner, I see a pretty significant amount of distance between the corner and the bag. Okay, granted, Blue Car would have more time to push me if I take a wide turn to grab it, but that's a painful turn. ... Wait, you mean the bag that Blue Car takes in the short straight segment before going over the bridge? Ah, that one is not so bad, probably only several frames out and back. Might be worth a look.
Wide turn in race 21: I don't like jumps. I keep wondering if I should slow down before the jump, trashing my speed for the entirety of the jump so I can turn earlier. In this particular case, the answer looks likely that I should trash the jump speed for a better cornering, as I do take it pretty wide. You can view a more extreme version of the speedy jump by looking at the CPU cars crashing into the far wall at that same spot.
Change in corners handling: I'm more careful about how I crash into them. If I don't touch them, I don't lose speed. The instant I'm two units below maximum, tight steering will continue to decrease my speed, and hitting a corner is enough to trigger this chain reaction of a loss. One particular type of corner doesn't eat into my speed, and actually helps to speed up shift in momentum, but it's difficult to track the exact micro-positioning changes of touching the corner, and driving too hard into that corner will slow you down anyway because you have a bad angle, whether or not it affects your speed. In any case, I'm still trying to adjust my timing of when I make my tight turns so that, one frame earlier, I hit the wall. Actually, I also adjust positioning at times, so that one frame difference of this light positioning, I hit the wall. Once in a while, I do still intentionally hit a wall, like in race 14 after the six zippers hall, as I need the cornering much more than the speed.
Also, probably the big thing is that most of my strategizing on these tracks are actually single-pass. Which is to say, I take whatever looks fast at the time, then drop things there and don't test other routes that might turn out faster. Basically, pioneer out something, get it under scrutiny of however many who want to look at it, then I can go back and patch any problems that, while I may catch a bunch of them myself, certainly wouldn't hurt to get someone else to help catch them as well.
Editor, Experienced Forum User, Published Author, Skilled player
(1197)
Joined: 9/27/2008
Posts: 1085
User movie #47117049451414724
Now there's progress. Enjoy it.
I'm confused, I thought there wasn't any invisible pick-ups. There's two nitros in track 24 that I pick up, but they never showed their sprite. Makes me want to poke through some bits of memory to see if there are other sorts of unseen pick-ups that just stay magically hidden like this.
Track 24, after the first three 90 degree turns, there's a pair of zippers. Hug the far wall. You'll get two nitros, not counting the easily visible one between the zippers. You won't know you got two because the game doesn't tell you these things, but you got 'em. The dirt barely slows you down, and that diagonal wall will also barely slow you down.
It is a bit of a maze trying to find spots where I can use the nitro between zippers without wasting much of it on exceeding 252 speed units. Red was staying pretty close to my tail on that last race.
Editor, Experienced Forum User, Published Author, Skilled player
(1197)
Joined: 9/27/2008
Posts: 1085
Something I should have done a while ago is set up my scripts to simply check my position against the last frame. Like what I did with the first game.
First, the angles work in steps of 4. I could easily detect this in TASing normally. If you're driving at a slight angle away from the straight segments of road, you're not really any slower than driving straight along it. Probably a good thing for realtime, as your steering affects your facing in increments of 3 per frame, and it can get kind of twitchy.
Second, the speed also work in steps of 4. It does, indeed, take the sum of the high bytes of engine speed, zipper speed, and nitro speed. If this sum is greater than 255, clip it into range. The steps of 4 is what's important, as it lets us know what we're really getting from our engines. Silver is just +2 from Black, regardless of vehicle, but it's enough to reach our "steps of 4" threshold. The real difference is more like 4 speedometer units rather than only 2, so Silver is actually that much more useful.
When steering, you do lose one unit of speed (apparently it's a glitch where you keep almost max speed so long as you don't fall below it), so I'm losing some distance every time I steer with Silver. A good amount of distance is from driving straight anyway, so it's not all that bad. Gold would fight against these steering losses with an extra 1 buffer. Hyper is completely useless by comparison to Gold, aside from edge cases with acceleration and boost speeds. Mega is only one "speed unit" above Silver, but then there isn't anything else we can do with our flowing cash at that point.
On a another note, since the 252-255 range is the absolute maximum, the sum of the +64 from nitro and +112 from the initial zipper velocity would leave only 76 more to max out, which the engine easily fills. The portion that exceeds 252 is completely wasted, and using a nitro on a zipper is not advised if you have other places to use one.
Not much TASing progress, been sort of on other projects for a time, but I did plan out which money pick-ups to skip.
As for that button mashing, 93 on the timer is still a rather short time. You're probably not at the point to be worrying about the maximum like a TAS would be.
Editor, Experienced Forum User, Published Author, Skilled player
(1197)
Joined: 9/27/2008
Posts: 1085
I'd claim a rather recent and rather similar case happened not too long ago:
[2833] SNES Brandish by FatRatKnight in 38:42.41[3657] SNES Brandish "map glitch" by Osse101 in 11:12.19The fact my run got obsoleted probably helped me recall this case.
In essence, in this JPN submission, very little is seen of each stage, and its challenges are bypassed entirely. The old USA run, which has no access to the glitch, is in question to obsolete.
In the Brandish case, the JPN run sees very little of each floor, and most of their challenges are bypassed entirely. My USA run, which has no access to the glitch, is obsoleted.
The only real difference to this parallel are the different games, I'm attempting to tie the floor of one game to the stage of another, and the fact the JPN Brandish TAS still has to deal with the final boss normally.
The parallel is scary-similar to me. Brandish did not get much of a publicity, but this run did. Of course, my Brandish TAS had a rather poor rating, so having it published alongside the glitched run made it less advisable. The currently published TAS of this game has a rather poor rating. If the example with Brandish and Street Fighter 2010 differs, I will have questions, as the two cases look extremely similar to me.
Editor, Experienced Forum User, Published Author, Skilled player
(1197)
Joined: 9/27/2008
Posts: 1085
Just a quick note, it's actually 11 frames slower to alternate A and B per frame in Tug-O-Truck the entire time. Once you hit max speed, the next press actually slows you down significantly.
After 30 presses in half a second, I was at maximum speed. Thereafter, the next presses should be once per 12 frames, at a paltry rate of 5 times per second average (the 31st press was less than these 12 frames, but the point stands). Actually, I'm curious how fast the realtime button mashing is. Can you mash 32 times in the first second? How about 36 times within the first two seconds? The ceiling might actually be low enough for realtime to consider slowing down the mashing after an initial furious burst.
Of course, the feedback on this ceiling isn't obvious from the game's own display. Well, aside from suddenly slowing down, but it's not like a lovely clean buzzer with bright flashy lights and a speed bar indicating just how much awesomeness you just lost.
The Drag Race is different. Mash A-B as hard as you can -- The ceiling has me pressing twice out of every three frames at peak speed. I doubt this ceiling is something a realtime should worry about.
Editor, Experienced Forum User, Published Author, Skilled player
(1197)
Joined: 9/27/2008
Posts: 1085
00:BA6C -- Cheat letter to CPU player
LDA $0750 ;Race ID
AND #$03 ;0 to 3, use as a player select
TAX
LDA $0764,X
BPL $BA9C ;Escape if positive -- bit 0x80 is clear (a player!)
LDA $07A1,X ;Letters collected
CMP #$FD ;253, special mark for "everything collected, twice"
BEQ $BA9C ;Escape if everything was collected, twice
ASL ;Shift out $80 -- Collected first set (unchecked)
ASL ;Shift out $40 -- P
BCC $BA94 ;Carry bit states if we had P. If not, award that!
ASL ;Shift out $20 -- R
BCC $BA9D ;Carry holds if we had R. Again, award if not present.
ASL ;Shift out $10 -- O
BCC $BAA6 ;You know the drill.
ASL ;Shift out $08 -- A
BCC $BAAF
ASL ;Shift out $04 -- M
BCC $BAB8
ASL ;Shift out $02 -- The first I
BCC $BAC1
JMP $BACA ;Clearly, we're missing the second I
$BA94 LDA $07A1,X
ORA #$40 ;Award letter P
STA $07A1,X ;Make it official in memory now.
$BA9C RTS
;The next pile of lines are for the individual letters
$BACA LDA $07A1,X ;This is the last letter code, by the way
ORA #$01 ;Award the second I
STA $07A1,X
RTS
Dang, you're right. The code itself agrees with you. CPU gets awarded their next missing letter, regardless of what it is. I have a habit of making an assumption and failing to test it. I need to crack that habit.
According to this piece of code, though, CPU will still grab their free letters after each race after their first upgrade. Ran a breakpoint for Blue in my latest TAS, and it triggered on the end of Race 13 (or 14, if you count Tug-o-Truck).
Incidentally, the code can trigger on the same race the CPU legitimately collects the final letter of the set. In this case, it will just OR in the second letter I, but since that's already set, it hardly matters. It just has a catch for when it's got the final upgrade settled in.
Lap counter, oh...
There's a segment counter at 0559 to 055C. No clue what would happen if that were cheated to 21 during the crossover in Race 7.
The lap counter is over in 055E to 0561. Currently no ideas come to mind. Well, apart from throwing the debugger at it and the trace logger and looking at what the code is looking for when incrementing the lap counter.
For the 1up collection to reduce lag, it probably depends on how many CPU are keeping up with you. Even with none, I experienced a few frames of lag. If you're getting a lot more lag, getting it will probably get rid of more lag, probably to help make up for the more chaotic difficulty of controlling your car in realtime.
If I hit the zipper, I miss the letter, however close to the edge of the zipper I was. At a glance, it also looks infeasible to get the letter then back onto the zipper. Green's rubber band did break in that same race. Was puttering along at such a slow speed when I was well ahead, fun to see it's possible to get any lapping done at all.
Editor, Experienced Forum User, Published Author, Skilled player
(1197)
Joined: 9/27/2008
Posts: 1085
While browsing through the code, I spotted the routine that initializes car stats at the start of each race (by FCEUX debugger, 0B:DB8F). It includes things like maximum speed, turning rate, and all that stuff.
Maximum speed is a table lookup of your current car/engine combo. Despite being a table lookup, there's code to arbitrarily add 32 on top of this, which is already seen in our top speeds. There's more code for each of the three CPU players to give them an arbitrary change in max speed, a table lookup for the three of them for each of the races. Actually three tables, looks like they get to choose between three max speeds mid-race? The penalty is as low as -20 for basically the first race and the bonus is as high as 20 for the end races, and they start getting positive numbers pretty early on.
Turning rate is also a table lookup, but with only one dimension, so it's short. Apparently, there were supposed to be more tires, with turning rates 0x0070 to 0x0270, steps of 0x80 in between (0.4375 at first). There was supposed to be a secondary tires stat, in which these tires are better in, that would limit the Facing-Momentum difference, but the stat loaded (to 05C2) is overwritten by some formula with your speed before ever getting used (about 3/4 of base+zipper). Actually, it's hard to tell the intent of what the "extra five tires" were supposed to be, most likely they were scrapped before they finalized the tire numbers, so that would explain why the particularly wide turning rates between tires.
It caught my fancy to also look at how the CPU cars shop. Apparently, they have six shopping lists implemented, but only three are ever used. I think? Lists 0, 2, and 3 are assigned to CPU players in order. They follow this list strictly, and only after they get each item in order do they look at the next.
List 0: Red, Silver, Skinny's, Gold, Mega
List 1: Black, Silver, Gold, Skinny's, Nobblies, Mega (unused)
List 2: Skinny's, Silver, Gold, Dynafit, Hyper, Mega
List 3: Black, Skinny's, Silver, Mega
List 4: Red, Black, Skinny's, Silver, Nobblies, Mega (unused)
List 5: Skinny's, Black, Nobblies, Mega, Dynafit (unused)
The first available CPU car takes List 0. The second one takes List 2. The third takes List 3. Maybe the unused lists are taken if a player hits a game over? List selections are stored in 071C to 071F. Where they are in the list are stored in 0724 to 0727.
By "first available CPU car", I mean the red one if that's not a player. If controller 1 already claimed the red car, then the "first available CPU car" is the blue one. Oh, but if it's a two-player game where both first and second controllers got these two cars, then the "first available CPU car" would be the green one. Predictably, players taking up the first three slots means that yellow car will take List 0. I may as well be thorough while I'm at it.
Eh, I'm just analyzing things for the heck of it. CPU cars do make use of the money they get, although they do also get a bonus max speed on top of whatever zany stuff they have. Furthermore, I have observed the rubber band effect where it speeds them up by around +32 just because they're far behind you. For a few races, the blue car maintained a +16 rubber band bonus despite being on my tail, literally pushing me.
Editor, Experienced Forum User, Published Author, Skilled player
(1197)
Joined: 9/27/2008
Posts: 1085
So, here's the adventures of the yellow car. The second set of letters collected before Race 8. Mega motor paid for before Race 16.
Got the Mega with 540 cash to spare. Well, that 40 isn't something we can spare due to not being a multiple of 50 (Tug-o-Truck is the only source of multiples finer than 50). But this suggests I picked up five money bags I didn't need, maybe there's some that are most out of the way I can avoid.
I did gloss over the detail of how CPU cars cheat their own letters, but I'll make it a point to mention what I know.
After Race 1: Red car (P1) gets P, if it's a CPU car
After Race 2: Blue car (P2) gets P, if it's a CPU car
After Race 3: Green car (P3) gets P, if CPU
After Race 4: Yellow (P4) gets P, if CPU
After Race 5: Red gets R
After Race 6: Blue gets R
... And so on.
A letter is not magically awarded if the target car already has the letter in question or the car is a human player. May as well reveal every potential advantage you can get.
Editor, Experienced Forum User, Published Author, Skilled player
(1197)
Joined: 9/27/2008
Posts: 1085
Been dealing with emotional issues at home, no desire to go into details, but they are resolved now. I haven't been able to really work on this under the stress I was feeling.
Took a brief look at the lights RNG. Apparently it's just a straight up 24 + RNG(0 to 63) timer. When the lights do their thing, it checks for specific light states, and when it gets to the second light, it branches to:
JSR $F636 ;RNG call
AND #$3F ;0 to 63
CLC
ADC $06E2 ;Before the branch, a 24 is stored here
STA $06E2 ;We now have 24 to 87
Granted, observations of the lights may show a bias. If the distribution is perfectly uniform, then we should be seeing 4 possible lights out of 256 timer values where we get the same result.
Of note, the RNG function is called seven times (for letters) between the time you finish shopping and the eighth RNG call at the light. Since there isn't really anything you can do to the timer between these eight calls, there's probably some skewing done by these eight calls.
I haven't seen a different function call in the first few races. Basically, the lights function looks like it's meant to be unpredictable. Whether patterns develop would be from an artifact of the RNG function.
No TASing progress to report.
Editor, Experienced Forum User, Published Author, Skilled player
(1197)
Joined: 9/27/2008
Posts: 1085
I will add my voice in disagreeing with p4wn3r. Sorry, I'm just not seeing your angle. Is the majority of the visible community here also at fault?
I have seen no conflict arisen in the process here. It was discussed in multiple areas, just not collected in this one topic. There is a mention that the rules have been updated in light of this submission in the judging notes, and there still hasn't been any disagreements I can spot since the update.
I can see a disagreement with the visible process (brought up by p4wn3r), but still nothing about the updated rule itself. I do not recognize the importance of this detail brought up. I've seen nothing challenging the new rule itself, only the fact it was changed. I personally see the rules adjustment more as a clarification of what is generally assumed than an actual change.
Rules are made. Submissions test against these rules. These tests reveal previously glossed over details. It is my impression that every single thread in this Workbench is an opportunity to change the rules, not to enforce them blindly.
Editor, Experienced Forum User, Published Author, Skilled player
(1197)
Joined: 9/27/2008
Posts: 1085
It's clear to me what "password" means to me... but I'm not everyone. Probably what skews my own view is what I did one April Fools'.
It's more a set of tracks than a single track. A set of five tracks. The game refers to it as Round 6, so "final round" might be a better fit than "final track".
To break things down, the method is "password", the effect is "final round", in some terms that makes sense to me. We're preferring the effect in this case, then?
Editor, Experienced Forum User, Published Author, Skilled player
(1197)
Joined: 9/27/2008
Posts: 1085
Reading over that Biker Mice from Mars submission, not all equipment is gotten by password. In fact, it is briefly visible between tracks that two of the four stats are maxed out, the other two are still at their defaults. Including "all equipment" would be inaccurate.
It's also not "default equipment" either. The TAS just gets whatever it needs from the password, and leaves the rest alone.
I still say "password". Any particular reason why I would think "warps" means I aim to take the maximum number of warps possible in a run? I agree that "password" has a minimum of description, but I ask to be convinced that "warps" is enough to specify fastest path using warps but "password" isn't enough to specify fastest path using password.
If it's a matter of expectation, then I may well have missed the point in my previous paragraph.
Editor, Experienced Forum User, Published Author, Skilled player
(1197)
Joined: 9/27/2008
Posts: 1085
Password
It's set up to basically win the game with ideal equipment at the last "world." There are no restrictions, and nothing special other than a password is used, and no restrictions on the password itself is given, aside from the fact it was something obtained normally.
I don't see any particular reason to name the branch anything but "password" myself. It's a password to the last world, much like how we don't specify "fastest warps path" in our Super Mario Bros. TASes. It's a password that gets the best relevant equipment, not something we'd care to mention that we get Erdrick's Armor and Erdrick's Sword in a Dragon Warrior TAS.
That's my reasoning, anyway. If it makes sense, then good. If not, you'll have your reasons why it isn't.
Editor, Experienced Forum User, Published Author, Skilled player
(1197)
Joined: 9/27/2008
Posts: 1085
Among the password games, there is one example that restart back to a password screen, Deadly Towers.
When you start the game, you go through the password screen, whether you want to start a new game or not. When you die, you are kicked back into the title screen, and pressing start takes you back to the password screen with a new password already put in for you.
However, while the player does go back to a functioning password screen after death, the game inserts the password of its state for you with zero input from the player. All the TASer has to do is confirm the password after restarting. Aside from the password, which could have been attained sooner by inputting it there and then as opposed to making progress then dying a humiliating death, there are no other practical differences.
In this particular case, the TASer does not need to somehow demonstrate acquired knowledge of the password. So, ignoring all the controls of the password screen other than "confirm password" is a perfectly acceptable means of restarting the game from a "save file" of sorts, I take it? This is the closest possible case I can recall where a "password save" is used in an active password screen.
So, I would suggest that Deadly Towers is much closer to this line than a lot of other games. If judged by today's Vault standards, is this Deadly Towers TAS on the side of acceptance or rejection of this line?
Editor, Experienced Forum User, Published Author, Skilled player
(1197)
Joined: 9/27/2008
Posts: 1085
In the case where we allow any and all sorts of arbitrary corruption, we would-
[1860] GBC Pokémon: Yellow Version "save glitch" by p4wn3r in 01:09.63
... Ah, right. That.
Suppose we disallow direct memory edit of a particular region where our Pokédex is. If we still allow ACE, then we would simply execute the lines of code in ROM that normally edits that spot of memory as appropriate, finding a code path that sets the bit and returns back to the ACE state as quickly as possible.
Well, let's figure out how to define restrictions to avoid ACE.
Let's avoid corrupting the stack. That thing has lots of return pointers, and probably a bunch of local variables. Messing with that messes with program flow. In case it's important, if the game stores the Stack Pointer somewhere in memory, don't corrupt that either.
Let's also avoid modifying function pointers. That would almost certainly let us jump anywhere. Even if we're only pointing to another spot in ROM, it would mean we can pick and choose which code runs to some extent, which would still give an incredible amount of control where we can just run the "100%-getting" function a few times, making the 100% definition very fuzzy.
In addition to the function pointers, if the game uses an index number to pick a list of functions, restricting ways to modify that would also keep "intended" code going. Obviously, if we can just put in an out-of-range number, we'd be getting out-of-range function pointers that jump to who knows where. This would probably affect using glitch items, although rearranging them is still fine. Poking in-range index values can be considered allowed for this particular restriction.
If there are other methods of sending the Program Counter where it doesn't belong, assume that any such methods I missed are to be reasonably restricted in the spirit of trying to come up with these restrictions.
Just in case, if the game puts code into memory and executes it there as if it were normal, do not modify that spot of memory prior to the game jumping there.
Let's leave data pointers unrestricted for now, so long as inside that data aren't function pointers or other ways for the game to jump into ACE state. If the data overwrites places it shouldn't, make sure that we don't modify function pointers we come across. That shop list thing feels like a data pointer to me.
With these thoughts in mind, I want to look at reasons for rejection listed in the submission.
Does not use glitches that allow executing arbitrary ROM addresses.
Well, my restrictions would catch this, as we're messing with function pointers or something to that extent. Modifying the map scripts would certainly allow us to jump the code and pick out what happens, basically.
Does not use glitches that allow writing to an arbitrary destination.
Messing with data pointers, not only that but also injecting almost any data desired. My restrictions do not stop this, except for any cases where it would write over "important memory" that I outlined above to prevent ACE. The text engine has an implemented but unused code path, should that be considered unintended execution if that special 0x03 byte is detected?
Does not use "mass corruption" glitches.
Another thing not caught by my restrictions -- Provided the mass corruption doesn't affect anything important, and itself doesn't run unintended spots of memory as code. Is encountering MissingNo. and that crazy glitched blotch a "mass corruption" of sorts that don't affect anything important outside of hall of fame? Or do you mean more massive sorts of corruption than that, with a good line to define?
I would also like to know if there's anything my set of restrictions would have said "no" to what was done in this submission, as well as other techniques that would have gone through that wasn't done. Mostly as a point of comparison, really. I'm mostly trying to put down guidelines to help figure out which restrictions are too much or too little.
TASes generally aim for some kind of perfection. We also want to be perfect in where to draw our lines, as natural for a site aiming for perfection in some form.
Editor, Experienced Forum User, Published Author, Skilled player
(1197)
Joined: 9/27/2008
Posts: 1085
ktwo wrote:
[...] I'm however still not sure if I have understood how the RNG-addresses (756-759) end up in the letter addresses (1CD-1D2). Would you mind explaining that again or just quote yourself if there is something I'm overlooking in your previous posts?
There is no direct RNG address to item conversion. Because a frame timer is involved, which is incorporated into the RNG, being one frame late on the first RNG call means your second RNG call will be completely different, and even if you got that one a frame early, your third RNG call will not be the same. Realtime manipulation will be essentially impossible.
The assembly code I put down is basically the formula used to create a new RNG value. If the game wants a new RNG value, that function is called, then the value stored in 0756 is used for decision making (something I haven't mentioned up until now).
There are seven RNG calls made each time the game wants to place items down:
1) One for Player 1
2) One for Player 2
3) One for Player 3
4) One for Player 4
5) One for a player based on current race (race 1 = P1, race 2 = P2, ...)
6) An RNG call to select player 1 to 4, at random
7) One letter for the randomly selected player
When it comes time to deciding letters, the game takes an AND of the RNG value (at 0756) and whatever letters the player doesn't have (an inverse of 07A1 to 07A4, depending on player). If we have bit 0x40, generate a P. This only happens if the selected player doesn't have P, and the RNG has that particular bit set, thanks to that AND. If we don't have bit 0x40, check bit 0x20, and if set, generate an R. If not, check 0x10 and generate an O if set. It goes on to check 0x08 (A) and 0x04 (M) before finally giving up and generating an I if everything else turned up zero.
Since there's always six addresses, the letter packs just pick from one of the six. In a few races, some letter packs pick the same address, and these ones will always show the same letter as each other on any given generation.
Again, because of the interaction with the frame timer, this isn't something a realtime run can reliably manipulate. Ideally, you find out which players the game reads for the later races. After you find out who the letters favor at an important time, intentionally play as that car and you might get luckier.
Editor, Experienced Forum User, Published Author, Skilled player
(1197)
Joined: 9/27/2008
Posts: 1085
So, here's a yellow car with PRO AM II collected as race 4 is concluded.
You get to see what race 5 looks like with that stuff.
Well. I didn't even try to manipulate race 6. I have a lot of letters to manipulate just right, and the "random" two must be I. If it can work out, race 7's letter depends on player 4 anyway, so not much manipulation needed after that mess. It's the mess I'm worried about.
I ended race 5 with 4 unspent nitros. I intentionally land in the water to deny the landing bounce. I didn't count frames to see how far ahead of my original WIP I was.
Editor, Experienced Forum User, Published Author, Skilled player
(1197)
Joined: 9/27/2008
Posts: 1085
So, there is something RNG related in the track itself, aside from spin-outs. I took some time to look at this. I'm not sure if it's the steering itself that's causing the RNG related stuff. It could just as easily be letting opponents get ahead of you, which means sitting pretty for a few seconds until they convince the RNG to do something. Hard to be certain, and I don't want to investigate that piece of code yet.
I have seen the "out of bounds" effect while TASing, particularly during a turbo+nitro+perfect steering moment. Indeed, I even saw random items on the track "swim" toward their normal spots from what looked like off the track. I agree that it's probably just a visual, but a curious visual nonetheless.
Working out my RNG prediction script.
Apparently, the game actually keeps multiple copies of the RNG function, in different banks, probably because bank switching is too inconvenient for the code at places. I was just looking for one specific copy of this function. Expanding my search for all instances where the memory is written to instead of when a particular function is executed is letting me catch more of those things I've been missing. Yep, there are copies of this RNG function I didn't see before. Copies, alright, everything's the same to the instruction, just in different spots in these different banks.
Anyway, once the script is worked out, I should hope I can get a lovely prediction thing going on so I don't have to hunt for decent possibilities. So far, it's saying I should expect around 20 possibilities in race 2 for some given "world" of 256 possible timer values, playing as yellow car who picked up the letter P in race 1. I expect worse, worse stuff if I'm trying to manipulate 6 letters at race 6. Like, zero possibilities until I stumble across a "world" that might have a few.
I think I've figured out 05C2 more precisely: It's actually used for the facing-momentum limit. I just noticed facing and momentum will not differ by more than whatever is in 05C2 (or the neighbors at 05C3, 05C4, or 05C5 for other cars).
I did some quick calculations based on my WIP, and guessing how many frames would be saved with a better engine. On a few sample races where we could potentially get Mega, I've seen less than 200 frames going from Black to Mega, and that's not accounting for speed arrows and nitros that would reduce this number further. If we're about $1000 away from getting Mega one race earlier, four clean nitros is around 120 frames, and it's hard to even say we'll make up for the 120 frames with an early Mega. Less, clean, sorts of nitros, sure. Random spares I skipped in one race, of course! Clean ones where I make full use of it is a hard trade only worth it if we're close, like you say.
Well, 3rd car Black's 130 speed and 3rd car Mega's 138 speed does leave a rather small 6.15% increase of speed. We're planning on Silver's 132, which is even smaller difference between it and Mega. Well. It seems likely hoarding what would be 4 clean nitros is a loss.
Obviously, nitros in slow obstacle moments are ideal. They still won't stop the obstacle from reducing the base rev of the car, unless it's part of a jump that lets us clear the obstacle. The nitro bonus itself isn't affected by the obstacle, which means less time we're stuck in there, and thus the sooner we can get back up to speed.
Editor, Experienced Forum User, Published Author, Skilled player
(1197)
Joined: 9/27/2008
Posts: 1085
ktwo wrote:
What does this mean? For example, let's say P2 has 'P', 'R' and 'M'. Does that mean 'O' is the most likely, followed by 'A' and 'I'? According to which probabilities? Are 'P', 'R' and 'M' impossible to be generated in this case?
The most likely letter is always 50% chance. Each step down is half as likely, until you get to I which takes whatever chance is left by then (regardless of whether the player already has two I). Skip letters that are already owned by the player.
The "blank" case:
P: 1/2
R: 1/4
O; 1/8
A: 1/16
M: 1/32
I: 1/32
If Player 2 has P, R, and M, a letter generated based on player 2 would have...
P: No
R: No
O: 1/2
A: 1/4
M: No
I: 1/4
ktwo wrote:
I don't see the pattern between the 6 dependence possibilities and how these are attributed to the different letter items here. Is there a way for any given race to make a similar list of how the letters are generated for the individual letter items? (I'm mainly interested in race 9-14)
It appears entirely dependent on the whims of the designer when they placed the item. I've been manipulating race 2 for a bit (not being successful with my trial-and-error so far), and so far the same dependencies I spotted earlier are what I'm seeing.
Anyway, the game generates six random letters. Which of these six each letter package picks is based on that whimsy designer. The results fill six memory addresses:
01CD - Picks whatever player 1 didn't get
01CE - Player 2
01CF - Player 3
01D0 - Player 4
01D1 - Picks a player based on current race
01D2 - Picks a random player
As for the value at the address (decimal):
103 - P
104 - R
105 - O
106 - A
107 - M
108 - I
Probably the simplest way to check which letter belongs to which slot is to go into a race, and after the starting line is visible, edit addresses 01CD to 01D2 with numbers 103 (0x67) to 108 (0x6C), in order, then note that all the Ps you spot depend on player 1, and so forth.
If you still want me to track down races 9 to 14, I'll take some time to look at some point.
ktwo wrote:
Just thinking loudly here, but couldn't you create a minor spin-out in race 1 to change the RNG the way you want it for race 2? If it's done right before the finish line, it can't be very time-consuming. At least surely less time-consuming than waiting at the map screen for an 'I'.
I'm... Interested to know of any method by which one can trigger a spin-out without oil slicks, ice, or roll cages.
ktwo wrote:
I very much doubt sacrificing "cleanly" used nitros in order to buy Mega earlier will pay off. Unless of course it's really an edge-case, where you just need $250 or $500 more to get the purchase done for a particular race. But the first ones to go would obviously be where you spent a nitro in the wip right before the finish line and so on.
Well, a single clean nitro (straight way without steering losses) got 35 frames with default car and Black motor. I spotted another clean nitro in my WIP with Black motor and second car that got only 32 frames. With the possibility of Silver motor in second/third car, we can expect slightly fewer frames saved.
The question then becomes how much of a difference is Silver vs. Mega in each of the races where we can possibly get Mega? Almost certainly worth sacrificing two clean nitros. The Mega is worth more than 60 frames for one race, right? ... Well, probably, we need to make measurements at some point. If we TAS out a difference of 420 frames for a race, that tells us that's about 14 nitros of difference. If we TAS out only 200 frames for a race, it's more like 6, maybe 7 nitros.
It is a thought I was playing around with. If you can think of things that can make a nitro worth more than 35 frames like in my test with 1st car + Black motor, then that would help to increase the value of using nitros as a speed boost rather than a cash boost.
Editor, Experienced Forum User, Published Author, Skilled player
(1197)
Joined: 9/27/2008
Posts: 1085
Well, there is a little extra something the game does with letters. The game takes a look at some player's letters as part of the letter generation. I initially thought it took some "random" byte out of RNG, but for some reason I didn't look too closely at the LDA $07A1,X somehow. Looking at notes on SDA, that's the address involving player letters.
So, the game takes the negative of someone's letters (XOR #$FF), ANDs it with an RNG address, then picks out a letter. Nifty. It explains why the I shows up more frequently around the time you start needing it.
The game generates six random letters. It will always do so, even if there aren't that many letters on the field. The first four correspond to the four players, the fifth depends on which race you're on (player 1 for race 1, player 2 for race 2, ..., player 1 for race 5, player 2 for race 6, ...), and finally it picks a random player (RNG call) for the sixth letter.
Also, computers "cheat" and pick up a letter at the end of a race even if the race had no letters on it. This actually works in our advantage as the generation algorithm is now less likely to pick that letter. In any case, if we can manipulate them picking up letters we won't care about, it means better manipulation for a later track.
The race 1 letter depends on player 1 (01CD). Not that it matters -- No one has any letters!
The race 2 letters depend on:
* Lone straight letter: Random player (01D2)
* First of three letters: P2 (01CE)
* Upper left of three letters: Race (01D1) (P2)
* Lower right of three letters: P3 (01CF) not DF. Crossing that t...
The race 4 letters depend on:
* Close to zipper letter: Race (01D1) (P4)
* Far from zipper letter: P4 (01D0)
* Letter past zipper: P1 (01CD)
Let's see... PRO AM II... There are eight letters in the first four races and we need to manipulate seven to be what we want. Meep.
It might actually help if we play as player 4, the yellow car. If the letters themselves don't pick random addresses, but always sample from what I spotted in my WIP, then we can at least guarantee two letters in race 4 will not be ones we collected in earlier races. ... We'd be hooking up the multitap just to play as one particular player.
We may want to manipulate something rare in race 1, as then we'd have a better shot at getting three letters of sorts we can pick up in race 2. The RNG is somewhat stiff, giving 256 possible "worlds" for any given race 1 output we do. And well, one "world" is clearly 255 frames of wait compared to another "world". The oil slick we can find in race 2 gives us more "worlds" to pick from by race 4, though.
In other news, I did look at the potential money we'd get if we didn't spend nitros like nuts.
Ye, snap! That's not a small amount of money! We're talking Mega by race 11! ... If we somehow get like all the cash from all the races. I did spend a nitro at the very end of race 4, on a straight road just before the finish, and removing that takes 35 frames. If nitros never amount to more than 35 frames with Black motor and default car, 20 nitros is 700 frames or 5000 cash. I suppose asking whether getting Mega one race earlier is worth 700 frames is a fairly good question at this point. Nearly 12 seconds of difference on spamming the nitros on races 5, 8, or 10 looks unlikely to overcome.
In any case, I'm wondering how I didn't notice unspent nitros are worth $250. There's actually several of them scattered about I didn't even try to pick up. Mega motor by race 13 (Black motor route) or 14 (Silver motor route) might actually be feasible without hoarding too many important nitros. But we definitely would need to do some amount of hoarding then.
Race WIP / Max So... What I got in WIP,
R 1: 2950/ 3450 and maximum possible if I got it all.
R 2: 3600/ 3600
R 3: 3500/ 4200
R 4: 3300/ 3750
R 5: 3300/10050 Heavy nitros level
R 6: 2100/ 2100
R 7: 5050/ 5150
R 8: 2000/ 8250 Another heavy nitros level
ToT: 4990/.....
R 9: 4050/ 4650
R10: 3700/ 9300 There's our third nitros level
R11: 3950/ 3950
R12: 3950/ 4400
R13: 4600/ 6250
R14: 4050/ 5250
R15: 4250/ 4800
But first, we have the letter manipulation problem to deal with...
What I mean about the lights is that, on your data, you've seen a different distribution of timings in later races. That distribution on your manipulation of race 2 later races was affected by your manipulation on race 1.
In TAS conditions, steering bonuses from tires help, but since we have perfect control, the improvements would not come from fewer mistakes. Good tires are probably behind a good motor in importance, so it might even be prudent to go Red (1), Silver (3), Skinny's (4), then Mega from there.
EDIT: Let's see... Race 6...
Of the six letters, my WIP indicates they source from P1, P2, P3, race (P2), random, and random. Unfortunately, random and random means they actually use the same address, so those two letters must always be identical. Okay, since race 7 has only one letter, these two "random" ones must both be I for any shot at a race 7 vehicle upgrade.
The initial group of three letters. Lower-left: P2 - Upper-right: P3 - Upper-left: Race (P2).
First letter of straight: P1
Second letter of straight: Random player
Zipper "side pit": Random player
Race 7's letter uses P4. If we got the other six as yellow car, we have 50% chance of P here.
It appears possible that, if we do select the yellow car, we can manipulate R O A M II from race 6. We can't manipulate P, as by then the CPU cars are all magically awarded the letter P and no letter will ask the yellow car for unspent letters, aside from the "random" ones we need on I.
It seems possible. There is a small chance it is possible to get our second upgrade by race 7, but if it can be manipulated, then it will happen. I just need to see if there's enough "manipulation space" to make it happen, I suppose.
By the way, the game will always allow I as a possible letter. It's why we wouldn't have 100% chance of P.
Editor, Experienced Forum User, Published Author, Skilled player
(1197)
Joined: 9/27/2008
Posts: 1085
FatRatKnight wrote:
I think I'll start picking apart the routine that determines the letters to deploy on the track. Getting at the actual assembly should catch a lot of the factors involved.
Nailed it. By FCEUX's debugger, routine 01:F636 has our RNG function. Delicious.
In short, you only have to look at addresses 0756 to 0759 to see if the game wanted an RNG. If they changed, the RNG function was called at least once.
Every time it's called, addresses 0756, 0757, 0758, and 0759 are modified. The only entropy introduced to the RNG is the frame timer, 043C.
Basically, I just looked for the race 1 letter package. When I got a different package, I looked for numbers that weren't equal. With rather few results (in the race itself, I searched for zero changes), I poked a new value on what I suspected was, indeed, the letter package (01CD). Yes, it was the one. I ran the debugger with a breakpoint looking for when 01CD was written to. Got a hit, judged the surrounding code not the right one I'm looking for, ran the game again and got another hit. That second one looked suspicious. It's part of a routine that iterates over a few different item slots, probably for multiple different letters.
I did see a function call to some "random" spot in code. Well, by "random", I mean it's address was rather distant from where the caller is. Following my intuition, 043C was involved, alright. So were a number of other addresses.
Okay, so what's the process? What new numbers are put into 0756 and friends? ... I'll let the code tags handle that.
01:F636 - Roll for random number function
LDA $0757 ;r[1]
PHA ;For now, store that in stack
ASL ;Left shift; put the upper bit into carry
LDA $0758 ;r[2]
ROL $0758 ;r[2] is shifted one bit up; it also has upper bit of r[1]
ROL $0759 ;r[3] is shifted up as well; it has upper bit of r[2]
EOR $0759 ;The old r[2] is XOR'd with shifted r[3]
STA $0757 ;r[1] now holds this XOR calculation
PLA ;Fetch the old r[1] intact
STA $0759 ;r[3] now holds the old r[1]
EOR $0758 ;This is old r[1] XOR shifted r[2].
PHA ;Stash it in stack for now
LDA $0756 ;r[0]
STA $0758 ;r[2] now holds old r[0]
PLA ;Now that we preserved r[0], fetch from stack
ADC $043C ;Add in frame timer; the carry from r[3]'s shift operation is added, too
ROL ;Left shift; The carry of the prior addition is placed in low bit
STA $0756 ;r[0] now holds... a complicated mess I don't want to English.
RTS
... Okay, so 0756 gets a complicated mix of RNG addresses plus the frame counter. 0758 simply takes whatever is stored in 0756. 0757 is some XOR mix of 0758 and some bits of each of 0758 and 0759. In turn, 0759 takes whatever is stored in 0757.
Anyway, this function is only called whenever the game needs an RNG value. It doesn't appear to be frequently called, mostly just race starts. I have enough information off of this function to probably create a good RNG output script. Oh, and those lights you might have looked at in a later race could have been skewed by timing the earlier race's start differently.
Well, now that I know of it, maybe I can find out how it's used for letters. Function 00:8BD3 looks rather important for that. It is called six times, even if there aren't six letters on the track. Actually, they cleverly saved a few bytes by simply placing that function straight over the end of the one picking out the item slots to fill, to save on an otherwise unnecessary JSR and RTS. In any case, I see a bunch of ASL and BCS, leading to LDA of some constant (for each of the letters), STA onto the item slot, and RTS to leave the function. As there is nominally a 50% chance that any particular bit is a 1, the BCS should trigger half the time, so each letter after the first has only half the chance.
In short, this function call is telling me that P happens 50% of the time, R happens 25%, O happens 12.5%, A at 6.25%, M at 3.125%, and I at 3.125%.
There may be other letter generation functions that skew the results differently. Just that this one I'm seeing at race 1 is doing what I'm seeing.
EDIT: Alright, I set my script with memory.registerexec on the RNG function. It prints the current frame count so I can at least guess when things happen.
1 RNG call at name entry.
7 RNG calls when track loads. This includes the challenges.
1 RNG call just as the second red light becomes visible.
Several RNG calls whenever a car spins out.
Several RNG calls during the Tug-o-Truck challenge.
I'm not sure what RNG a spin out needs, but it does mean we can manipulate luck by driving into an oily puddle. Not only that, but by varying the frame we enter such a puddle, we can also manipulate luck, due to how the frame counter interacts with the RNG addresses.
Okay. The script so far hasn't picked up other RNG sources. I haven't identified the exact purposes to these RNG calls, but knowing what they're used for should help us focus on the right things.
Incidentally, looking through the letter generation algorithm, there are seven JSR $F636 (the RNG call) in there. Well, strictly speaking, there's only two, but there are five JSR $8BD3 that immediately lead to a JSR $F636. One of the RNG calls is so the game can figure out which RNG address to use for a letter (specifically, the 6th one), and the seventh call is when the function naturally gets to 8BD3 without a JSR. So I can identify the seven RNG calls each time a track loads, to generate 6 different letters every time.
Not sure where the game is determining the starting order, but it's probably not from these RNG addresses.
Editor, Experienced Forum User, Published Author, Skilled player
(1197)
Joined: 9/27/2008
Posts: 1085
There appears to be two addresses for the pixel-level precision on both X and Y positions. My script is reading one I basically chose at random. I've been comparing the mirrors and never saw any difference, practical or otherwise. The 256pixel-level and sub-pixel-level addresses appear to be one-of-a-kind. (The fact the "pixels" are diagonal rather than aligned with the screen means calling them pixels is a bit of a misnomer, but for lack of a better word, that's what I chose)
I have not studied the RNG. Only that delays affects it in some way, so I generally chose for faster starting lights and, with low priority, an earlier vehicle upgrade. It is almost certainly worth trying to get letters sooner.
Mostly I charged forward so we have a view of later tracks, and can potentially work out the cash available for when we get upgrades. We can count how many tracks we're at Standard and Black before getting Mega engine, and how long we're on Standard, Silver, and finally Mega if we take that instead. Based on address 0596, Red is +8, Black is +12, Silver is +14, and Mega is +20.
Getting Silver delays us one race in our finances, just as a ballpark measurement. If we could have Black one race earlier, Silver means we're at a "score" of -12. Since Silver is itself +14, each race we have that instead of Black means +2 per race. Each race we'd have Mega instead of Silver if we went Black, this is a deficit of -6.
In my WIP, I managed Black ready by race 3, and was short a Mega by $410 by race 15. I also gain more than $4000 in race 15 as well, where if I went Silver, I'd be just $160 short by race 16. Let's assume I could have gotten the $410 difference, perhaps realizing nitros are worth cash like you said. So I'd have Black in races 3 to 14 (12 races), and Silver in races 4 to 15 (12 races). I'd be enjoying an extra +2 speed in 11 races, and suffering -12 and -6 for races 3 and 15, respectively. The total is a rather slim +4.
Of course, this is all just a ballpark guess. The actual, exacting frame counts would certainly have some difference, particularly dependent on just how long races 3 and 15 are. Both engine routes are close enough together that it's hard to tell if Black or Silver is better, with a slight encouragement for Silver, at a glance. There's also the "pushy CPU" factor I've crashed into at race 15, which would help a slower engine more than it helps a fast engine, giving Silver an extra push toward making it worth picking as the Black route would have Mega by then.
Oh, and it might affect the Scoopers purchase. Well, if the tires affect us meaningfully, anyway. I did have trouble keeping up with some of the curves, so yes, it might mean something. Skinny's is definitely worth taking early.
I think I'll start picking apart the routine that determines the letters to deploy on the track. Getting at the actual assembly should catch a lot of the factors involved.
Editor, Experienced Forum User, Published Author, Skilled player
(1197)
Joined: 9/27/2008
Posts: 1085
I had worked on this game already for some significant time. Your post convinced me that I really should be writing down what I've got, and I just put it off for way too long.
Movie: http://tasvideos.org/userfiles/info/46246125573589327
My lua script is pretty much a glorified RAM Watch at the moment, so unless you want me to share that anyway, I don't see much of a point over just handing over the addresses.
Addresses.
Multiple addresses on a line indicate values that need two bytes (0-65535) or more (sub units and 0-65535), the first address is always the smallest unit, italics indicate I believe it to be a sub-unit.
0540,0504,050E - X position (player), signed
0545,0518,051D - Y position (player), signed
0592,0596 - Engine rev (base speed)
05B6,05B2 - Speed arrow bonus
0626 - Nitro bonus (did not check for sub-value)
05C2 - I suspect this is just engine noise, rev and arrow affects it, nitro doesn't
059E - Facing (player)
05A6,05A2 - Momentum (player)
0748 - Nitro count
As for the speed, it is my experience that the game applies three factors and sums them together. No careful analysis made.
* Your base engine rev
* Speed arrow
* Nitro
However you crash or whatever, that only affects your base engine rev. If you crash badly enough, it can also set your speed arrow and nitro values to zero, but otherwise, anything not "major" just affects your rev, and nothing allows that to accelerate faster than a good upgrade.
As for turning, I've analyzed the tires to simply affect base rate of how quickly momentum shifts to match your facing:
0.7500 - Standard (0x0C0, 192 per frame)
1.0000 - Skinny's (0x100, 256 per frame)
1.1250 - Nobblies (0x120, 288 per frame)
1.1875 - Dynafit (0x130, 304 per frame)
1.2500 - Scoopers (0x140, 320 per frame)
As long as your facing and momentum are different, each frame, the game applies the above values, plus the immediate difference between facing and momentum that frame. For reference, a 90 degree difference is 64 units, so when steering that hard, you can add an extra 0.2500 to your steering rate. This is unlike the first game, and you're encouraged to steer pretty hard in most turns if you need to turn even slightly hard.
There is an upper limit to the facing-momentum difference. When you hit that, momentum suddenly speeds up to keep up with further changes to your facing, which is 3.0000 per frame.
While on ice, tires have no effect, and they all apply 0.0000 steering (Well, the Skinny's had zero effect). Only your facing-momentum difference will apply. Furthermore, the limit between facing and momentum no longer applies, and trying to steer past a full 180 degrees will cause you to spin out.
Steering hard does drop your speed. At least, supposedly. In practice, if you're at maximum speed, apparently you keep your full engine rev? Well, after an upgrade or something. Not analyzed deeply.
The side-challenges are button mashers. Try not to go beyond speed 40 in the Tug-o-Truck, I didn't notice the reset to speed 20-ish on my TAS.
Black motor looks useful. Silver is a maybe. Gold and Hyper are definitely bad.
I have not read most of the notes presented in the SDA link. I just wanted to get my side of things here. You seem to have some numbers for the motors already.
Editor, Experienced Forum User, Published Author, Skilled player
(1197)
Joined: 9/27/2008
Posts: 1085
Let's first pull out a few movies that catches 'em all:
[1860] GBC Pokémon: Yellow Version "save glitch" by p4wn3r in 01:09.63Gets 152, as a side-effect of winning quick[2653] GB Pokémon: Red Version "Gotta Catch 'Em All!" by MrWint in 1:54:56.62Glitches are involved[3134] GB Pokémon: Blue and Red Version "Coop Diploma" by MrWint in 3:48:04.10Two games cooperate without glitches
If we're defining 100% as filling out that pokédex regardless of arbitrary corruption or code execution, then the first movie has already beaten this run, and is itself already obsoleted anyway as its primary goal is actually any%. The fact it has 152 shouldn't really matter as, rest assured, it has the other 151 necessary for the 100% criteria. Then again, if everyone agrees that level of corruption shouldn't count for 100%, then we can disregard the first one, and the goals set out in this submission may well be the closest possible practical definition for Vault 100%, while that first movie isn't.
Clearly, since the third movie I listed is glitchless, and does interesting routing stuff to get the 150 available without special one-time events or glitches, it is clearly out of the question to obsolete that with this movie. The goals are vastly different, giving a vastly different experience viewing either run.
This leaves the second movie, with a curious route and catches exactly 151, which the other movies either overshot with 152 or undershot with 150. If a movie is to become obsolete, the second listed movie would be the most likely candidate, although I'm not sure if it should.
If the goal is to fill out the 'dex with all 151 Pokémon, using the usual catching routine to do so, this submission broke apart the game and distilled the actions down to exactly that one function over and over again, bypassing even the usual combat entry to get to the function. It did not bypass the normal collection routines, just the normal sense of encountering stuff to then move on to the normal collection routines.
Just wanted to point out previous movies that have filled out the Pokédex, with three different methods.