Object dependencies: references, interfaces and signals
Supply an external target explicitly instead of coupling a reusable object to another hierarchy.
Command or notification
| Connection | Use when |
|---|---|
| Direct call through a supplied reference | The command needs an immediate result |
| C# interface | Different types must support the same command |
| Signal | An object announces change without selecting receivers |
| Internal child path | The prefab owns that stable part of its structure |
HitController receives IDamageable through SetTarget. It needs no GetParent, level name or global service. HealthModel implements the contract without Entity; DamageReceiver implements it as an engine object.
HealthModel.cs
using System;
public interface IDamageable
{
bool TryApplyDamage(int amount);
}
public sealed class HealthModel : IDamageable
{
public int Maximum { get; }
public int Current { get; private set; }
public HealthModel(int maximum)
{
if (maximum <= 0) throw new ArgumentOutOfRangeException(nameof(maximum));
Maximum = maximum;
Current = maximum;
}
public bool TryApplyDamage(int amount)
{
if (amount <= 0 || Current == 0) return false;
Current = amount >= Current ? 0 : Current - amount;
return true;
}
}HitController.cs
using Reckfell;
public partial class HitController : Entity
{
private IDamageable? _target;
public void SetTarget(IDamageable? target) => _target = target;
public bool TryHit(int amount)
{
if (_target is ReckfellObject native && !ReckfellObject.IsInstanceValid(native))
{
_target = null;
return false;
}
if (_target is Entity entity && entity.IsQueuedForDeletion()) return false;
return _target?.TryApplyDamage(amount) ?? false;
}
public override void _ExitTree() => _target = null;
}Reference lifetime
A C# reference can remain after the native object is freed. The controller checks IsInstanceValid before accessing an Entity and separately refuses a QueueFree target while deletion is pending. _ExitTree clears the reference; assign the target again after reattachment.
RemoveChild does not delete the controller. If you retain a detached object, explicitly decide who will later Free it or reattach it.
IDamageable is a C# contract rather than an exported data type. It does not supply automatic reference persistence, RPC or the ability to pass arbitrary models through Variant.
Initial state and signals
DamageReceiver emits HealthChanged after a successful change. Subscribing after _Ready does not replay its initial notification: read CurrentHealth and MaximumHealth for the initial display, then keep it updated through signals. Unsubscribe when ending a subscription to an external long-lived sender.