Solitude Tech Demo 2 @ WGDS2015

Over the last few weeks we’ve been working very hard on Solitude tech demo 2. Last year we took tech demo 1 to the Wales Games Development Show (WGDS) and it received an amazing response by all those who played it. You can watch two community members play the demo below.

Since tech demo 1 was so well received we’ve decided to attempt another ambitious tech demo. The main role of these tech demos is to pull together all the game systems we’ve put in place to ensure we’re on the right track and they work well together. These systems include things like a flexible, user friendly structure / ship creator, moddable runtime 3D model importer and editor, fully moddable game logic, an upgrade to Unity 5 with their new physically based rendering (PBR) systems and much more! The demos are created in such a way that show stylised scenarios similar to those that might be found in the future releases of Solitude. We’re very happy with our progress, especially the flexibility of the game, and we’re very excited to share it with you all.

We’ll be keeping the actual scenario of tech demo 2 under wraps so to be a nice surprise for the actual show, but after we’ll make sure we release a video of what it’s like.

The show is on the 19th of June 2015 in Cardiff City Hall. You can buy tickets on their website. If you’re going, make sure you come say hi to us!

Tech Demo Aftermath

It’s been a month since our last post and we’ve been pretty busy so we haven’t had time to put together another one of our blog series’ posts. However, we will update you on what we’ve been up to recently.

As mentioned in the previous blog post, the Wales Games Development Show went really well for us, leaving us on a bit of a high and raring to jump straight back into game dev. Still, we decided to take a step back and analyse why the tech demo went down so well. We know what we have planned for Solitude, but the tech demo was a very small slice and a very specific scenario that could possibly arise within the game, and because it was so successful we wanted to make sure what it had was not lost as we progressed.

After we examined the tech demo and determined the core gameplay mechanics that made it so much fun to play, we proceeded to refactor and clean up the entire codebase. The entire tech demo was developed in just over 2 months from beginning to end, with the last 5 weeks being some pretty intense crunch. The result, there was a lot of messy code, quick fixes and hard-coded systems to get the tech demo ready in time. So, naturally we had go back through and sort it all out. At the time of the tech demo, the server-side mod scripting system was already in and the scenario was written in it. However, the client-side mod scripting was not, so all the client-side tech demo scenario stuff had to be hard-coded. Over the past month Rich has implemented the client-side mod scripting layer and rewritten the entire tech demo to use it as a test. As of now, none of the tech demo game logic is hard-coded and it completely resides as scripts that get loaded at runtime. However, Unity does not natively support runtime model loading, so in order for our modding system to be complete, Rich is having to implement his own runtime model loader (I’m sure Rich will write up a whole post on his as it nears completion).

We also brought in an intern (Steve Cox) to work with us for a couple months and got him doing some of our outstanding tasks and has generally been a massive help. He’s already ported the dedicated C++ written server from Windows to Linux and replaced our build process with an ant build script. This allowed us to hook it up to Jenkins to automate the build process. He’s also created some targets in the ant build script for cross-compiling so we can automate Windows builds from our Linux dev server. All stuff that was on the to-do list and incredibly important. Kind of nice having an extra pair of hands around. We’ve currently got him working on some of the procedural generation code that will eventually feature in Solitude and that’s looking good so far, but there’s still lots more to do on it. We put together a short video to show where we are on that front (height deformation works but currently turned off).

James has been busy working on Solitude’s mod synchronisation system between the server and the client. The idea is that when a server is launched, it scans over its own installed mods (which includes the client-side assets as well) and stores that information in a registry. When players join a game’s lobby (before the game has started), the host is able to select which mods they want enabled for that particular play-through. Once decided, they hit launch and the server checks if the clients have those mods installed and that the files match. If not then the server begins transferring the mod files to the clients that need them while they are still in the lobby (so they are still able to chat). Once all mod files are transferred, the clients load them and then receives the state of the environment from the server before launching into the game. This means that any player will be able to join any server regardless of whether they have the mod files installed or not as they’ll be install on-demand.

That pretty much summarises what we’ve been up to lately. Hopefully, we’ll be able to get out a blog series’ post in a couple weeks.

Thanks for reading!

Solitude at the Wales Games Development Show 2014

It’s been a week since we exhibited our Solitude tech demo, which has given us a bit of time to unwind after 5 weeks of solid crunch. In that time we went from pretty much nothing, to a 2 player cooperative scenario that not only played well, but was also quite polished. Still, we had no idea what to expect until we got there.

Solitude Booth at Wales Games Development Show 2014

We managed to get the our booth set up in pretty good time but then ran into a few networking issues. Since our tech demo is multiplayer and we know from previous experience that the provided wifi and Internet at these venues cannot be trusted, we opted to bring our own networking gear. After testing pretty much everything at home before we arrived, one of the network cables still resulted in being faulty, which meant one of the connections had to rely on own mini wifi network. This worked fine for the most part, but we suffered from minor latencies in the afternoon for some reason. That was the first issue we ran into, the second was that after we got the network up and running, the Commander’s machine (left) was refusing to connect to the server. After assuming that firewalls were to blame and disabling them everywhere, it wasn’t until a fresh pair of eyes looked over the client config and spotted an issue with the second octet of the IP address, which had been entered incorrectly and completely blind-sighted from then on. Whoops! After this was corrected, we had both machines connected to the server and ready to play one minute after the doors opened.

From here on out, things just got better and better. We could not believe how much fun people were having. One of the key gameplay requirements is communication, so we had a voice chat system running with headsets for people to communicate in-game. Players were getting really into it and being very vocal about it, and this was drawing in an even bigger crowd. Apologies should go out to the talkers on stage. When the room was quiet for talkers, occasionally there’d be a “GO LEFT! NO, YOUR OTHER LEFT!” emanating from our booth. Whoops. For the entire day we pretty much had people playing the tech demo with a crowd spectating behind, we even got the Wales Interactive directors into the driving seats.

Wales Interactive plays Solitude

Even though the booth was really busy most of the day, we managed to get out and about a couple times to check out what the rest of the show had to offer. This would not have been possible if we didn’t have our additional helpers, thank you Chris, Andy & Ben! A few of our personal favourites were Infinity Runner by Wales Interactive, really polished game with good use of the Oculus Rift and, surprisingly enough, does not come with the nauseating side-effect that most VR games seem to induce! Friendship Club by Force of Habit, a great little top down battle arena game that supports up to 4 players via local multiplayer. And Sim Raiders by the single developer (the entire game, down to the music and art), Matt Stockham, a fully procedurally generated RPG dungeon crawler that’s different every time you play.

All in all, the show was absolutely brilliant for us. Solitude got way more attention and positive feedback than we could have ever hoped for. We were definitely one of the more active booths at the show so it’s incredibly encouraging. A big thank you to everyone who came to the show and made the day awesome, both exhibitors and visitors alike. An even bigger thanks to everyone who came over and tried out the Solitude tech demo, we had a lot of fun and a lot of laughs throughout the day. If you didn’t get a chance to come over to our booth or didn’t attend WGDS2014 but are still interested in the tech demo, we’ll be releasing a video based on the tech demo gameplay soon to both this site and the Solitude site.

Announcing Solitude, A Coop Space Survival Game

After months of blog posts alluding to our current game in development, we’re ready to let everyone know what we’re up to. Announcing…

Emergency Repairs Wallpaper

Solitude is a cooperative multiplayer action survival game set in space. We’re a big fan of space games and feel there aren’t enough cooperative games out there, however players may play on their own if they choose to do so with computer controlled crew mates. The game is played from a first person perspective as a crew member of the Solitude.

In Solitude, you and your crew find yourself stranded on the other side of the galaxy after humanity’s first experimental warp drive malfunction. Now alone in unknown space, it is the job of the crew to repair the ship and begin the long journey home.

Solitude is one of the games we’ve been wanting to make for a long time now and we’re finally in a position where we’re able take it on as our main game development project. We’ll be releasing information and blog posts about it over the coming months but for more detailed information visit the Solitude website. You’ll also be able to follow our progress in more detail with the Solitude Facebook page and Twitter account too!

As you may know we’re heading to the Wales Games Development Show this year and we’ll be bringing a Solitude tech demo with us. If you’re going to be there come say hi and check it out!

Wales Games Development Show 2014

Hey everyone!

Unfortunately there’s no development post this week as we’ve not been able to spare the time. However, here’s a brief update on what we’ve been up to and what our plans are for the near future.

Last week we were in Swansea doing a talk about how we got into independent game development, as well as our trials and tribulations, for the game dev graduates over there. We think it went down pretty well and got chatting to quite a few people afterwards. David Alden from Rockstar North (Swansea Met. alumni) also gave a really inciteful talk on how he got into the AAA game development industry. All in all, it was a great evening and thanks to everyone who attended.

We’re in Cardiff this coming week, on the 26th June, for the game dev social / TIGA event. Both of us will be doing a small talk there on what we’ve been up to recently. Up until now, we’ve been pretty quiet about it, but if all goes according to plan, we’ll be talking about our latest game.

Wales Games Development Show 2014 LogoThis is the reason why we’ve not had any time to work on development posts. We are exhibiting at the Wales Games Development Show (as usual) and we’ve been pushing ourselves hard to get a tech demo ready for it. We had some big ambitions, but the results are already looking really good and we’re very excited! So, if you’re interested in what we’ve been up to, you should definitely come along and say hi!

Tickets for WGDS2014 are around £6 and are available here.

Hope to see you soon!

Mod Support #1 – Scripting Languages

This is part of a series of posts revolving around mod support, the introduction and links to the other posts can be found here.

For our current game, we’ve decided to provide as much mod support as possible. One large part that will contribute to this is providing a scripting language both on the server and client.

 

Scripting Language

So… what exactly is a scripting language? A scripting language is a programming language used to control another application. In the case of games, and depending on how they are implemented, they can be embedded and used to control the game logic layer. There are advantages and disadvantages of embedding a scripting language in your game, these are:

 

Good: Mod Support

By pushing as much as possible of the game logic into the scripting layer you allow for a mod community to grow around your game. Over the last few years mod support in games has been very lacking and if you provide mod support you’ll be greatly increasing your game’s shelf life and differentiate yourself from the crowd. Modders can become a very loyal and technically helpful addition to your community. Also, who wouldn’t like to see what other people can do with the world you’ve provided them? You make a game because you love the idea and world (hopefully!). Seeing what others can craft with the tools you give them is a great feeling and can even rekindle your original feelings if you’ve unluckily burnt yourself out.

Good: Fast Development Iterations

When developing, if you can do something faster without sacrificing quality – you’ll want to do that. By pushing the game logic out to the scripting layer you’ll be able to reload the scripts without restarting, or recompiling, the game. This is especially useful for developing artificial intelligence and if you’re working with C++. Recompiling your project for every minor edit is exhausting and, after the thousandth time, can send a developer to the edge of insanity and then past the gates of Oblivion.

Bad: Initial Integration

The initial research, selection, embedding and binding of the scripting language to your game core can take a while and is not the easiest thing to do. It may seem like too much effort for developers who are on a very tight schedule and are not experienced enough to get through the process.

Bad: Slower Processing

Any embedded scripting language will almost certainly run slower than the core language you’re running it from. This can eventually have an effect on the end game system requirements but there are steps that can be taken to mitigate the worst cases. Any heavy duty, performance critical code should be run in the core language and then this can be provided to the scripting language as an API call. By doing this, you’re correctly breaking the core logic and the game logic apart and keeping them in their respective places too.

Bad: Exposure of Source

Whilst some scripting languages allow you to pre-compile your scripts to shield your code from prying eyes – you may actually want to share the uncompiled scripts with your community and modders. Your scripts can be the best teaching tool for how to use your scripting API and provide a great start to mods. This matter really depends on how you view your game logic source code and if you’re willing to provide it for the greater good of your game and the modding community, or not.

Bad: Security

If you expose a way for the community to mod your game you will always get someone who will try and do malicious things with it. You will need to sandbox your scripting language runtime and / or whitelist libraries to prevent this. It’s very hard to maintain a complete sandbox but in the end you have to try your best. No one likes a rogue mod deleting save files… or worse.

 

Prerequisites

After deciding that we want to use a scripting language for the above reasons, and feel the above disadvantages aren’t too bad, we need to decide on what language to use. There are lots of choices out there for game scripting languages. For a good game scripting language a few prerequisites need to be met.

 

Performance

Since we aim to provide extensive mod support we are developing as much of the game logic in the scripting layer whilst keeping any processing intensive code and generic client / server logic in the core layer. Due to this the scripting layer needs to be as fast as possible. This is a very important point as stacked inefficiencies will eventually bite you.

Ease of Use

We want modders to be able to get up and running creating mods as quickly as possible. For this we need a scripting language that won’t take new users too long to get into so the lowest possible barrier to entry is required. My early days of development was modding newly released Fallout 1 and 2 so I’d like to give people an easier ride than what I had to do with installing compilers and editing huge files of identifiers.

Security

Since we plan for mods to be client and server side then we need to ensure nothing terribly bad can happen when running mods. Crashing games from bad mods can’t usually be avoided, however, preventing unrestricted access to the end user’s computer is very important. Either a sandbox or whitelisting of functionality is a must here.

Power / Extensibility

Game logic can become very complex so we want to use a language that is either powerful enough to do what we want or can be extended to do what we want. There is no reason to handicap ourselves.

Easy to Embed

At the end of the day, Rogue Vector is a two person company and adding mod support is a huge undertaking that can equally provide huge benefits. We need a language that will be fast for us to embed without spending months trying to integrate and bind it.

 

Language Choice

With the prereqs all agreed on, we need to select which language will be a good fit for us. There are too many scripting languages for me to go into them all, however, they fall into two main categories: dynamically or statically typed. Here are a few languages and the considerations to take into account.

 

Statically Typed

As a rough generalisation, statically typed languages are high level languages that, at compile time, execute extensive checks to ensure type safety and are bound to a data type and an object (or null). Compiler optimisations are also applied in statically typed languages.

mono

Mono is a .NET framework runtime that supports embedding and running of many other languages, even those not from the .NET family such as Java. While Mono is rather large to include in your game it’s surprisingly nimble when it comes to the benchmarks and code execution. In many of the benchmarks it comes out as the fastest scripting system of them all. The main issue is that to use Mono embedded in a commercial product you have to pay a licence fee. This was a deal breaker for us so we stopped investigating it but it has been used amazingly well by Unity and Second Life as their scripting base.

angelscript

AngelScript is a mature language that is very close to C++ in syntax. It hides and handles pointers and memory automatically so that reduces the complexity, however, for a scripting language to remain so similar to C++ may raise the barrier to entry for modders. On the other side, it allows for developers to swap between the scripting and core language without any worries on having to mentally swap development modes. If you want to have C++ style scripting and your core game is C++ then AngelScript may be your winner here. It has a very clean integration and so that reduces the need for a binding library, which is a big plus. It’s used successfully in games such as SOMA, Amnesia and Overgrowth.

Thanks to Ian Thomas (@wildwinter) from Frictional Games and GameDevWales for feedback on AngelScript.

 

Dynamically Typed

Again as a rough generalisation, dynamically typed languages are high level languages that, at runtime, execute many common programming behaviors that statically typed languages perform during compilation. They are not bound to a data type but only to the object (or null).

lua

Lua is generally seen as the games industry scripting language of choice. It’s very lightweight, fast and very portable. Lua becomes even faster when using the JIT compiler called LuaJIT. While it’s only a procedural language it does have a very flexible data structure that allow for object oriented programming techniques to be used. Extension libraries can bring that support even closer to full object orientation. The language itself has a few things to get used to, such as indexes starting at 1 and not 0 and missing expected keywords like ‘continue’, but it’s not too bad to get used to. All in all, it’s easy to see why Lua is used frequently for embedded game scripting and has been used in games such as World of Warcraft, Freelancer, Garry’s Mod and Natural Selection 2.

python

Python is another popular procedural language similar to Lua. It’s a lot heavier due to it including all the nuts and bolts that Lua does not. It also runs slower than Lua so this is something to keep in mind. I have an issue with the white space nature of Python but that’s more a personal dislike more than anything else. In the end, Python’s focus is wider than Lua for better or worse. Python has been successfully used for game scripting, like in Civilisation 4 and Battlefield 2, so that speaks for itself.

v8

Google’s V8 Javascript-based scripting language seems to be a faster choice than core Lua, however, it’s slower than LuaJIT according to the sources I’ve found. I haven’t been able to confirm this with hard benchmarks as I don’t have time so I’d just say it’s pretty fast. Binding support seems to be lacking and it’s an uphill struggle to get it embedded and working the way you want, especially if you want to pass complex objects between the core language and V8. I couldn’t find any games that currently use V8 as their scripting language but, on the brightside, a lot of people know Javascript syntax.

 

Our Conclusion

We decided to back Lua (LuaJIT) for our scripting language of choice. The main reasons are already mentioned above but also we needed a scripting language that is consistent between the server and client. While Unity has no native scripting support, there are assets that help integrate LuaJIT in nicely. Other scripting languages would be harder to integrate into our game client. At the end of the day most of the scripting languages highlighted have been used very successfully so personal preference is also a key deciding factor.

For a more indepth look at some of these languages and a set of benchmarks see the blog post at upvoid.com. A wider set of benchmarks are found here and here. My next post will go into more details of LuaJIT embedding and binding into a C/C++ game core.

Thanks for reading. Feel free to get in contact with me on the comments, email or grab me on Twitter at @CWolf.

Mod Support #0 – Introduction

Mod support is a loved, much asked for and difficult to implement side of game development. It can range from small configuration file changes to full blown total conversions. In the more extensible form it takes enough experience with games to extract game logic from core logic, embed scripting languages, load models and animations at runtime and merge it all together as seamlessly as possible.

Coming from a modding background before entering software and games development it’s an area very close to my heart. I feel it’s an amazing tool to help increase your game’s longevity and, more importantly, allow for a community to form around your game. In the best situations this community can create amazing additions or changes to your game that can add new life to a game that, even as the developer of, may rekindle your interests after you’ve long exhausted yourself.

As we’ll be adding mod support to our current game we’ll write about what we use and how we go about using it. As there tends to be little information about the more complex side of things we’ll try to expose these under discussed areas to help more developers planning the same thing.

If anyone wants to get in contact with me feel free to reach me at richard@roguevector.com or my Twitter at @CWolf.

Contents

The IOs of Game Netcode #3 – Synchronisation and Locks

This is part of a series of posts revolving around game netcode development, the introduction and links to the other posts can be found here.

 

We’ve already established you need to run your netcode framework on a different thread to your main game’s update/render loop, something which all netcode developers will agree is a requirement for writing good netcode. This means you’re already in danger of the threading and concurrency issues mentioned in the last post. So how do you ensure that you don’t run into these issues? Well, you have a few weapons in your arsenal to tackle the problem. The first one I’m going to discuss is locks.

 

Locks

Think of locks as your most basic weaponry against threading issues. The pistol with infinite ammo you switch back to after your power-up wears off. Locking is a synchronisation mechanism that ensures that only one thread can execute a piece of code at any given time. It does by forcing other threads to wait until the currently active thread is finished with the locked code.

Locks are such a common mechanism that I’m pretty sure all modern languages that support multi-threading also support locking. It’d be pretty disastrous if they didn’t. The main differences are the types of locks, the terminology and how they’re used. You usually have a couple of types available to you, such as object-level locks and method-level locks. Object-level locks are the bread and butter here and more complex locking mechanisms can be built upon them. In C# an object-level lock looks like this:

lock (this) {
	// Your synchronised code
}

In Java you achieve object-level locks using synchronized blocks, which are essentially the same thing:

synchronized (this) {
	// Your synchronised code
}

Unfortunately, in C++ you do not have a simple statement for object-level locking (although I’m sure you can create a template to do it). Instead, you need to instantiate a mutex (mutually exclusive) object (part of the C++ standard library) and perform the lock operation on that.

std::mutex mtx; // Declared in the class constructor

mtx.lock();
// Your synchronised code
mtx.unlock();

These code snippets will all do the same thing when multiple threads hit it at the same time. The first thread to request the lock will get it and be allowed to proceed to execute the code within the lock. All other threads will request the lock, but will be forced to wait (block) until the thread with the lock leaves the synchronised code, after which another thread will receive rights to the lock and proceed.

There are also method-level locks, which work similarly to the object-level locks, except work at the method level, synchronising everything inside a particular method. In C# this is achieved with the following:

[MethodImpl(MethodImplOptions.Synchronized)]
public void SynchronisedMethod() {
	// Your synchronised code
}

In Java, you use the same synchronized keyword as in object-level locking:

public synchronized void synchronisedMethod() {
	// Your synchronised code
}

C++ does not have a mechanism for method-level locking, but this can be easily achieved with a simple object-level lock. The method-level locking is just a convenience mechanism for object-level locking everything in a method.

Now, method-level locking and the examples I’ve shown for object-level locking have a pretty serious issue to take into consideration. A thread can achieve a lock on a method or an object while another thread has the same lock on a different object of the same class. This is because these types of locks are handled at the object level (locking against it’s own instance or a member object). For the most part this is exactly what is required, but sometimes there are situations in which you need to synchronise all instances of a particular class. This is called class-level locking and can be achieved in a couple of ways. You can perform an object-lock on a static object shared by all instances of a specific class, or you can do method-level locking on static methods.

Of course, with most coding concepts, there is a down-side to very up. With locking mechanisms, that is deadlocks

 

Deadlocks

A deadlock is when a thread is indefinitely blocked by a lock and they usually occur when multiple threads are executing code that results in nested locks on. For example, let’s take the classic bank transfer scenario.

public class Account {

	private double balance;

	public Account(double balance) {
		this.balance = balance;
	}

	public void withdraw(double amount) {
		balance -= amount;
	}

	public void deposit(double amount) {
		balance += amount;
	}

}

public class Bank {

	public void transfer(Account from, Account to, double amount) {
		synchronized (from) {
			synchronized (to) {
				from.withdraw(amount);
				to.deposit(to);
			}
		}
	}

}

Both accounts are synchronized so that exclusive access is obtained and the program is assured that it can perform all operations required of the transfer without blocking. The deadlock arises when a Bank executes two opposing transfers between the same two accounts at the same time (separate threads).

final Account account1 = new Account(1000);
final Account account2 = new Account(1000);
final Bank bank = new Bank();

new Thread(new Runnable() {
	public void run() {
		bank.transfer(account1, account2, 500);
	}
}).start();

new Thread(new Runnable() {
	public void run() {
		bank.transfer(account2, account1, 500);
	}
}).start();

The result can vary depending on execution order, but if both threads manage to obtain their first lock, then a deadlock will occur. This is because both threads cannot obtain their second lock until the other thread releases it, resulting in both thread blocking indefinitely.

The primary reason behind deadlocks is bad software design. Deadlocks can easily be avoided if the developer takes a step back and designs the inter-thread communication first. If the program/system makes use of multiple threads, then a deadlock scenario should be at the forefront of the developer’s mind. I’ve seen a number of poorly written programs where the deadlock scenario isn’t even considered and, for the most part, the program runs fine, but occasionally a deadlock will occur. This is because the developer will just throw in a lock here or there to ensure they don’t run into concurrent modification exceptions and suddenly have methods with locks calling other methods with locks, resulting a nested deadlock. Of course, the way they solve this is to ensure the proper execution order by adding more locks, which as you can guess, just makes things worse.

In my experience, the best implementation of multi-threaded operation consists of very few locks, but in the right places. DESIGN YOUR MULTITHREADING FIRST! :)

 

Thread-safe and Concurrent Data Structures

So now you should understand how to synchronise your multithreaded code, while avoiding potential deadlocks. It will help you avoid the concurrency issues when writing good threaded netcode. Now, I’m going to briefly touch on a set of special data structures that are designed to further help you avoid concurrency issues and deadlocks.

Thread-safe and concurrent data structures are a set of data structures that follow a certain set of rules to ensure that race conditions do not happen. This is done through a variety of different methods, such as locking and atomic operations.

They take care of all of the concurrency issues without any of the potential deadlocks, making your life a lot easier. Java, C# and C++ all have a decent set of thread-safe data structures in their standard libraries, too many to go through here, but it’s definitely worth searching their respective documentations and read up on the specifics.

One thing you need to keep in mind though, even though the add and remove operations are thread-safe, any iterators or enumerations generated from these data structures may not be. Meaning, if you loop over all the elements in a thread-safe data structure, the resulting collection may not be thread-safe. So if another thread adds or removes an element to the data structure while the loop is being processed, you’ll end up with concurrent modification and a race condition causing unpredictable behaviour. Fortunately, these thread-safe data structures usually offer up some kind of fail-fast iterator or enumerator which will throw a concurrent modification exception when it detects that the underlying structure has been modified after it has been created, which can then be handled properly by the developer.

You can usually avoid the concurrent modification exception by using the correct concurrent data structure for the job and in the right place. I like to use a concurrent queue for inter-thread communication as it allows me to iterate through the queue in a thread-safe way using peek and pop operations (no need for iterators or enumerators), which I will show an example of in a later post.

 

This pretty much wraps up this post. It’s a bit longer than the previous ones but I wanted to finish with the multithreading so that I can actually get into some nitty-gritty netcode stuff next post :) Hopefully you can take something away from this that will aid you in your game development, and as always, if you want to chat or pick my brains about anything you can either comment below, catch me on IRC (click Chat above) or fire me a tweet to @Jargon64.

Thanks for reading! :)

The IOs of Game Netcode #2 – Threading and Concurrency

This is part of a series of posts revolving around game netcode development, the introduction and links to the other posts can be found here.

 

In the last post of The IOs of Game Netcode (found here), I talked about a few general rules of thumb I usually follow when starting a new netcode framework. Over the next few posts I’m going to go a little deeper into the technical options available to us as netcode developers and what routes I take based on different scenarios. The first topic I’m going to start with is threading, and the resulting issue – concurrency. This post is quite long so I’ve only addressed the issues the developer should keep in mind while working with threads. The solutions to these issues will be covered in the next post :)

 

Threading

As any netcode developer will know, the first hurdle you will hit when writing netcode or working with sockets is the threading issue. Normally, you can only execute a single piece of program code at a time. Threading allows you to execute multiple pieces program code simultaneously by running it on different threads. By default, reading and writing via sockets will block current execution of program code until it is complete. This isn’t necessarily an issue with writing to a socket unless you are writing faster than the hardware can handle (network card or modem), but if you’re reading, the operation will block until there is data to be read. One of the ways around this is to check the number of available bytes to be read before reading and if there are bytes available, only read that much. However, even with using this method, the actual reading and writing of bytes will block, even if it’s just a moment, and you don’t want this in your main game or render loop. Another way around this is to use asynchronous read and write operations. These run in their own threads automatically (provided by the socket library you are using) and pass the data back via a callback when complete. They have their uses, such as web services, but for real-time game netcode they can begin to cause problems as you cannot be sure of the order of transmission and you start to encroach of race condition territory.

So, in order to effectively read and write across a network with sockets, without causing the main program to hang while it is doing so, you’ll need at least one additional thread to perform the socket operations on. The reason I say at least one additional thread is because when developing your game client, you only really need a single socket to connect to your server. However, for the server, you’ll need a thread for every connecting client to handle each of the socket operations. For those of you who are now thinking “Why not use non-blocking sockets?”, I’m aware of this and it will be covered in a future post, but for the time being I’m focusing on the standard variety of sockets as there’s a lot more to consider with using non-blocking sockets :)

Anyway, as soon as you start working with multiple threads, it opens up a whole new bag of worms in the form of concurrent modifications.

 

Concurrency

Concurrent modifications are when you are reading a value of a variable in one thread, while it is being modified in another. Another example is looping over a collection while different thread is adding or removing an element from the collection. Most languages languages allow this type of access with unpredictable results. This is due to two main reasons.

 

Race Conditions

The first is the race condition, you just don’t know what thread is going to access the variable first. There are three scenarios for a race condition:

  • Read & Read – Both threads want to read the value of a variable. It is unknown which thread reads the variable first but it doesn’t matter as it does not change. Both threads read the same value.

  • Read & Write – One thread reads the variable, while the other writes to it. The final value of the variable will always be what is written, but the value read by the reading thread may be that of the variable before the write, or after. This can lead to the aforementioned unpredictable behaviour and potential crashes.

  • Write & Write – Both threads want to write. No read operations are carried out, but that does not eliminate an unpredictable value being read later. This is because the final value of the variable is unknown. It is the value of whichever thread wrote to the variable last.

The above scenarios are very specific and only show two threads accessing a single variable. However, in reality, these threads would be doing more than just reading and writing to a variable. For example, we have a shared (global or static) float variable called currentSpeed accessed by both threads:

Thread 1 – Anti speed-hacking protection

currentSpeed = player.getVelocity().getMagnitude();
if (currentSpeed > MAX_PLAYER_SPEED) {
    player.disconnect();
}

Thread 2 – Find the fastest moving entity

Entity fastestEntity = null;
currentSpeed = 0;
for (Entity entity : entities) {
    if (entity.getVelocity().getMagnitude() > currentSpeed) {
        currentSpeed = entity.getVelocity().getMagnitude();
        fastestEntity = entity;
    }
}
return fastestEntity;

For the record, you should never share a variable between two different tasks like this, but if you did this is how it might play out. For this example we are going to assume that the player is moving at a speed of 4 and there is one other entity in the world moving at a speed of 10:

// Start with Thread 2
Entity fastestEntity = null;
currentSpeed = 0;
for (Entity entity : entities) {
    if (entity.getVelocity().getMagnitude() > currentSpeed) {
// Switch to Thread 1
currentSpeed = player.getVelocity().getMagnitude();
// Switch to Thread 2
        currentSpeed = entity.getVelocity().getMagnitude();
        fastestEntity = entity;
    }
}
// Switch to Thread 1
if (currentSpeed > MAX_PLAYER_SPEED) {
    player.disconnect();
}

In this scenario, the first time currentSpeed is assigned is after the first switch, where it gets set to 4. Before it can test the value of currentSpeed, the process switches to thread 2, where currentSpeed is set to the value of the fastest moving entity’s speed, which 10. Then the process switches back to thread 1 to perform the test. Oh look, the player is moving at a speed of 10, they must be speed-hacking, better disconnect them!

This occurs because the threads can switch at any point in during normal processing and is always something you need to keep in mind while working with multiple threads. There are mechanisms to get around these issues, but first…

 

Non-Atomic Operations

The second reason concurrent access can cause unpredictable results is due to non-atomic load and store operations. This is a bit more low level and might be harder to grasp for those who aren’t familiar with CPU architecture. There are a couple of definitions when it comes to the atomicity of an operation. It can refer to a single instruction or an operation of multiple instructions. Essentially, an operation is considered atomic if it completes in a single step relative to other threads. Therefore, a non-atomic operation can also result in a race condition as described above, but for the purposes of this section, we’ll be focusing on single instructions.

When you want to run your game (or program), you need to compile it into machine code first. Every developer knows this. During the compilation process, the compiler reads our source code and optimises it internally before outputting machine code, therefore the machine code doesn’t directly reflect the logic that we’ve defined. Most developers know this. One of the optimisations compilers do is to maximise CPU register usage. General purpose CPU registers typically have a size equal to the bit-architecture of the system. Modern day systems are 64 bit architecture and have 64 bit general purpose CPU registers. If you have two 32 bit integers that have some operation performed on them, the compiler will attempt to optimise the machine code to load them both into the same 64 bit register to perform the operation more efficiently. Some developers know this.

Now, the problem lies in the scenario where you attempt to perform an operation on a data type that has a larger bit requirement than the CPU register can handle, or the register already has some active data in it. The data ends up being split into multiple machine code instructions – and this is what causes the problem. Can you remember when I mentioned that threads can switch at any point in normal processing? Well, this happens at the machine code instruction level. So, a simple variable assignment such as:

long timestamp = 1L;

Can be split into two machine code instructions, with a thread switch right in the middle.

Not many developers know this.

This is the very essence of non-atomic operations. If processing switches to another thread during a multi-instruction load or store, the race condition is the least of your worries. Depending on your operation, you’ll either end up with a torn-read or a torn-write. One thread attempts to write a 64 bit integer to a variable but only gets as far as the first 32 bit store instruction, another thread reads the full 64 bit contents of the variable, then the first thread writes the second 32 bit store instruction. What the second thread ends up reading is one-half correct data, one-half bad data and one-whole big problem.

 

Some of you may now be thinking “Holy crap, threads are dangerous, how the hell do programs even function without exploding into a flaming ball of random corruption!?” Well, the answer is yes, they are dangerous, but there are also certain principles you can abide by and mechanisms you can use that prevent this pseudo-random behaviour. However, these topics will be addressed in the next post ;)

Like before, if you have any questions about this post or just want to chat netcode, please comment below or fire me a tweet at @Jargon64.

Thanks for reading! :)

IGC Conference for Game Devs 2014

This last week was GDC for a lot of the games community. Not being able to go this year we joined the rest who were eager to talk games and listen to the announcements. Not only that but we noticed the Indie Games Collective in London were hosting a Conference for Games Developers so we instantly signed ourselves up for two free tickets. It was well worth it.

IGC-logo-300x193

We travelled up to London on Thursday night so we wouldn’t have to travel early on the first day plus we heard rumours of a small get-together at the Loading Bar, a game themed bar in Soho (sadly moved to another location now). With a good few drinks and a game of Cards Against Humanity we closed the night off having a great time.

The venue at London South Bank University was pretty accessible and the first day of talks were enjoyable. We especially liked the chunk that involved Louise James from Generic Evil Business (Holy crap, how good is Twitter?), Andy Esser from Zero Dependency (Carving Your Own Path – Making Tools, Not Games) and James Parker from Opposable Games (Dual-screen vs Second-screen).

Danny Goodayle from Just a Pixel gave his first first talk about Light then tweeted about setting up a weekly indie Google Hangout. We signed up to take part in that so we’ll see if anything evolves out from there.

The evening event was a good chance to talk in a more casual environment (more drinks!) and we both had fun chatting the night away. Sadly, we had to leave after lunch on the second day but all the talks were great too.

The conference was recorded and the videos should be uploaded over the coming week or two. Even though there was nothing ground breaking we had a lot of fun and we’ll definitely try to attend any more events that are organised in the future by the great people that make up the IGC. Special thanks to Byron Atkinson-Jones and Natalie Griffith for getting the event rolling.

Interfacing with UI #4 – Coherent UI

February 5th, 2016

This is part of a series of posts revolving around user interface design and development, the introduction and links to the other posts can be found here. Last I wrote about user interfaces I discussed the new Unity UI system and I wrote about our process of porting from Daikon Forge to it. That was a year and a half ago and a lot has changed since then. To keep things interesting we decided to move from Unity UI (yet another move?!) to Coherent UI and I’ll explain why we did it. Why Move… Again?!... (read more)

RT @CWolf: That's module script state syncing complete for chunking support in @SolitudeGame #RV

14/08/2017 @ 4:20pm UTC

RT @Jargon64: MFW I finally get the Lua game update loop working for the thruster controls but neglect to multiply acceleration b… https://t.co/upYsrFRr4V

4/08/2017 @ 7:06pm UTC

RT @SolitudeGame: Now that server-side physics has been implemented, @Jargon64 & @CWolf get in their box ships for some multiplayer t… https://t.co/60zNflf3Hm

3/08/2017 @ 4:53pm UTC

RT @CWolf: Almost able to merge in a major refractor for ingame multiplayer computer terminals. Tomorrow's the day! Then more… https://t.co/gzenvN0rmU

31/07/2017 @ 9:10pm UTC

RT @CWolf: The biggest ones are easy enough to keep tabs on but I'd love to know the smaller events going on these days

26/07/2017 @ 10:17am UTC