Rolled Out! Dev Blog #1

Starting today, we’re going to be posting an update on our development progress twice a month - once on the 15th, and again at the end of the month. Since we’re crowdfunded, it’s important to be transparent with our supporters!

Let’s jump right into it, with a writeup from one of our developers, CraftedCart.

The Big Cleanup

When we initially began work on developing the game, neither me or Brandon (the only two people on the team at the time) had much experience working within the Unreal Engine. Naturally, opting to learn as we went has lead to some… let’s say sub-par design from a programming standpoint.

So what are the issues we’re running into now?

There’s two main aspects that we’ve got kicking around at the moment: multiplayer woes, and various synchronization issues (with this impacting multiplayer massively). There’s a few other issues I’d like to address but these are the two I’d like to focus on.

Starting with multiplayer, I didn’t really grasp the Unreal gameplay framework initially. For those unaware, Unreal Engine has a framework defining where certain parts of game logic and data should go (the game has logic and state; players have a controller, state, and physical presence in the world; etc.). Importantly, Unreal also defines various networking rules on the gameplay framework: certain objects exist only on the server, certain objects exist only on certain clients, and networking is most conveniently handled in the player controllers, to name a few examples.

Adhering to this framework makes it “remarkably easy” (relatively speaking) to add in networking to a game since Unreal can take care of a lot of the networking for you behind-the-scenes. If you’re me however, you run into various crashes from accessing server-only info from clients; multiple clients sharing data they shouldn’t/clients being unable to share data that they should; and just generally having a big headache.

On a side note, Cedric Neukirchen has a great reference on how networking fits in with the gameplay framework, among other things if you’re interested. Page 8 in particular was most helpful.

In addition, synchronization issues is just the term I’m using for various race conditions. Strictly speaking, the spawn order of various objects in the game (the player ball, the stage, the minimap, etc.) is undefined - it just happens to work out fine most of the time, at least in singleplayer. You may have noticed, particularly if the game lags when loading in a stage, that certain aspects of the game don’t work as intended (the stage not tilting being the most noticeable one). When each object is spawned it, it tries to grab references to other objects in the world. If the stage doesn’t exist when the player ball is spawned for example, the ball fails to grab a reference to the stage and therefore can’t tell the stage about how to tilt.

Some other issues I’d like to get round to fixing, that I won’t explain in so depth here, include…

  • Baking fixed stage transforms into the vertex data on import, rather than transforming it after-the-fact (which makes for some fun for the physics crew)
  • Handling malformed level configs more gracefully, instead of crashing the game
  • Fixing the darn stage indexing so you don’t have to delete Game.sqlite all the time

What does this mean, then?

It means I’ve got some code to refactor.

Oh, you wanted more than eight words? Alright, then.

It means that you might not see all too much progress in the game for a little while, at least with regards to new and tweaked features. I’m gonna be working on cleaning up our code base, making it easier to extend (which is a must if we’re gonna have a level editor and Lua scripting support) and fixing some of those bugs in the process.

Now have a very uninteresting screenshot from the current state of the stage loading rewrite.
A very uninteresting screenshot

Here’s a Morris, for scale.
Morris for scale

Moving On…

We’re still in the depths of rewriting the physics. We’re trying to disentangle ourselves from PhysX wherever possible, as we’re aiming for a very specific implementation that is simply out of scope for Unreal Engine’s infamous embedded physics simulator.
C++ physics code
Blueprint physics code

Most physics engines perform calculations in discrete distances and steps, where an object exists in one position on frame 1, and a different position on frame 2, where all of the space between those frames isn’t tested. This means in a typical physics simulation, something moving at a sufficiently high velocity can travel through other objects - a phenomenon referred to as ‘tunneling’.

We’re aiming for a completely continuous simulation, where no matter how fast either the ball or a stage object moves, the interaction is always what you would expect. This isn’t as hard as it sounds if you’re building physics objects to certain specifications - constructing their collision out of one or more convex hulls (shapes which all vertices point ‘outwards’) makes the math for this simpler. Doubly so if you only want to translate - no rotation. However, we have objects which consist of completely arbitrary shapes, which can move and rotate in absolutely any way desired by the level designer.

Constructing a robust collision detection and resolution solution for this is difficult, to say the least. However, we’re making pretty good progress on that front - expect more regarding that in the next update.

That’s everything we have to share today. See you all in two weeks!