Skip to content

GECS v5.0.0-rc3 Release Notes

Pre-release
Pre-release

Choose a tag to compare

@csprance csprance released this 14 Oct 00:17
· 410 commits to main since this release
image

[5.0.0] - 2025-01-XX - Relationship System Complete Overhaul

⚠️ BREAKING CHANGES

Removed Weak/Strong Matching System

The weak/strong matching system has been completely replaced with a simpler, more intuitive approach:

  • weak parameter removed from all relationship methods
  • Component.equals() method removed - use component queries instead
  • Type matching is now the default - matches by component type only
  • Component queries for property matching - use dictionaries for property-based filtering

Migration:

Old (v4.x) New (v5.0)
entity.has_relationship(Relationship.new(C_Eats.new(5), target), false) entity.has_relationship(Relationship.new({C_Eats: {'value': {"_eq": 5}}}, target))
entity.has_relationship(Relationship.new(C_Eats.new(), target), true) entity.has_relationship(Relationship.new(C_Eats.new(), target))
entity.get_relationship(rel, true, true) entity.get_relationship(rel)
entity.get_relationships(rel, true) entity.get_relationships(rel)
Override equals() in component Use component queries: {C_Type: {'prop': {"_eq": value}}}

Component Query Improvements

  • Target component queries added - Query both relation AND target component properties
  • Cannot add query relationships to entities - Queries are for matching only, not storage
  • Fixed bug with falsy values - Component queries now correctly handle 0, false, etc.

✨ New Features

Simplified Relationship Matching

# Type matching (default) - matches by component type
entity.has_relationship(Relationship.new(C_Damage.new(), target))

# Component query - matches by property criteria
entity.has_relationship(Relationship.new({C_Damage: {'amount': {"_gte": 50}}}, target))

# Query both relation AND target
var strong_buffs = ECS.world.query.with_relationship([
    Relationship.new(
        {C_Buff: {'duration': {"_gt": 10}}},
        {C_Player: {'level': {"_gte": 5}}}
    )
]).execute()

Target Component Queries (NEW!)

# Query relationships by target component properties
var high_hp_targets = ECS.world.query.with_relationship([
    Relationship.new(C_Targeting.new(), {C_Health: {'hp': {"_gte": 100}}})
]).execute()

# Mix relation and target queries
var critical_effects = ECS.world.query.with_relationship([
    Relationship.new(
        {C_Damage: {'type': {"_in": ["fire", "ice"]}}},
        {C_Entity: {'level': {"_gte": 10}}}
    )
]).execute()

Limited Relationship Removal

# Remove specific number of relationships
entity.remove_relationship(Relationship.new(C_Damage.new(), null), 1)  # Remove 1 damage
entity.remove_relationship(Relationship.new(C_Buff.new(), null), 3)    # Remove up to 3 buffs

# Combine with component queries
entity.remove_relationship(
    Relationship.new({C_Damage: {'amount': {"_gt": 20}}}, null),
    2  # Remove up to 2 high-damage effects
)

🚨 Migration Guide

1. Remove weak Parameters

# ❌ Old (v4.x)
entity.has_relationship(rel, true)
entity.get_relationship(rel, true, true)
entity.get_relationships(rel, false)

# ✅ New (v5.0)
entity.has_relationship(rel)
entity.get_relationship(rel)
entity.get_relationships(rel)

2. Replace Strong Matching with Component Queries

# ❌ Old (v4.x) - strong matching for exact values
entity.has_relationship(Relationship.new(C_Eats.new(5), target), false)

# ✅ New (v5.0) - component query
entity.has_relationship(Relationship.new({C_Eats: {'value': {"_eq": 5}}}, target))

3. Remove equals() Overrides

# ❌ Old (v4.x) - custom equals() method
class_name C_Damage extends Component:
    @export var amount: int = 0

    func equals(other: Component) -> bool:
        return amount == other.amount

# ✅ New (v5.0) - use component queries
# No equals() method needed!
# Query by property: {C_Damage: {'amount': {"_eq": 50}}}

🧪 Test Suite Improvements

Performance Test Cleanup

  • Eliminated orphan nodes - Refactored all performance tests to use scene_runner pattern
  • Proper lifecycle management - Tests now use auto_free() and world.purge() for cleanup
  • Consistent test structure - All performance tests follow same pattern as core tests
  • Zero orphan nodes - Performance tests now maintain clean test environment

Files Updated:

  • addons/gecs/tests/performance/performance_test_base.gd - Uses scene_runner for proper test setup
  • addons/gecs/tests/performance/performance_test_entities.gd - Refactored to use auto_free pattern
  • addons/gecs/tests/performance/performance_test_components.gd - Simplified cleanup using world.purge
  • addons/gecs/tests/performance/performance_test_queries.gd - Removed manual cleanup code
  • addons/gecs/tests/performance/performance_test_systems.gd - Uses scene_runner for world management
  • addons/gecs/tests/performance/performance_test_integration.gd - Consistent with core test patterns
  • addons/gecs/tests/performance/performance_test_system_process.gd - Proper node lifecycle management

📦 Files Changed

  • addons/gecs/ecs/relationship.gd - BREAKING: Removed weak parameter, added target_query support
  • addons/gecs/ecs/entity.gd - BREAKING: Removed weak parameters from all methods, added limit parameter for removal
  • addons/gecs/ecs/component.gd - BREAKING: Removed equals() method
  • addons/gecs/lib/component_query_matcher.gd - FIXED: Properly handle falsy values (0, false, etc.)
  • addons/gecs/docs/RELATIONSHIPS.md - Complete rewrite for new system
  • addons/gecs/docs/CLAUDE.md - Updated with new relationship patterns
  • addons/gecs/tests/core/test_relationships.gd - Updated all tests to new API

Full Changelog: v5.0.0-rc1...v5.0.0-rc3