The nested factory pattern

When writing code, I try to structure my project in such a way that it’s impossible to misuse. I often run into cases where I need some class to be responsible for instantiating and managing its own resources, such as a message hub (which needs to maintain a list of subscribers) or a tweening engine (which would need to update and dispose of tween control objects according to a timer). In these cases, I like to ensure that these objects can never be created outside the class which manages them.

A simple solution, of course, is to use internal constructors, but I personally prefer to avoid using the internal access modifier whenever possible, as I find it does a poor job of signalling the intent of the code, and in many cases is just a band-aid fix for a poorly planned access scheme. Furthermore, in cases where the class in question will only be consumed within the same project, internal is essentially no different than public.

My solution to this problem is as follows:

Continue reading →

Haxe still has problems

Following up from my post about using Haxe/OpenFL to save some of my old Flash games, I do feel like I have to talk about some frustrating points that came up during the progress.

I will preface this by saying that the problems Haxe has now are different than the problems it had when I was using it previously. Throughout this process, I only came across a bare few instances where switching targets led to suddenly broken code. The OpenFL runtime never totally crashed on me like it used to do. I didn’t have to fiddle with DCE flags to prevent my code from being erroneously stripped from the build. It’s obvious that Haxe has improved a lot over the past few years, and that’s great. I do plan on continuing to use it to port my other game projects, and I would recommend it to anyone else for the same purpose. I do believe in criticizing the things we love though, so let’s get into it.

Continue reading →

Glide update: Tween overwriting

I’ve just added support for property overwriting to Glide, my Tweening engine for C#. This functionality exists in Actuate (a great Haxe library from which I’ve taken a lot of inspiration) and I’ve wanted it in Glide for a while now because it’s just so darn handy.

Imagine you start a tween off on its way:

// move image to (100, 200) over five seconds
Tweener.Tween(image, new { X = 100, Y = 200 }, 5);

…but then something changes, and now you want your image to travel instead to (X = 500) instead, and it should only take two seconds:

Tweener.Tween(image, new {X = 500}, 2);

At first this will work fine, but when the second tween finishes, suddenly the first one takes precedence again and your image will keep moving towards (X = 100). You could cancel the first tween, but that would also cancel the movement towards (Y = 200).

Now, creating a new Tween on an object that’s already being tweened will cancel the movement of any properties that are currently being tracked. In the example above, the new X tween would overwrite the old one, the original Y tween would keep on working, and there’s no need to manually cancel anything.

The old behavior is still available; just pass false to the overwrite parameter. I’m pretty sure that won’t be necessary in the majority of cases, but it does exist if you want it.

Glide update: Structs don’t work that way

Glide has seen some modest adoption despite the fact that I’ve barely made any effort to get the word out. A handful of developers have contacted me thanking me for the project and asking for help, which I’m always glad to offer. One issue in particular has come up a few times recently, and it relates to the way .NET handles structs.

Structs are passed and returned by value, not reference. This means that when you assign an instance to a variable, that new variable has no relationship to the original object; any properties set on it will only apply to that variable. This is a problem in Glide, since I have to store a reference to the tween’s target object in order to apply the transformations. Worst of all, while normally this issue would be caught at compile time, it’s impossible to detect when you’re using reflection to set values, and the resulting behavior was that the operation would appear to silently fail.

Today I made some changes that should help users realize when they’re attempting to tween an incompatible type. Passing an instance of a struct to the tweener will result in a compile-time error, and if you sneakily box your variable into an Object it will throw an exception at runtime. This still doesn’t solve the problem of how to tween these types of properties, but I’ve got you covered on that front as well.

Glide already has support for extension classes that allow you to add specialized behavior for tweening your own types, but this feature wasn’t really documented anywhere. Now it is! I’ve added a wiki to the Glide Bitbucket repository with an example showing how to tween an XNA Vector2. It should be pretty simple to modify for your own needs…maybe a StringTyper extension that causes letters to show up over time like a typewriter, or a GlitchString that fills the whole string with garbage and slowly fills in the correct letters.

Stuck Scripting overhaul

Early on in the development of Slide (before Iridescence had come to be), I added support for small script files to allow levels to contain more complicated puzzles without running into false positives that caused the reset button to show up while the level was still perfectly solvable. I was using C# at the time, and options for proper scripting languages on the .NET platform are shamefully limited, so I rolled my own.

Here’s a sample of what it looked like:

R > B;
G > B;
B > G ! B -> [B];
B > R ! B -> [B];

The use-case for stuck scripts is extremely specific, so the language itself didn’t need too many bells and whistles. All I needed to do at any time was compare the number of game objects of a given color, and check if pawns had a valid path to their targets. The snippet above basically translates like so:

The puzzle is unsolvable if any of these are true:

there are more red pawns than blue
there are more green pawns than blue
there are more blue pawns than green, unless all blue pawns can reach a target
there are more blue pawns than red, unless all blue pawns can reach a target

Needless to say, it’s as ugly as it is functional, and adding new features proved difficult. The inflexibility of the original design meant for some truly impressive hijinks as I tried to implement more complex behaviors with only the original syntax.

Today I stripped the whole system out and replaced it with a new one. Since I’m using Haxe for this remake, I was able to take advantage of hscript, a subset of Haxe that allows for runtime interpretation. Now, the script above looks like this:

var reds = count(Pawns.Red);
var greens = count(Pawns.Green);
var blues = count(Pawns.Blue);

if (reds > blues) fail();
if (greens > blues) fail();

if (blues > greens && !hasPathToExit(Pawns.Blue))
	fail();

if (blues > reds && !hasPathToExit(Pawns.Blue))
	fail();

Much better.

The original scripting system was designed as a black box, with a minimal number of inputs and outputs. By keeping the interface consistent between implementations, I was able to completely change the underlying code without changing any other aspect of the program. It’s nice to be able to change something so integral to the gameplay without worrying about side effects.

Glide update: From()

I made a small addition to Glide, my tweening library for C#. You can now specify starting positions for the variables you’re tweening, useful for when you need to change a variable instantly and then tween back to the default value. I use this when I’m making things flash for alerts or other important things for the player to notice.

tweener.Tween(sprite, new { Scale = 1 }, 1)
    .From(new { Scale = 1.5f });

Obviously you could just set the values manually before telling them to tween, but this is a nice shortcut if you’re setting a lot of them at once.

You can download Glide here.

Haxe macros are amazing

Here’s a neat trick I discovered today while working on Iridescence.

Haxe has native macros that are very different from those found in C; rather than using a separate pre-processing language, Haxe macros are simply snippets of Haxe code that are run at compile time instead of run time.

In native builds, Iridescence populates its soundtrack dynamically by searching for all song files in the /assets/music folder. On more restrictive platforms like Flash, all assets have to be known at compile time so they can be embedded in the SWF, which meant I needed to create a list of files manually and update it whenever I added a new song. I wrote this little macro to iterate through the music folder at compile time and build a list of song files automatically.

macro public static function getSongList(extension:String)
{
	var songs = FileSystem.readDirectory("assets/music")
		.filter(function(s) return s.endsWith(extension))
		.map(function(s) return "assets/music/" + s)
		.array();

	return Context.makeExpr(songs, Context.currentPos());
}

Color/Shift input woes

When I released the Color/Shift demo, one of the main issues that were being reported was that dragging the pawns around was really difficult. This confused me as I had spent a lot of time painstakingly tweaking the controls so that sliding pieces felt natural and responsive, but it was obvious by watching people play that there was something seriously wrong. I made some changes to try to make it better, but the result was still pretty bad. The pawns would slide around loosely in any direction they wanted until crossing a grid line, at which point they would snap to an axis and move along it, It didn’t feel good, and it introduced all kinds of new problems including the possibility of phasing through objects or traveling in two directions at once. Worst of all, it still didn’t address the issue entirely.

Dwm 2013-11-11 10-21-38-83

Yuck. 🙁

I let it be and moved on to other things, planning to come back to fix it later. There was probably a little bit of hubris involved, if I’m being completely honest with myself; if I didn’t have a problem controlling the game, other people shouldn’t either, right?

A few days after leaving the issue behind, I was working on my laptop (most of Color/Shift’s development has been done on my desktop computer) and suddenly started having the same problem as my testers. Pawns were moving sideways when I wanted to move up, and sometimes they wouldn’t even move visibly before smacking into a wall to either side. What was going on?

As best as I can figure, the input issues had to do with the sensitivity of the mouse being used for control. My desktop has a high DPI gaming mouse with the sensitivity cranked way up, and my wireless mouse and laptop trackpad are much less precise. Armed with this new information, I set about making things right.

angle0

Here’s a visualization of the way I’m handling input now. When the user presses the mouse button, the pawn remembers where the pointer was when it was pressed. In the image above, it’s right in the center of the piece.

At this point, no dragging is actually done yet. The mouse must move 7px in any direction before the pawn will move at all; this is represented by the circle cutout at the center of the transparent fans.

When the mouse has moved far enough from its original position, its angle to that position is checked. If the angle is within 30° of an axial direction, the pawn is then allowed to move on that axis. If not, no movements are made.

angle1

The angle is relative to the mouse click position, so it’s possible to start the drag by clicking anywhere.,

I still need to stress-test this to make sure it works for everyone, but it feels much better with all of my mouse devices and I have yet to move a piece in a direction I didn’t intend since improving this mechanic. Feedback is important! Listen to your testers!

 

Action scheduling with Lua

One of the downsides to moving between programming languages is that you inevitably lose all the base code you’ve gotten used to using. When I was using Actionscript 3 regularly, I wrote Slang to meet the lack of a scripting language that ran inside of Flash and ended up using it for a number of purposes in my subsequent game projects. The most useful application I found for it was for setting up cutscenes and scripted sequences, and I’ve missed using it now that I’m spending more of my time using C#.

Rather than porting Slang to C# (which would have been quite an ordeal), I’ve been playing around with Lua in an attempt to recreate a similar system. Here’s the first draft of how a scene might be set up.

Continue reading →

Must’ve been rats!

This past weekend I participated in the Global Game Jam with Chris Logsdon and Paul Ouellette. The theme was “heartbeat”, so we made a stealth game called “Must’ve been rats!” in which you have to search for a briefcase containing a beating heart so you can escape in a heart-powered elevator.

Download here!

Overall I’m pretty satisfied with the way this jam turned out. We had a lot of fun designing the gameplay and systems, and the game is feature complete despite having only one level at the moment. Even after testing and debugging for 48 hours straight I still enjoy playing the game, which feels like an accomplishment of its own. Still, it’s not a game jam if you don’t make some stupid mistakes and learn a few things, so here are my Things That Went Right and Wrong.

What went right

Flashpunk

At this point I can’t imagine using anything but Flashpunk for my game jam needs. Paul was able to pick it up fairly quickly, despite the fact that he hadn’t used it at all until a few days before the jam. Chris and I have used it a number of times, and even so we both found new features that we’d never known about. The API feels complete and intuitive, and it seems like there’s a function or class for everything we could ever need.

Systemic design with message passing

We designed our base engine as a set of systems that communicated with each other indirectly through message broadcasting, instead of directly through function calls. This allowed us to focus on programming the rules of the game world instead of specific interactions between different entity types. Even though getting each system working correctly was a challenge, adding new rules and rule responses is quite simple.

Data-driven workflow

We did all of our level design using Ogmo Editor, and as usual it served us well. Since we used a tileset for our levels’ art and a grid for collision and pathfinding, I modified my OgmoWorld utility classes to automatically import each of these types automatically and take advantage of FLAKit‘s live reloading capabilities. These changes will be included when I get around to officially releasing OgmoWorld.

What went wrong

Systemic design with message passing

Yeah, I know this one is in both groups. That’s deliberate.

Despite the fact that message passing is really cool and allows for some interesting emergent interactions, it’s not a good fit for everything. One example of a poor application is updating each enemy with the player’s position. My solution was to broadcast a message that told the player to report back with his position. This was slower and less elegant than searching the world for the player instance, and I wish I had realized that sticking rigidly to message passing was a bad approach.

Preconceived ideas

Chris and I had decided we wanted to make a stealth game before the jam started. Even though we didn’t do any kind of brainstorming beforehand, that decision still limited our ability to be creative with our interpretation of the theme. Fortunately we still managed to stay in scope and get the game to feature-complete, but I still wish we had come into the jam without any plans.

 

Overall, I’d call this Game jam another success. Make sure you play the game!