Vagrearg Logo  
Minimalistic 1D Pong
How little do you need for a game
An exercise in futility. That is what many would call this endeavor. How few elements (signifiers and affordances) do you need to not only recognize a game for what it is, but also are able to play it?

It turns out that you only need very little to do very much.
Figure 1: Complete minimalistic 1D Pong game (click to enlarge)
So, what do you need to make the 1D Pong game?
Input You need to have some input device. Buttons are some of the simplest of input devices that simply indicate "here you can press". For the adventurous, you simply press a button and see what happens. The conservative requires more information and needs to see a button in relation. The positioning of the buttons must direct you, in some fashion, that it is related to what is found around it. Placing the buttons next to an LED should signify that its function will relate to that LED.
Course What is the minimum of lights you need to hit from A to B? The absolute minimum could be two. However, that could cause confusion. For example, it may indicate that the light only belongs to the button. So, three would be a better option. Three would make a line, have symmetry and make bouncing more natural. However, the time it takes to get from A to B and the other way around would be really fast. The gameplay needs to have some temporal spacing for the player to adapt and react. Therefore, five lights would be a practical minimum to preserve symmetry and have good temporal separation.
Feedback Every system you operate requires some kind of feedback. Without it you'd never know whether or not something happened. There are already buttons. You know that you pressed one when it gives you the feel of being operated. Once you press, you also want to experience a response to your action. If you do not notice a response, then you probably pressed the wrong button. Responses can be visual or auditive. Note that a tactile response to a button does not say that the operation succeeded because it is associated only with the action of pressing the button, not the response to that action. An auditive feedback for the gameplay can be used to indicate that you hit or missed the ball. It also can indicate the movement of the ball. The movement of the ball is conveyed visually by the movement of lights on the line (it is the premise of the game). Feedback is guaranteed by using tactile buttons, a buzzer that can generate sound and the LEDs that blink in a specific order.

In summary, the required elements of the game are:
  • five LEDs
  • two tactile buttons
  • one buzzer
That means a total of 8 I/O pins on a microcontroller. That is too much! A design of minimalism should use a very small microcontroller and that is one having 6 or 8 physical pins. Subtracting two pins for the power supply leaves 4 or 6 I/O pins.
The LEDs can be arranged in a charlieplex, which gives n*(n-1) LEDs for n pins. Three pins allow for 6 LEDs. That would result in 6 I/O pins in total and could work. However, practical considerations, when looking at microcontrollers, will tell you that one pin is the reset-pin. Using the reset pin as input or output is possible, but is makes programming the device much harder. Therefore, we should reduce the pin-count to five I/Os. The buttons can be arranged to be read analog and the buttons are setup in a combined voltage divider way. That will make you read two buttons with one (analog) input.
Figure 2: Schematic diagram of minimalistic 1D Pong game (click for PDF version)

The system runs on two AAA batteries. There is enough juice in then to run an ATTiny85V for quite some time. The current consumption is limited to under 10 mA in full running mode. In power down mode it is in the tens µA range. All LEDs are high efficiency LEDs and are driven in a 1:6 ratio at about 3...4 mA peak. The charlieplex allows for one extra LED. A green LED is used to indicate when the player is allowed to hit back. This gives one more indication when the player must act beside sound.

The buttons are set up in a voltage divider way and can distinguish any or both buttons by measuring the voltage using the ADC. The voltage divider uses a relatively high driving impedance to the ADC, but that is of little consequence because the ADC resolution is high enough to distinguish buttons with rather large errors.

The buzzer is current limited by a series resistor just to reduce the volume level a bit. The positive side is that the batteries hold a tiny bit longer. On the other hand, the buzzer is actually on the wrong timer. It was intended to use OC1A, but PB0 has inverse OC1A, which cannot be used without also enabling OC1A on PB1. This is an oversight in the schematic symbol of KiCad, which should have indicated this. Instead, the buzzer is driven from OC0A, which is on PB0. The problem is that timer 1 uses nearly four times as much power as timer 0. The sound generation only needs the timer when there is sound, which can save average power consumption. The other timer is used for general timing in the application. Now, a more expensive timer has to be used for application timing.

The software is based on a simple event system and state machine model. Buttons and timers generate events and direct the way through the game's state machine.
Figure 3: Game state machine (click for SVG version)
The idle state reduces power consumption to an absolute minimum. The machine comes alive once a button is pressed and will go back to idle if nothing happens. Either button can be pressed to start a game and the one pressing will get to serve first. The state machine will be hovering between states Move and Bounce when both players keep on hitting at the right time.

A set of simple animations are implemented to indicate waiting for start of game (Start state), waiting to start the game (Init state) and a winning situation (Win state). These animation should support a visual queue of what is to happen next. Alternatively, you can always try pressing a button, but that only works for the adventurous.

A small video...

Posted: 2018-05-27
Updated: 2018-05-27

Overengineering @ request