June 2019 Update - Small steps
2019-06-06

June 2019 Update - Small steps

So it has now been a month since I started treating skipifzero like a real job. I would say it has gone well enough, but it has been a weird couple of weeks. Summer hit Sweden, the heat and longer days always makes me a bit groggy, which hasn’t been the best for productivity. There has also been a lot of Swedish holidays this month, which has made it somewhat hard for me to tell whether a given day was a vacation day or skipifzero work day. I have learned from previous mistakes that you can’t work all the time and must give yourself time to relax as well, otherwise you burn out.

There has been progress on the game, but maybe not as much as I would have liked. I have worked on Phantasy Engine in some form of another for quite some time now, but until now I hadn’t actually attempted to make a game with it. In other words, it is time for me to eat my own dog food.

As might have been expected, there has been a lot of sharp edges when actually trying to use Phantasy Engine. There were design decisions that made sense when designing the engine, but was hard to use in practice. Some glue needed to tie together the engine and game code was missing, etc.

Overall I’m not that surprised that the startup would be slow, in fact it was exactly what I was expecting. Still, one always hopes that things will go faster and smoother than they inevitably end up doing. I did choose to use my own engine, so this project will likely always progress slower than if I used Unity or Unreal Engine. But I’m fine with that, it’s what I enjoy, and I expect to get some gains out of it further down the line.

Project Apocatropics

Like last time, I will summarize the current state of the game with a gif:

Of course, it still looks very ugly. A lot has happened behind the scenes though.

Level format

One of the main things I have spent time on is designing a level format. In theory I could define levels directly in code, and honestly it might even be fine for my purposes. However, defining levels in code makes it very hard to create visual tools to modify levels (e.g. level editors). In addition, it would make it very hard for me to outsource creation of levels to other people. For these reasons I decided to make a level format from the very beginning.

One of my main requirements was that the level format was easily human readable and modifiable. I choose to use JSON as the base. Not because I think JSON is the best format (personally I might have preferred TOML), but because JSON is the most common. I did not want to write my own parser (even I have limits), and there are tons of different JSON parsers available. I ended up using sajson, which has worked out pretty well for me so far.

Physics

Besides the level format I have looked quite a bit at physics engines this month. Phantasy Engine does not have any physics engines built-in, and it honestly might never have (because then it would no longer be lightweight). Picking and integrating a physics engine is usually something I try to avoid as long as possible, because from my experience it causes so much pain in all sorts of practical manners when you end up doing it.

First I looked a the usual suspects, Bullet and PhysX. I decided to not use any of these. They struck me as being way too complicated, and really too heavy dependencies to include. They would make my build system more complicated, and would likely significantly increase my build times. The integration itself would be complicated, and my end product would be very dependent upon whichever one of them I ended up using.

The truth is I don’t really need that complicated physics. In fact, I mostly need collision detection. I might not need physics (beyond very simple things) at all. So I decided to try out the most simple (3D) physics engine I could find, which ended up being qu3e by Randy Gaul.

The physics itself in qu3e ended up working out fine, perhaps even a bit too well. Boxes rotated a bit too realistically when I perhaps prefered them to not do that. Applying forces was a bit more complicated than just setting velocities directly from a game programming perspective. But those things are details I could work around, not that much of a problem.

What was a bigger problem was that even qu3e, the simplest physics engine I could find, was not “stateless”. What I mean by not “stateless” is that qu3e (and all other physics engines) have their own simulation of the world. This is a problem because that means I have to keep my own simulation, which I store in my fancy single chunk game state, in sync with it. In fact, unless I can do this synchronization extremelly efficiently, it negates a lot of the useful properties of my single-chunk game state.

This left me with essentially two choices. Either I could attempt to modify qu3e to make it “stateless”, or I could write my own simple physics simulation. After a lot of thinking I made the hard decision to make my own physics simulation. This is something I would have preferred to avoid, but given the situation I think it was the best alternative.

So the work on my own physics simulation has mostly been on collision detection and response. I have implemented OBB SAT (Separating Axis Theroem) tests before, but I have not really been entirely convinced of their correctness. This time I implemented quite a bit of unit tests, and it turns out my suspicions were correct. I have spent quite a bit of time this month struggling with making the SAT tests work correctly. I think have it mostly correct now, but my unit tests covers far from all cases.

Lore

In order to give myself a break from the physics engine pains, I decided to start writing down lore for the world of the game. Writing lore has turned out to be a nice change of pace. I don’t have to engage the logical part of my brain the same way, which is really relaxing.

My brain produces lore way faster than I have time to write it down, so coming up with material is never a problem. The main limitation is how well and fast I can translate what I have in my brain to text that can easily be understood by other people.

I have currently written down a few pages of lore, and the people I have shown it to have been positive so far. It seems coming up with and designing the world itself will not be a problem. The question remains how well I can actually write a story in this world.

Phantasy Engine

One of the main problems with Phantasy Engine itself turned out to be the resource system. The way it worked was that you registered e.g. a texture with the renderer, and you then got an index back which was used to refer to it. This turned out to be very annoying when trying to write a level format as you would rather like to refer to resources with a name (in my case, the file path).

However, just using strings everywhere is not a particularly good idea. Strings are expensive to compare and hash, and they take up quite a bit of space. A solution to this problem is to pre-hash strings and just store and compare the hashes.

The above works well under two assumptions:

  1. You have a well defined hashing algorithm that always returns the same hash for the same string, on every run on every platform (i.e., std::hash<std::string> would not do it).
  2. You don’t have any collisions, all strings you use as identifiers produce unique hashes from all other strings you use.

Luckily, this is something I had actually written and implemented ages ago in sfzCore, under the name of StringID. I just never ended up actually using it, until now that is. It somehow ended up working perfectly almost immediately, which is not always the case when using old (practically untested) code. I’m very proud of past me.

So with the help of the StringID’s I can now track and can refer to all resources with the help of their paths (relative to the executable). For now this is working out fine, but we will see if it ends up problematic in the long run.

ZeroG

No updates to ZeroG this month, focus has been on getting Project Apocatropics started. I haven’t yet decided if I’m going to start integrate ZeroG into Phantasy Engine this month or not, but probably not. Frankly, it is not that important at the current state of development.

Conclusion

If you made it this far, good job, and thanks for taking the time! As always, don’t forget to follow me on Twitter if you are interested in more updates!

< May 2019 Update - Big Announcement