/gecs
gecs ECS framework API reference — the Entity-Component-System addon for Godot 4.x used by this project. Covers Entity, Component, System, World, QueryBuilder, Relationship, Observer, CommandBuffer, SystemTimer. Use when the task involves ECS architecture: creating entities with
$ npx -y skills add RandallLiuXin/GodotMaker --skill gecs --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/gecs
Context preview
The summary Claude sees to decide when to auto-load this skill.
gecs ECS framework API reference — the Entity-Component-System addon for Godot 4.x used by this project. Covers Entity, Component, System, World, QueryBuilder, Relationship, Observer, CommandBuffer, SystemTimer. Use when the task involves ECS architecture: creating entities with
SKILL.md
gecs.SKILL.mdname: gecs
description: |
gecs ECS framework API reference — the Entity-Component-System addon for
Godot 4.x used by this project. Covers Entity, Component, System, World,
QueryBuilder, Relationship, Observer, CommandBuffer, SystemTimer.
Use when the task involves ECS architecture: creating entities with components,
defining component data classes (C_ prefix), writing game logic systems,
querying entities by component composition, entity relationships or links,
reactive observers for component changes, safe structural changes during
iteration, system tick rates, ECS world setup, debugging ECS queries or cache,
or deferred entity destruction. Also trigger on gecs API calls: q.with_all(),
ECS.world, ECS.process(), define_components(), cmd.add_component(). gecs has
zero LLM training data — without this skill all ECS API calls will be
fabricated. NOT relevant for standard Godot subsystems (physics, animation,
UI, tilemap, shader, particles, navigation, signals, audio) unless explicitly
connected to ECS.
gecs — ECS Framework for Godot 4.x
$ARGUMENTS
gecs is the ECS backend for GodotMaker. It has **zero LLM training data coverage** — all API knowledge must come from this skill.
Core Concept Mapping
| gecs Class | Godot Base | Key Insight | |------------|-----------|-------------| | `Entity` | `extends Node` | Entity IS a Node — lives in scene tree, can have child nodes | | `Component` | `extends Resource` | Pure data, `@export` properties with defaults, no logic | | `System` | `extends Node` | Contains game logic, queries entities, placed in scene tree | | `World` | `extends Node` | Manages all entities/systems, archetype storage, query engine | | `QueryBuilder` | `extends RefCounted` | Chain API: `with_all`/`with_any`/`with_none`, auto-cached | | `Relationship` | `extends Resource` | Pair (relation_component, target), archetype-level indexing | | `Observer` | `extends Node` | Reactive: fires on component add/remove/change events | | `CommandBuffer` | `extends RefCounted` | Safe structural changes during iteration via `cmd` | | `ECS` | Autoload singleton | Global access: `ECS.world`, `ECS.process(delta, group)` |
Quick Start
# --- Component (pure data, extends Resource) ---
class_name C_Health extends Component
@export var current: float = 100.0
@export var maximum: float = 100.0
class_name C_Velocity extends Component
@export var direction: Vector3 = Vector3.ZERO
@export var speed: float = 100.0
# --- Entity (extends Node, define default components) ---
class_name Player extends Entity
func define_components() -> Array:
return [C_Health.new(), C_Velocity.new()]
func on_ready():
add_to_group("player")
# --- System (game logic, extends Node) ---
class_name MovementSystem extends System
func query() -> QueryBuilder:
return q.with_all([C_Velocity])
func process(entities: Array[Entity], components: Array, delta: float) -> void:
for entity in entities:
var vel = entity.get_component(C_Velocity)
var pos = entity.get_component(C_Position)
pos.value += vel.direction * vel.speed * delta # Entity is Node, not Node2D!
# --- Main scene processing ---
# main.gd
func _process(delta):
ECS.process(delta, "input")
ECS.process(delta, "gameplay")
func _physics_process(delta):
ECS.process(delta, "physics")
ECS.process(delta, "run-last")Naming Conventions
| Type | Class Name | File Name | Example | |------|-----------|-----------|---------| | Component | `C_Name` | `c_name.gd` | `C_Health` / `c_health.gd` | | System | `NameSystem` | `s_name.gd` | `MovementSystem` / `s_movement.gd` | | Entity | `Name` | `e_name.gd` | `Player` / `e_player.gd` | | Observer | `NameObserver` | `o_name.gd` | `HealthUIObserver` / `o_health_ui.gd` | | Relationship component | `R_Action` | `r_action.gd` | `R_ChildOf` / `r_child_of.gd` |
Common Operations
Entity
# Create programmatically
var entity = Player.new()
ECS.world.add_entity(entity)
# Instantiate from scene prefab (.tscn with Entity root)
var entity = preload("res://entities/e_player.tscn").instantiate()
get_tree().current_scene.add_child(entity)
ECS.world.add_entity(entity)
# Component operations (pass CLASS to get/has, INSTANCE to add/remove)
entity.add_component(C_Health.new(100))
var health = entity.get_component(C_Health) # returns instance or null
var has = entity.has_component(C_Health) # bool check
entity.remove_component(health) # pass the instance
# Enable/disable
entity.enabled = false # excluded from queries
ECS.world.disable_entity(entity)
ECS.world.enable_entity(entity)
# Destroy (calls on_destroy, queue_free, cleans up relationships)
ECS.world.remove_entity(entity)Query
# In a System — use q shorthand
func query() -> QueryBuilder:
return q.with_all([C_Health, C_Velocity]) # must have ALL
.with_any([C_Player, C_Enemy]) # must have at least ONE
.with_none([C_Dead]) # must NOT have
.enabled() # only enabled entities
# Batch component access (faster — avoids per-entity get_component):
func query() -> QueryBuilder:
return q.with_all([C_Velocity]).iterate([C_Velocity])
func process(entities: Array[Entity], components: Array, delta: float):
var velocities = components[0] # Array of C_Velocity, same order as entities
for i in entities.size():
var pos = entities[i].get_component(C_Position)
pos.value += velocities[i].direction * delta # Entity is Node, not Node2D!
# Standalone query (outside a System):
var enemies = ECS.world.query.with_all([C_Health, C_Enemy]).execute()
var player = ECS.world.query.with_all([C_Player]).execute_one()CommandBuffer (safe structural changes during iteration)
class_name LifetimeSystem extends System
func query():
return q.with_all([C_Lifetime])
func process(entities: Array[EntRead more
name: gecs description: | gecs ECS framework API reference — the Entity-Component-System addon for Godot 4.x used by this project. Covers Entity, Component, System, World, QueryBuilder, Relationship, Observer, CommandBuffer, SystemTimer. Use when the task involves ECS architecture: creating entities with components, defining component data classes (C_ prefix), writing game logic systems, querying entities by component composition, entity relationships or links, reactive observers for component changes, safe structural changes during iteration, system tick rates, ECS world setup, debugging ECS queries or cache, or deferred entity destruction. Also trigger on gecs API calls: q.with_all(), ECS.world, ECS.process(), define_components(), cmd.add_component(). gecs has zero LLM training data — without this skill all ECS API calls will be fabricated. NOT relevant for standard Godot subsystems (physics, animation, UI, tilemap, shader, particles, navigation, signals, audio) unless explicitly connected to ECS.
gecs — ECS Framework for Godot 4.x
$ARGUMENTS
gecs is the ECS backend for GodotMaker. It has **zero LLM training data coverage** — all API knowledge must come from this skill.
Core Concept Mapping
| gecs Class | Godot Base | Key Insight | |------------|-----------|-------------| | `Entity` | `extends Node` | Entity IS a Node — lives in scene tree, can have child nodes | | `Component` | `extends Resource` | Pure data, `@export` properties with defaults, no logic | | `System` | `extends Node` | Contains game logic, queries entities, placed in scene tree | | `World` | `extends Node` | Manages all entities/systems, archetype storage, query engine | | `QueryBuilder` | `extends RefCounted` | Chain API: `with_all`/`with_any`/`with_none`, auto-cached | | `Relationship` | `extends Resource` | Pair (relation_component, target), archetype-level indexing | | `Observer` | `extends Node` | Reactive: fires on component add/remove/change events | | `CommandBuffer` | `extends RefCounted` | Safe structural changes during iteration via `cmd` | | `ECS` | Autoload singleton | Global access: `ECS.world`, `ECS.process(delta, group)` |
Quick Start
# --- Component (pure data, extends Resource) ---
class_name C_Health extends Component
@export var current: float = 100.0
@export var maximum: float = 100.0
class_name C_Velocity extends Component
@export var direction: Vector3 = Vector3.ZERO
@export var speed: float = 100.0
# --- Entity (extends Node, define default components) ---
class_name Player extends Entity
func define_components() -> Array:
return [C_Health.new(), C_Velocity.new()]
func on_ready():
add_to_group("player")
# --- System (game logic, extends Node) ---
class_name MovementSystem extends System
func query() -> QueryBuilder:
return q.with_all([C_Velocity])
func process(entities: Array[Entity], components: Array, delta: float) -> void:
for entity in entities:
var vel = entity.get_component(C_Velocity)
var pos = entity.get_component(C_Position)
pos.value += vel.direction * vel.speed * delta # Entity is Node, not Node2D!
# --- Main scene processing ---
# main.gd
func _process(delta):
ECS.process(delta, "input")
ECS.process(delta, "gameplay")
func _physics_process(delta):
ECS.process(delta, "physics")
ECS.process(delta, "run-last")Naming Conventions
| Type | Class Name | File Name | Example | |------|-----------|-----------|---------| | Component | `C_Name` | `c_name.gd` | `C_Health` / `c_health.gd` | | System | `NameSystem` | `s_name.gd` | `MovementSystem` / `s_movement.gd` | | Entity | `Name` | `e_name.gd` | `Player` / `e_player.gd` | | Observer | `NameObserver` | `o_name.gd` | `HealthUIObserver` / `o_health_ui.gd` | | Relationship component | `R_Action` | `r_action.gd` | `R_ChildOf` / `r_child_of.gd` |
Common Operations
Entity
# Create programmatically
var entity = Player.new()
ECS.world.add_entity(entity)
# Instantiate from scene prefab (.tscn with Entity root)
var entity = preload("res://entities/e_player.tscn").instantiate()
get_tree().current_scene.add_child(entity)
ECS.world.add_entity(entity)
# Component operations (pass CLASS to get/has, INSTANCE to add/remove)
entity.add_component(C_Health.new(100))
var health = entity.get_component(C_Health) # returns instance or null
var has = entity.has_component(C_Health) # bool check
entity.remove_component(health) # pass the instance
# Enable/disable
entity.enabled = false # excluded from queries
ECS.world.disable_entity(entity)
ECS.world.enable_entity(entity)
# Destroy (calls on_destroy, queue_free, cleans up relationships)
ECS.world.remove_entity(entity)Query
# In a System — use q shorthand
func query() -> QueryBuilder:
return q.with_all([C_Health, C_Velocity]) # must have ALL
.with_any([C_Player, C_Enemy]) # must have at least ONE
.with_none([C_Dead]) # must NOT have
.enabled() # only enabled entities
# Batch component access (faster — avoids per-entity get_component):
func query() -> QueryBuilder:
return q.with_all([C_Velocity]).iterate([C_Velocity])
func process(entities: Array[Entity], components: Array, delta: float):
var velocities = components[0] # Array of C_Velocity, same order as entities
for i in entities.size():
var pos = entities[i].get_component(C_Position)
pos.value += velocities[i].direction * delta # Entity is Node, not Node2D!
# Standalone query (outside a System):
var enemies = ECS.world.query.with_all([C_Health, C_Enemy]).execute()
var player = ECS.world.query.with_all([C_Player]).execute_one()CommandBuffer (safe structural changes during iteration)
class_name LifetimeSystem extends System
func query():
return q.with_all([C_Lifetime])
func process(entities: Array[EntAutonomous text-to-game pipeline for Godot, powered by Claude Code,Codex,Opencode
Repo: RandallLiuXin/GodotMaker
Other skills on godotmaker.
- /background-map
Generate and validate a fixed-viewport background, map base, or parallax plate as a ready-to-load Texture2D.
Open skill - /card-kit
Produce reusable card art sources and native Godot card UI resources.
Open skill - /character-bundle
Produce one illustrated character SpriteFrames resource from high-level body-action intent, optional character and style references, and a resolved animation plan.
Open skill - /compact-prop-pack
Produce a reusable compact-prop atlas from one provider source sheet, with independently loadable AtlasTexture resources for every declared prop.
Open skill - /fx-bundle
Produce a standalone static Texture2D effect or one explicitly timed animated SpriteFrames effect.
Open skill - /platform-strip
Generate non-pixel-art, horizontally repeatable platform strips from real image sources as fixed Texture2D cells or AtlasTexture regions.
Open skill

