Index  Comments

Both of ball breaker.chip8 and ball breaker.mmc are available under the CC0 Public Domain Dedication.

This is documentation for the Ball Breaker game of mine own writing. This was created in pursuit of a rather simple mechanism which could be used to demonstrate a compelling game, using a small space. This game has been written to later be improved for the Octo Jam VII event, as with those preceding.

Follows is the program upon being loaded into the MMC:

200-201 0512-0513 ▀▄█▄  █▄ A273 41587                 I ← from
202-203 0514-0515 ▀██▀▀█▀█ FF65 65381                 Load V0→VF; I ← I + 16
204-205 0516-0517 ▀▄█▄ ▄▀  A274 41588                 I ← paddle
206-207 0518-0519 ▀█ █ ▀ ▄ D451 54353                 Draw 08×01 at V4,V5; VF ← XOR
208-209 0520-0521 ▀▄█▄  █  A272 41586                 I ← blocks
20A-20B 0522-0523 ▀█▄▀▀█▀  DE64 56932            draw Draw 08×04 at VE,V6; VF ← XOR
20C-20D 0524-0525  ▀▀▀█▀▀  7E08 32264                 VE ← VE + 008
20E-20F 0526-0527  ▄▀▀▀▀▀  3E40 15936                 Skip next if VE = 064
210-211 0528-0529    ▀▄ █  120A 04618                 Jump to draw
212-213 0530-0531 ▀▀▄▄███▄ CE3F 52799                 VE ← ??? AND 063
214-215 0532-0533 ▀▄█▄▄▄▀▄ A27D 41597                 I ← ball
216-217 0534-0535 ▀▀▄█▀▀▀▄ DE31 56881                 Draw 08×01 at VE,V3; VF ← XOR
218-219 0536-0537 ▀▄█▄▄▄▀▄ A27D 41597           prime I ← ball
21A-21B 0538-0539 ▀▀▀█▀█ ▄ FC15 64533                 delay ← VC
21C-21D 0540-0541 ▀▀▄█▀▀▀▄ DE31 56881                 Draw 08×01 at VE,V3; VF ← XOR
21E-21F 0542-0543  ▀    ▀  4200 16896                 Skip next if V2 <> 000
220-221 0544-0545   ▄▀▄ ▀  1228 04648                 Jump to continue
222-223 0546-0547 ▀▀▄█▀▀▀▄ DE31 56881                 Draw 08×01 at VE,V3; VF ← XOR
224-225 0548-0549 ▀   ▀ ▄█ 8903 35075                 V9 ← V9 XOR V0
226-227 0550-0551  ▀▀▀▀  █ 7901 30977                 V9 ← V9 + 001
228-229 0552-0553  ▀  ▀▀▀  4E00 19968        continue Skip next if VE <> 000
22A-22B 0554-0555  ▀▀ ▀  ▄ 6801 26625                 V8 ← 001
22C-22D 0556-0557  ▀▄▄███▄ 4E3F 20031                 Skip next if VE <> 063
22E-22F 0558-0559 ▄██▄█▄▄▄ 68FF 26879                 V8 ← 255
230-231 0560-0561  ▀    ▀▀ 4300 17152                 Skip next if V3 <> 000
232-233 0562-0563  ▀▀ ▀  █ 6901 26881                 V9 ← 001
234-235 0564-0565  ▀ ▄▄▄██ 431F 17183                 Skip next if V3 <> 031
236-237 0566-0567   ▄█ ▄█  1236 04662            self Jump to self
238-239 0568-0569 █   ▀█▀  8E84 36484                 VE ← VE + V8; VF ← overflow
23A-23B 0570-0571 █  ▄ ▄▀▀ 8394 33684                 V3 ← V3 + V9; VF ← overflow
23C-23D 0572-0573 ▀▀▄█▀▀▀▄ DE31 56881                 Draw 08×01 at VE,V3; VF ← XOR
23E-23F 0574-0575 █▄▄▄  ▀  82F0 33520                 V2 ← VF
240-241 0576-0577  ▀ ▄▄▄█▀ 431E 17182                 Skip next if V3 <> 030
242-243 0578-0579 ▀ ▄ ▀▄▀▄ 8A25 35365                 VA ← VA − V2; VF ← borrow
244-245 0580-0581  ▀ ▄▄▄█▀ 431E 17182                 Skip next if V3 <> 030
246-247 0582-0583 ▀▀▄█▀▀▀▄ DE31 56881                 Draw 08×01 at VE,V3; VF ← XOR
248-249 0584-0585  ▀ ▄▄▄█▀ 431E 17182                 Skip next if V3 <> 030
24A-24B 0586-0587 ▀ ▄ ▀▀█▄ 8E23 36387                 VE ← VE XOR V2
24C-24D 0588-0589 ▀ ▄ ▀▄▀  8A24 35364                 VA ← VA + V2; VF ← overflow
24E-24F 0590-0591 ▀▄█▄ ▄▀  A274 41588                 I ← paddle
250-251 0592-0593 ▀█ █ ▀ ▄ D451 54353           delay Draw 08×01 at V4,V5; VF ← XOR
252-253 0594-0595 █▀▀▄▄██  E69E 59038            left Skip next if V6 = key
254-255 0596-0597  ▄ █▄ █  125A 04698                 Jump to right
256-257 0598-0599   ▀▀ ▀   3400 13312                 Skip next if V4 = 000
258-259 0600-0601 ▄███▄█▄  74FE 29950                 V4 ← V4 + 254
25A-25B 0602-0603 █▀▀▄▄██▀ E79E 59294           right Skip next if V7 = key
25C-25D 0604-0605  ▄▄▀  █  1262 04706                 Jump to move
25E-25F 0606-0607   ██▄▀   3438 13368                 Skip next if V4 = 056
260-261 0608-0609  ▀▀▀ ▀▄  7402 29698                 V4 ← V4 + 002
262-263 0610-0611 ▀█ █ ▀ ▄ D451 54353            move Draw 08×01 at V4,V5; VF ← XOR
264-265 0612-0613 ▀▀▀▀▀███ FF07 65287                 VF ← delay
266-267 0614-0615   ▀▀▀▀▀▀ 3F00 16128                 Skip next if VF = 000
268-269 0616-0617  ▄ █  ▀  1250 04688                 Jump to delay
26A-26B 0618-0619 ▄▀▄█▀ ▀  5AB0 23216                 Skip next if VA = VB
26C-26D 0620-0621    █▄ ▀  1218 04632                 Jump to prime
26E-26F 0622-0623 ▄▄▄      00E0 00224                 Clear the screen
270-271 0624-0625    ▀  ▀  1200 04608                 Jump to 0512
272     0626      ████████   FF   255          blocks
273     0627      ████████   FF   255            from
274     0628      ████████   FF   255          paddle
275     0629                 00   000
276     0630          █ █    0A   010
277     0631         ███     1C   028
278     0632         ████    1E   030
279     0633           █     04   004
27A     0634           ██    06   006
27B     0635             █   01   001
27C     0636             █   01   001
27D     0637      █          80   128            ball
27E     0638       █         40   064
280     0640           █ █   05   005
281     0641                 00   000

The register usage is as follows:

  1. V0 Hold a constant.
  2. V1 Unused.
  3. V2 Store the collision datum, which is also used as a mask.
  4. V3 Store the vertical ball coordinate.
  5. V4 Store the horizontal paddle coordinate.
  6. V5 Store the vertical paddle coordinate.
  7. V6 Store the left key constant and the field vertical coordinate.
  8. V7 Store the right key constant.
  9. V8 Store the ball horizontal delta.
  10. V9 Store the ball vertical delta.
  11. VA Store the relative collision count and ball sprite.
  12. VB Store the relative collision maximum.
  13. VC Store the delay.
  14. VD Unused.
  15. VE Store the horizontal ball and field coordinate.
  16. VF Hold the collision datum; manipulate the delay register.

It's appropriate to explain the history of these games I've authored. This game was created from my desire to create very small and simple games from very basic instruction sequences. I realized mere conditional redrawing was sufficient to implement block erasure for a ball breaker game. While that code surrounding this is more complex, the core of the game is still very simple. Later, I realized the simplest method available for checking if the field is clear, knowing that total and counting in sync with its destruction. This implementation makes the counting unconditional, but requires a one be used for collision indication; this also has the caveat that the ball must destroy one-at-a-time.

The registers were chosen for the following reasons:

  1. V0 Ease of access and happenstance.
  2. V1 Unused.
  3. V2 Ease of access.
  4. V3 Ease of access.
  5. V4 Ease of access.
  6. V5 Ease of access.
  7. V6 Ease of access.
  8. V7 Ease of access.
  9. V8 Ease of access.
  10. V9 Ease of access.
  11. VA Ease of access.
  12. VB Ease of access.
  13. VC Ease of access.
  14. VD Unused.
  15. VE Distance from other registers.
  16. VF Unimportance and by its necessity.

The game begins by initializing all registers to their initial states, and then drawing that paddle:

200-201 0512-0513 ▀▄█▄  █▄ A273 41587                 I ← from
202-203 0514-0515 ▀██▀▀█▀█ FF65 65381                 Load V0→VF; I ← I + 16
204-205 0516-0517 ▀▄█▄ ▄▀  A274 41588                 I ← paddle
206-207 0518-0519 ▀█ █ ▀ ▄ D451 54353                 Draw 08×01 at V4,V5; VF ← XOR

The game then draws that field of blocks using a simple loop. Originally, this was intended to be a four-by-sixty-four field, but this introduced a one-off problem with the game finishing calculation, and I ultimately found it simpler to reduce size than to organize the game to begin with a breaking:

208-209 0520-0521 ▀▄█▄  █  A272 41586                 I ← blocks
20A-20B 0522-0523 ▀█▄▀▀█▀  DE64 56932            draw Draw 08×04 at VE,V6; VF ← XOR
20C-20D 0524-0525  ▀▀▀█▀▀  7E08 32264                 VE ← VE + 008
20E-20F 0526-0527  ▄▀▀▀▀▀  3E40 15936                 Skip next if VE = 064
210-211 0528-0529    ▀▄ █  120A 04618                 Jump to draw

The ball is initialized to a random horizontal coordinate and wastefully drawn before the prime loop is entered. The prime loop sets the delay, wastefully draws the ball, and wastefully undraws it, if register two indicates a collision occurred. The latter two instructions take advantage of the bits in register zero to flip register nine between positive and negative one upon a collision. The idea of the game came about from the realization leading to this block, although not as nice as I prefer:

212-213 0530-0531 ▀▀▄▄███▄ CE3F 52799                 VE ← ??? AND 063
214-215 0532-0533 ▀▄█▄▄▄▀▄ A27D 41597                 I ← ball
216-217 0534-0535 ▀▀▄█▀▀▀▄ DE31 56881                 Draw 08×01 at VE,V3; VF ← XOR
218-219 0536-0537 ▀▄█▄▄▄▀▄ A27D 41597           prime I ← ball
21A-21B 0538-0539 ▀▀▀█▀█ ▄ FC15 64533                 delay ← VC
21C-21D 0540-0541 ▀▀▄█▀▀▀▄ DE31 56881                 Draw 08×01 at VE,V3; VF ← XOR
21E-21F 0542-0543  ▀    ▀  4200 16896                 Skip next if V2 <> 000
220-221 0544-0545   ▄▀▄ ▀  1228 04648                 Jump to continue
222-223 0546-0547 ▀▀▄█▀▀▀▄ DE31 56881                 Draw 08×01 at VE,V3; VF ← XOR
224-225 0548-0549 ▀   ▀ ▄█ 8903 35075                 V9 ← V9 XOR V0
226-227 0550-0551  ▀▀▀▀  █ 7901 30977                 V9 ← V9 + 001

This block manages the bounds of the game; if the ball hits the bottom of the screen, the game ends:

228-229 0552-0553  ▀  ▀▀▀  4E00 19968        continue Skip next if VE <> 000
22A-22B 0554-0555  ▀▀ ▀  ▄ 6801 26625                 V8 ← 001
22C-22D 0556-0557  ▀▄▄███▄ 4E3F 20031                 Skip next if VE <> 063
22E-22F 0558-0559 ▄██▄█▄▄▄ 68FF 26879                 V8 ← 255
230-231 0560-0561  ▀    ▀▀ 4300 17152                 Skip next if V3 <> 000
232-233 0562-0563  ▀▀ ▀  █ 6901 26881                 V9 ← 001
234-235 0564-0565  ▀ ▄▄▄██ 431F 17183                 Skip next if V3 <> 031
236-237 0566-0567   ▄█ ▄█  1236 04662            self Jump to self

The game then adds the deltas, and redraws the ball. The collision information is saved in register two, to be unconditionally added to the hit count, with a compensating subtraction for the case when the paddle is hit, using this to determine when the field is clear. Collisions must be zero or one. As a late change, collision with the paddle is wastefully determined thrice to also redraw the ball, and so avoid display errors, and also potentially shifts it by one, to prevent ball journey looping:

238-239 0568-0569 █   ▀█▀  8E84 36484                 VE ← VE + V8; VF ← overflow
23A-23B 0570-0571 █  ▄ ▄▀▀ 8394 33684                 V3 ← V3 + V9; VF ← overflow
23C-23D 0572-0573 ▀▀▄█▀▀▀▄ DE31 56881                 Draw 08×01 at VE,V3; VF ← XOR
23E-23F 0574-0575 █▄▄▄  ▀  82F0 33520                 V2 ← VF
240-241 0576-0577  ▀ ▄▄▄█▀ 431E 17182                 Skip next if V3 <> 030
242-243 0578-0579 ▀ ▄ ▀▄▀▄ 8A25 35365                 VA ← VA − V2; VF ← borrow
244-245 0580-0581  ▀ ▄▄▄█▀ 431E 17182                 Skip next if V3 <> 030
246-247 0582-0583 ▀▀▄█▀▀▀▄ DE31 56881                 Draw 08×01 at VE,V3; VF ← XOR
248-249 0584-0585  ▀ ▄▄▄█▀ 431E 17182                 Skip next if V3 <> 030
24A-24B 0586-0587 ▀ ▄ ▀▀█▄ 8E23 36387                 VE ← VE XOR V2
24C-24D 0588-0589 ▀ ▄ ▀▄▀  8A24 35364                 VA ← VA + V2; VF ← overflow

The paddle is erased, and a delta is collected whilst the remaining delay is exhausted; importantly, the paddle is bounds checked before that delta is changed. A faster paddle makes for a better game:

24E-24F 0590-0591 ▀▄█▄ ▄▀  A274 41588                 I ← paddle
250-251 0592-0593 ▀█ █ ▀ ▄ D451 54353           delay Draw 08×01 at V4,V5; VF ← XOR
252-253 0594-0595 █▀▀▄▄██  E69E 59038            left Skip next if V6 = key
254-255 0596-0597  ▄ █▄ █  125A 04698                 Jump to right
256-257 0598-0599   ▀▀ ▀   3400 13312                 Skip next if V4 = 000
258-259 0600-0601 ▄███▄█▄  74FE 29950                 V4 ← V4 + 254
25A-25B 0602-0603 █▀▀▄▄██▀ E79E 59294           right Skip next if V7 = key
25C-25D 0604-0605  ▄▄▀  █  1262 04706                 Jump to move
25E-25F 0606-0607   ██▄▀   3438 13368                 Skip next if V4 = 056
260-261 0608-0609  ▀▀▀ ▀▄  7402 29698                 V4 ← V4 + 002
262-263 0610-0611 ▀█ █ ▀ ▄ D451 54353            move Draw 08×01 at V4,V5; VF ← XOR
264-265 0612-0613 ▀▀▀▀▀███ FF07 65287                 VF ← delay
266-267 0614-0615   ▀▀▀▀▀▀ 3F00 16128                 Skip next if VF = 000
268-269 0616-0617  ▄ █  ▀  1250 04688                 Jump to delay

The program compares the aligned count of struck blocks to a counter relatively aligned to the total amount, and when they're equal the condition is equivalent to determining whether the field be empty or not. If so, the screen is cleared and the game returns to the beginning, to repeat indefinitely. There were originally four rows, but this aligned perfectly with the value for register rollover; it was far too difficult to avoid this, by adjusting the ball to strick a block before that comparison:

26A-26B 0618-0619 ▄▀▄█▀ ▀  5AB0 23216                 Skip next if VA = VB
26C-26D 0620-0621    █▄ ▀  1218 04632                 Jump to prime
26E-26F 0622-0623 ▄▄▄      00E0 00224                 Clear the screen
270-271 0624-0625    ▀  ▀  1200 04608                 Jump to 0512

The game is terminated by the sprites for the blocks and paddle, interleaved with register initials:

272     0626      ████████   FF   255          blocks
273     0627      ████████   FF   255            from
274     0628      ████████   FF   255          paddle
275     0629                 00   000
276     0630          █ █    0A   010
277     0631         ███     1C   028
278     0632         ████    1E   030
279     0633           █     04   004
27A     0634           ██    06   006
27B     0635             █   01   001
27C     0636             █   01   001
27D     0637      █          80   128            ball
27E     0638       █         40   064
280     0640           █ █   05   005
281     0641                 00   000

I've successfully crafted another small game to elaborate in that Octo Jam VII with this. This game contains minor inefficiencies I'll correct, and could be made more elaborate. Currently, the paddle merely prevents the ball from falling, but has no true control, which can be easily fixed; it's much easier to test two simple predicates than one slightly more complex, which is why the paddle lies on that penultimate row, but better ball control will combine with better paddle detection, eliminating code and also allowing it to lie on that final row. In sum, it's nice for this simple game to work.