FelECS
The Engine Agnostic ECS Ruby Framework
Install / Use
/learn @realtradam/FelECSREADME

<!-- vim-markdown-toc GFM -->
- What is FelECS?
- What is ECS? * Components * Entities * Systems * Scenes * Stage * Order
- Usage
- Contribution
What is FelECS?
FelECS is an ECS framework for developing games in the Ruby language. FelECS has been designed from the ground up with these three ideas in mind:
- Engine Agnostic: FelECS has been designed to be rendering engine agnostic as long as the target rendering engine is written in Ruby. This means that this framework can be dropped into existing rendering engines such as Ruby2D or DRGTK.
- Easily Extensible: FelECS has been designed such that extensions to its capabilities can be easily added. Extensions such as rendering engine wrappers, premade systems, premade components, etcetera can be easily added on and distributed.
- Principle of (My) Least Astonishment: I want to develop games using a language and framework I love and makes sense to me, inspired by the Philosophy of the creator of Ruby.
What is ECS?
ECS is a software architectural pattern that is used in video game development. Traditionally games were programmed using an object oriented method, while ECS instead attempts to program games using a data oriented method instead.
ECS stands for Entity, Component, and System.
Components
This is where the data or information of a given "object" is stored. There is no logic or code here.
Entities
Entities will contain one or more Components, but contains no logic or data otherwise
Systems
Systems are where all the logic or code is kept. There is no data stored in here.
By using this pattern it allows programmers to easily control what an "object" or entity can do and how much data it needs to have. It avoids the issue of inhertance as no inhertance is ever required in this system. If you need a certain entity to have a certain functionality you just add the relevant component to it, and the systems that automatically go over specific components will give your entitiy the desired functionality.
"But your framework also has Scenes, Stage, and Order, what is that about?"
Scenes
Scenes are simply a collection or subset of Systems. This allows for an easy way to activate and deactivate Systems.
Stage
The Stage is Scenes which are activated. This means any Scenes on the Stage are executed each frame, while the rest of the Systems are not.
Order
Order is a helper class which can set the priority of Scenes and Systems.
Usage
There are 3 ways of using FelECS.
- You can use it with the FelFlame Engine
cd FelFlameEngine/mrbgems
git clone git@github.com:realtradam/FelECS.git
cd FelECS
git checkout mruby-gem
- You can include it as a gem in your project
gem install felecs
# or if you use bundler:
bundle add felecs
- You can copy the single file into your project and include it manually
Entities
Creation
Entities are essentially "objects" in the game world. To create a new Entity we do the following:
@entity = FelECS::Entities.new
or if we want to add (any number of)components to it when creating it:
@entity = FelECS::Entites.new(
FelECS::Components::Health.new,
@component,
FelECS::Components::EnemyTeam.first
)
Accessing
Oftentimes you will not be accessing an Entity this way. Later we will shows you a more common way of accessing entities.
If you need to you can access Entities using the Entities module:
@entity = FelECS::Entities[2]
@entity = FelECS::Entities.first
@entity = FelECS::Entities.each # you can iterate over all entities this way. Any valid array method can be used
Adding and Removing Components
We can still add or remove Components from an Entity after it has been created. Here is how:
@entity.add @component
@entity.remove @component
Accessing Entities' Attached Components
This is the most common way of accessing an Entity
When Components are added to Entities, they can be accessed from the Entity. By using a Component Manager as a key we can access an array of all components created from that Component Manager that are attached to an entity:
@entity.components[@component_manager] # => [@component1, @component2, @component3]
Iterating Over Grouped Entities
You can execute a block for each entity that has all matching component types attached to it like so:
FelECS::Entities.group(@component_manager_one, @component_manager_two).do |cmp1, cmp2, ent|
# do stuff with the components and entity
end
# or
FelECS::Entities.group(@mgr1, @mgr2, @mgr3, @mgr4).do |cmp1, cmp2, cmp3, cmp4, ent|
# do stuff with the components and entity
end
# or
FelECS::Entities.group(@component_manager_one).do |cmp1, ent|
# do stuff with the component and entity
end
# etc
You can use any number of component managers and it will only iterate over all entities that have at least all these components from these managers attached to them. The arguments in the block(the arguments surrounded by |pipes|) always correspond to each component manager passed as parameters into the group method and then followed by the entity object.
This means there will be a number of these arguments equal to the number of component managers passed into the group method plus one for the entity.
Deletion
To have all Components from an Entity removed and the Entity deleted we do the following:
NOTE: The components will not be deleted. They are simply removed from the entity and then the entity is destroyed. You must handle component deletion yourself as for example singleton components need to removed instead of deleted.
@entity.delete
Components
Creating a Component Manager
Components are where all the data is stored. The data is stored in variables or accessors in each component. These accessors and their defaults are configured when a component manager is created, like so:
@component_manager = FelECS::Components.new('Stats', :armour, hp: 100)
In this example we created a component manager called "Stats".
The name given to component managers must follow the same rules for naming constants in ruby for a reason you will shortly see.
The parameters following are all creating the attributes we can set.
We can set any number of parameters we wish, in this example we define two.
The :armour parameter is being created without a default, it will equal to nil when a new component is created, while hp will be equal to 100 when a component is created.
When defining attributes symbols should be used.
Creating a Component from a Component Manager
Now that we have a component manager we can make components from it like so:
@component = FelECS::Components::Stats.new
Or we can even override the defaults when creating the component:
@component = FelECS::Components::Stats.new(armour: 'steel')
Related Skills
node-connect
345.4kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
104.6kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
345.4kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
345.4kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
