Ludum Dare

This weekend I decided to participate in my first Ludum Dare. My idea was to create a simulation-type game inspired by the likes of Monopoly, or Sim City (though not substantially similar to either). My focus would be the property developers who operated during the Celtic Tiger in Ireland.

To help me with research and material, I put out this call to friends and the internet at large for stories. Very interestingly, it got shared quite a bit and commented on, but I got very few replies. Apart from weekendy apathy, this could be an indication that Irish people of my generation have little interest in looking back on what was a very different time. Low emigration, loads of jobs and a bright future, as well as copious amounts of corruption, greed and stupidity. My game focuses on the latter.

The working title I have for the game is Unreal Estate. My idea is that during the boom, property developers succeeded by projecting an image of success. The banks didn’t care about existing debt because they seemed to think that more and more money would be pouring into Ireland forever. Instead, getting access to further loans is accomplished by appearing to be more and more successful.

I’ve never made a sim game before, though I’ve always wanted to. As I’m really sinking my teeth into it, I’m starting to realise what a mammoth task balancing it is going to be, but I can’t wait. Even though it’s just in a rough prototype state right now and I’m still adding features, it’s really exciting to see basic things like turns and money management working. I’m also working on building it in a scalable way, using prefabs and some tricks to make building a bigger, more ambitious map quite easy.

I’ll be hosting the prototype on this site shortly and will post a link here when it’s live. In the meantime, I’d love to hear your comments, suggestions, stories and anecdotes about the boom – the excess, greed and corruption. If you include your name I’ll credit you, if you want to remain anonymous, just leave your name blank (or include it, but mention that you don’t want to be credited). You can email me, or just enter your details and material into the contact form in the sidebar (bottom of this page if viewed on mobile).

Working with Fungus

I’ve done some playing around with Twine before, and while I love the simplicity of the platform, the software isn’t very stable or fun to use. I’ve been getting my head around C# and Unity3D, and was thinking that it’d be amazing to be able to make interactive fiction with a robust platform like Unity. A quick bit of Googling and I found Fungus by Snozbot. If you don’t know them, Snozbot is a small crowd of game developers based in Dublin, making a lot of small, polished games. Fungus is a library for Unity3D that’s designed to make it easier to create interactive stories.

Flicking through the thorough documentation I got stuck into setting up a scene. It requires rethinking how you work within Unity, but the library seems very well-thought-out so far.

If you’d like to see how the following code plays out, take a look at the game as it is right now, it’s available in the web player or as a Mac OS X or Windows download.

[codebox]using UnityEngine;
using System.Collections;
using Fungus;

public class FirstScene : Room {

public Page GoodGuy;
public Page BadGuy;
public string levelToLoad;

// Use this for initialization
void OnEnter ()
{
SetPage(GoodGuy);
Say(“Uh…ugh. Where am I?”);
SetPage(BadGuy);
Say(“Don’t worry, you’re safe.”);
SetPage(GoodGuy);
Say(“Why can’t I see anything? Agh, I can’t move!”);
SetPage(BadGuy);
Say(“Your hands are tied and I put a hood over your head.”);
Wait(2);
SetPage(GoodGuy);
Say(“Wait. Did you say I’m safe?”);
SetPage(BadGuy);
Say(“Yes.”);
SetPage(GoodGuy);
Say (“I don’t feel safe.”);
SetPage(BadGuy);
Say (“You’re not. I lied.”);
Wait (1);
Say (“There’s going to be a lot of that.”);
SetPage(GoodGuy);
Say (“Please, I’m a father. You have to let me go.”);
SetPage(BadGuy);
Say (“Wah wah wah, I’m a father! Who cares?”);
// Fade down here?
Call(LoadLevel);
}

private void LoadLevel()
{
Application.LoadLevel(levelToLoad);
}
}[/codebox]

As you can see, there’s no Start() or Update() methods, those aren’t necessary with this library. Instead, we just go straight to OnEnter () and use Say() instead of getting into OnGUI functions.

There is definitely a learning curve, when I first put the code together I thought I could just call the next level by putting in the line Application.LoadLevel(levelToLoad) but that would just skip all of the scene and go straight to the next level. Then I tried encapsulating it in its own function as LoadLevel() but that didn’t work either. In the end I referred back to the documentation and saw that in order for the command to be processed by the command queue they’ve built for their system, you need to refer to other member functions with the Call() command, hence the Call(LoadLevel) at the end of the OnEnter() method.

It’s early days yet, but this is a powerful way to avoid all that messy GUI stuff in Unity.

Designing a Checkpoint System

As mentioned over on No Robots, I was at a game jam the weekend just gone. It was an amazing experience and it felt great to stretch my development muscles. It was also a powerful learning experience working in a team. I couldn’t be lazy, I needed to design my code so it was easily used by the designers who were laying out the levels and applying my scripts in Unity.

Since our game is a 3D platformer, we decided to insert checkpoints. I felt strongly that these should be tuneable, even though we had a group discussion about how many there should be, and where. Things happen, minds change and sometimes what seems like a perfect idea just doesn’t hold up to play testing, so the checkpoint system I eventually came up with was easily scaled from one to as many checkpoints as you like.

The first step was designing the relationships between the different objects in the scene. The player was tagged Player, the checkpoints were tagged Checkpoint and the enemies and hazards were labelled Enemy. This is important, because the scripts need to be able to make sense of this kind of logic flow:

Checkpoint System - Logical Flow

The controller contains pointers to all of the checkpoints in the scene, in the order that they will be triggered. This is a limitation of the system, but one that doesn’t impact our game as it’s a linear experience, are most checkpointed games. When the player enters a checkpoint, the checkpoint makes a record of the location of the player as a Vector3 struct, sets its triggered flag to true and calls the GetLatestCheckpoint() method on the controller. This method iterates through the array of checkpoints starting from the end and stops as soon as it reaches a triggered checkpoint. It remembers this as an integer.

This process repeats any time the player enters a checkpoint, but when the player dies – that is to say, when the player collides with an Enemy object, the respawn method on the Player calls the GetRespawnLocation() method on the controller. This returns a Vector3 from the latest-triggered checkpoint, which the player’s respawn method uses to relocate the model.

Example

In the below example, we have a list of checkpoints, ordered top to bottom in the list and left to right on the map.

List of Checkpoints

Checkpoints on Map

These checkpoints are tagged Checkpoint and have the Checkpoint.cs script attached as a component.

Checkpoint with script

You’ll notice I’ve also included an object using the CheckpointController script. This is to make it a little more fool-proof. You can totally use searching functions to make that stuff implicit, but I don’t like the idea of the overhead, or the scope for weird bugs to creep in, so I like to keep it explicit.

The object with the CheckpointController script applied is an empty game object with a bunch of different controller scripts applied, it just makes it much easier to find when you’re laying out the hierarchy of the scene.

screen_shot_2014-04-15_at_11.03.19

Incidentally, one of the nicest things about working in Unity has to be how it handles circular references – like the above, including pointers to the controller in the checkpoints, and pointers to the checkpoints in the controller. One of the most annoying aspects of C++ is planning out your code to avoid interdependencies, which thankfully isn’t necessary here.

You’ll notice that I’ve put the checkpoints into the array in the order that they will be hit, this is because the member functions will be iterating through the array in reverse to find the latest-triggered checkpoint, so the sequence is important.

That last field, the Latest Checkpoint one, is really just for debugging, to make sure the system is working properly, or to skip the player ahead to a later part of the level.

The code is quite straightforward. The main methods in the controller are:

[codebox]// This method should get called when the player collides
with a checkpoint, this is in the checkpoint script.

public int GetLatestCheckpoint()
{
for (int i = createdCheckpoints.Length – 1; i >= 0; i–)
{
if (createdCheckpoints[i].triggered)
{
latestCheckpoint = i;
break;
}
}
return latestCheckpoint;
}[/codebox]

and

[codebox]public Vector3 GetLatestCheckpoint()
{
return createdCheckpoints[GetLatestCheckpoint()].respawnLocation;
}
[/codebox]

The GetLatestCheckpoint() is called by the respawn function of the Player object to get the location it needs to respawn to, and as you probably guessed, createdCheckpoints[] is the array of checkpoint objects.