Wednesday, May 23, 2018

Ships and Dynamites: A father and son made video game

My son is five years old now, and as he has got older I have begun to share my love of video games with him. He has taken a keen interest in my last two or three PyWeek entries, as so after the last comp he asked if he could help me make a video game. I told him "sure! why don't you design the game and make the graphics and sound, and I can do the programming". I asked him what the game should be about, what does the player do? He told me "You jump out of a big spaceship and jump over lots of dynamite and then get in another spaceship and shoot all the dynamite with your lasers". Sounded good so far. I asked him to draw me a picture of what the game looked like. He drew this:

I then got him to draw a few additional assets on paper: a dynamite box exploding, the word "level", the numbers 0-9 and a titlescreen for the game. I asked him "what about the player's character before they get into the ship? what do they look like?" He drew me this:

I took all of the pictures he drew, scanned them and then chopped them all up in Gimp. I wrote a quick bit of prototype code in python and pygame with the player running around in the game world, with the big ship in the background, little ships that you can jump in and shoot with, and dynamite blocks. My son gave some feedback on how the levels should be structured and gave the nod of approval.

Next I told him "we are going to need some sound effects ... what sort of sounds do you want in the game?". He made the sounds for the lasers, dynamite explosions and a little jingle for when the player dies. We recorded him making the sounds on my laptop's built-in microphone, and I used Audacity to crop the sounds and perform a bit of basic normalisation and noise filtering, before loading them into the game. "What about music?" I asked. He told me "the music has to go like this: da da da daaa da, da da da daaaa da! ...", so I recorded a snippet and set about making a quick orchestral arrangement around the tune he had hummed in Musescore.

Finally I asked him "So, what are you going to call our game?". He told me "It's called 'Ships and Dynamites' ...". "Shouldn't that be 'Ships and Dynamite'?" I asked. "No, dad ... it's Dynamites" he insisted. "OK fair enough ... Dynamites it is".

This is a brief playthrough of our final game:


It was really fun to do this together, we both had a great time. He has had fun showing his game to friends and cousins, and everyone we have shown so far seems to like the game, and I think he's learnt a bit about logically what has to go into a game, how to get something like this to work etc. If interested, you can download the game here:

ships_and_dynamites.zip (1.2Mb)
Source distribution: requires python and pygame


Monday, May 7, 2018

PyWeek 25: The Desert and the Sea


"The Desert and the Sea" was my solo entry for PyWeek 25 (April 2018), a twice yearly video game development competition that gets competitors to build a complete game from scratch in seven days using the python programming language. This competition's theme was "Two Worlds" and I made a 3D exploration and adventure game set across two parallel worlds connected via a series of portals.

 

The game was inspired (sort of) by early 90s adventure games like Myst; there's a bit of exploration to do and some spatial puzzles built around teleportation and having to move between parallel worlds to by-pass obstacles that exist only in one world or the other. The game uses Pygame and PyOpenGL to produce it's first-person perspective graphics, and I was pretty happy with the final visuals and feel of the game. I spent a lot of time "world building" in this one, trying to use the visuals along with audio and music to create a nice atmosphere.

 

Although it wasn't my best entry in recent times, it still managed to narrowly win both the individual and overall winner for the comp with an overall score of 3.95/5.0, so I was pretty pleased :).

Playthrough Video:


You can currently download the game as either a source release (works with Windows/OSX/Linux, but requires additional installations) or as a standalone Windows application (I'm still in the process of getting the standalone OSX version working):

 

Windows (tested on Windows 7/10):
the_desert_and_the_sea_pyweek25_windows.zip (76.4Mb)

Mac OSX: stay tuned!

Source Distribution (compatible with Windows/Mac OSX/Linux, requires python 2.7, pygame, numpy and PyOpenGL, see installation notes in README):
the_desert_and_the_sea_pyweek25_source.zip (11.9Mb)

If you are having trouble getting the game to run, or have a bug/crash to report, please email: randomprojectlab@gmail.com

Sunday, April 29, 2018

Python-based MIDI Keyboard Visualisation

On my walk home from work the other day, I came upon a discarded electric piano keyboard on the side of the road. It looked to be in fairly decent condition except for a layer of dust that had built up on the top of the case; it had probably been sitting inside unused for quite a while. I brought it home, thinking that it was probably broken, but that I would salvage the main keyboard and any other nice working bits inside (including a pitch bend wheel). When I got home, I chucked a couple of AA batteries in a switched it on and voila, working perfectly; all keys in working order, and the USB MIDI interface too.

It seemed like a bit of a waste to rip it all apart, so I got thinking about interfacing something interesting to the MIDI interface. I did a bit of research looking for video games that had been designed with a piano keyboard as an input device: I found a reasonable number of projects involving adapting existing games to use a piano input as a bit of a novelty (i.e. this and this), but I couldn't find much in terms of games that explicitly designed with piano input from the start.

I started off by coding up a relatively simple rainbow fireworks display linked into key presses using pygame running through a laptop connected to the midi keyboard and into a TV via HDMI. I coded little fireworks to go off at horizontal positions corresponding to pitch of the pressed key, cycling through colours in the rainbow and handed it to my five year old son to let him have a bit of fun. He seemed to like it; it was a bit like an experiment for him to see how it worked.


I might end up expanding on this idea: I've found products like this that create a whole game out of playing the piano.

Code available at:
https://github.com/mit-mit-randomprojectlab/midi_piano_visual


Monday, January 29, 2018

Global Game Jam January 2018


Global Game Jam is an annual event held at approximately 700 sites simultaneously across the world in which participants join teams to create a video game in 48 hours. I participated this year at the Academy of Interactive Entertainment, Sydney site: was awesome. This year's theme was "Transmission" and I worked in a team with two programmers/developers and two 3D artists to create our game "Sonav" in which you control a boat navigating through a minefield under heavy fog. You need to use your transmitting sonar pulse to clear the fog and see obstacles while trying to move between objectives under a time limit. I worked on music, sound and UI graphics which was good fun (a nice change from programming).


I had chunks of free time during the weekend which I used to work on my own side project game (called "Transmission: defence") using a custom-built alternative bluetooth video game controller (called "Turny") that I had designed and built in the weeks leading up to the jam (see previous post on the development of Turny). You control four defence platforms using transmitted energy pulses to defend against incoming missiles. The frequency and range of the pulses are controlled by the four colour-coded knobs on Turny. The game was written in python and pygame.



Both games are available to download and play at:

https://globalgamejam.org/2018/games/sonav
https://globalgamejam.org/2018/games/transmission-defence

"Transmission: Defence" and "Turny" have also featured on "Shake That Button", a website that curates alternative controllers and games. There are some super cool projects listed there, check them out!


Thursday, January 25, 2018

Turny: an alternative bluetooth video game controller

With Global Game Jam 2018 coming up soon, I had the idea of building an alternative video game controller for which I could design a game for during the jam. I recently got my hands on an Adafruit Bluefruit LE m0 Featherboard, an Arduino-compatible microcontroller with built-in low-energy bluetooth module and I was quite keen to try and find a project to test it out on. I started thinking of types of control mechanisms that you don't really find on modern, conventional game controllers: I didn't really have too much time to try and use something really exotic that I'd have to order in, so I ended up thinking about paddles. Old games controllers dating back to the 1970's commonly used a single paddle, or rotational knob, for example on the Magnavox Odyssey and the Atari 2600. The original arcade version of Pong, one of the first video games used two potentiometer knob controllers for two player controller of in-game "paddles" (hence the origin of the term, in relation to the on-screen object the players control). No modern game controllers seem to use paddles or knobs anymore. I had a bunch of spare potentiometers sitting around, so I decided that I'd base the controller around a group of these rotational inputs.

I started off by testing out the bluefruit featherboard; I soldered on the headers, downloaded the appropriate packages for this board for use with the Arduino IDE. Connected it up and got the blink sketch working. I downloaded the Arduino bluefruit library and uploaded and ran the "controller" sketch from the examples that came with the library. I then installed the Adafruit Bluefruit LE Connect app on my android phone and connected to the featherboard. Messages all appearing normally on the serial console when selecting colours in the app. I then modified this sketch to colour a Neopixel based on the colour received through the colour picker function. I connected a neopixel up to PIN 5 and everything working well. I also downloaded the Adafruit BLE desktop app for OSX and tested the connection was working smoothly between the featherboard and my laptop, all good.

I found this library for interfacing on the desktop end via python. I tested the provided example 'list_uarts.py'; was working correctly to find the featherboard when it was switched on. I used this code as the basis for integrating communications with the bluetooth module in a pygame loop. I had to embed all of the code to connect to the device and continuously poll data into a separate thread which was called from a Scene/Director class and dumps the latest polled controller data into variables that gets read by the game during an event call. Everything seemed to work ok; perhaps a little bit laggy (approx. 100-200 ms of lag), but it's hard to tell.


I started designing a 3D printed case: I wanted to design something that was relatively quick to knock up in OpenSCAD: basically just a box with four pots, one each corner. I added space for a panel mounted momentary button in the middle on top and a hole from which I would mount a neopixel shining up to provide some feedback to the player for when the controller was connected/searching for a connection, or perhaps to use as indicators during a game. I printed a separate thin white circle that would sit on top of this hole (superglued on) to help diffuse the light coming from the neopixel. I also added holes on the sides for both a power on/off switch and the usb port for charging the battery via the featherboard. I designed a little logo to go on the top of the controller: I placed an imprint of this into the case model and separately printed (in a different colour) a solid version of the logo text that I could superglue on top of the imprint, to make it readable.


I connected up all of the electronics on a breadboard circuit to test everything was working ok. I connected the four potentiometers through to four analog input pins on the featherboard, a momentary button to a pull-up enabled GPIO input pin, the neopixel to one of the GPIO output pins, and a slide switch connecting the ground and enable pins on the featherboard. For the final electronics, I ended up designing everything around a small solderless breadboard which housed the featherboard; I wanted to be able to easily salvage out this board for future projects, and it meant a little less time soldering too.


Once I had all the parts printed and electronics wired up, I glued it all together. I wrote a little demo python script using pygame to connect to the controller and display a series of coloured panels corresponding to each of the rotational values of each potentiometer, just to test everything was working OK.

So far, my plan is to perhaps use this as a controller to design a game around for the upcoming Global Game Jam in a few days: I've thought of a couple of little "mini-game" ideas like a physics-based game where the knobs control the position of little trapdoors, or perhaps a tower defence game where the knobs control the viewing direction of little defence towers ... will have to see what the theme is when it is announced! If I do end up making a game for it (I'm sure I will), I'll post about it.

Update (30/01/2018): I did make a game, see: https://globalgamejam.org/2018/games/transmission-defence



Downloads:

3D model files and OpenSCAD source for the controller case can be found at:
https://www.thingiverse.com/thing:2769138

Code for running the controller can be found at:
https://github.com/mit-mit-randomprojectlab/turny-controller

Code for running a pygame demo on a desktop/laptop that connects to the controller: to be uploaded.


Wednesday, January 3, 2018

Starfox Arwing Softie

Do a barrel roll! Christmas and New Year holidays are a great time for vegging out and playing some video games. I recently picked up a second-hand copy of Starfox Zero for Wii U: it's the first Starfox game I've played since Lylat Wars 64 on the old N64 as a teenager. For some reason (as kids do) my son has become obsessed with everything Starfox after watching the game. He asked if I could make him an Arwing (the Starfox team's space fighter of choice), so I made a softie version using thread and felt.

I had originally planned to give it some flashy lights and some sounds by building in an Arduino Gemma, a small speaker and some neopixels, but it was going to take a while to get it working, and I'm not sure my son wasn't that keen to wait, so it's just a inanimate toy for now. I may try to retro fit these elements on at a later date.

Friday, December 15, 2017

Teensytune: A Teensy-based MIDI controller/keyboard


Teensytune is a homebuilt MIDI controller/keyboard built around an old broken keyboard using the Teensy microcontroller. It features 49 keys, a programmable 16 beat drum machine, pitch bend/modulation control and two recordable loop channels with controllable tempo. It outputs MIDI signals along a USB, so you can plug it into a laptop or any other MIDI synth to generate the actual sounds. It is constructed from a wooden frame with custom sideboards and control panels made using Carvey, a programmable 3D carving machine.

This post is a continuation of previous post on rebuilding an old broken electric piano. I last touched this project about 12 months ago, where I had a Teensy reading the keyboard state and passing MIDI messages to a Raspberry Pi which was running a synthesiser and outputting sound to an amplified speaker. I ended up having a lot of troubles getting the sound output from the RPi working reliably: I could never really find an acceptable balance between getting nice stutter-free sounds with low latency, even after trying custom firmware and playing with countless settings. I got frustrated and moved on to other projects.

12 months later I decided that it's time I moved on with this: I've dropped the RPi synth for now and have just focussed on getting a workable MIDI instrument up and running, leaving space inside the case for expanding the project to include a synth, amplifier and speaker at a later stage.


Implementing the Controls:

After I got the basic circuit and code setup on the Teensy for reading the keyboard state, I started to focus on developing some cool controls. I started by adding a simple drum accompaniment function using a single on/off switch and a potentiometer for controlling the tempo. The beat is run through an interrupt using a PIT timer on the Teensy that sends a MIDI note for the current beat in a static 16 beat pattern, that is looped on repeat. Changes in the tempo pot are used to reset the interrupt interval time. I added an old two axis joystick I had sitting around and read the values using two analog inputs on the Teensy and translated these into pitch bend and modulation MIDI messages.

In order to provide a bit of feedback to the player, I decided to try and add in some Neopixels for coloured, flashy fun and a two-line character display. I plugged in a Neopixel to test everything was working fine: all good. I got this two-line character display which interfaced to the Teensy via I2C to display out data, for example, on the instrument selection and provide feedback for the programable drum machine. The display is a 5V device, so I used a logic level convertor to convert to/from the 3.3V signals on the Teensy. I2C on the Teensy 3.1 requires that both SDA and SCL data lines be connected to 4.7KOhm pull-up resistors, which I did. I used this library to control the display: tested I could display some basic text and instrument number, and all is working well. I ended up using the character display to provide visual feedback for programming the 16 beat drum pattern: one line of the display shows the instrument number assigned to each beat, and the position of the current working beat flashing on the screen. I added two extra buttons for scrolling the working beat left or right, and setup the beat to be programmed to a new drum instrument by pressing one of the bottom 10 keys on the keyboard.

In order to add a few more buttons (running short on GPIO pins by this stage) I got a I2C port expander which provides an additional 8 digital inputs and communicates on I2C. I tested this on the same bus as the I2C character display and everything seemed to be working fine with a single button, but wouldn't work with the other seven. After a bit of debugging I realised that the default I2C for the expander and the display were the same: I changed the address for the expander using the external address pins and everything was working fine.


Finally, I implemented two recordable loop channels. The idea with this was that I could play an input sequence to the keyboard over the 16 beat period of the drum machine, and the loop channel would record and playback this sequence on repeat, while the drum machine was switched on. I could also playback these sequences at a variable tempo using the drum machine's tempo knob, providing the ability to record complex patterns at slow speeds, then ramp this up to a fast speed at playback which would otherwise be impossible to play manually. Each channel is controlled by a single button: when the button is initially pressed, the recording begins and starts to playback the input sequence in a loop. Subsequent button presses turn the playback for this loop on and off, and holding the button down for 1 second deletes the sequence, making the channel open for re-recording a new sequence. To implement the record and playback, I created two arrays in memory that contain the note pressed and the sampling time over the time period of the 16 beats. During recording, these arrays are written to using the main program loop with timing provided using Teensy's "elapsedMillis" type. Playback is achieved by using two PIT timers with interrupts to ensure playback timing is smooth regardless of what is happening in the main program.

I linked one of the two channels to have additional pitch control using the bottom octave of the keyboard during playback, gaining inspiration from this project. During recording, the first note of the pattern becomes the "root" note of the sequence. During playback, keys pressed in the bottom octave of the keyboard are used to re-assign the root note of the sequence, which acts to shift the pitch of the entire sequence up or down by a fixed amount. This provides that ability to make this sequence a "baseline" and have the player manually control a chord progression in a song with a single key press.

Designing the Case:

I bought some 19 mm thick dressed pine for building a new housing for the keyboard, because the old plastic one looked ugly, and I wasn't looking forward to 3D printing new panels to fit the controls I wanted. I put together the base and back board by hand: glued two bits of timber together and screwed them in for good measure. I then designed side panels and top panels to be cut out and decorated using Carvey. I designed the panel to hold all of the controls to be carved also using Carvey. I had to use two different milling bits to get the right combination of cutouts and fine detail in the lettering on the panels, and I had to carve first on the front and then on the back to complete the design/housing for the display, joystick and electronics PCBs.

Putting it all together:

I wired up the Teensy and connections to the keyboard on a perma-protoboard, tested this was working well leaving the other components on a breadboard. I connected up two neopixels to use as part of the visual feedback to the player: I mounted these to be facing up through the top control panel adjacent to each of the loop channel control buttons. These light turn yellow for standard operation, pink when the player is selecting a new instrument, blue to indicate a loop channel has a recorded sequence available, green to indicate this channel is currently playing and red to indicate the channel is currently being recorded. I then wired up and soldered on the remaining components to the back of the control panel, connected everything up to the keyboard and screwed it into the wooden frame.



This is a video of Teensytune in action playing an interpretation of "Rainbow Road" from Mario Kart 64 (I love that game). Starts off by programming the drum machine, then recording two loops: a baseline and a little flourish. The actual song starts about 1:27. When playing with the right hand, the left hand is controlling the chord progression by shifting the baseline. Sorry about my poor piano skills :).

I'm hoping to expand the project by using the available space to install a small embedded computer to perform the synthesis, and add in an amplifier and speaker, so that the Teensytune can operate independently of a laptop. Stay tuned!

Teensytune Code:

The code that runs on the Teensy can be found at:
https://github.com/mit-mit-randomprojectlab/teensytune

There are a few required libraries for the neopixels, two-line display and port expander, listed in the readme.