A deeper dive into entities and attributes
Last changed on
Hello! In this previous post, we went over an entities and attributes overview, which hopefully exposed, in a clear fashion, the basic building blocks of the upcoming Ad Lumens "game engine".
In this post I would like to dive a little deeper on exactly how entities are designed, manufactured and what their operational requirements are. Same overall goal:
- Exposing some of the principles behind the nascent mechanics
- Sanity check for me, with ideally feedback sent by leaving me a message or directly on Discord
Chronofagism
The first reality of it all is: this is time-consuming. Very time-consuming. Hopefully the dive we are about to get into will be able to explain/justify it, but several factors kick in:
- "Two step forward, one step backward" very much summarises the qualitative phase I am currently in. That means experimenting, prototyping, trying to anticipate upcoming mechanics problems/incompatibilities between what is and what will problably be.
- Quantitatively is less of a problem, although still a lot to do: this is more about populating content, finding nice, relevant, varied and (hopefully) original ideas
- … while making it all fit inside a clear, solid and logical unified system.
The two entity types this post will talk about are two among around 220 that have been (and are being) designed. I think that illustrates why this (nice and interesting) endeavour is taking so long! Note: this is about 50% of the entity classes, so about as many more will be to work on.
Quick overview of our deep dive
- We will use two arbitrarily selected entity types, rather different in the role they play. Both belonging to the
unitlayer - We will discover what their slots are
- We will pick a material used in the crafting of those units.
- We will discover how attribute emergence works, also using examples and explanations
- We will briefly touch on what manufacturing them means
- And finally we will discover how unit-layer entities can run and operate, usually within the context of a higher-order entity
Entity types
We will use two rather different entity types:
- A specific energy generation unit: the Tokamak fusion reactor
- And a specific ship frame unit: the Load-bearing Frame
They are humanly defined as follow:
| Entity type | Description |
|---|---|
| Tokamak fusion reactor | Tokamak fusion reactors confine and heat plasma using strong toroidal magnetic fields combined with a central current. They achieve stable, long-duration fusion reactions through well-established magnetic confinement techniques and remain the most mature approach for continuous power generation. |
| Load-bearing Frame | A fixed-geometry structural frame that never changes shape during operation. All forces from thrust, rotation, impacts, and docking are resolved locally through rigid members, making behaviour highly predictable and easy to model. Performance is tightly constrained by material limits and joint strength, and failure tends to be abrupt rather than graceful. While inefficient under extreme acceleration or asymmetric loads, this frame excels in reliability, simplicity, and low control overhead, forming the baseline architecture for early spacecraft, stations, and orbital infrastructure. |
Their availability is gated behind the following sciences:
| Entity type | Tier | Science |
|---|---|---|
| Tokamak fusion reactor | 1 | Fusion physics |
| Load-bearing frame | 1 | Metallurgical chemistry |
Which makes them both entry-level entity types, i.e., ones available at the very beginning of the game.
Their slot definitions is as follows:
| Slot | Mass fraction | Tag |
|---|---|---|
| VACUUM_VESSEL | 0.35/0.31/0.39 | STRUCTURE_CONTAINMENT |
| SUPPORT_FRAME | 0.15/0.13/0.17 | STRUCTURE_SUPPORT |
| TOROIDAL_MAGNET_COILS | 0.20/0.18/0.22 | MAGNETIC_CONTAINMENT |
| PLASMA_HEATING_SYSTEM | 0.15/0.13/0.17 | ENERGY_GENERATION |
| CENTRAL_SOLENOID | 0.10/0.09/0.11 | ELECTROMAGNETIC_CONTROL |
| DIVERTOR_PLATES | 0.08/0.07/0.09 | PARTICLE_ABSORPTION |
| FEEDBACK_SENSORS | 0.05/0.04/0.06 | PLASMA_DETECTION |
| CRYOGENIC_COOLING | 0.02/0.01/0.03 | TEMPERATURE_REGULATION |
| Slot | Mass fraction | Tag |
|---|---|---|
| RIGID_MEMBERS | 0.40/0.35/0.45 | STRUCTURE_SUPPORT |
| JOINTS | 0.20/0.18/0.22 | INTERFACE_SUPPORT |
| LOAD_BEARING_LATTICE | 0.15/0.13/0.17 | STRUCTURE_DISTRIBUTION |
| FORCE_RESOLVER | 0.10/0.09/0.11 | FORCE_DISTRIBUTION |
| STRESS_CONCENTRATOR | 0.08/0.07/0.09 | FORCE_CONTROL |
| PREDICTABILITY_OPTIMIZER | 0.07/0.06/0.08 | STRUCTURE_STABILISATION |
Where all masses are expressed in fractions (base/minimum/maximum), and end up being normalised so that their sum == 1.0. As you will see below, mass fraction do have an impact in terms of game mechanics; they are not here only for fluff!
Materials and tags
In order to manufacture/build/craft instances of the two entity types above, a faction needs to use materials. The fact that material themselves need to be crafted is interesting, but irrelevant to this post.
As the previous post briefly explained, materials can be only used to manufacture a unit slot if they have the tag that matches the one assigned to that slot.
Conveniently, the tag STRUCTURE_SUPPORT is used in both entity types (for the slots SUPPORT_FRAME and RIGID_MEMBERS), which is why we will use it for our deep dive.
Our picked material for structure: Titanium-reinforced structural alloy
This alloy, belonging to the entity class MATERIAL_METAL, has the tag STRUCTURE_SUPPORT, so is the one we will use for this example.
This section will be an opportunity to show how materials are generally defined; so even though all the details therein will not be immediately relevant to our dive exercice, it's always nice to get those extra bits, isn't it?
| "Field" | Content |
|---|---|
| Description | Alloys primarily composed of titanium, exhibiting high strength-to-weight ratio, corrosion resistance, and uniform microstructure. The lattice maintains dimensional stability under repeated thermal cycling and mechanical load, balancing toughness, ductility, and fatigue endurance. |
| Science / tier | metallurgical chemistry / 1 |
| Crafting ingredients | Ti (0.88), Al (0.05), V (0.05), Fe (0.02) |
| Attributes | See below! |
| Tags | STRUCTURE_SUPPORT, STRUCTURE_STABILISATION, FORCE_DISTRIBUTION, ELASTICITY_ADAPTATION, ENTROPY_REGULATION, MASS_REGULATION, PRESSURE_STABILISATION, ENERGY_ABSORPTION, PHASE_STABILISATION, FORCE_CONTROL, THERMAL_CONTROL, ELASTICITY_CONTROL, VIBRATION_DAMPING, ENERGY_CONVERSION, FORCE_AMPLIFICATION, PARTICLE_STABILISATION, DEFECT_SELF-REPAIR, THERMAL_STABILISATION, INTERFACE_STABILISATION, FORCE_ADAPTATION |
Attributes deserve their own table, as they are common to all materials. In other words: all materials, whether metals, polymers, time crystals or biomaterials, share these attributes.
Important: all material attribute values are expressed as a multiplier of Iron (Fe). This choice was made because Iron is a univeral point of convergence whether energy is added or removed; in many ways, it is also the most stable element in the universe.
| Attribute symbol | Attribute name | Attribute description | Unit | Value |
|---|---|---|---|---|
STRI | Structural Integrity | Capacity to resist fracture, deformation, and fatigue under sustained or sudden load, reflecting bond strength, defect tolerance, and mechanical reliability across scales. | Pa | 2.8 |
COHS | Cohesion Stability | Strength and persistence of internal bonding across molecular or lattice structures, determining resistance to separation, delamination, and structural disorder over time. | J/m2 | 1.5 |
DEFT | Defect Tolerance | Capacity to maintain functional performance despite structural imperfections, impurities, or microfractures, supporting reliability under imperfect fabrication conditions. | normalised | 1.2 |
THSR | Thermal Stability Range | Temperature interval across which the material maintains structure and function without phase change, breakdown, or loss of mechanical, electrical, or chemical integrity. | K | 1.1 |
RADT | Radiation Tolerance | Capacity to endure ionising or high-energy radiation exposure without structural damage, property drift, or functional loss across prolonged or intense energetic bombardment. | Gy | 1.2 |
This is only 5 attributes out of 44 possessed by all materials; but only those 5 are going to be used in our example.
Player factions will of course be able to manufacture slightly better (or worse!) versions of such materials!
Attribute emergence expressions
Now each of our two example units (the reactor and the frame) also have attributes; these make far more sense in functional/performance terms and are more "macro" in the characteristics they describe.
One universal unit-level attribute is Integrity (ING). By universal is meant that all units have the ING attribute.
This attribute is defined as follows:
| Attribute symbol | Attribute name | Attribute description | Unit |
|---|---|---|---|
ING | Integrity | The amount of damage energy the unit can absorb per unit mass before becoming non-viable. It tracks the presence of physical degradation, fractures, or circuit damage that threatens the entity's existence. | J/kg |
One extremely important point: ING, like many other unit attributes, is expressed per unit of mass. Which means it is an intensive attribute. Very logically, to obtain the actual total integrity of a unit, one must simply multiply its ING attribute value by its mass. This then results in an extensive (or quantitative) attribute value!
The ING expression for the reactor
Is defined as:
(2.8e5
+ 3.6e5 * norm(
sawhm('STRI', ['PRESSURE_VESSEL','SUPPORT_FRAME'])
* math.sqrt(sawhm('COHS', ['PRESSURE_VESSEL','MODERATOR_WATER']))
* math.sqrt(sawhm('DEFT', ['CONTROL_RODS','HEAT_EXCHANGER']))
* (0.7 + 0.3 * sawhm('RADT', ['SAFETY_SHIELDING','PRESSURE_VESSEL'])),
0.16,
0.40
)) * rho_modThe ING expression for the frame
Is defined as:
(3.0e4
+ 3.0e4
* norm(sawhm('STRI', ['RIGID_MEMBERS', 'JOINTS', 'LOAD_BEARING_LATTICE'])
* math.sqrt(sawhm('COHS', ['RIGID_MEMBERS', 'JOINTS']))
* math.sqrt(sawhm('DEFT', ['FORCE_RESOLVER', 'PREDICTABILITY_OPTIMIZER']))
* (0.7 + 0.3 * sawhm('THSR', ['RIGID_MEMBERS', 'JOINTS'])),
0.16,
0.30
)) * rho_modEmergence explanation
The expressions above of course deserve a little bit of explanation!
First, the values are temporary so can be more or less ignored. What is important is the form of each expression, which I will try and detail here.
The basic anatomy of an expression is as follows:
(BASE + SPAN * normalise(
DRIVER
* math.sqrt(SHAPER_1)
* math.sqrt(SHAPER_2)
* (0.7 + 0.3 * LIMITER),
M,
K
)) * density_multiplierMore details:
| Parameter | Explanation |
|---|---|
BASE | The minimum achievable value of the attribute. Represents worst-case performance (poor materials, bad combinations). |
SPAN | The maximum improvement above BASE. Defines the range of variation the system can express. |
norm | Normalisation layer; implemeted as y = M + (1 - M) * (1 - exp(-K * x)) |
M | The baseline output of the normalisation, prevents the result from ever reaching 0. |
K | Steepness; controls how quickly the normalisation function saturates. |
DRIVER | The primary controlling factor of the attribute. It very often aggregates material attribute values across several slots. |
SHAPERS | Secondary attributes that influence how effective the driver is. Applied as square roots to reduce dominance, smooth the scaling and avoid multiplicative explosion/collapse. |
LIMITER | A soft cap / gating factor. |
density_multiplier | AKA rho_mod, an overall density multiplier that potentially penalises designs outside an accepted density window (min/max expressed in kg/m3). |
sawhm | Is a helper function among several. This one in particular is slot_attribute_weighted_harmonic_mean and produces an effective value dominated by the weakest contributors, while still respecting mass distribution. |
Emergence breakdown
First, let's examine a typical driver/shaper/limiter:
norm(sawhm('STRI', ['RIGID_MEMBERS', 'JOINTS', 'LOAD_BEARING_LATTICE'])This does the following:
- It picks the slots whose names/symbols are
['RIGID_MEMBERS', 'JOINTS', 'LOAD_BEARING_LATTICE'] - It takes the materials that were slotted into them
- For each material (they do not have to be all the same), it picks the
STRIattribute as a multiple of Iron - It then performs a weighted hamornic mean on each slot on the list of
STRIattribute values, thus taking into account mass fractions of the picked slots - Then returns the value
Next, let's imagine a crafting design results in the normalise output being 0.5 and the final computed unit densities being within the allowed ranges. We will then end up with the following intensive intensive values
- For the reactor:
2.8e5 + 3.6e5 * 0.5 = 4.6e5 J/kg - For the frame:
3.0e4 + 3.0e4 * 0.5 = 4.5e4 J/kg
Which, when multiplied by the total desired mass, will result in final ING values for both units.
Why is this time-consuming?
Well, first of all each entity class has to be assigned unit-level attributes (note: I have not really started working on entity-level attributes yet, although those should be quicker/easier as they will emerge from far less moving parts).
Then several things have to be done for each entity type (as children of their respective entity classes):
- Define the slots
- Each attribute has to be mapped to an expression (dynamic since each entity type has a unique slot layout)
- Given ~200 entity types and around 15 attributes per entity class so far (including universal ones)… well yeah… it does take time
But this is all making good progress! I estimate being about halfway through this process; knowing a lot of time has been spent on going backwards and forwards after discovering "problems". Standard stuff :-)
Another complexity layer: crafting time and difficulties
The above various steps illustrate the kind of logic that will be run when designing an entity based on an entity type. In memory data will hopefully make this reasonably quick.
But that is just the design; once that design is saved in the database, etc. a player faction still has to manufacture the unit using its specifications: mass fractions, materials used, etc. Here two main attributes are taken into account:
MTIMor manufacturing time, expressed ins/kgMDIFor manufaturing difficulty, expressed in the engine's internal difficulty class (more on this in an upcoming post)
Both attributes are intensive: they represent the inherent and qualitative difficulty and time to manufacture/craft the unit; to compute the final time and difficulty the engine takes them both and modifies them using the unit's desired mass (obvious) but also the faction's expertise in the manufacturing of such an entity type.
It is still a bit early to talk about faction skills, but too late: in a nutshell, some faction-wide skills (as opposed to crew member skills) will be applied to the manufacturing process, and will allow factions to (non-exhaustive list):
- Manufacture more quickly
- Manufacture more easily
- Manufacture with a higher chance of high quality output
Neat, heh? :-)
Yet another complexity layer: entity metabolism
Now we are happy: we have designed our unit-layer entity and we have manufactured it. So it sits there or what? No of course not, its exists to be slotted into a higher-order entity - for example: a ship!
It's kind of screamingly obvious but it bears repeating: a ship runs on power. Sometimes a lot of power.
But that's okay… this is sci-fi!
But that's not okay as Ad Lumens tries to be almost realistic. :-)
Enter what is perhaps a solution (it certainly looks like it at the moment!): Entity Metabolism.
First of all, even equipment, units, ships, etc. all have metabolisms - the principle is not limited to organic/living units, but is applied to everything that:
- Consumes
- Produces
- … and generates waste
So a human crew member will consume food, atmosphere, entertainment, etc. It will produce work, morale, social cohesion (or lack thereof!), and generate waste (heat, organic, atmospheric, perhaps others). A cyborg will consume mostly energy and perhaps parts? Will produce pretty much what a human does and probably generate only waste heat. All this, for crew members and "smaller entities" is to be determined still.
What is however well under way is the mechanics for larger stuff, namely: units. Now units can be split into broad families when it comes to metabolism:
- Units that generate power by burning fuel
- Units that generate power by harvesting it passively from the environment (no, there are no wind turbines in space, although it is probably a good idea to think about them in atmospheres!)
- Units that store energy and can release it in a system when needed
- Units that consume energy
… all of which will generate waste: heat, radiation, etc. Said waste must be managed lest you turn a ship into radioactive slag. Not good, very not good.
Metabolisms are thus being put in place, slowly… and via unit-layer attributes such as:
| Attribute symbol | Attribute name | Attribute description | Unit |
|---|---|---|---|
ENEF | Energy efficiency | Fraction of input or output energy successfully converted into intended input/output, capturing losses due to heat, resistance, or inefficiencies across operational processes. | normalised |
PWDS | Power density | Rate of energy generation or consumption per unit mass, defining how intensively a system produces or draws power relative to its size and structural capacity. | W/kg |
ENDS | Energy density | Amount of energy stored per unit mass, defining how much usable energy a system can carry intrinsically, shaping endurance, autonomy, and storage efficiency. | J/kg |
DISR | Discharge rate | Maximum rate at which stored energy can be released per unit mass, governing burst output capability, responsiveness, and peak power delivery under load. | W/kg |
RECR | Recharge rate | Maximum rate at which energy can be absorbed and stored per unit mass, defining recovery speed, cycling efficiency, and resistance to thermal or structural charging limits. | W/kg |
All the above are intensive; again, this means that a final unit corresponding attribute will have to be multiplied by its mass, to get, for example, total energy density (for a battery).
Another important detail of metabolism is the route via which resources can be transported. Why? Well to cover cases similar to the following:
- A propulsion engine being fed its fuel via more than one storage unit
- Some units being assigned dedicated power sources; for various reasons: critical support, or to avoid unwanted strain of other systems.
- When a ship or station has several heat dissipation units/heat buffers. In which case the route determines the destination of waste heat.
… and so on. :-)
In conclusion
This was reasonably long and dense so thank you for reading what I hope can start to clarify some mechanics around entity design and manufacturing! As always, please feel free to comment, or drop a constructive feedback message here or directly on Discord.
Sounds complex? Sure it kind of is. But again, my goal is to put in place a complex system that does not feel complicated to use. So anyone would be able to chuck in default values and launch a manufaturing process, without the least care in the world about optimising a unit!


Please signin to add your comment.