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

소스 보기

사용 방법

  1. 설치 명령을 복사하고 자신의 에이전트 환경에 설치하기 전에 소스 패키지를 확인하세요.
  2. 필요한 도구, 인증 정보, 지원 환경은 원본 문서에서 확인하세요.
  3. 입력과 원하는 산출물을 설명하고 출처와 결과를 대조하세요.
npx skills add https://github.com/mynamekse/godot-gecs --skill gecs-relationships

시작 전 확인

  • 설치에는 모델 구독, API 한도, 파일 접근 권한이 포함되지 않습니다.
  • 별점 수와 설치 수는 활동 지표이며 독립적인 품질·보안 검증이 아닙니다.
원본 Skill 문서

원본 저장소의 제목, 예시, 코드, 표, 링크, 이미지를 유지해 표시합니다.

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
같은 저장소의 Skills

더 많은 Skills

모든 Skills