The experience of developing “Quak” during a hackathon.

In March 2019 we held a 2-day hackathon named “Ship IT!” in TouK. I was part of the team developing “Quak” – a 2D Liero/Soldat inspired game where players can immerse themselves into being a cute blob-like character while simultaneously laying waste to their opponent.

In this post I want to share our experience writing and designing the game, what kind of roles team members assumed and some of the technical choices we made.

Development

Working for a company that swims in JVM technologies – naturally we chose Kotlin as our development language. Our leader Rafał Golcz created a simple game engine in the ECS Model using the standard java game development library – libgdx and box2d for physics.

ECS stands for Entity Component System, and its main advantage over a standard object hierarchy (as games tend to be strongly object-oriented programs in principle) is its behavioural nature.

Instead of drowning in large inheritance trees and having potential “problems” with instantiation or making sure what kind of object goes where – we receive an elegant solution where the behaviour of every game object can be defined as a list of scripts that are attached to it. From design perspective it also allows for a more natural approach to creating specific objects (as in what properties an object has like dealing damage on impact, destruction on collision, bleeding).

Team Roles

Large gamedev companies (Blizzard, CD Project Red, Bethesda – to name a few) usually have strict roles for people working on their projects. Game directors, designers, writers, composers, testers, programmers, marketing teams, managers – all of which (except maybe for directors/managers) tend to be split between junior, senior and leads.

Developers are also often split according to their main responsibility: engine/tools development, gameplay programmers, special effect programmers. However, in smaller teams responsibilities tend to be way more relaxed. What I find really interesting is the natural emergence of similar structures during these 2 days of developing Quak.

We had a person responsible for art, another person for music and sound effects, 5 people who were actively developing various features for the game (controllers aka joystick and keyboard integration, weapons and missiles/bullets, collisions, character movement/controls, map loading, destructible terrain, blood splatter and camera shake effects).

At some point someone took the mantle of mapper and started creating the terrain you can see in the various screenshots in this article and a few others. What did wonders, in my opinion, was when one person became some sort of a Game Director and Designer’s hybrid. By making sure that everyone had a similar grasp of the direction the game was taking this person made sure that contradicting ideas and implementations didn’t emerge. I was this person.

Experience Itself

New features were “flowing in” as our leader noticed. Everything seemed to work seamlessly, every time someone wanted to push their changes to the repository they were met with the necessity of git pulling the changes which often introduced multiple new features. All of this added up made for a great passionate atmosphere, full of fast development and motivation. At some point we had outsourced testers from other projects to playtest early versions of the game as the sound of quacking echoed through the vast open-space of TouK.

Conclusions

During the project showcase Quak has been met with laughter and smirky remarks – great signs. We concluded that the game was a success – we delivered more than we thought we were capable of before the actual hackathon.

Making sure that the game is “juicy” (in gamedev slang – a game is juicy if love and care has been put into small details/finishing touches) at a relatively early stage with camera shake, visual effects like explosions or blood, sounds of duck quacking (as our bullets are all some kind of variation of TouK’s “duck” mascot) all made the game much more interesting to playtest and to develop – boosting the morale and work efficiency of the team.

Having little stand-ups every few hours to quickly discuss who is responsible for what and in which direction the game is going (what features to cut, which to implement, maybe some new ones?) as well as the aforementioned game director all made sure every member of the team knew what to do and in my opinion was the reason we managed to successfully finish the game. Quak has since then appeared at our stand during Scalar conference and was met with positive feedback.

It was an awesome experience but it wouldn’t be possible without a great team. Kudos to the entire Quak squad: Rafał Golcz, Robert Piwowarek, Agata Kłoss, Mateusz Mazur, Hubert Lipiński and Filip Majewski.

You May Also Like

Control your bandwidth using ntop

I was looking for tool which could help me check who is using my bandwidth. Here are requirements which I want from this kind of tool:local hosts bandwidth distribution - it is helpful when you are loosing your bandwidth and don't know who abuse it in ...

Recently at storm-users

I've been reading through storm-users Google Group recently. This resolution was heavily inspired by Adam Kawa's post "Football zero, Apache Pig hero". Since I've encountered a lot of insightful and very interesting information I've decided to describe some of those in this post.

  • nimbus will work in HA mode - There's a pull request open for it already... but some recent work (distributing topology files via Bittorrent) will greatly simplify the implementation. Once the Bittorrent work is done we'll look at reworking the HA pull request. (storm’s pull request)

  • pig on storm - Pig on Trident would be a cool and welcome project. Join and groupBy have very clear semantics there, as those concepts exist directly in Trident. The extensions needed to Pig are the concept of incremental, persistent state across batches (mirroring those concepts in Trident). You can read a complete proposal.

  • implementing topologies in pure python with petrel looks like this:

class Bolt(storm.BasicBolt):
    def initialize(self, conf, context):
       ''' This method executed only once '''
        storm.log('initializing bolt')

    def process(self, tup):
       ''' This method executed every time a new tuple arrived '''       
       msg = tup.values[0]
       storm.log('Got tuple %s' %msg)

if __name__ == "__main__":
    Bolt().run()
  • Fliptop is happy with storm - see their presentation here

  • topology metrics in 0.9.0: The new metrics feature allows you to collect arbitrarily custom metrics over fixed windows. Those metrics are exported to a metrics stream that you can consume by implementing IMetricsConsumer and configure with Config.java#L473. Use TopologyContext#registerMetric to register new metrics.

  • storm vs flume - some users' point of view: I use Storm and Flume and find that they are better at different things - it really depends on your use case as to which one is better suited. First and foremost, they were originally designed to do different things: Flume is a reliable service for collecting, aggregating, and moving large amounts of data from source to destination (e.g. log data from many web servers to HDFS). Storm is more for real-time computation (e.g. streaming analytics) where you analyse data in flight and don't necessarily land it anywhere. Having said that, Storm is also fault-tolerant and can write to external data stores (e.g. HBase) and you can do real-time computation in Flume (using interceptors)

That's all for this day - however, I'll keep on reading through storm-users, so watch this space for more info on storm development.

I've been reading through storm-users Google Group recently. This resolution was heavily inspired by Adam Kawa's post "Football zero, Apache Pig hero". Since I've encountered a lot of insightful and very interesting information I've decided to describe some of those in this post.

  • nimbus will work in HA mode - There's a pull request open for it already... but some recent work (distributing topology files via Bittorrent) will greatly simplify the implementation. Once the Bittorrent work is done we'll look at reworking the HA pull request. (storm’s pull request)

  • pig on storm - Pig on Trident would be a cool and welcome project. Join and groupBy have very clear semantics there, as those concepts exist directly in Trident. The extensions needed to Pig are the concept of incremental, persistent state across batches (mirroring those concepts in Trident). You can read a complete proposal.

  • implementing topologies in pure python with petrel looks like this:

class Bolt(storm.BasicBolt):
    def initialize(self, conf, context):
       ''' This method executed only once '''
        storm.log('initializing bolt')

    def process(self, tup):
       ''' This method executed every time a new tuple arrived '''       
       msg = tup.values[0]
       storm.log('Got tuple %s' %msg)

if __name__ == "__main__":
    Bolt().run()
  • Fliptop is happy with storm - see their presentation here

  • topology metrics in 0.9.0: The new metrics feature allows you to collect arbitrarily custom metrics over fixed windows. Those metrics are exported to a metrics stream that you can consume by implementing IMetricsConsumer and configure with Config.java#L473. Use TopologyContext#registerMetric to register new metrics.

  • storm vs flume - some users' point of view: I use Storm and Flume and find that they are better at different things - it really depends on your use case as to which one is better suited. First and foremost, they were originally designed to do different things: Flume is a reliable service for collecting, aggregating, and moving large amounts of data from source to destination (e.g. log data from many web servers to HDFS). Storm is more for real-time computation (e.g. streaming analytics) where you analyse data in flight and don't necessarily land it anywhere. Having said that, Storm is also fault-tolerant and can write to external data stores (e.g. HBase) and you can do real-time computation in Flume (using interceptors)

That's all for this day - however, I'll keep on reading through storm-users, so watch this space for more info on storm development.