051 - Capuchins and Kubernetes

January 19, 2020

This week I picked up where I left off in 050 with normalizing the pre-defined TileBoxees.

I made some changes to the PredefinedTileBox data structure that I mentioned last week in order to make it more flexible.

I also normalized a pattern that I'm using in a few places now - using a build script to take the keys from a YAML map and code generate an enum so that I can reference the deserialized data from the map in a type safe way.

Now going forwards whenever I have to do this again it should be straightforwards instead of duplicative.

Capuchin walk cycle

I added the AutonomousNpcComp, the MovementComp and the AreaConstrainedComp to Pookie - but the web client crashed when he attempted to walk.

This was due to code that assumed that if an entity walks its armature has a walk animation - but I hadn't made one for the Capuchin mesh.

At first I considered just making the code fall back to Idle to prevent mistakes like this in the future - but then I thought that I'd much rather have some sort of linter that ensured that every armature has all of the animations that it needs.

This would be complex since it would mean we'd need to statically know all of the animations that an armature might need to play - based on all of the entity's that use that armature. I decided to save this for another day.


It took me a hours to finish the animation since I had to re-do the rig and weights a few times due to different mistakes that I made.

But from that rework I ended up learning a lot about rigging. Practice makes perfect!

Far from perfect - but good enough for now. As my skills improve I can come back and redo a lot of the early art in the game. Practice makes perfect!

I was having trouble with Spline IK for the tail and I forgot how I ended up getting Spline IK working a few months ago so switched to a much easier to set up but much less flexible method for animating the tail using a single IK bone.

At some point I can change back to Spline IK but did not want to continue spending time on it and I wasn't finding any tutorials online.

I should've written down the process that I used when I got it working a few months ago. Alas.

Researching Kubernetes

Our game server is stateful in the sense that at any point there could be players connected to it - so we don't automatically update it during our continuous deployment process.

Instead we have a command ak deploy game-server that we run manually whenever we want to update the game server.

$ ak deploy game-server --help
ak-deploy-game-server 0.0.1
Chinedu Francis Nwafili <frankie.nwafili@gmail.com>
Deploy our game server

USAGE:
    ak deploy game-server [OPTIONS] --minutes <minutes_until_shuwdown>

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information

OPTIONS:
    -m, --minutes <minutes_until_shuwdown>    The minutes from now that the game server should shut itself down
    -c, --commit <s3_commit_hash>             The commit hash of the game server deploy
    -n, --name <s3_name>                      The name of the game server deploy

This sends an HTTP request to our game-server-deploy-manager that runs on the same EC2 instance as the game server.

It then tells the game-server to shut itself down in some number of --minutes. The game server can use this time to let connected players know that a shutdown is coming so that they can be sure not to be in a dangerous area when they're eventually disconnected.

Then when the minutes elapse the game server disconnects all players and gracefully shuts itself down and lets the game-server-deploy-manager know that everything went alright.

Once the game-server-deploy-manager is notified of the clean shutdown it runs the new version that was specified with --name or --commit. An example --name=latest-green-master will deploy the last binary to pass our master branch CI.

This process works - but there are already a few things that make me want to explore something like Kubernetes to manage as much of my deployment process as possible.

The first is that right now if you try to deploy the same version twice the first server binary will get shutdown but the new binary won't start. I wrote the game-server-deploy-manager before I started test-driven development so the code isn't as well put together as it could be - hence a bug like this surfacing.

This of course could be fixed and I could clean up and better test that code - but if I'm going to continue to invest in a custom solution I should first be certain that it is the right path forwards.

Another thing is that I am currently managing an EC2 instance - and I'd much prefer to deal only with deploying Docker containers and not have to manage any underlying infrastructure. This is one of the reasons that I use AWS ECS for the game's website, authentication server and payment server.

Which brings me to another advantage - if I started using Kubernetes I could move my ECS services over to Kubernetes and only have to invest in one tool instead of several.

There are other advantages - as well as potential downsides such as needing to invest in and learn and manage another tool.

My preference is to leverage something existing if it meets my needs and meets them well - but I'm too inexperienced with Kubernetes to know whether or not that is the case.


Even if I incorporate another tool I will still need some sort of light deploy manager that would notify servers that they need to shut down in --minutes and then trigger the new server version to run when --minutes elapses, but it would be nice to trigger these shutdowns and updates by interacting with something like the existing Kubernetes API instead of maintaining a custom process of downloading binaries from S3 and spawning a child processes like we do now.

This is all just preliminary research though as I don't need to address this problem right now.

At some point I'll mess around with getting a Kubernetes cluster in place locally to see if it meets my needs or not and then make a decision from there.

More time working on the game

Last week was my last week working full time. Starting in February I'll be contracting for around 15-20 hours per week.

I'm happiest when I'm spending my time consumed with programming and computer graphics related goals and projects that feel incredibly challenging.

So I'm working on designing my life to lean even more in that direction than it already is.

I'll be using the extra time per week to continue to study and implement different computer graphics concepts and work on the game.

Next Week

I started working on the CombatSystem and some of the related components.

Each time I write a system I improve upon the patterns I put in place in the last one. This takes a little time and thought - but I can see myself getting closer to having a mostly stable approach to building the systems in my Entity Component System.

This time around I'm making sure to consider logging right from the start.

I read up on slog! to figure out how to make including key-value context a bit more seamless and started using thiserror.

I'll get combat working and deployed this week - but it'll take more tuning over time to really nail it. Combat is something that I want to be very fun for both beginners and experience players - and I have a lot of ideas around how to accomplish this.

I'll explain some of the inner workings of the combat system in next week's journal entry.

One caveat though - I'm traveling for two weeks starting on Friday and I haven't decided whether or not I'll be bringing my laptop due to a couple areas that I'm going not being all that safe.

If I don't end up bringing it I might miss the next two dev journals.

We'll see.


Cya next time!

- CFN