使い方
- インストールコマンドをコピーし、自分の環境へ導入する前にソースを確認します。
- 必要なツール、認証情報、対応環境を原文で確認します。
- 入力と成果物を指定し、出力を資料と照合します。
npx skills add https://github.com/mynamekse/godot-gecs --skill gecs-relationships開始前の確認
- 導入にはモデル契約、API枠、ファイルへのアクセス許可は含まれません。
- スター数や導入数は活動の指標であり、独立した品質・安全性試験ではありません。
見出し、例、コード、表、リンク、参照画像を含む原文を表示しています。
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 · versionv9· 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:
- Source: The entity that owns the relationship.
- Relation: A Component instance defining the relationship type (e.g.,
R_ChildOf,R_Attacking). - 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).
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
# 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:
# 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:
e_unit.add_relationship(Relationship.new(R_Likes.new(), Food))3. Querying Relationships & Wildcards
Exact Match Queries
# Match entities attacking e_boss
var attackers = ECS.world.query \
.with_relationship([Relationship.new(R_Attacks.new(), e_boss)]) \
.execute()Wildcard Queries (ECS.wildcard)
# 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 toNmatching instances.limit = 0: Removes none (used for validation).
Example: Poison Stacks & Antidote
# 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 stacksBatch Cleansing
# 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`:
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:
if entity.has_relationship(Rels.attacks):
pass
entity.remove_relationship(Rels.attacks, 1)6. Naming Conventions
| Type | Class Name | File Name |
|---|---|---|
| Relation Component | R_ChildOf, R_Attacks | r_child_of.gd, r_attacks.gd |
| Static Relationships | Rels.attacks_target(e) | rels.gd |

