← All articles

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:

BytesWhat they hold
3Where the award's test is (an address and which 16 KB page of the ROM it is on)
1A flag byte (only one award uses it; what for is not known)
1The base weight: how many tickets the award gets
3Where 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:

AwardTicketsAwardTickets
25,000,00051 MARTIAN BOMB5
50,000,0005SNEAK ATTACK5
+5 BONUS X10START ATTACK WAVE15
HOLD BONUS X10LIGHT EXTRA BALL5
LIGHT LOCK10STROBE MULTIBALL0
AWARD LOCK10VIDEO MODE0
MULTIBALL10
LITE MARTIAN ATTACK10

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:

Tickets on the first Stroke of Luck A bar of 36 tickets split between four awards: 50,000,000 has 1 (2.8 percent), Light Lock 10 (27.8), Lite Martian Attack 10 (27.8) and Start Attack Wave 15 (41.7). Ten other awards have no tickets and cannot be won on this collect. TICKETS ON THE FIRST COLLECT 10 10 15 0 36 50,000,000 1 (2.8%) LIGHT LOCK 10 (27.8%) LITE MARTIAN ATTACK 10 (27.8%) START ATTACK WAVE 15 (41.7%) NO TICKETS, CANNOT BE WON THIS TIME 25,000,000 +5 BONUS X HOLD BONUS X AWARD LOCK MULTIBALL 1 MARTIAN BOMB SNEAK ATTACK LIGHT EXTRA BALL STROBE MULTIBALL VIDEO MODE A random draw from 0 to 35 lands in one segment.
The first Stroke of Luck of a game, on ball 1: 36 tickets shared by four awards, and ten awards with none.

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:

  1. 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.
  2. If the real award is not among the four, overwrite one of them, at a random position, with the real award.
  3. Write down the order in which the four will disappear, 1-2-3-4, and shuffle it with ten random swaps.
  4. 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.

What happens after the ball lands Eight steps. The game runs each award's test, then draws the award, which is stored 15 to 20 frames after the ball lands. Only then does the show pick four of the fourteen awards ignoring tickets, put the winner in if it is missing, shuffle the order they vanish in, swap the winner to the end, and remove the other three. On one first collect Multiball and Hold Bonus X, which had no tickets, went first, then Light Lock, leaving Lite Martian Attack. Ball lands in the right eject frame 0 Run each award's test, count tickets Draw a number, count along: award chosen stored 15-20 frames in Pick 4 of all 14 awards, ignoring tickets Winner missing? Overwrite a random slot Shuffle the order they vanish in 10 random swaps Swap the winner's slot to the end Remove the other three, one at a time pausing between each DECIDED THE SHOW ONE FIRST COLLECT, BALL 1 MULTIBALL out 1st HOLD BONUS X out 2nd LIGHT LOCK out 3rd LITE MARTIAN ATTACK stays Red: no tickets, could not have been won.
What happens after the ball lands: the award is decided first, then the four-item list is built and rigged around it.

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.

CollectAwards with ticketsAwardFour shownShown but had no tickets
1st50M (1), LIGHT LOCK, LITE MARTIAN ATTACK (10 each), START ATTACK WAVE (15)LITE MARTIAN ATTACKLITE MARTIAN ATTACK, MULTIBALL, LIGHT LOCK, HOLD BONUS XMULTIBALL, HOLD BONUS X
2ndsix awards+5 BONUS XVIDEO MODE, 1 MARTIAN BOMB, +5 BONUS X, LIGHT LOCKVIDEO MODE
3rdSTROBE MULTIBALL at 100STROBE MULTIBALLSTART ATTACK WAVE, STROBE MULTIBALL, LITE MARTIAN ATTACK, LIGHT LOCKLITE MARTIAN ATTACK
1st, another gamethe same four as the first rowLIGHT LOCKLIGHT EXTRA BALL, LIGHT LOCK, +5 BONUS X, 50,000,000LIGHT 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.cpp at 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.