On the game engine: entities and attributes

Published on
Last changed on

This is a tentative post about the way the engine is currently evolving. As such, I hope it proves useful both for 1) you to get a view of what is going on 2) me as a therapeutic "thought dump exercise" helping me clarify my logic.

Ce qui se conçoit bien s'énonce clairement,
Et les mots pour le dire arrivent aisément.

Damn… ok here goes

Introduction and mile-high overview

Adumens's "engine" is I believe nothing new; more a hot-pot of things I have discovered, tried and experienced over the years and whatever relevant literature I could/can find on the subject or related subjects. Add in various bits of personal tastes and you get where we're currently at.
The result, one might ask? Well, the way the engine is being designed is inspired more by Pen & Paper and tabletop games rules than currently existing systems and/or frameworks such as ECS and the like. But of course with coding in mind…so make of that what you will!

Several beams converge on what I am trying to build:

  • Pseudo realism: where I strive to express things in Standard Units (metres, seconds, Joules, Kelvin, etc)
  • Modularity: how to build an engine that offers deep & wide customisation possibilities.
  • Complex but not complicated and ideally based on the "Easy to learn, hard to master" motto.
  • Extensible: both from a base framework perspective, but also player perspective, where one should be able to create their own variants by experimenting.
  • Fast: not fast at design/admin time but fast at runtime; which means all of the below will have to result in a lot of aggregating/flattening, ideally for injection into a nice little rust binary for quick processing.

The following sections will try and illustrate where the engine is currently at. In so doing, they will attempt to explain and justify why certain choices were made -- and how :-).

Nothing is certain nor engraved in stone just yet, but as this post is written, the engine seems to have reached a conceptual stability that makes me confident enough to write about it. But hey… who knows what will happen, right?

Entities

Entities are what players interact with: a ship, a station, a laser cannon, a mining drone… you name it.

  1. It is on entities that a player right-clicks to visualise contextual actions and menus.
  2. It is entities that players interact with, whether to act or to understand: what can this do? How well? What are its stats? How long would it take it to perform X or Y?

In short, entities are what populate the game world. Groundbreaking, heh? Of course not, but the way they are organised is worth mentioning; consult the following table to know what is what.

NameDefinition
Entity classThe top-level taxonomy; this indicates to which very broad group an entity belongs to; this can be a ship, a propulsion engine in N-space or an Optical energy weapon.
Importantly, all entities of the same Entity Class share the same attributes.
Entity typeIs a more granular approach; for example, the "Optical energy weapon" entity class could be subdivided into several entity types: IR lasers, Optical WL lasers, UV lasers… all the way up to Gamma lasers. Each entity type will have various ways to calculate/compute their attributes (inherited from their class).
LayerIndicates which "layer" an entity belongs to; this can be: entity, unit or material. More on this below.
EntityAn actual instance that evolves in the game world.

Entity classes

As mentioned above, this is the broadest taxonomy in the game engine. It has several main goals:

  • Provide players with a sense of clarity when navigating the various options and possibilities
  • Good opportunity for fluff & background writing!
  • Mechanics-wise, classes act as the enforcer of which entity has which attributes - see this as entity_class == role kind of rule.

For example, the HULL entity class is defined as:

Hulls form the enclosing structural envelope surrounding internal systems and structural frameworks. Multilayer construction combines structural alloys, insulation materials, and shielding layers within a continuous outer shell. The hull structure maintains pressure boundaries, moderates thermal gradients, and provides a mounting surface for external equipment, sensors, and structural interfaces while contributing to overall rigidity and environmental separation.

It also enforces the presence of attributes linked to protection from external damage, sometimes to forms of stealth and also to streamlining (equivalent to the ability to move in atmospheric mediums), etc. Nothing is finalised yet, but the global picture is likely to remain the same.

And last, it is useful as a sorting proxy for when a player simply wants to consult the list of available hulls - whether in the game, or available to them at a given time given their faction's scientific progress.

As of writing this, the following entity classes are very, very well under way:

  • Energy generation
  • Energy collection
  • Energy storage
  • Frame
  • Thermal dissipation
  • Armour belt
  • Hull
  • Locomotion shield (don't like the name but so far it's all I've got)
  • Fuel storage
  • Motion internal dampeners
  • N-space locomotion (the "engines")
  • Manoeuvring thrusters
  • Linear displacement systems
  • Surface locomotion
  • Atmospheric locomotion
  • … and about 12 different material classes, from ceramics to metalloids to degenerate matter.

Still to be worked on:

  • Control, communication and detection
  • Life support & recycling
  • Habitat modules
  • Crew quality of life modules
  • Scientific extensions
  • Industrial modules
  • Storage beyond fuel & energy
  • Weapons (several classes)
  • Navigation
  • Non N-space propulsion: H-space and V-space
  • Ewar, intelligence and non-weapon combat systems
  • Medical?
  • Food!
  • Hangars, docking bays…
  • … and probably many others but in due time! :-)

Entity type

Entity types are the children variants within a class (yes, it is that hierarchy again…). If we refer to the lasers example above, all of the lasers will have the same set of attributes, for example Energy (J) or Power(W), Focus or dispersion at X meters, etc. Again nothing is finalised but the principle very likely is.

Entity types are "unlocked" via scientific progress and research. I am working the mechanics at the moment, but the overarching idea is that entity types availability is gated behind:

  1. Access to relevant sciences (from the Tech tree)
  2. In some cases, the accumulation of enough research points within sciences. Reminder: when a science is discovered, it needs to be researched in order to accumulate research points; those researches are then used to 1) accumulate knowledge points in the related aspects and 2) unlock the "toys" inside that science.

This "I need to go on working on a science to extract benefits from it" is what separates Adlumens from many other games/engines out there. In many (most?) of them, you spend points to unlock sciences and all the toys that come along with it. Adlumens does it the other way around: your progress in the (mystery) universe's aspects unlocks sciences. Those sciences then need to be worked on in order to get benefits from them; in more ways than one, unlocking a science is the beginning, not the end!

Layer and Slot

In the database, all entity types are stored flat. Which means there needs to be a way to differentiate them. This is done via the class and the layer.

  • class: which broad group does the entity type belong to?
  • layer: which logic layer can it exist in?

A layer can be one choice amongst the ones from the following summary table:

NameDefinition
EntityNot to be confused with an actual entity (see below); this is the topmost layer; the one assigned to the entity types that are of the highest order, be they self-contained, independent, interactable with in the engine or simply composed of subcomponents.
UnitIs the layer reserved for the building blocks of entities. For example a "ship" entity type belongs to the entity layer; its subparts all belong to the unit layer: engine, weapons, habitation modules, hangars, etc.
MaterialIs the layer reserved for the ingredient used to craft/manufacture a unit.

At this stage it seems primordial to introduce the concept of slots.

Slot definition

Ha… it's a slot. No wait that's not helpful. A slot can be defined as:

A physical and/or logical mount point that belongs to a parent, and to which can only be attached a child that satisfies certain criteria.

With such a formal definition in mind:

  1. Entity slots can be populated using children of a certain entity_class and belonging to the unit layer. Which means you cannot mount a gun where an engine should be and vice-versa.
  2. Unit slots can be populated with children of the material layer and matching certain tags. Which means you will not be able to build an antimatter reactor using polymers.
EntityShip, station, building, vehicle...Unit AHull segmentUnit BReactor / engine / sensorUnit CSupport systemMaterial 1Structural materialMaterial 2Functional materialMaterial 3Conductor / shield

Entity slots

Wait, so does that mean slots are fixed? So much for flexbility!

Not quite! Just because an entity has slots does not mean its slot layout is fixed. limited or constrained; on the contrary, it remains extremely flexible and each entity slot is defined as follows:

  • Minimum amount required: if 0, then this slot is purely optional; if 1 then the slot must be populated for the entity to be functional. I still have not found a case for 2+… but who knows?
  • Maximum amount allowed: useful for redundancy scenarios (power generation), or layering hulls, or adding scientific research modules later on to a station…

Which means players can mix & match almost any combination of units as long as they respect the minimal requirements for the entity class instance they are trying to design/build.

In practice, this means that players will be able to perform the following:

  • slot 2 engines and 3 weapons on a ship
  • slot 2 hulls for more protection
  • or just one small-size/limited mass habitat module in a tiny station.
  • … and the list goes on. The only thing they will have to strongly consider: by adding all these unit to the entity, are they starving the ship of resources it might need? For example, if one tries to cram 12 high-powered laser guns on a ship; fine. But what gives them power? A large(r) reactor? A dedicated reactor? Great, yeah that works - but that means more overall ship mass, and so the overall ship agility will suffer, etc, etc.

All about choices.

Unit slots

Unit slots are different; for example, a fusion reactor is composed of the following slots:

NameMass fraction (base/min/max)Required material tag
VACUUM_VESSEL0.35/0.31/0.39STRUCTURE_CONTAINMENT
SUPPORT_FRAME0.15/0.13/0.17STRUCTURE_SUPPORT
TOROIDAL_MAGNET_COILS0.20/0.18/0.22MAGNETIC_CONTAINMENT
PLASMA_HEATING_SYSTEM0.15/0.13/0.17ENERGY_GENERATION
CENTRAL_SOLENOID0.10/0.09/0.11ELECTROMAGNETIC_CONTROL
DIVERTOR_PLATES0.08/0.07/0.09PARTICLE_ABSORPTION
FEEDBACK_SENSORS0.05/0.04/0.06PLASMA_DETECTION
CRYOGENIC_COOLING0.02/0.01/0.03TEMPERATURE_REGULATION

At the moment, only fixed slots are implemented; but I am thinking of optional ones. This is something I will definitely have a look at, but a bit later! :-)

Check "Rounding up the above" below for more details.

Material tags

Tags are unique to materials and declare what they can be used for; each material is assigned a variety of tags, picked among the 589 that are available.
The main consequence of this is that certain materials are extremely versatile and can be applied to a wide variety of usages, whereas others are more specialised. This was implemented to try and introduce the notion of choice, balance and drawback management.

Entity

Entities (not to be confused with the entity layer) are the actual entity_type instances who populate the game world.

If entity types can be defined as the rules around what defines an entity, what it can be made of and what it is made for, then an entity is an actual manifestation of that type: one that has been manufactured, purchased or found by the player… and one that can be destroyed, traded, lost or stolen!

Like in many games (Adlumens is not yet one, but it's trying hard), each entity can be 100% unique, depending on the following choices that were made during manufacturing and over the lifetime of the entity:

  • Which units were initially selected? Were some added later on? Others replaced by better versions? Others completely removed?
  • For each unit: which materials were selected? Using which mass fractions? What was the crafter's skill (and luck) when manufacturing it?

This will all be clarified later on in a future post and via the upcoming site reorganisation but the flow will be something similar to this:

  1. Player accumulates enough knowledge points in enough aspects to unlock a science
  2. The science can either a) unlock an entity type instantly or b) gate it behind some extra research (which has to be done most of the time anyway as the only way to accumulate aspect knowledge points is via scientific research - see this post for more details)
  3. The unlocked entity type can be of the entity, unit or material layer. Which means: you can unlock ships, vehicles, new weapons or engines, ways of detecting stuff or hiding, and better/more specialised building block. The works.
  4. The new entity type can be manufactured; either using the values offered by the default blueprint of that entity type; or by using desired variations, whose values will be stored in a faction blueprint.
  5. A faction blueprint can then be used to manufacture the entity type using the given parameters; it can also be duplicated, sold, cloned, reverse engineered or stolen!
  6. Once the entity is produced, it can be used as intended: either as a top-level entity, or as a unit used as replacement, trade good, etc.

Attributes

A while ago, I mentioned the absolute normalisation of attributes; today I can say with an exceedingly strong confidence that I was both right and wrong to have written that:

  • Wrong, because attributes are now far far more numerous than they were before and certainly not shared by all entities or entity types. As written above, the only taxonomy that satisfies the "attributes are identical across the board" is the entity class
  • Right, because the way attributes are applied to entity types and entities is indeed very strongly normalised: this is always via an identical many-to-many relationship; easy to track, easy to quantify, qualify and debug.

Universal or not?

Some attributes are truly universal, i.e., shared across all entity classes: age, longevity and mass to mention but a very few ones.

  • Entity classes from the material layer make use of 44 attributes; for example: signal fidelity (normalised), entropy resistance (J/mol/K), elastic response (ratio), thermal conductivity (W/m/K) or quantum coherence retention (s)
  • Entity classes from the unit layer make use of around 40 attributes so far, and more are born every day.
  • Entity classes from the entity layer make use of a small amount of attributes so far, mostly because I have not been working on them just enough. But there is a deeper reason for it as well, and see below for that.

WATF I hear you think! Yes the list of attributes is long, and will get longer; but there is a good reason for it: attribute emergence.

Attribute emergence

This concept is the foundation to Adlumens's crafting system: its underlying idea is that an entity's attributes emerge from the attributes of its children, using expressions. A couple examples:

AttributeLayerEmerges from…Comments
ACCELERATIONentityComputing the entity's total thrust (by doing a lookup on the relevant unit) against the total mass of the entity.This one is easy: engines push the ship forward. The more thrust, the more acceleration, the more mass, the less acceleration.
ENERGY_EFFICIENCYunit (for example fusion reactor)Computing and aggregating the unit's relevant slots/materials and reach a normalised value [0.0-1.0]This one is more complex and must account for the normalised nature of the output.

An important point: those calculations are run even when the slightest change is made to a material, a mass fraction, etc. Which is why on-the-fly computing must be done 100% in memory. Given that slots are usually limited to 9 and that an entity is unlikely to have more than 15-20 children units, this is likely to run reasonably quickly. In a (very very simplified) nutshell:

  1. Select the entity type to design
  2. Select the units to slot in (required and optional)
  3. For each unit:
    1. select unit total mass
    2. select slot mass fraction
    3. select materials
    4. Volume and density are calculated for the unit
    5. Emergent attributes are calculated for the unit
  4. Calculate total mass, volume and density for the entity
  5. Emergent attributes are calculated for the entity
  6. Rinse & repeat until satisfied
  7. Save and persist faction blueprint to database
  8. Manufacture
  9. Entity exists not only in the database but also as a runtime instance

Many nice things can be said about the above summarised process:

  • Entities are customisable by player factions
  • In many ways, player factions can create entity type variants
  • Player factions can accumulate expertise in the manufacturing of entity types
  • The crafting process can be involved but is ultimately rewarding
  • The final quality level of an entity depends on blueprint expertise, but also crew skills: see it as a combination of both faction-wide knowledge and know-how and more transient applications of personal skills by crew members
  • … and probably others but to me that's already a nice list <3

Why so few entity attributes?

Two main reasons:

  1. The first is that not many attributes need to emerge/bubble up from units to the entity.
  2. The second is probably the deepest one: even at runtime, an entity will not be considered as a simple aggregate of attributes. No, it will remain an aggregate of children entities, that can be:
    • Damaged or repaired and whose performance will suffer depending on their individual integrity
    • Throttled or pushed beyond normal limits
    • Turned off, replaced or upgraded

Rounding up the above

A visual representation of that "V-shaped" crafting and emergence pipeline:

MaterialsMaterial Attributes × Mass FractionsUnit ExpressionsUnit AttributesEntity Aggregation → Entity Attributes

In closing for now

I hope I did not betray Boileau too much on this one! If I did though, do not hesitate to comment, leave a message or react on Discord! And again, thank you for taking the time to read!

Please signin to add your comment.