Update 2: Adding ECS to the mix


While libgdx is an absolutely fantastic framework, a tremendous open-source contribution as well as the enabler of an even nicer community, it lacks too many libraries and specific modules to be able to be called an engine. The official definition on github is as follows: "libGDX is a cross-platform Java game development framework based on OpenGL (ES) that works on Windows, Linux, Mac OS X, Android, iOS and your WebGL enabled browser". And so in this update and the next, I'd like to take the time to go through my thought process as I started to build my tech stack, both "below" and "above" libgdx. This is a more technical update and might be a bit of a tougher read for the casual reader, but I'll try to keep it as light as I can. As stated in the definition above, it's a framework, not an engine. A very basic way of understanding that is that you'll be writing code, lots of code. Don't expect a studio. Well, for me that's perfect, that's precisely what I was looking for, as explained in update 1. Now there are some strings attached to that fact though. While it gives you immense freedom, freedom itself can very much be a poisonous gift to the occasional wanderer. What I mean by that is that the more code you write and have to maintain as a developer who's inexperienced in that specific field (or even worse potentially, as an inexperienced developer), not only the more work you have on your plate, but the more likely you are to come up with anti-patterns that will come back to bite you in the ass (or worse). So as you can see, it didn't take very long until I added Artemis to my project:
Image attachment

In fact, I now realize I set it up only 2 days after I began working on the game itself. Artemis is what they call an "ECS" for Entity-Component-System framework and what it does for you is that it forces you to work within a very specific paradigm. It cuts on that freedom I was talking about in order to promote a concept called composition rather than the more traditional inheritance that most developers are familiar with, in particular the ones versed in object-oriented programming. ECS are very popular in game development and the reason behind that is that inheritance tends to make separation of concerns very difficult as the number of entity types increases in your game and as these entities become more and more specialized WHILE ALSO sharing an increasing number of common aspects. Multi-inheritance is a classic problem that different languages solve (or work around) differently. Artemis uses aspect semantics in particular to do achieve composition and establish relationships, which is in my opinion a great way to deal with this problem. I'm not going to cover this topic in depth here but I will provide a quick example.

Let's say I have an entity type (I personally call them "Being" in my codebase to reflect the fact that they are living / animated things, as opposed to static objects or items) called "Monster" and then another called "NPC". In traditional OO programming, one might create an abstract class or interface called "Being", implement stuff like positioning and collisions there (the stuff they share) and then extend / inherit from / implement that abstract class. Then they'll have their own behavior implemented in their own type. Now let's say that some of these beings need to live on the server and some need to be controlled by the client (for instance, in a monster-play scenario). Well, if you've made the parent class deal with motion you're in trouble because you'll have to separate this concern to keep your code generic and not introduce massive redundancy. That's the type of problem that ECS and Artemis help you avoid, by decoupling behaviour (Systems) entirely from data (Components) through Entity references. It then uses Aspects to figure out which entities are relevant to which system.

Artemis is therefore the second cornerstone of my project and I use it both on the client and the server for processing all in-game events. Which leads me to the next important library that I had to choose: the networking one. Much like with the topic of multi-inheritance here, I'm not going to cover the reasons behind using TCP and UDP and in which cases they apply. There is tons of literature about it as well as online articles and I'm no expert at it, at least not yet. However, it was absolutely essential for me to implement basic networking as early as possible. I think it's kind of a classic mistake to have networking be an afterthought when building a game prototype. It's a particularly big mistake when the game relies heavily on multiplayer and pvp as it is the case for me here. If you don't design your game's architecture from the ground up to support multiplayer and make it a great experience from the get go, you'll likely pay the price big time and have to rewrite a ton of code later on, and that's if you succeed at all at porting the game then. So I did consider a few options there. I took a quick look at Apache Mina, Netty and (one of the many implementations, or forks rather, of) Kryonet. I ended up rolling with Kryonet as I simply liked the API better and got great results with it immediately (and I particularly liked Kryo, the underlying default serialization lib). Out of these three it also seemed to be the library that cared most about efficiency and performance.

Leave a comment

Log in with itch.io to leave a comment.