My turn (part 1)

Unity has all sorts of automatic support for networking.. as long as you’re looking to build a real-time game where your objects automatically synchronize across all your clients from a single controlling host.

Things get a bit more difficult if you’re trying to make a turn based game.

Altair is such a game. Players submit turns by clicking the end turn button which queues up the commands until everyone has completed their turn. Once all players have completed their turn, a signal gets dispatched to go along and collect all the commands and drop them in to the turn processor.

This part is actually pretty elegant. It leverages strangeioc’s signalling mechanism to fire off an EndTurnSignal  of which there could be any number of listeners. The signal is dispatched synchronously to all listeners and each listener is passed a list object to populate with whatever player commands they wish. Once every observer has had its turn to do what it needs to do, an EndTurnCommand is dispatched which takes the command list, fires it into the bound turn processor and actually calls the Process method accordingly.

So this works great in a single player setup (and is wonderfully disconnected I might add), but things start to break down when we want to have this work over the network.

Each player actually has their own unique view of the game world. Why? Because each player is going to have the ability to scrub back and forth over the turn history so they can see what happened from any angle at their own pace.

This presents an interesting challenge as we are no longer able to leverage most of Unity’s automatic synchronization magicks. If we did, everyone would see what the host sees and that’s not the point at all.

selected_ship_0.1.7-alpha
selected ship + movement ui overlay

So what do we do?

Honestly, I’m still sorting it out. I’m working with the idea of simply serializing the command list across the network as required but Unity won’t serialize any complex classes. The list of supported types pulled from the docs is:

  • basic types (byte, int, float, string, UInt64, etc)
  • arrays of basic types
  • structs containing allowable types
  • built-in unity math types (Vector3, Quaternion, etc)
  • NetworkIdentity
  • NetworkInstanceId
  • NetworkHash128
  • GameObject with a NetworkIdentity component attached

Note how it doesn’t even accept classes of any kind? Structs only! No lists either, arrays only!

My current approach is to create a custom network view of each command in struct form to enable serialization across the network pipe. I think this is a good thing as it will actually force me to think about what really needs to make that jump. It is however going to require a bit of extra work as I am probably going to have to implement my own id system (of which I’ve already mostly done anyway) in order to keep track of the game state.

Wish me luck!

Tune in next time for part 2 of this post.. In which I will hopefully have an actual working multiplayer turn processor!

How strange..

When I first started to look at strangeioc, I felt a little bit like I was headed down the all too familiar path of learning something new just because it’s there. It’s not like I have a huge history of successfully completing.. well.. anything. So it was entirely possible that altair was doomed..

It turns out however that strangeioc is not only really cool, but highly functional as well.

Strange (see how I dropped the ioc? It’s because we’re friends now.) lets me code in a style that I am more accustomed to seeing in enterprise grade business applications rather than game development; the MVC development pattern.

The beauty here is just how natural a fit this actually is. My views get to be whatever they need to be to get the pixels onto the screen and intercept user input. Then they get nicely translated into the appropriate events by way of a mediator object before getting routed to an appropriate controller/command to actually make things happen. And all of this happens by way of an easy to follow binding process.

If you’re working in Unity and haven’t given strangeioc a try (The ioc is back. Things got weird. People were beginning to talk.), I recommend you check it out.

My latest efforts have seen me refactoring (for some very loose definition of refactoring) my movement arc into its own game object so that I can easily put it on.. anything.

I’ve bumped into some interesting scenarios with using the default object picking functionality built in to Unity. Specifically, there’s a beautiful little method called OnMouseUpAsButton which fires off the appropriate events on an object that you’ve clicked on. It however relies under the hood on simple raycasting which has the undesired effect of having objects get in the way of my mouse clicking.

movement_arc_collision_box

In this image you’ll note the green box is the clickable region used by the movement arc. There’s some logic in there to ensure that it only actually uses clicks that fall within the designated movement space but that bounding box is a Unity collider. This is a really easy way to leverage the built in click functionality. However, note the asteroid in the lower right corner and how it overlaps with our bounding box. Its collision mesh actually ends up coming first along the y-axis so it intercepts clicks in that corner.

How annoying..

The quick fix is quite simply to move the asteroid on to the Ignore Raycast layer. This layer is ignored when doing the built in mouse click raycasting. This of course has a caveat, you can’t put your object on another more meaningful layer. I suppose you could use tags to help organize things but the physics system leverages layers so I’m certainly losing something.

This solution seems good enough for me for now as I don’t intend to ever have a player click on an asteroid. We’ll save that for my next game, asteroid clicker.

Also, blogger was terrible so I’ve migrated to WordPress in the hopes that it is slightly less terrible. Let’s see how it goes!