Freedom of Motion Alpha 2

by Taylor Hadden | 1:19

The primary feature of this release is multiplayer support. You can start up a server running a world on your local machine and others can join you in building and running around in an infinite world. Unfortunately, this build doesn’t support worlds from Alpha 1, but any worlds created in Alpha 2 will be supported in all future updates.

An incomplete change list:

  • User-defined settings for control preferences and input
  • Spawn points
  • Light nodes
  • Text nodes
  • Infinite worlds
  • Multiplayer support
  • Ability to change player color and name
  • Faster chunk mesh generation
  • Improved accuracy for detecting ledges
  • Improved handling of sliding
  • Smoother transitions out of jump landings
  • Balanced wall running distances and height

Once again, this is very early software. All models, textures, sounds, animations, UI, and many implementations are placeholder. While I’ve endeavored to make it as stable as possible, things may break with no warning and data may suddenly become corrupt. It shouldn’t melt your computer, but use at your own risk.

Download Links

Freedom of Motion Alpha 2 — Windows

Freedom of Motion Alpha 2 — Mac

(Note that Safari has issues with Mega. Here’s an alternative Mac link)

Future Plans

Sharing a disturbing amount of details about a project’s development seems to be in vogue these days, and I want to run an experiment. I’m going to open up the Trello boards I’m using to manage development to the public so you can see exactly what I’m planning to finish for the next release and how those features are progressing.

For Alpha 3, I am focussing on exploiting the wealth of voxel data in order to inform the movement systems. This should let me fully develop the climbing system to include hanging on and moving along ledges and climbing from one ledge to another. Additionally, the system should eventually allow me to fix the issues the current system has with stairs, doorways, and small gaps.

Dependencies and IoC

by Taylor Hadden | 16:50

While I’m programming, there are two overarching goals that I’ve come to strive for while architecting and developing my applications:

  1. Single Solution: Objects and their functions exist to solve a single problem, and that problem is solved once.
  2. Minimum Dependency: Objects require and depend on as few other types and objects as possible in order to solve their problem.

I’ve found these two goals encourage me to build well-structured, easily maintained, and easily modified code.

Single Solution

The first concept is very simple. If you have a task that is required in multiple places and is algorithmically complex, you don’t want to have the same code duplicated all over your program. If you then find a bug in the algorithm or want to change how it functions, you now have to find all of the places where you copy-pasted that code and fix it.

This also applies to non-complex tasks. If you want to know whether or not your player can jump, you don’t want to manually check the requirements every time you need to know. You want to hide that functionality behind a property or function call so you can simply ask: if (player.CanJump()). Take advantage of every opportunity to save yourself time in the future.

Minimum Dependency

Minimizing the number of dependencies an object has is a broader concept. A dependency is any discrete link between one object and another. The most fundamental example of this is any direct instantiation or storage of a discrete type:

public class Foo {
	public string Name;
}

public class Boo {
	public Foo myFoo;	// Discrete storage

	public Boo() {
		myFoo = new Foo();	// Discrete instantiation
	}
}

But a dependency can also come from the dependencies of your dependencies:

public class Grue {
	public string Name;
}

public class Slew {
	private Grue myGrue

	// Discrete instantiation requirement
	public Slew Slew(Grue theGrue) {
		myGrue = theGrue;
	}
}

public class Moo {
	public Slew mySlew;

	public Moo() {
		// Because we depend on Slew, we also
		// depend on Slew's dependencies.
		mySlew = new Slew(new Grue());
	}
}

Minimizing dependency is a good thing because it makes objects more portable and easier to use. Fewer steps to access or create an object or feature means fewer ways to accidentally create a bug. Fewer arguments for instantiation or function calls also means that you don’t have to be dependent on the objects for the arguments as well. If you are constantly thinking about whether or not an object really needs all of the functionality and baggage that comes with a particular object, you will be more likely to reduce the requirements of an object to just what it needs to complete its objective.

Even the most basic of systems needs some manner of input, output, or assisting functionality, but we can work to reduce dependency to those objects by using interfaces:

public interface IFoo {
	public string Name { get; set; }
}

public class Foo : IFoo {
	public string Name { get; set; }
}

public class Boo {
	public IFoo myFoo;	// Storage of interface

	public Boo(IFoo myFoo) {
		this.myFoo = myFoo;
	}
}

Using an interface is a great way of providing just the methods and properties that your object needs while leaving the actual implementation of the functionality open-ended. It means that you can now completely change the objects that a class refers to without having to modify the class itself.

Additionally, instead of calling functions directly, you can use function delegates as callbacks (C# provides excellent support for this). The use of delegate callbacks (or event systems) means that an object isn’t making the decision over what functionality comes next, it is merely providing hooks that other objects can listen for and react to. For a more concrete example, instead of your Player class requiring a reference to your HUD in order to tell the health bar to flash when the Player takes damage, the Player class can provide a delegate callback for when it is damaged that the HUD class can hook into. This way, the Player doesn’t need to know anything about the HUD at all, removing that dependency.

public class Player {
	private float health = 100.0f;

	public float Health { get { return health; } }

	public Action onDamaged;

	public void DealDamage(float damage) {
		health -= damage;
		onDamaged();
	}
}

public class PlayerHUD : MonoBehavior {
	public Player player;

	void Start() {
		player.onDamaged = HandlePlayerDamage;
	}

	private void HandlePlayerDamage() {
		// Here, we can start the process of flashing the health bar
	}
}

Again, keeping a leash on your objects’ dependencies is a balancing act. Code is built to get stuff done, and sometimes classes need to be tightly coupled to one-another. It can be very beneficial to consider dependencies from the perspectives of “features.” A feature like a chat box might consist of several classes that work together tightly, but the rest of your program may only need to know about one or two. Dependencies are just as much about what one system knows as they are about what other objects or systems need to know in order to use that system.

Organizing Dependencies into Applications

If you just created objects with no dependencies, nothing would ever happen. An application needs to be able to do the following:

  1. Organize the creation of objects
  2. Organize the communication between objects
  3. Provide objects with common state information

To do this, I see application code as broken up into three layers:

  1. Framework code is things like the Unity Engine, or any other core library (such as C#’s Mono or .Net).
  2. Domain-Specific code solves the localized problems in your application. This includes everything from the code defining how the player moves to the code that defines how your scoring system works.
  3. Application-specific code organizes the domain-specific code so that everything communicates correctly and has the correct information. This can be thought of as the “glue” code.

In an application that has a large number of interconnected dependencies, your domain code and application code will likely be all mixed in. After all, the most straightforward way of calling a function is having a reference to that particular object and calling the function directly. However, often what’s really going on at the core of an application is a collection of systems that are mostly self-sufficient but have to communicate and react to various events. Thus, each component has its own goals, and only needs to listen to and broadcast a few events in order to function.

I shouldn’t have to provide a reference to my GUI in my player, nor should my game have to manually stop music and sounds whenever the user pauses. Instead, my player should alert the system that he has taken damage, and the GUI should react to that. My application should broadcast a “paused” event and my sound system should handle the pause and continuation of the appropriate music. Providing the right instances and connecting delegates to each other is the job of our glue code, but if we were to write all of that out by hand, our code would quickly become a twisted mess that would be more difficult to maintain than simply structuring our code in a more traditional manner. Luckily, we can avoid this problem.

Inversion of Control with Strange

StrangeIoC is an Inversion of Control framework. It provides very easy to use tools designed to solve the problem of organizing code and its dependencies. There are several useful systems provided with the framework, but the ones I want to bring up today help solve some of the issues that I talked about above: Dependency injection, Signals, and Commands.

Dependency Injection

Dependency injection allows a class to state that it expects to be handed an object of a certain type. This works best with interfaces, but it works for any type at all. Requesting an injection in a class is dead simple:

public class Moo {
	[Inject]
	public IFoo foo { get; set; }
	// An IFoo will be automatically added by Strange
// when the object is created
}

Injections are then linked to concrete types in the “Context” class, using the InjectionBinder. You can think of the Context as the switch-board for your application. You wire up your dependencies in one place, and then Strange takes over, providing instances of the correct type as necessary.

public class MyContext : MCVSContext {

	protected override void mapBindings() {
		// Provide a new instance of Foo every time
		// We fill an IFoo request
		injectionBinder.Bind<IFoo>().To<Foo>();

		// Provide a single instance of Boo every time
		// We fill an IBoo request
		injectionBinder.Bind<IBoo>().To<Boo>().ToSingleton();
	}
}

Strange’s MCVSContext is specifically tailored to Unity. The pattern set by the framework is that a small MonoBehavior rests on a root GameObject, and creates the Context upon Awakening. Any MonoBehavior that extends Strange’s View class and is placed on a child GameObject of the Context can use injection. I will talk more about the specifics of this in future posts.

Signals

Signals and Commands form the primary backbone of communication and application-level functionality in Strange. A Signal is essentially a collection of function delegates, and is a perfect way of easily expanding the single-delegate model I demonstrated earlier. An individual object can use it to easily announce various events and any number of other objects can listen for those events.

public class Player {
	...

	public Signal onDamaged = new Signal();

	public void DealDamage(float damage) {
		health -= damage;
		onDamaged.Dispatch();
	}
}

public class PlayerHUD : MonoBehavior {
	public Player player;

	void Start() {
		player.onDamaged.AddListener(HandlePlayerDamage);
	}

	void OnDestroy() {
		player.onDamaged.RemoveListener(HandlePlayerDamage);
	}

	private void HandlePlayerDamage() {
		// Here, we can start the process of flashing the health bar
	}
}

(In cases like this, I like to hide the actual usage of Signals behind my object’s interface and use the Signal as a backing object. That way, I can avoid the dependency of the exposure of the Signal object.)

Using Signals moves the responsibility for initiating action away from the initiator and onto the object that needs the action to be called. In the previous example of having the HUD flash when the player takes damage, now we can easily remove, change, and add functionality that occurs when the player takes damage, all without having to change the player code at all.

Strange’s signals have one key benefit over a more common event system as they allow for strongly typed arguments. We can expand the example above so that when the player gets hit, the “onHit” signal passes along the damage taken by that hit.

public class Player {
	...

	public Signal<float> onDamaged = new Signal<float>();

	public void DealDamage(float damage) {
		health -= damage;
		onDamaged.Dispatch(damage);
	}
}

public class PlayerHUD : MonoBehavior {
	...

	private void HandlePlayerDamage(float damage) {
		// Here, we can start the process of flashing the health bar
	}
}

Now, objects like our HUD system can differentiate between a large hit and a small hit very easily. Signals support up to five arguments (a restriction based on C#’s underlying Action class), and they will complain at compile time if another object tries to listen to a Signal without the correct arguments in its listener function. This makes Signals not only a fantastic device for alerting other objects about events, but also a great way to move data through your game.

Commands

Commands are highly specialized classes that perform specific functionality. Commands and Signals are used in partnership to organize functionality across an entire Context. The CommandBinder allows Signals to be tied directly to Commands, so that any time that Signal is Dispatched, a new Command is created, run, and disposed of. Like any other type, Signals can be bound in the Context and injected into objects, and any Signals bound with the CommandBinder are automatically setup in the InjectionBinder as singleton bindings. That means by injecting a signal into an object and calling Dispatch(), objects can trigger Commands.

// Creating a "stub" signal class allows for clear differentiation
public class StartSignal : Signal {
}

public class StartCommand : Command {
	// Inject the various systems you need to talk to to start the game.
	public override Execute() {
		// Do whatever you need to do to start the game.
	}
}

public class MyContext : MCVSContext {
	// Unbind EventCommandBinder and rebind to SingalCommandBinder
	// Necessary, as Strange uses an Event system by default.
	protected override void addCoreComponents() {
		base.addCoreComponents();
		injectionBinder.Unbind<ICommandBinder>();
		injectionBinder.Bind<ICommandBinder>().To<SignalCommandBinder>().ToSingleton();
	}
	...
	protected override void mapBindings() {
		...
		// The "Once()" statement means that once the command has been
		// run, the binding will be broken, and Dispatching StartSignal
		// will no longer run a StartCommand.
		commandBinder.Bind<StartSignal>().To<StartCommand>().Once();
		...
	}
}

Though the above example uses a signal and a command specifically for handling the start of the Context, I’ve found that Signals and Commands become most powerful when they aren’t necessarily created in pairs. Instead of injecting a Signal in order to run a specific Command, you should be injecting and dispatching a Signal when a certain event has occurred. That way, if you want to change how you react to that event, you only have to change the Command binding in the Context, and you don’t have to change which Signal is injected and dispatched.

Commands work best when they are handling a specific duty that requires interacting with a large number of systems. Because they use injection to get the objects they need (including any parameters passed along from the signal), the same Command can be used in many different contexts that use, for example, different implementations of the IPlayerManager interface without any issue. Because of this, Commands are an excellent answer to the Single Solution goal for specific but possibly wide-reaching tasks. I use Commands to handle when a remote player joins or drops from a multiplayer game and when I need to create a new entity in the game world (requiring initialization of data, controller, and view information), among many others.

A Practical Example: Injecting Game Settings

A common reason people use the dreaded hard-coded singleton is to provide access to various game settings. For example, you want to have your player be able to invert their mouse. With static variables, you would check GameSettings.isMouseInverted in the code that handles your mouse look, but that would mean that code requires the GameSettings class in order to work at all. Instead, we can use Strange’s injection system to provide access to specific setting objects, and now the mouse look code only needs to inject the specific settings that it needs to function.

public interface ISetting<V> {
	// These are separate to make the changing of a setting
	// a more deliberate act.
	V value { get; }
	void SetValue(V value);
}

public class Setting<V> : ISetting<V> {
	private V _value;

	public V value {
		get { return _value; }
	}

	public void SetValue(V value) {
		_value = value;
	}
}
public enum GameSettings {
	INVERT_Y_AXIS, LOOK_SPEED
}

public class MouseControl : View {
	[Inject(GameSettings.INVERT_Y_AXIS)]
	public ISetting<bool> invertY { get; set; }

	[Inject(GameSettings.LOOK_SPEED)]
	public ISetting<float> lookSpeed { get; set; }

	void Update() {
		...
		float mouseYDiff = Input.GetAxis("Mouse Y");
		if (invertY.value == true) {
			mouseYDiff *= -1;
		}
		...
		mouseYDiff *= lookSpeed.value;
		mouseXDiff *= lookSpeed.value;
		...
	}
}

The injections in this case use Strange’s named injection feature, using the GameSettings enum for names. Named injection allows you to differentiate between different bindings of the same type. In this particular example, there are no type duplicates (as generic classes of different types are treated as different types); in an actual game you may have many “ISetting<bool>”s. I will point out that using a common enum like GameSettings does create a similar sense of dependence as a static settings class; however, because the value will be stored in an instance, it is more flexible. If it still bothers you, consider having multiple groups of setting enums, such as a LookSettings, MovementSettings, and so on. Now, we fulfill these injections in the Context:

public class MyContext : MCVSContext {
	...
	protected override void mapBindings() {
		...
		Setting<bool> invertYAxis = new Setting<bool>();
		Setting<float> lookSpeed = new Setting<float>();
		lookSpeed.SetValue(1.0f);
		// Here, we could load the value of the setting from a file
		// or initialize it in another way

		injectionBinder.Bind<ISetting<bool>>().ToValue(invertYAxis).ToName(GameSettings.INVERT_Y_AXIS);
		injectionBinder.Bind<ISetting<float>>().ToValue(lookSpeed).ToName(GameSettings.LOOK_SPEED);
		...
	}
}

With these objects bound, the MouseControl script will be provided with these instances (and they will complain if a setting is not provided). Any other script that needs to use these settings can also inject them, and they will be provided with the same bound instances. Because any reference to a specific setting is looking at the same object, any change to those settings is inherently shared among all of the scripts that access them. In this way, each script only needs to know about the specific settings that it actually requires while still maintaining synchronized settings across the entire game.

Overview

The use of Strange allows you to easily build your application out of contained systems. Your inventory system, your HUD, and your enemies can be built as black boxes with input and output hooks with Injections and Signals, and all of those hooks can be connected in a single location. Additionally, broader, system-spanning functionality can be defined in very specialized Commands, and the sequence and triggers of those Commands are set up in the same place.

While it introduces a sizeable learning curve, I’ve grown to very much enjoy using Strange. Once you wrap your head around its concepts and how best to build things for it, it actually becomes very liberating. I know that if I need access to something in an object, I can simply inject it. It also encourages  you to write code with very clear responsibilities and boundaries.

This discussion of some of the essential components of Strange has only scratched the surface. If you want to immerse yourself fully, there is an exhaustive description here.

Freedom of Motion Alpha 1

by Taylor Hadden | 16:30

FoM Alpha 1 SmallIt has been a while since my previous post, but in the silence I’ve been working. Freedom of Motion has now broken into the earliest stages of Alpha and I have something to properly show off.

The current movement features include running, jumping, rolling, sprinting, sliding, climbing up ledges, wall jumps, and wall running. Additionally, the world is built using a custom voxel terrain engine, and you are able to freely edit the included testing world or build your own. Full details are provided in the readme.

Of course, this is still the earliest of Alphas, so there aren’t any objectives, and you should fully expect things to break or simply not work without warning. That said, this forms a solid jumping-off point for further development of the game, and I’m excited about its potential.

Without any further ado, here are download links to Freedom of Motion Alpha 1:

Thanks for reading, and please leave any and all feedback below!

Voxels, Octrees, and Collision

by Taylor Hadden | 21:18

Today’s subject is collision. There are a number of ways one could setup a collision and physics system with voxel data. I could build my own full physics solution, but I really don’t need (or want) to. Unity has its own physics system; the question is then how to interface with it.

Like last time, we’re talking about a single cubic chunk of voxel data. I already have the mesh data used to display the chunk, so Unity’s Mesh Colliders could turn that mesh data into collision, but Mesh Colliders have some pretty severe performance issues when used in bulk. Other developers have also mentioned that the procedural generation of a Mesh Collider can take a long time. I want to have effectively limitless terrain with good draw distances, and I also want my terrain chunks to react to user changes quickly, so Mesh Colliders for terrain are right out.

That leaves building a collision set to represent the voxel data out of collider primitives (box, sphere, and capsule colliders). One option is to place one Box Collider for every cube in the chunk. This results in several thousand colliders however, and we can do better.

An Illustration of Octrees

I mentioned this in my last post, but this voxel terrain is being stored in octrees, which is a data structure that can store eight sub-versions of itself. We can use this data structure to generate a much more efficient collection of Box Colliders. For simplicity’s sake, let’s look at the cube without the mesh, just viewing the Box Collider borders:

Cube Collision Full

This Box Collider represents the root octree of the voxel data. An octree knows its own center and size (the distance between opposite faces) and also holds onto a piece of voxel data.

Now, say we want to remove the top right corner. To do this, the octree constructs eight children, each positioned in a corner and with a copy of the original octree’s block data. Then, the octree in the top right is told that it is empty. At this point, the series of Box Colliders are regenerated:

Cube Collision 8th

First Division

Cube Collision 16th

Second Division

Cube Collision 32nd

Third Division

This operation can be repeated until we hit the minimum size of the octree structure. Since the octree uses integers for size and positioning, that value is 1. The smallest block I want is a half-meter, so the Mesh and Collision Generators are set to translate a “1” in octree space to a “0.5” in world space, but this is freely adjustable.

Generating Colliders

The actual process of generating the colliders is quite simple. You just need to loop through the octrees and place a Box Collider where the solid octrees are. This dramatically cuts down on the number of colliders used per chunk when compared to simply placing a collider for every block.

Fourth Division

Fourth Division

I’ve broken this process up into two discrete operations: the object that loops through the octrees (called a Crawler) and the object that translates this information into the actual Unity objects (the “Generator”). The CollisionGenerator class has no idea about the octree or how the data is stored. It only requires a VolumeCrawler interface. Meanwhile, the OctreeVolumeCrawler class implements that VolumeCrawler interface and provides a sequence of volumes defined by their minimum and maximum points.

This separation is an important programming pattern that means I can, for example, decide to completely change how the voxel data is held in memory. So long as I write a class that implements the VolumeCrawler interface that can handle the translation of the data, the CollisionGenerator will continue to work perfectly. Having each process segmented out into its own class that is only loosely connected to others makes code more reusable and easier to understand.

Some Code

Let’s now take a look at the actual bits of code that are being used here (I apologize in advance to those who prefer their braces on individual lines). First up is the VolumeCrawler interface:

public interface FoGVolumeCrawler {
	/// <summary>
	/// Loads in the next volume
	/// </summary>
	/// <returns>If there is data available</returns>
	bool Next();

	/// <summary>
	/// Resets the crawler information to the start
	/// </summary>
	void Reset();

	/// <summary>
	/// The minimum corner of the volume
	/// </summary>
	FoGPosition min { get; }

	/// <summary>
	/// The maximum corner of the volume
	/// </summary>
	FoGPosition max { get; }
}

In developing this framework, I’ve been keeping it as separate from Unity as possible. That meant, for example, making my own Position struct consisting of X, Y, and Z integers. Next, let’s take a look at the OctreeVolumeCrawler. I won’t include the WorldOctree code as it’s exceptionally long, but I’ve added comments to the appropriate function calls.

public class OctreeVolumeCrawler : VolumeCrawler {

	private WorldOctree masterOctree;

	private IList&lt;WorldOctree&gt; octrees;
	private int index;

	private Position _min;
	private Position _max;

	public OctreeVolumeCrawler(WorldOctree octree) {
		masterOctree = octree;
		Reset();
	}

	public bool Next() {
		if (octrees == null) {
			octrees = new List&lt;WorldOctree&gt;();
			// WorldOctree.Solids() returns a list of all solid octrees in the hierarchy.
			octrees = masterOctree.Solids();
		}

		if (index &lt; octrees.Count) {
			// WorldOctree.center is the center Position of the Octree.
			Position center = octrees[index].center;

			// WorldOctree.size is the width of the Octree between two opposite faces.
			int halfSize = octrees[index].size / 2;
				if (!octrees[index].IsLeaf()) {
				_min = center - halfSize;
				_max = center + halfSize;
			}
			else {
				_min = center;
				_max = center + 1;
			}


			index++;
			return true;
		}

		return false;
	}

	public void Reset() {
		octrees = null;
		index = 0;
	}

	public Position min {
		get {
			return _min;
		}
	}

	public Position max {
		get {
			return _max;
		}
	}
}

Finally, we can look at the CollisionGenerator itself.

public class CollisionGenerator {

	private float blockSize;

	public CollisionGenerator(float blockSize) {
		this.blockSize = blockSize;
	}

	public void Generate(VolumeCrawler crawler, GameObject chunkRoot) {
		int i = 0;
		float startTime = Time.realtimeSinceStartup;

		// The existing box colliders
		BoxCollider[] boxColliders = chunkRoot.GetComponents<BoxCollider>();
		// The index of the existing box colliders
		int index = 0;

		while (crawler.Next()) {
			Vector3 min = new Vector3(crawler.min.x, crawler.min.y, crawler.min.z) * blockSize;
			Vector3 max = new Vector3(crawler.max.x, crawler.max.y, crawler.max.z) * blockSize;

			BoxCollider collider = null;
			if (index < boxColliders.Length) {
				// Retrofit an existing collider
				collider = boxColliders[index];
				index++;
			}
			else {
				// Add a new one once there are no more existing ones.
				collider = chunkRoot.AddComponent<BoxCollider>();
			}

			collider.center = (min + max) / 2;
			collider.size = max - min;

			i++;
		}

		// Remove any old box colliders
		while (index < boxColliders.Length) {
			Object.Destroy(boxColliders[index]);
			index++;
		}

		float timeSpent = Time.realtimeSinceStartup - startTime;
		Debug.Log(i + " collision volumes created in " + timeSpent + " seconds");
	}
}

There are two important things to mention about this class. The first is that it attempts to reuse any existing BoxColliders attached to the GameObject. This is a major time saver, as generally any single action is only going to add or remove a handful of colliders. Reusing the ones that are already there means we don’t get hit trying to Destroy() and instantiate new ones every time we want to update a chunk. With this very simple optimization, I was able to cut the time it takes to regenerate the collision by nearly a factor of 10. Time is very important in this process. Any code that interacts with Unity has to play on the main thread, and an operation that takes a long time in that thread will make the game appear to “hang” until the process is finished. The second thing to note is that this collision is regenerated during FixedUpdate() on the Unity side. I found that this fixed a problem of sometimes falling through the collision while it was being regenerated.

I hope that was informative. If you have any questions, leave a comment, and I will do my best to answer. The next step in development is building outwards and creating the structures to manage the several hundred chunks that will make up the player’s view of the world.