Right time for another post mortem. Drop. has been fairly successful on Kongregate, Stabilising at around 4.08 rating which means its sitting in 2nd place in the Project Eden contest behind Step Seq. So altogether I’m pretty happy with how its been received. The future of Drop is an unknown right now, there’s a million ideas of what I want to do with it in my head, expansive composition elements, more focus on the music aspect… but for now as I’m hideously hung over, I thought I’d just write a post mortem of the first version instead. There’s a few interesting key things I’d like to go over how I did them.
physics
Arguably the most important aspect of the game, which was going to determine how the thing felt under your mouse, was the physics.


Now my first prototype of this project (which had a little youtube video about a month or so ago) used Unitys built in Nvidia Physx engine, constrained to 2 dimensions. Each line was a box collider and each drop a spherical rigidbody. Using the various physics material properties and rigidbody mass and drag settings I got a pretty good model of how I wanted it to feel. There was one quite major issue with this method though, and that is that Physx is non deterministic, there’s no way to make it fully deterministic as well, which means, two balls hitting exactly the same point on a line, with exactly the same velocity, may bounce in slightly different arcs.This essentially makes the game feel completely unfair as your balls will start deviating when your not doing anything. Bad bad user experience in a game like this. So, only one thing for it, write a really simplified physics engine from scratch with just the bare essentials to handle line/ball collisions. Nothing else was really needed and without the complexity of a full simulation the deviation from floating point rounding errors and such (which are prevalent in an advanced simulation such as using physx) are gotten rid of.

As I have a flash background (back in the days of actionscript 1) I’m quite used to not having luxuries such as physics libraries, I did a lot of this kind of thing, simplified vector maths and such. I remembered a set of tutorials from a guy called Tony Pa. (Essential reading for anyone interested in vector math Check it out here)So just using the bare minimum of what he describes here (handily open in my visual studio side by side with my code) I was able to get a ball line simulation running in a couple of hours with ease, and with no deviation! Once that was in place it was fairly easy to start adding properties to the lines I created such as bounciness.
So what about the solid objects? All I have in my simulation is Line/Ball collision, there’s no rigidbodies?

All the shapes (triangles, pipes, stars and boxes) were created in 3D as simple 2d polygons, then I use a script to parse the vertices of the 3d shape and convert them into lines which can be utilized by my quick physics engine. Then I just have boolean switchees to define if the object needs to be updated per frame (if it has any movement behaviours attached this is necessary) which just keeps the lines updated to the co-ordinates of the vertices. The only caveat which I’ve yet to explore is corners! This is evident as droplets can be fired inside objects if you hit right on corner. (Thankyou Kongregate users for the approximately 400 bug report e-mails detailing this fact with many screenshots!) I admit I knew about the ‘bug’ but kind of appreciated the effect it had, (it made really nice sounds after all) so decided it gave it character… possibly a bad call on my part but… Moving on!
the logo


The logo was a bit of fun, just making some nice little animation gave it a bit more character than a static image. So I made all the individual dots animate to there appropriate place. So how do they all know where they are going? Simple point cloud, manually edited. That’s it! As the name was simply Drop. I thought manually adding points wont take very long so just super imposed a grid in photoshop and copied the values into a script. Had it been called “Drop! – The Ambient Reflective Music Puzzle Game” I would of probably found a way to auto create the data :) Once I had all the positional data stored I just used Bob Berkebiles wonderful iTween with varying delays to make all the dots fall into place.
the audio
Given there is 12 notes in the scale, there’s quite a lot of audio bits, 36 in total for the hit sounds covering 3 octaves of plinky tones, I’m using the same logic as I used in Step Seq to pick the correct sound files for the key in which the level your playing is in. The theme tune is in the key of A as it’s alphabetically the first key and also the key of your first set of levels. The only clever bit really was in the drone pad. This was just the same sound file and I just adjusted the pitch by a certain amount to get it to the right key. However this had me confused for a while as I could hear the difference between a pitch value of 1 and 2 seemed like exactly one octave, so I thought well there’s 12 semi tones in an octave so each semi tone would be 1/12 pitch value right?
WRONG… all along its
float targetPitch = Mathf.Pow(2, semitones/12f);
So there, if you need to pitch shift by a certain number of semi tones, that line will save your life.
Level Structure
Right so making all those levels was actually really fun and only took 2 days, because of the great way Unity components are setup I was able to easily setup a really simple serialisation system that would serialize any properties of components I wanted. It was really simple I just had an abstract class called Serializable that looks like this
using System.Globalization;
using UnityEngine;
public abstract class Serializable : MonoBehaviour {
public abstract string GetSerializedData();
public abstract void SetSerializedData(string[] data, NumberFormatInfo nfi);
}
Then anything I want serializable, instead of extending MonoBehaviour, I just extend my Serializable class and implement the methods. As an example, here is my EasedMovement behaviour:
using System.Globalization;
using UnityEngine;
using System.Collections;
public class EasedMovement : Serializable {
public Vector2 amount;
public float duration;
private Vector3 startPosition;
private float time;
private float oneOverDuration;
private int direction;
// Use this for initialization
void Start() {
direction = 1;
oneOverDuration = 1f / duration;
startPosition = transform.position;
}
// Update is called once per frame
void FixedUpdate() {
time += Time.deltaTime * 0.5f * oneOverDuration * direction;
if (time >= 1f && direction == 1) direction = -1;
if (time <= 0f && direction == -1) direction = 1;
float newX = (amount.x != 0) ? Mathfx.Hermite(startPosition.x, startPosition.x + amount.x, time) : startPosition.x;
float newY = (amount.y != 0) ? Mathfx.Hermite(startPosition.y, startPosition.y + amount.y, time) : startPosition.y;
transform.position = new Vector2(newX, newY);
}
public override string GetSerializedData() {
return amount.x + "," + amount.y + "," + duration;
}
public override void SetSerializedData(string[] data, NumberFormatInfo nfi) {
amount = new Vector2(float.Parse(data[0], nfi), float.Parse(data[1], nfi));
duration = float.Parse(data[2], nfi);
}
}
You can ignore most of this, but pay attention to the GetSerializedData and SetSerializedData. Notice how Get just returns the values I want serialized and Set parses the values returned to it (always strings from a .txt file in my setup) and sets the variables up. This is it! Now thanks to my level saving and loading stuff (all very bespoke and messy so not posting ;) ) I can assign as many serializable components to every level object and all their individual datas will be stored, so I can just build my levels off of a few select prefabs, add components as I see fit and save to text format. (and obviously reload and make changes if necessary)
The end
I’m going to finish by saying thankyou for reading all this crap, most importantly thanks for playing the game (if you did!) If you haven’t played it yet head on over to drop.quickfingers.net to learn more!