Joined: 11/15/2004
Posts: 804
Location: Canada
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
$PurposeObserved values
00Game modeHigh 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-10Qotile 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.
11Neutral Zone status00 = no Neutral Zone, FE = Neutral Zone
12Destroyer Missile speedStarts at 04 in Game 0/1, 03 in Games 2-7. Decreases to 0, lower number is faster.
13P1's turn7C = yes, FE = no
14Qotile statusBit 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?
16Zorlon Cannon status04 = not loaded, 44 = loaded, 64 = in-flight
17Yar statusBit 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
1FYar y04-AE
20Yar x08-95
21UnusedAlways 0
22Yar movement00 = Yar stationary, 03 = Yar moving
23Yar appearanceChanges 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
25Energy Missile y02-BE. Does not reset.
26Energy Missile x01-9F. Yar x+4 when not firing.
2AQotile yGoes up and down from 36-74 when not attacking, changing 1 every 2 frames
2BQotile x96 when not attacking
2EDestroyer Missile y0C-B6
2FDestroyer Missile x0C-9A
39-3CUnusedAlways 0
47Life 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-58Qotile 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.
5BP2's turn7C = yes, FE = no
5DBackground color00 (black) during gameplay. Cycles through palette during attract screen
60-62P1 scoreEach nibble is one digit of score. $12 $34 $56 = 123456
63P1 life countHigh nibble is life count, thus Lives * 10. High nibble is Game during Game select screen, thus Game * 10.
64-66P2 scoreEach nibble is one digit of score. $01 $23 $45 = 12345
67P2 life countHigh nibble is life count, thus Lives * 10. Always 40 (4 lives) during 1-player game.
69Game timer00-FF, +1 every frame
70TRONs00-FF in all game modes
71Easter egg can be revealed00 = no, 01 = yes
73-7BUnusedAlways 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.
$PurposeObserved 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
35Probably for audioAlternates 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,48Unused?Repeating pattern. 3D,3F,41,43,45 = 50; 3E,40,42,44,46,48 = FE
68Qotile color34 = Swirl
7EProbably for videoAlternates 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.
TASing or playing back a DOS game? Make sure your files match the archive at RGB Classic Games.
Joined: 11/15/2004
Posts: 804
Location: Canada
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.
TASing or playing back a DOS game? Make sure your files match the archive at RGB Classic Games.
donnaken15
He/Him
Joined: 1/8/2017
Posts: 28
Location: Us
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.
- Wesley
Joined: 11/15/2004
Posts: 804
Location: Canada
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.
TASing or playing back a DOS game? Make sure your files match the archive at RGB Classic Games.
Site Admin, Skilled player (1256)
Joined: 4/17/2010
Posts: 11495
Location: Lake Char­gogg­a­gogg­man­chaugg­a­gogg­chau­bun­a­gung­a­maugg
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.
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
Joined: 11/15/2004
Posts: 804
Location: Canada
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.
TASing or playing back a DOS game? Make sure your files match the archive at RGB Classic Games.
Site Admin, Skilled player (1256)
Joined: 4/17/2010
Posts: 11495
Location: Lake Char­gogg­a­gogg­man­chaugg­a­gogg­chau­bun­a­gung­a­maugg
Ugh, I edited the first sentence as you were replying. Check it out.
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
Joined: 11/15/2004
Posts: 804
Location: Canada
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.
TASing or playing back a DOS game? Make sure your files match the archive at RGB Classic Games.
donnaken15
He/Him
Joined: 1/8/2017
Posts: 28
Location: Us
hopper wrote:
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.
why would setting the color to black and white do anything?
- Wesley