Spaceteam was originally an awesome mobile game that our team adapted to the real world. Spaceteam is a multiplayer, collaborative game. Each player mans a spaceship console with a variety of buttons, switches, and other features.
When a level starts, all the name screens get updated, and commands appear on the command screens. To complete commands, the team needs move a specific feature in a specific way - before the time runs out. When a command is completed, your spaceship on the central display moves closer to to victory. Should a command fail, your spaceship moves closer to destruction. In either case, a new command is generated. The features that commands apply to may be on your console, or they may be on one of your spaceteammates consoles, in which case you need to communicate the command to them. There may be commands that the whole spaceteam has to complete in unison. As your spaceteam advances levels, time constraints get tighter, and communication between spaceteammates becomes more challenging.
In adapting spaceteam the mobile game to spaceteam the arcade game, we had to make some tradeoffs.
For budget reasons, we decided to build three consoles instead of four.
Given the project timeline and budget, we decided that there would be no powered actuators. No motors, no pneumatics, no solenoid valves. All the haptic feedback would have to be passive and the confusion inherent in the game would come from changing the actuator labels.
He is the master of destroying curiosity by promptly googling things. He is not a car.
Just because you are unique does not mean you are useful
- Demotivational poster
He inverts things with astonishing skill, leaving the bewildered objects no doubt about who is boss. Like all good Idahoans, he gets his strength from potatoes.
Shoot for the moon, and if you miss, you will land among the stars
- Motivational poster
He impresses others with his abilty to eat anything. Except his pet plant, who is named Stephan.
Live. Love. Butter.
- The Mouton clan
He is renowed for his ability to never wear shoes, even in the winter. He was once headbutted by a cow.
Nitwit, Blubber, Oddment, Tweet.
She has the uncanny ablilty to turn even the most unforgiving objects into soft blanket nests. She once dreamed of becoming a dinosaur.
Destruction, after all, is a form of creation.
- Graham Greene
Gameplay takes place at the three unique command consoles, each with their own screens, lights, and features.
One of the best part of spaceteam are the non-sensical actuator labels, and the chaos that ensues when those labels become hard to read. The actuators are each labeled by half of a 16x2 character LCD screen. The actual screens came from a variety of vendors, but they are all controlled by HD44780 type controllers. These controllers have a custom 9 pin interface that allows the microcontroller to send text to the display. We did not have that many pins to spare, so we attached I2C I/O expanders, based around the PCF8574, to the screens. This allowed all the label screens to be on one bus.
In order to augment our gameplay experience, we designed and fabricated four “custom actuators” to work in parallel with our pre-bought buttons.
The cabinet acts as the home for internal electronics and better differentiates the different consoles. Each interface is mounted at an angle to allow for easier visibility, and vertical barriers inhibit a player from being able to see the other interfaces or what the other players are doing. The cabinet is constructed of .74” birch plywood and .21” Tri-PLY plywood. They were machined on a shopbot cnc router and Trotec laser cutter respectively. The main method of joining the various pieces of plywood is a combination of mortise and tenon joinery and bolt and inserted nut that creates a rigid fit that is easily disassembled.
The center display displays the progress through the current level as well as the proximity to a fiery death. It is created using a painted wooden dowel supported within a polycarbonate diffusing tube. A string of adressable LEDs controlled by the main PIC are wrapped around the dowel, allowing us to have an LED tower that is visible from all three consoles.
No one part of our electrical system was particularly complex, but wiring together four microcontrollers, four LED strips, 9 LCD Screens, and over 40 actuators was non-trivial. The Master PIC uses SPI to communicate with the console PICs, which are all on the same SPI bus. The Master PIC also uses I2C to communicate with the larger command display LCDs. It also runs the central LED strip display and the command countdown LEDs. These addressable LEDs are all wired together and controlled by a custom single wire protocol. The console PICs have to connect to all the actuators on their console. Some of the actuators are analog inputs, while others are digital. The console PICs also have an I2C bus with their label LCD screens. Our game is powered by a ATX computer power supply, which provides 12V, 5V and 3.3V. The LEDs and LCDs are powered off 5V, and the PICs are powered off 3.3V. The lights on the buttons are powered from the 12V rail. To ensure that the buttons light up when pressed. We switched ground and used a pull up, as shown.
Our game is fundimentally a state machine with four states. The states are wait_for_coin, pre_level, level, and game_over. Most of these states are very simple and only messages to be displayed on LCD screens and an exit function based on button pushes, a specific pin going high, or a certain amount of time elapsing. Generating and playing levels was more challenging as it required the master to choose which commands to select out of its list, and how to send these commands and figure out if a command was completed. At the beginning of each level, the master would create a list of possible commands. Associated with each command are actuators, LCD display strings for the masters and the consoles, and which bit of a console needs to be checked for a command to be interpreted as correct. The master would then send the correct labels to each console for each actuator. Then each console would send a 32 long list of bits to the master every time a console updated. The master would check if certain bits were in certain positions to verify if a command was completed. If so, the command timer would reset, a new command would be chosen, and the spaceship would advance closer to the end of the level. If the spaceship advanced far enough or if enough time elapsed without enough commands being completed, the game would move to the game over or next level state. If enough levels were completed, the game would advance to the game over state except a string saying the player had won would be printed instead. The finite state machine was very easy to implement and work with once we figure out how to use function pointers.
The consoles and the master hold very distinct types of information. The consoles only hold information about their individual actuators, which ones are active, and what labels need to be displayed. The consoles have a state machine which checks whether or not they have received information about the labels to be displayed. If they receive a message, new labels will be displayed on their LCD screens depending on the message. If there is no new messages, the console will poll their actuators for their state. If the state has changed from the previous state, the console will send the entire state to the master. The master checks if this is a desired state and updates its own game information based on its state machine and level commands. The communication between the consoles and the master is done through SPI. The consoles are all on the the same SPI bus. Both the master and slave choose to communicate using either Slave select interrupts or console interrupts.
No line of embedded code can be ignored.
You don’t know if something works 'til you actually build it.
Sometimes sandpaper should do a mallet's job.
Function pointers are awesome!
Complicated things are made up of lots of simple things.