mynamekse/godot-gecs

gecs-relationships

Use when connecting entities or adding link-attached data in GECS — Entity-Entity pairs, Entity-Component data links, Entity-Archetype relationships, wildcard queries, stacked removals (buffs/debuffs), and the Rels factory pattern

Ver código fuente

Cómo usar

  1. Copia el comando y revisa el paquete antes de instalarlo en tu entorno de agente.
  2. Consulta las herramientas, credenciales y entornos necesarios en el documento original.
  3. Describe las entradas y el resultado deseado; contrasta la salida con las fuentes.
npx skills add https://github.com/mynamekse/godot-gecs --skill gecs-relationships

Antes de empezar

  • La instalación no incluye suscripción al modelo, cuota API ni permisos sobre tus archivos.
  • Las estrellas e instalaciones reflejan actividad, no una prueba independiente de calidad o seguridad.
Documento original del Skill

Contenido del repositorio de origen con títulos, ejemplos, código, tablas, enlaces e imágenes preservados.

GECS Relationships in Godot 4.3+

Express links between entities as first-class pairs in GECS v9. A Relationship connects a Source Entity to a Target through a Relation Component. Relationships support arbitrary metadata, stacked instances (e.g. poison stacks), wildcard queries, and graduated cleansing.

Addon: GECS · version v9 · Godot 4.3+ · MIT Related skills: gecs-core for primitives, gecs-queries for relationship queries, gecs-observers for .on_relationship_added().

1. Anatomy of a Relationship

A relationship consists of 3 elements:

  1. Source: The entity that owns the relationship.
  2. Relation: A Component instance defining the relationship type (e.g., R_ChildOf, R_Attacking).
  3. Target: One of three target types:
  • Entity: Linking two entities (e.g., attacker -> target).
  • Component Instance: Storing link-attached data directly on the relationship (e.g., unit -> C_Burning.new(10.0)).
  • Archetype / Class Type: Categorical tagging (e.g., unit -> Food).
mermaid
flowchart LR
    E1["Source Entity (e.g., Player)"] -- "Relationship (R_Attacks)" --> E2["Target Entity (e.g., Boss)"]
    E1 -- "Relationship (R_StatusEffect)" --> C["Target Component (C_Poison.new(5s))"]
    E1 -- "Relationship (R_Likes)" --> A["Target Archetype (Food)"]

2. The Three Relationship Types

1. Entity → Entity Link

gdscript
# e_alice is attacking e_bob
e_alice.add_relationship(Relationship.new(R_Attacks.new(), e_bob))

2. Entity → Component Instance (Link Data)

Attach custom data directly to the connection without modifying the entity's direct archetype:

gdscript
# Apply 50 fire damage over 5 seconds directly to target
entity.add_relationship(Relationship.new(R_Damaged.new(), C_FireDamage.new(50.0, 5.0)))

3. Entity → Archetype

Tag relationships with high-level classifications:

gdscript
e_unit.add_relationship(Relationship.new(R_Likes.new(), Food))

3. Querying Relationships & Wildcards

Exact Match Queries

gdscript
# Match entities attacking e_boss
var attackers = ECS.world.query \
	.with_relationship([Relationship.new(R_Attacks.new(), e_boss)]) \
	.execute()

Wildcard Queries (ECS.wildcard)

gdscript
# 1. Any entity attacking ANY target (wildcard target)
var in_combat = ECS.world.query \
	.with_relationship([Relationship.new(R_Attacks.new(), ECS.wildcard)]) \
	.execute()

# 2. Any relationship targeting e_boss (wildcard relation)
var targeted = ECS.world.query \
	.with_relationship([Relationship.new(ECS.wildcard, e_boss)]) \
	.execute()

# 3. Omitting target defaults to wildcard:
var has_buff = ECS.world.query \
	.with_relationship([Relationship.new(R_Buff.new())]) \
	.execute()
Performance Rule: Wildcard queries scan multiple archetypes (O(N)). Always combine wildcards with a component filter like .with_all([C_Alive]) in performance-critical code!

4. Limited-Count Removal (Buffs, Debuffs & Stacks)

The remove_relationship() method accepts an optional limit argument:

  • limit = -1 (Default): Remove all matching relationships.
  • limit = N (N > 0): Remove up to N matching instances.
  • limit = 0: Removes none (used for validation).

Example: Poison Stacks & Antidote

gdscript
# Apply 4 poison stacks
for i in 4:
	entity.add_relationship(Relationship.new(R_Poison.new(), null))

# Minor antidote cleanses 2 stacks
entity.remove_relationship(Relationship.new(R_Poison.new(), null), 2)

# Verify remaining stacks: entity still has 2 poison stacks

Batch Cleansing

gdscript
# Remove up to 2 stacks across multiple negative effects
entity.remove_relationships([
	Relationship.new(R_Poison.new(), null),
	Relationship.new(R_Bleed.new(), null)
], 2)

5. The Rels Factory Pattern (Recommended)

To avoid allocating new relation objects repeatedly, create a static Rels helper class. See `examples/rels.gd`:

gdscript
class_name Rels

static var attacks: Relationship = Relationship.new(R_Attacks.new(), null)
static var child_of: Relationship = Relationship.new(R_ChildOf.new(), null)

static func attacks_target(target: Entity) -> Relationship:
	return Relationship.new(R_Attacks.new(), target)

static func child_of_entity(parent: Entity) -> Relationship:
	return Relationship.new(R_ChildOf.new(), parent)

Usage in gameplay code:

gdscript
if entity.has_relationship(Rels.attacks):
	pass

entity.remove_relationship(Rels.attacks, 1)

6. Naming Conventions

TypeClass NameFile Name
Relation ComponentR_ChildOf, R_Attacksr_child_of.gd, r_attacks.gd
Static RelationshipsRels.attacks_target(e)rels.gd
del mismo repositorio

Más Skills

Todos los Skills