Year Month Date

5…4…3…2…1…Happy New Year!

It’s midnight, January 1st, 2021. The ceremonial ball has dropped in Times Square and 2020 has just come to a close. As the festivities begin to wind down, your phone buzzes. It’s a text from your friend in Los Angeles.

“My wife just delivered our baby! It’s a boy!”

What is the baby’s birthday?

Continue reading →

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 →