Skip to content
kzsh edited this page Aug 3, 2024 · 3 revisions

ECS: Entity Component System

In 2024 a major update of EmptyEpsilon is planned to be released. This is the first major update in 10 years that actually changed a lot of the engine code and ways everything works.

General

In the pre-ECS EE engine, each object is distinct. An object is a space-station or a ship or an asteroid. And those distinct objects have certain behavior and allowed actions. Stations can be docked, ships can fly around, asteroids explode if you fly into them. And those behaviors are fixed in stone.

Post-ECS, each object is an entity. And entities have components attached to them. And those components define what the entity does in specific cases. A DockingBay component will allow entities with a DockingPort component to dock to it. Which means, if you attach a DockingBay component to a Planet you can actually dock on this planet.

But what about systems?

Unless you dive into the C++ code, you'll never encounter a system. But, in ECS, components are just data, they do not define behavior, that's the job of systems. So while the DockingBay and DockingPort define that you can dock together, it is the DockingSystem that actually has the code for this behavior.

Scenario scripting

This update means a LOT of scenario scripting. It gives unprecedented capabilities, as almost all components are exposed to scripting. Want to give a ship a small "radar blackout zone" similar to a nebula? Just do ship.components.radar_block = {range=2500, behind=false}

There is no documentation for this yet, but if you want to see what components and properties are available, they can be found in code at: https://github.com/daid/EmptyEpsilon/blob/ECS/src/script/components.cpp

Ship templates

Ship templates in the pre-ECS engine are loaded on game startup and then "fixed", and need to be the same on all clients or you will get odd desync issues.

With the post-ECS engine, this is no longer the case. Ship templates are loaded as part of your scenario, can be added, updated and modified by scenarios. And clients no longer need to be in sync. As templates are simply a set of components that will be set on an entity. The engine is actually not even aware of the templates anymore, its fully a scripting concept. (Same goes for ModelData)

Compatibility

A lot of care was put into ensuring most of the older scenario code could still run unmodified. All functions that you know and love are still available. And actually defined in lua code now. So if you call ship:setPosition(x, y) that actually runs a lua function which then updates the proper component.

HOWEVER there is one major thing that is no longer available. And that is obj.typeName this used to be a string that can be used to check what type of object something is. However, as objects can now be mixed and matched, it no longer makes sense. So usage of obj.typeName need to be replaced with different checks. Usually it's not a specific object type you want to check for, but a certain property.

For example, if obj.typeName == "ScanProbe" then can be replaced with if obj.components.share_short_range_radar then instead of checking if something is a probe, we check if it has the component that makes it a probe.

Status

While all of this sounds great, the ECS engine isn't fully up to the same level as the pre-ECS engine. There are various bits of implementation still missing or broken. This list is incomplete:

  • Copy to clipboard on the GM screen isn't doing anything
  • hardware.ini is not functional
  • Certain included scenarios still use obj.typeName
  • Network code is less efficient, sends things with much shorter intervals causing a pretty large increase in network traffic
Clone this wiki locally