Inspired by J.S. Joust, I recently decided to pick up some Playstation Move controllers and attempt a video-less video game. This meant taking advantage of audio cues generated by the computer, and relying solely on controller input/output for the gameplay itself.
The main motivation behind the project was speed and design 'purity': designing a game like this forces you to make sacrifices and keep things simple. Using the controllers also allows you to design an inherently multiplayer game, removing any need for AI. Most of all though, frankly, I haven't made (read: finished) anything game-related in too long. This was a way to get me inspired. And I think it worked.
The art quality displayed here hopefully explains why I went for video games without visuals
Most of the games I would love to make are complicated. Especially when it comes to multiplayer: I like a layer of depth and complexity that lends itself to replay and also post-game discussion. Sometimes talking about how events unfolded is actually more interesting than the game itself - and for that to happen there has to be something a bit 'deeper' to the strategy of the game. Unfortunately, aiming for this type of game immediately seemed like a bad idea - after all, I was chasing quick-fire execution to get me inspired: I didn't want to get bogged down in designing and tuning complex strategy.
So, I pursued a far more simplistic idea: shooting people. Everybody understands that. It's quite brain-dead and incredibly unoriginal, but it was a good starting point for testing the capabilities of the controllers.
The game I devised as a prototype is that of a 1 vs. 1 western-style shoot-out:
There are a few things to note about this idea that may not be wholly obvious from the above:
Without the use of a camera, it doesn't seen possible to establish an accurate 'absolute' orientation for the controller. The PSMoveAPI can give a very good approximate orientation as a quaternion (through fusion of accelerometer and gryo data) but this is subject to a great deal of drift. If the player twists the controller, the planes of the reported values also remain relative to the controller's orientation, rather than to the player or the ground. This makes a great deal of sense, but it makes it difficult to establish whether the controller is indeed flat (horizontal) or not. Note: Obviously you can use the accelerometer to determine if the controller is flat - but the accelerometer does not 'recover' quickly enough to be of any use in this kind of game (given that the player will probably move the controller very quickly when the signal is heard).
The joys of calibration
For the sake of simplicity, the quaternion produced by the PSMoveAPI is used as-is, in tandem with frequent orientation resets. The quaternion is converted into an axis-angle vector and finally multiplied through into a standard X/Y/Z rotation vector, allowing more intuitive conditions/checks against the controller's angle in degrees.
Issues with controller twisting and rotation axis are simply ignored: the X axis is always treated as the angle to check for 'horizontal-ness'. If the player twists the controller, obviously this ceases to make sense: but it also makes it harder for the player to get the game to believe the controller is flat. Therefore, twisting the controller is discouraged (both through practical limitation and gameplay disadvantage). Mechanically this does make sense for the game, since twisting guns is generally not a good idea and greatly decreases accuracy.
Before the game starts, the user is expected to calibrate the down angle by pressing the move button of the controller whilst it is pointed down. This resets the orientation, therefore making the horiztonal angle the reset orientation + 90 degrees. [Note that this is very difficult to cheat or work around, since if you fail to point the controller downward, the 'horizontal' angle becomes whatever the cheat angle is + 90 degrees which is unlikely to be any more convenient than laying the controller flat]
In short: The orientation of the controller is detected very naively and is effectively a hack through frequent orientation resets. For future projects a more robust mechanism would be required. It is interesting to consider whether there would be some other way besides simply using the camera or some other fame of reference.
An additional gameplay rule, not mentioned previously, is that of a 'fault': If a player moves the controller much beyond the 'down' angle during the game's countdown (i.e. before the draw is signalled by the train whistle), the player is in fault, and the countdown is cancelled. This is intended to be considered cheating, since otherwise the player could get their controller horizontal and ready before the draw is even signalled. The blue light video in the above video shows this 'fault' rule in action.
A key component of the game is audio, since it is the primary communication form the game has with its players. Although overkill for a such a simple project, Pure Data via libpd was used as a backend for producing sound, and it did not disappoint.
In short: Pure Data is a tool for creating audio by connecting virtual 'wires' together. It has tons of documentation and a cross-platform editor UI. libpd allows files (a.k.a patches) produced by Pure Data to be processed by any arbitrary application. libpd simply produces a buffer of audio data, and from there it's up to the application (i.e. libpd is not capable of actually outputting audio - it only generates the buffer).
In the case of this game, the data was plugged into portaudio for realtime playback. What is brilliant about libpd / Pure Data, is that it is naturally a good fit for event-based systems: the code can send special signals (known as 'bangs') which have string names. The string names can be associated with anything (even >1 thing) inside the patch. This means that if the design of a sound completely changes inside of the patch, the code does not require modifying, provided the bang is still of the same name. This would no doubt be heaven to audio designers working on larger projects, since they can modify their work without requiring programmer intervention.
An additional timesaver is the fact that Pure Data literally handles all audio processing. The result is a single, flattened, stream of audio, meaning there is no need to manage multiple streams inside of the chosen output API.
In summary, despite being slightly clumsy when dealing with WAV samples (which are certainly not its forte), Pure Data was a resounding success, even in this relatively simple game, and will no doubt be reused for future projects.
The prototype's C/C++ code can be found on Github here
The code is an absolute mess. It was written very, very rapidly, and the guts of the game logic are sprawled randomly across different subsystems. You have been warned.
The code currently depends upon the following libraries. The plan is to slim these dependencies down significantly at some point, with a view to having these kinds of games running on the Raspberry Pi alongside the BlueZ bluetooth stack. (Given the quantity of dependencies, the code is really only released as a reference/curiosity at this point).
The control interface of the final product. Some parts are totally unused (e.g. game state) and really the entire interface is vestigial (removing it would remove the need for depending on Qt). But it does provide a useful diagnostic for the state of each controller
First and foremost: It works. It is in fact playable.
The downside: The only live human being I've played against so far is some guy with a beard, so I cannot really draw any solid conclusions from a design point of view. I would love to video some people besides myself playing it, as I imagine it would be very informative.
Despite this though, I have noticed some issues:
Here are some more abstract issues I've noticed:
To conclude: Despite the uninspired concept and poor orientation tracking for controllers, on a basic level, the project has been a success. I enjoyed working within the confines of 'no screen', and I felt it forced me to actually focus on issues of gameplay rather than getting caught up with other concerns.
Specifically, I'm definitely interesting in trying another move-based game, and I particularly want to aim for:
Additionally, Pure data (libpd) is brilliant and I probably need to find better ways of taking advantage of it. One of its strengths is generative/procedural synthesis, so maybe music-making could become part of the game...?