Steve Salmond bio photo

Steve Salmond

Game developer, professional coder, amateur artist

Twitter LinkedIn Instagram Tumblr Github

Introduction

Last week was Ludum Dare 30, and as usual there were a bunch of amazing entries. Congratulations to everyone who finished a game! I’ve been reviewing a bunch of entries since then and can highly recommend the following:

As for my own efforts, I’m pretty happy with how things went. My entry has plenty of flaws, but I feel like there’s some potential there.

What went right

Freeform gravity field

I think some technical aspects of the game worked nicely, such as the gravity system. I came up with a technique to allow the player to feel attractive forces from arbitrary objects in the scene. Basically, the game fires out a bunch of rays from the player every frame, looking for nearby surfaces marked as ‘Ground’. It then averages out all the surface normals (weighted by distance) and comes up with an overall gravity direction. This means you can smoothly transition from running on a planet surface to climbing a beanstalk, and can jump off the end of a stalk and ‘freefall’ to a nearby planet. Neato! The key method looks like this:

/** Return a gravity force vector, given a point in world space. */
public Vector3 ForceAt(Vector3 point)
{
	// Scatter rays out randomly, looking for solid ground.
	// When we hit it, accumulate the resulting surface normal.
	Vector3 gravity = Vector3.zero;
	for (int i = 0; i < Samples; i++)
	{
		Vector3 direction = Random.onUnitSphere;
		if (Physics.Raycast(point, direction, out hit, GroundMaxDistance, GroundLayers))
			gravity -= (hit.normal * 1 / (hit.distance * hit.distance));
	}

	// Return the overall gravity direction.
	return gravity.normalized * Strength;
}

I then use this gravity vector to apply force to and orient the player. You can check out the full source on GitHub.

Beanstalk growth algorithm

A pretty straightforward system, but injected some much needed life into the game. The beanstalk is created using a set of growth rules. At each stage, the plant figures out what possible rules it can apply given the current growth state, then performs a weighted random selection to pick one. The selected rule then produces some stalk or leaf pieces that are positioned in the correct location, and scaled up over time using coroutines. You can find the relevant code here.

Go go gadget bean!

Music

In previous Ludum Dares I have either used procedural music or recorded myself playing some bad guitar/drums. Luckily, I stumbled upon GarageBand a few months ago. What a great piece of software! It’s really easy to lay down a few notes, fix the timing/emphasis and loop them, add the next layer, and so on. Before you know it you have something that sounds like music! Here’s the track I ended up with for the game:

What went wrong

Vague initial concept

When the starter gun fired, I quickly decided to make something involving orbiting planets, and jumped straight into coding up a system for freeform gravity. It became clear as Day 1 progressed that moving the planets in orbits was going to be a bit tricky. With a naive implementation, the player was bouncing off planets or being left stranded in space as they drifted away!

Initial Concept Sketch

I would have had to figure out a way to ‘reset’ the physics system when the player touched down, so that the planet became the new ‘center of the universe’ - stationary and centered about the origin. I think that should be possible, but it seemed too big a challenge to my frazzled brain at the time.

Without orbiting planets, I suddenly realized that I had no core gameplay mechanic to work with! I had some ‘bridges’ between the planets, but the whole thing seemed like it might turn out to be extremely boring. The beanstalk idea was a bit of a Hail Mary, born on Day 2 out of sheer desperation.

Floaty controls

I had a lot of trouble with getting the controls to feel good. In the end they turned out very ‘floaty’, like you’re skating on ice. I have a pretty good solution for that in the pipeline, which incidentally make the beanstalk climbing feel better too.

Crazy camera

A number of reviewers mentioned the camera going crazy as they climbed - I think the beanstalk leaves were causing that. I had inadvertently marked them as both solid and gravity-inducing, so you can get into all sorts of trouble if you bump into them. This one can easily be fixed by moving the leaves onto a different physics layer.

Limited gameplay

I ran out of time to implement enemies or other interesting gameplay elements. The plan was to have a hungry giant wandering around on each planet, giving you a definite incentive to jump from one to the next at the right time! The gems are a pretty but kinda cheap solution I shoehorned in at the eleventh hour (hence the name of the game).

Future work

I’ve been doing a bit of work towards a tidied-up post-compo version. A few of the improvements I’d like to get in:

  • Improved control feel.
  • Enemies (or at least other lifeforms - giants perhaps?)
  • Fix beanstalk leaves
  • Experiment with orbiting planets?

Well, that about wraps it up for this one. Hope to see you at the next Ludum Dare!