Reading & Writing Components
Consider Streams First!
For bulk operations, Streams are the way to go – they're faster and more ergonomic for processing many entities.
But for one-off access? Ref and Get are perfect. Don't overthink it! 💙
When Direct Access Makes Sense
- UI event handlers – User clicked a button, update the entity
- Serialization – Save/load entity state
- Debugging – Inspect values at runtime
- Tests – Verify component values
- Initialization – Set up entity after spawning
// This is totally fine!
ref var health = ref entity.Ref<Health>();
health.Value = slider.Value;Ref<C>() - Get a Reference
Returns a reference to the component, allowing both reading and writing.
Method Signatures
| Signature | Description |
|---|---|
Entity.Ref<C>() | Reference to a plain component |
Entity.Ref<C>(Match match) | Reference with match expression |
Entity.Ref<L>(Link<L> link) | Reference to a linked object |
Usage Examples
// Read a component
ref var pos = ref entity.Ref<Position>();
Console.WriteLine($"Entity at ({pos.X}, {pos.Y})");
// Modify a component
ref var health = ref entity.Ref<Health>();
health.Value -= 10;
health.LastDamageTime = DateTime.Now;
// Modify struct fields directly
entity.Ref<Position>().X += velocity.X * deltaTime;
entity.Ref<Position>().Y += velocity.Y * deltaTime;With Relations
var target = world.Spawn();
entity.Add(new Distance { Value = 100 }, target);
// Get reference to relation component
ref var dist = ref entity.Ref<Distance>(target);
dist.Value -= 5; // Getting closer!With Object Links
var gameObject = new GameObject("Player");
entity.Add(Link.With(gameObject));
// Get reference to the linked object itself
ref var go = ref entity.Ref(Link.With(gameObject));
go.SetActive(true);
Dangling References!
The returned reference becomes invalid if the entity's archetype changes. Don't hold references across structural changes!
ref var health = ref entity.Ref<Health>(); // ✅ Valid
entity.Add<Shield>(); // Archetype changes!
health.Value = 100; // ❌ Dangling reference!Rule of thumb: Use the reference immediately, don't store it.
Get<C>() - Get Multiple Values
Returns an array of all matching component values. Useful with wildcards!
Method Signature
| Signature | Description |
|---|---|
Entity.Get<C>(Match match) | Array of all matching components |
Usage Examples
// Get all int relations
var target1 = world.Spawn();
var target2 = world.Spawn();
entity.Add<int>(10, target1);
entity.Add<int>(20, target2);
int[] scores = entity.Get<int>(Entity.Any);
// scores = [10, 20]
// Get all linked GameObjects
GameObject[] objects = entity.Get<GameObject>(Link.Any);Components Property - Get Everything
Returns all components on the entity as boxed values. Great for debugging and serialization!
IReadOnlyList<Component> components = entity.Components;
foreach (var component in components)
{
Console.WriteLine($"{component.Type.Name}: {component.Value}");
}
About Boxing
The Components property boxes all values each time it's called. That's fine for debugging, serialization, or occasional use – just don't call it every frame in a hot loop!
Comparison Table
| Method | Returns | Use Case |
|---|---|---|
Ref<C>() | ref C | Read/write a single known component |
Ref<C>(match) | ref C | Read/write with specific match |
Get<C>(match) | C[] | Get all components matching expression |
Components | IReadOnlyList<Component> | Inspect all components (boxed) |
Ensure<C>() | ref C | Get or create component |
Safe Patterns
Check Before Access
if (entity.Has<Health>())
{
ref var health = ref entity.Ref<Health>();
health.Value -= damage;
}Use Ensure for Optional Components
// Don't check + add, just ensure!
ref var counter = ref entity.Ensure<HitCount>();
counter.Value++;Immediate Use Pattern
// ✅ Good - use reference immediately
entity.Ref<Position>().X += 10;
// ❌ Risky - storing reference
ref var pos = ref entity.Ref<Position>();
DoSomethingThatMightAddComponents(entity); // Danger!
pos.X += 10; // Might be danglingConstraints
Cmust benotnull- Component must exist (throws
KeyNotFoundExceptionotherwise) - For
Link<L>,Lmust be a reference type (class) - References are invalidated by structural changes