In this series of posts I’ll show you how to use JRuby and Entity-Component architecture to build a working game. Entity-Component Systems are a fairly new alternative programming methodology. They are prominent in the game-programming community and solve many of the problems that OOP cannot solve.
If you’re a Rails programmer you’re already familiar with the mantra “composition over inheritance.” Entity-Component Systems are probably the highest form of composition over inheritance that you will encounter.
“Pure” EC is what I’ll work with in this blog series. There are also hybrid systems and alternative methodologies. EC is a young enough architecture that even in the “pure” space there are still disagreements about certain implementation details. I’ll give you the solid foundation; the mechanism I’ll discuss in these posts will be adaptable by you to embrace these subtle shifts as you see fit.
- Part 1 – introduction and nomenclature
- Part 2 – entities and the entity manager
- Part 3 – components
- Part 4 – systems
- Part 5 – libGDX concepts
- Part 6 – the Lunar Lander game
- Part 7 – serialization
- Part 8 – collision detection and more
This article series is for you if some of the following are true for you:
- Game programming sounds interesting
- You’ve heard about Entity Component stuff and would like to dabble with it in Ruby
- You want to learn about an efficient way to bypass OO’s problems
- You want to program your game in Ruby
- You already believe in “composition vs. inheritance” and want to take it to the next level
I could go into great detail about the advantages of EC over OO, but so many others have thoroughly addressed this that it would be very un-DRY for me to try to distill or repeat their words. I think you’ll get the most out of this article series if you do some initial “homework” before you begin:
- In this article, Justin (aka Hume) tidily articulates the typical problem that OO creates but EC fixes.
- This T=Machine blog series offers a highly detailed and experienced look at the advantages to EC in MMO development.
- This article is a commonly referenced piece on OO vs. EC.
- This wiki is considered one of the canonical EC references; you’ll return there often for advice.
JRuby is absolutely awesome.
First of all, JRuby isn’t necessarily just “Ruby for Java people.” JRuby is a heavily optimized, very fast Ruby interpreter that outperforms the vanilla MRI that you have probably used for all your Ruby (and Rails) projects. You can switch to JRuby and gain some nice performance improvements “for free.”
But then you can start to leverage the underlying Java VM in some pretty interesting ways. JRuby, for example, gives you true kernel level treading — even Ruby 1.9 can’t do that. Do you covet Java’s vast set of specialized collections such as java.util.LinkedList and java.util.TreeMap? JRuby lets you utilize those right out of the box.
And going further, JRuby lets you exploit some very nice third-party Java frameworks. The Slick2D and libGDX game-development frameworks are popular and have energetic communities…but they’re designed for Java developers. Why should those folks have all the fun? Using JRuby you get the best of both worlds: you get to leverage libGDX to build cool games, but using the elegant Ruby language instead of verbose and crufty old Java.
Let’s begin by learning the nomenclature you’ll need to grok for EC.
First, the Entity. An entity is simply a game object, a “thing” in your game world. Examples:
- A tank
- The player’s base
- Enemy plane
- Landing pad
You’ll note my deliberate non-use of any “class-like” naming convention here. You probably thought in your OO head “Tank, PlayerBase, Plane” but you need to endeavor not to. It’s hard to divorce yourself from OO sometimes, but EC requires you to dispense with some of your comfortable ideas and to absorb some new ones. Stop thinking in OO and just perceive what your entities are.
Next, the Component. A component is an attribute, behavior, or aspect of one your entities. A component is how you breathe life into your entities, which so far are mere lifeless shells with a name. By “attaching” one or more components to an entity, you imbue the entity with that attribute or behavior. Examples of components are:
- Casts magic
- Responds to user input
In “pure” EC — which is what we’re embracing here — components merely define attributes and behaviors, which means that they contain only data. No algorithmic logic is ever embedded in a component, only the data to support the attribute and the getter/setters to access this data. For example, the Position component will contain x_coord and y_coord variables, but no movement logic. The Health component might contain a hit_points variable and, say, a poisoned boolean.
Some components won’t have any data at all, but more on that later.
Finally, the System. A system contains algorithms and logic, and makes things happen in your world. Each system — and you’ll have many — acts on your entities based on their components. Examples of systems are:
Each system knows what components it needs to query to do its job. The Movement system, for example, probably needs to know about Position and Velocity components. Therefore there need not be a 1:1 ratio between systems and components.
So back to Entities. If Components hold all the data, and Systems hold all the logic…then what does an Entity hold? The answer: its unique ID and nothing else. If that blows your mind, just wait until Part 2.
Summary of Part 1
- Just dumb bags of data. No logic.
- Getters and setters.
- Never talk to one another nor, in fact, have any awareness of one another.
- Hold all logic and algorithms
- Know their own component needs
- Allowed to talk to as many components as necessary to fulfill their requirements
- Generally do not talk to other systems but get all their info from components
- Represent game-world “things”
- Have one or more associated components in order to define their behavior and attributes
- Nothing but a unique ID. Nothing else.
In the next installment we’ll learn about entities and the entity manager.