Post subject: Yars' Revenge
hopper
Experienced Forum User
Hi folks. Inspired by donnaken15's Yars' Revenge submissions, I decided to study the game and possibly make my own run. I'll give him/her a chance to make a proper TAS of the game, and then I'm doing it mysef. I'm going to use this first post to keep track of what I've learned about the game, so it will see many edits. Please bear with me as I work on this, my first serious TAS. Movement Joystick input (directions, fire button) is checked every second frame. Whether this is the even or odd frames depends on what frame the level started on. Yar gets to move 4 pixels every 2 frames: 4x, 4y, or 2x+2y. Energy Missile (bullet) gets to move 4 pixels every frame: 4x, 4y, or 2x+2y. Difficulty B: Swirl gets to move 4 pixels per frame in 16 directions: 4x, 4y, 3x+1y, 3y+1x, or 2x+2y. Difficulty A: Swirl gets to move 6 pixels per frame (50% faster) Pressing opposite directions does nothing helpful. U+D = D L+R = D U+D+L = D U+D+R = L U+L+R = D D+L+R = D U+D+L+R = D Ghost of Yars There's an Easter Egg in Yars' Revenge. Wherever you kill the Qotile, there's a black vertical line on the screen during the explosion. Normally the Qotile is up against the right wall, so the line is too close to the edge of the screen for Yar to get on top of it; the Easter Egg is only available if you kill the Swirl while it's attacking. If the Yar is on that line, and in the bottom 1/3 of the screen, at the end of the explosion, the score lists as HSWWSH, which is the author's initials forwards and backwards. The downside to this is that it ends the game (for both players!), which could really tick you off if you were in a high scoring game. Therefore, the instruction manual says: "When you destroy the Qotile, or a Swirl, there will be an explosion, during which the Yar stays on the screen. Use this opportunity to make up your own victory dance. And watch out for the Ghost of Yars! You'll see his mean streak, so stay off it!" Why is it the Ghost of Yars and not the Ghost of the Qotile? I don't know. But it turns out that this Easter Egg is even Easter Eggier than Howard Scott Warshaw led on. When Yar is on the Ghost of Yars line, it collects 2 TRONs every second frame, and there's enough time to collect 218 TRONs! Your TRON count is never displayed during the game, so there was no way to know this before it became possible to watch the RAM while playing the game in an emulator. RAM addresses All numbers are hexadecimal unless otherwise stated. Well understood
 \$ Purpose Observed values 00 Game mode High nibble = game state Bit 8=Game Over Bit 7=Select screen Bit 6=Swirl triple frequency Bit 5=Swirl attacks twice Thus: 0 = Brown shield (0) 1 = Gray shield (150,000) 2 = Purple shield (70,000) 3 = Pink shield (230,000) 8 = Game over C = Game select/Easter Egg screen E for 1 frame when Game Select triggered on Game select screen. Low nibble = 0-7, matches game mode. 01-10 Qotile shield (active player) Binary representation of 8x16 shield. Rotating shield begins as all 1s. Solid shield begins as: ``````01 1111 0000 02 1111 1000 03 1111 1100 04 0111 1110 05 0011 1111 06 0001 1111 07 0000 1111 08 0000 1111 09 0000 1111 0A 0000 1111 0B 0001 1111 0C 0011 1111 0D 0111 1110 0E 1111 1100 0F 1111 1000 10 1111 0000`````` Addresses go from bottom to top (\$01 is bottom row) and right to left (Bit 8 is right-most pixel), so image is upside-down and backwards. 11 Neutral Zone status 00 = no Neutral Zone, FE = Neutral Zone 12 Destroyer Missile speed Starts at 04 in Game 0/1, 03 in Games 2-7. Decreases to 0, lower number is faster. 13 P1's turn 7C = yes, FE = no 14 Qotile status Bit 8: 1=Swirl active Bit 7: 1=Swirl traveling Bit 6: 1=Yar is firing Energy Missile (2 frames) Bit 5: 0=solid shield, 1=rotating shield Bit 5 remains when Qotile becomes Swirl, and Bit 8 remains when Swirl attacks. So, high nibble: 0 = Solid shield 1 = Rotating shield 2 = Solid shield and Yar is shooting 3 = Rotating shield and Yar is shooting 8 = Solid shield and Swirl 9 = Rotating shield and Swirl active A = Solid shield and Swirl active and Yar is shooting B = Rotating shield and Swirl active and Yar is shooting C = Solid shield and Swirl traveling D = Rotating shield and Swirl traveling E = Solid shield and Swirl traveling and Yar is shooting F = Rotating shield and Swirl traveling and Yar is shooting 4-7 are impossible because Bit 7 is never 1 without Bit 8=1. Lower nibble observed values are 0 and 9-F. Changes when Swirl attacks, unchanged when Qotile returns, and when Qotile becomes Swirl. Might have to do with attack frequency? 16 Zorlon Cannon status 04 = not loaded, 44 = loaded, 64 = in-flight 17 Yar status Bit 8=dying, Bit 7=imploding, Bit 6=exploding Bits remain set during each phase of death process. Thus: 00 = alive 80 = dying C0 = imploding E0 = exploding 1F Yar y 04-AE 20 Yar x 08-95 21 Unused Always 0 22 Yar movement 00 = Yar stationary, 03 = Yar moving 23 Yar appearance Changes every 3 frames if not moving, every frame if moving. Facing up, wings down = 8E, wings up = BB Facing down, wings down = 6A, wings up = 97 Facing left/right, wings down = 7C, wings up = A9 Facing up+left/right, wings down = 85, wings up = B2 Facing down+left/right: wings down = 73, wings up = A0 25 Energy Missile y 02-BE. Does not reset. 26 Energy Missile x 01-9F. Yar x+4 when not firing. 2A Qotile y Goes up and down from 36-74 when not attacking, changing 1 every 2 frames 2B Qotile x 96 when not attacking 2E Destroyer Missile y 0C-B6 2F Destroyer Missile x 0C-9A 39-3C Unused Always 0 47 Life count (x8) Life count for P1 in 1-player game, for P2 in 2-player game. Starts at 20 (4 lives). 18 = 3 lives, 28 = 5 lives, etc. 50 = 0 lives. 49-58 Qotile shield (inactive player) Binary representation of 8x16 shield for P1 on P2's turn, P2 on P1's turn. Not used in 1-player game. 5B P2's turn 7C = yes, FE = no 5D Background color 00 (black) during gameplay. Cycles through palette during attract screen 60-62 P1 score Each nibble is one digit of score. \$12 \$34 \$56 = 123456 63 P1 life count High nibble is life count, thus Lives * 10. High nibble is Game during Game select screen, thus Game * 10. 64-66 P2 score Each nibble is one digit of score. \$01 \$23 \$45 = 12345 67 P2 life count High nibble is life count, thus Lives * 10. Always 40 (4 lives) during 1-player game. 69 Game timer 00-FF, +1 every frame 70 TRONs 00-FF in all game modes 71 Easter egg can be revealed 00 = no, 01 = yes 73-7B Unused Always 0 282 (PIA) SWCHB (console switches) Bit 8 = Right/P2 difficult: (0=B, 1=A) Bit 7 = Left difficult (P1): (0=B, 1=A) Bits 5,4,2: Unused Bit 3 = Color/B&W toggle (0 = Black&White, 1=Color) Bit 1 = Game Select (0=pressed) Bit 0 = Game Reset (0=pressed)
Not well understood.
 \$ Purpose Observed values 15 ? 80,82,88,8A,C0,C2,C8,CA 1B ? Cycles from 07 to 00, -1 every frame 1C ? Goes up and down from F7-FF, by 1 every 16 frames. Spends 2 frames at F7, 22 frames at FF. 1D ? Always 09 35 Probably for audio Alternates between A0 and A4 (sometimes B0 and B4) every frame when not in Neutral Zone, E0 and E4 (sometimes F0 and F4) when in Neutral Zone, 20 when displaying score 3D-46,48 Unused? Repeating pattern. 3D,3F,41,43,45 = 50; 3E,40,42,44,46,48 = FE 68 Qotile color 34 = Swirl 7E Probably for video Alternates between 6B and FF during gameplay: 6B when Neutral Zone and Destroyer Missile display, FF when shield displays. 1B during score/lives display, 8A frame gameplay resumes. 7F ? Normally 00. Alternates between EF and F0 when Yar is dying. F6 frame before score/lives display.
Odd things observed
If you press Reset without pressing Select, game defaults to 2, not 0.
I mention \$282 because it shows us that, by default, BizHawk sets SWCHB to 3F (B difficulty for both players, Color). In Difficulty B, the Zorlon Cannon passes through the Destroyer Missile. In Difficulty A, the Zorlon Cannon destroys the Destroyer Missile (which reappears at the Qotile's location as soon as the Qotile is not in Swirl mode), and the Swirl moves much faster. To play this game at the "hardest" difficulty, Game 6 should be used with Difficulty A.
Whenever you destroy the Qotile in a solid shield level, whatever is left of the shield begins rotating through memory. 01-10/49-58 don't change to all 1s until the level begins, so you can watch the 0s and 1s dance for you in the memory viewer during the explosion and score/lives screen.
hopper
Experienced Forum User
I did a run-through of the first stage. I can select the A difficulty and Game 6 and start the game in 10 frames. When I did that, the Qotile became Swirl on frame 190, which is way more time than I needed to collect my 5 TRONs, so I used up the time taking out the lower half of the shield. Nothing I did during the level changed how long it took for the Qotile to become the Swirl, or for the Swirl to attack; it seems to be set before the level begins. The Qotile attacked on frame 389 which, again, was way more time than I needed to load the cannon, so I took out some of the upper half of the shield as I headed left, and got most of the rest of it while the Zorlon Cannon was crossing the screen. That ended the first round on frame 393 with a score of 11,206. I then tried adding random inputs for Player 1 and 2, and messed about with the difficulty switches, etc., to see if I could get the Qotile to change to the Swirl on a different frame, or attack on a different frame, to get an idea for how and when the random attack time is calculated, but nothing I did had any effect. I then tried taking an extra frame to start the game... and the Qotile turned Swirl on frame 191 and attacked on frame 390. Delaying starting the game by 2 frames caused the Qotile events to be delayed by 2 frames, 3 frames delayed 3 frames, etc. Also, no matter what I did on either joystick during the explosion, the Qotile attacks on the same frame in the second round. No luck yet figuring out how to affect the wait time.
donnaken15
He/Him
Experienced Forum User
The L/R difficulty switches don't seem to do anything. How about I livestream what it looks like and you can guide me on it.
hopper
Experienced Forum User
When difficulty is set to A, the Zorlon Cannon will destroy the Destroyer Missile if it hits it (instead of passing through it), and the Swirl will move much faster. Let my WIP play out and then do nothing. The Swirl will begin to attack on frame 1379. The Swirl will attack in a straight line, which usually means x decreases by 4 pixels per frame. The Qotile's x value will display: 96,90,8A,84,84,7E,78,72,6C,66,66,60,5A,54,4E,48,48,42,3C,36,30,2A,2A,24,1E,18,12,0C,0C,06,96 It visibly moves on every frame, but every 6th frame the value isn't updated in \$2A. If you toggle the L difficulty before frame 1379, the x value displays: 96,92,8E,8A,8A,86,82,7E,7A,76,76,72,6E,6A,66,62,62,5E,5A,56,52,4E,4E,4A,46,42,3E,3A,3A,36,32,2E,2A,26,26,22,1E,1A,16,12,12,0E,0A,06,02,96 It displays the same odd behavior where the x value doesn't change every 6 frames, despite moving visually, but now it finishes crossing the screen on frame 1424 instead of 1409. Difficulty B = 4 pixels/frame, Difficulty A = 6 pixels/frame (+50%). Incidentally, when I made my WIP, I had to make the Yar follow the Zorlon Cannon from above it instead of below it to prevent the Destroyer Missile tracking Yar downwards and crossing the Cannon's path, destroying it before it hit the Swirl.
feos
Experienced Forum User, Site Admin, Skilled player (1167)
I briefly looked at the code. Address \$68 gets explicitly checked against value 0x34, only then the guy turns into a swirl. It looks like some sort of a timer, and color is tied to it too. If you don't kill him right as he launches at you, he will remain in the 0x34 color while he flies, and only then he'll advance to next colors. If you kill him, he starts advancing to next colors right away, that way you shorten his swirl loop. hopper, can you make a proof of concept run beating a few levels, so I could objectively and fully evaluate the current submission when judging it? I don't want to simply reject it for beating too many waves, I'd like to understand the whole situation. With swirl not being random, what would be your estimates on the times? Also, when making a competitive run, you don't have to wait for your opponent. Just build your run, and add them as a co-author if they manage to beat you. You seem to be simply more of an expert at this game, and at the same time in tasing itself, so if you only give advices, the run won't be as optimal as if you participated.
hopper
Experienced Forum User
Yes, it says in the instructions that the color changing lets you know when the Qotile is about to change to Swirl, and I had already identified 0x34 as the attack color. So, you're saying that killing or not killing the Qotile/Swirl is the only thing that affected the time to the next attack? It will be disappointing if the timing isn't random. Based on not finding a way to alter the Swirl's attack time, I've been adding to the WIP that I posted. I'm too busy with exams right now to give you anything tonight. No need to reject the current run for having too many waves. Reject it for not being optimal. There are many waves where Yar kills the Qotile before it becomes the Swirl or before the Swirl attacks, taking 1000/2000 points for the kill instead of 6000. I doubt it would ever be faster to kill the Qotile right away than to wait for it to attack and sextuple the value of the kill, but I suppose it could be justified for a particularly long wait. Of course, the wait wouldn't be so long if it was Game 6. Also, through the use of TRONs (which can be collected during the time between waves), you can already have the Zorlon Cannon when you start the next level. So reject it for not using hardest difficulty, and for the fact that harder difficulty level would be faster! The strategy that I proposed works. If there's no randomness to manipulate, I can produce a publishable TAS to an appropriate score in a few hours. donnaiken can, too. One or the other of us will produce a much faster run than the one that's currently up for judgment.
feos
Experienced Forum User, Site Admin, Skilled player (1167)
Ugh, I edited the first sentence as you were replying. Check it out.
hopper
Experienced Forum User
For the record, setting B&W to TRUE has no effect on anything. The Qotile still changes to Swirl on frame 190, and attacks on frame 389.
donnaken15
He/Him
Experienced Forum User
why would setting the color to black and white do anything?