Attack From Mars Picks Your Stroke of Luck Before the Show
Roll over all four lanes at the bottom of an Attack From Mars playfield and the right eject lights for Stroke of Luck. Shoot the ball in and the display puts up four prizes: say LIGHT EXTRA BALL, LIGHT LOCK, +5 BONUS X and 50,000,000. One by one they blink away until a single prize is left, here LIGHT LOCK. It looks like a draw happening in front of you.
It is not. By the time the first name appears, the program already knows the answer. Two of the four names on that screen could not have been won at all. This article goes through how the 1995 program was written to do this, from the table that holds the odds to the short routine that rigs the countdown.
One table runs the whole feature
The programmers did not write fourteen awards as fourteen pieces of special code strung together with "if" tests. They wrote one table, with one row per award, eight bytes each:
| Bytes | What they hold |
|---|---|
| 3 | Where the award's test is (an address and which 16 KB page of the ROM it is on) |
| 1 | A flag byte (only one award uses it; what for is not known) |
| 1 | The base weight: how many tickets the award gets |
| 3 | Where the code that gives the award is |
The "test" is a small routine that answers one question: how many tickets does this award get right now? Most return the base weight unchanged when the award makes sense and 0 when it does not. HOLD BONUS X returns 0 on the last ball, since there is no next ball to hold it for. LIGHT EXTRA BALL returns 0 on ball 1. A few raise their number: 1 MARTIAN BOMB jumps from 5 to 15 tickets in one situation.
Here is the table as the ROM has it, before any test runs:
| Award | Tickets | Award | Tickets |
|---|---|---|---|
| 25,000,000 | 5 | 1 MARTIAN BOMB | 5 |
| 50,000,000 | 5 | SNEAK ATTACK | 5 |
| +5 BONUS X | 10 | START ATTACK WAVE | 15 |
| HOLD BONUS X | 10 | LIGHT EXTRA BALL | 5 |
| LIGHT LOCK | 10 | STROBE MULTIBALL | 0 |
| AWARD LOCK | 10 | VIDEO MODE | 0 |
| MULTIBALL | 10 | ||
| LITE MARTIAN ATTACK | 10 |
The names are in a separate list in the same order, so "award 11" means the same thing to the code that picks, the code that pays out and the code that draws the screen. Adding an award, or changing its odds, is a matter of changing one row.
The pick: about a quarter of a second
When the ball drops into the right eject, the program walks the table. For each row it runs the test and writes the answer into a row of fourteen bytes in memory. Then it does three things.
First, it looks for any award with 100 tickets or more. That is the programmers' way of saying "must": the first one found wins and nothing random happens. STROBE MULTIBALL and VIDEO MODE have no tickets of their own, and only ever appear through this door. The third Stroke of Luck of a game gave STROBE MULTIBALL 100 tickets, and STROBE MULTIBALL was the award chosen.
Otherwise it adds up all the tickets, draws a random number from 0 up to that total, and counts along the row until it passes the number:
ldb a,x ; this award's tickets
beq next ; none: it can never be landed on
lda #0
addd total,s ; running total plus this award's tickets
cmpd draw,s ; past the random number yet?
bhi found ; yes: this is the award
std total,s ; no: keep counting
It is the same as giving each award a stack of raffle tickets and pulling one out. On a player's first Stroke of Luck, on ball 1, only four awards had any tickets:
The result is stored in one byte of memory, 15 to 20 frames after the ball lands (about a quarter of a second, across seven collects), before anything about the award has appeared on the display.
The show is built around the answer
Only then does a second piece of code, on another page of the ROM, put on the show. It runs as a separate little task, so the rest of the game keeps going, and it pauses between steps. It is handed the award, and does this:
- Pick four different awards out of all fourteen at random. It does not look at the tickets, so an award that had none is as likely to be chosen as any other.
- If the real award is not among the four, overwrite one of them, at a random position, with the real award.
- Write down the order in which the four will disappear, 1-2-3-4, and shuffle it with ten random swaps.
- Find the real award in that order and swap it to the end.
Step 4 is the whole trick, and it is six instructions long:
leax 5,s ; the disappearing order, four entries
leax a,x ; the entry that holds the winner
leay 8,s ; the last entry
lda ,y ; swap them, so the winner goes last
sta ,x
stb ,y
Then the task removes the other three, one at a time, pausing between each. Whatever is left is always the award chosen a moment earlier.
For step 1 the programmers used a neat textbook method. Instead of picking four numbers and throwing away repeats, it goes through the awards from 14 down to 1 once, and takes each with the chance "how many I still need, out of how many are left". It always ends with exactly four, never picks one twice, and needs no memory beyond a few counters.
Where the random numbers come from
Every one of these draws goes through one small routine. It keeps two bytes that behave like a row of sixteen lights: each call shifts them along by one, and the new light coming in at the top is worked out from two of the others. A third byte mixes the result: the previous answer times three, plus a constant, plus both of the first two bytes.
lda $170D ; low byte of the sixteen
lsra ; slide it three places...
lsra
lsra
eora $170D ; ...and combine with itself
lsra ; the new top light falls out here
ror $170E ; shift all sixteen along by one
ror $170D
The numbers only move when something asks for one. The program asks often: there are dozens of places that call this routine across the game. Once at power-up it also adds the machine's real-time clock into the three bytes. And because they live in battery-backed memory, the sequence picks up where it left off every time the machine is switched on: the first number drawn at power-up follows exactly from the bytes saved the last time.
So for a player, the outcome depends on everything the machine has asked for since it was last switched on, and is not something anyone can time or predict. A model of the routine drawing 400,000 picks from the first collect's tickets landed within half a percentage point of the ticket shares. The luck is real. It is just that the odds are set by the table, not by the countdown on the screen.
The extra ball rate tunes itself
One row of the table is different. LIGHT EXTRA BALL does not use its base weight. On ball 1 it gets nothing, and a player who has already had one from Stroke of Luck gets a single ticket. Otherwise it gets a number kept in battery-backed memory, between 1 and 10, that starts at 5. A collect on ball 3 gave it exactly that 5.
Read from the program (this part was not run under test), that number moves. Once per game (exactly when was not traced) the program adds the number of players to one count and the extra balls lit that game to another. When the first count reaches 100, it compares the second with the operator's Extra Ball Percent setting. Four or more too many, and the extra ball loses a ticket; four or more too few, and it gains one. Then both counts start again. The operations manual for the 2017 remake describes the same thing from the operator's side: the game adjusts the Stroke of Luck extra ball to hit the requested percentage, or leaves it alone when the setting is FIXED.
So the machine keeps its own books, and quietly nudges the odds on one prize every hundred player-games.
How this was tested
Every number in this article comes from the original 1.1 program running under test in MAME, with blank stand-ins for the sound ROMs and a script in place of the ball: it fed the trough, pressed the launch button, rolled over the four lanes, dropped the ball into the right eject and moved the bank of Martian targets when the game asked. (Without that last part, the game does not kick the ball back out of the eject.) The row of tickets and the award byte were recorded as they were written, and the four-item list was read just after it was built.
| Collect | Awards with tickets | Award | Four shown | Shown but had no tickets |
|---|---|---|---|---|
| 1st | 50M (1), LIGHT LOCK, LITE MARTIAN ATTACK (10 each), START ATTACK WAVE (15) | LITE MARTIAN ATTACK | LITE MARTIAN ATTACK, MULTIBALL, LIGHT LOCK, HOLD BONUS X | MULTIBALL, HOLD BONUS X |
| 2nd | six awards | +5 BONUS X | VIDEO MODE, 1 MARTIAN BOMB, +5 BONUS X, LIGHT LOCK | VIDEO MODE |
| 3rd | STROBE MULTIBALL at 100 | STROBE MULTIBALL | START ATTACK WAVE, STROBE MULTIBALL, LITE MARTIAN ATTACK, LIGHT LOCK | LITE MARTIAN ATTACK |
| 1st, another game | the same four as the first row | LIGHT LOCK | LIGHT EXTRA BALL, LIGHT LOCK, +5 BONUS X, 50,000,000 | LIGHT EXTRA BALL, +5 BONUS X |
In every case the real award was last in the disappearing order. For the last row the display was also captured: it listed those four names in that order and finished on LIGHT LOCK, the award stored a quarter of a second after the ball landed.
What is still open
The ROM's list of operator settings includes "RANDOM SEED", and the 2017 manual says it sets the starting value of the random number generator. No code that writes the generator's bytes reads it, so how it is used in the 1995 program is not yet known. The flag byte in the table, the exact moment the extra ball count is updated, and the conditions inside several award tests are also still to be read.
Credits and further reading
- Chicago Gaming Company, Attack From Mars Operations Manual, Rev 1.5, for the 2017 remake: the Stroke of Luck rules (PDF pages 15-17) and the Extra Ball Percent setting (PDF page 68). It describes the remake's software; it was used only where the same feature appears in the 1995 ROM.
- Bally, Attack From Mars Operator Handbook, for the lamp and switch lists.
- The MAME team, the WPC-95 driver
wpc_95.cppat MAME 0.289, for the machine's memory map, switch and output names. The driver credits the PinMAME developers for their research. - The full notes behind this article, with addresses: Stroke of Luck in this lab.