Skip to content

Removing Components Neofox: floof_sad_reach ​

Neofox: thumbsup Tidying Up

Sometimes components need to go! Removing components is just as important as adding them – it's how entities change over time and respond to game events.

Neofox: hug_haj Remove<C>(...) ​

The Remove method detaches a component from an entity. It returns the entity itself, enabling fluent method chaining.

Method Signatures ​

SignatureDescription
Entity.Remove<C>()Removes a plain component
Entity.Remove<C>(Match match)Removes all components matching a Match Expression (Wildcards allowed!)
Entity.Remove<C>(Match match, RemoveConflict mode)Same, with explicit conflict resolution: Strict throws if nothing matches (default), Allow is idempotent
Entity.Remove<C>(Entity relation)Removes a relation to a specific entity
Entity.Remove<L>(L linkedObject)Removes a link to a specific object
Entity.Remove<L>(Link<L> link)Removes a link by its wrapper

All overloads return the Entity, allowing fluent chaining.

Neofox: owo Component Must Exist!

Attempting to remove a component that doesn't exist will throw an exception. Use Has<C>() to check first if you're unsure – or pass RemoveConflict.Allow to make the removal idempotent.

cs
entity.Remove<Health>();  // ❌ Throws if no Health component!
entity.Remove<Health>(Match.Plain, RemoveConflict.Allow);  // ✅ No-op if absent

Usage Examples ​

Basic Removal ​

cs
// Remove a status effect
entity.Remove<Poisoned>();

// Remove health component (entity is now invincible? 🤔)
entity.Remove<Health>();

Fluent Chaining ​

cs
// Clean up multiple components at once
entity
    .Remove<Stunned>()
    .Remove<Slowed>()
    .Remove<Confused>();

Conditional Removal ​

cs
// Only remove if present
if (entity.Has<Shield>())
{
    entity.Remove<Shield>();
    Console.WriteLine("Shield broken!");
}

Removing Relations ​

cs
var leader = world.Spawn();
var follower = world.Spawn();

follower.Add<FollowsEntity>(leader);

// Later, stop following
follower.Remove<FollowsEntity>(leader);

Console.WriteLine(follower.Has<FollowsEntity>(leader));  // false
cs
var gameObject = new GameObject("Effect");
entity.Add(Link.With(gameObject));

// Remove the link (doesn't destroy the GameObject!)
entity.Remove(gameObject);
// or equivalently:
entity.Remove(Link.With(gameObject));

What Happens to the Data? ​

When you remove a component:

  1. The data is discarded – The component value is gone (for value types) or dereferenced (for links)
  2. Archetype changes – The entity moves to a new archetype without that component type
  3. Queries update – The entity will no longer match queries requiring that component

Neofox: think Reference Types and Links

For object links, removing the link doesn't destroy or dispose the linked object – it just removes the association. The object continues to exist in managed memory.

Removing Multiple of Same Type ​

If an entity has multiple components of the same type (via relations), you can specify which one to remove:

cs
var target1 = world.Spawn();
var target2 = world.Spawn();

entity.Add<int>(50, target1);
entity.Add<int>(25, target2);

// Remove specific relation
entity.Remove<int>(target1);  // Only removes the target1 relation

// target2 relation still exists
Console.WriteLine(entity.Has<int>(target2));  // true

Removing with Wildcards ​

Remove<C>(Match) accepts Wildcard Match Expressions to strip all matching components of a type in a single structural change:

cs
entity.Remove<Owes>(Entity.Any);    // remove all Owes relations, to anyone
entity.Remove<Bank>(Link.Any);      // remove all Bank object links
entity.Remove<Owes>(Match.Target);  // remove all relations AND links (keeps plain)
entity.Remove<Owes>(Match.Any);     // remove everything Owes: plain, relations, links

This also works on the EntityRef handed to you inside Stream runners (deferred, like all structural changes there).

Like all removals, this throws if nothing matches the expression – unless you opt into leniency with RemoveConflict.Allow, which makes the removal a no-op when nothing matches:

cs
entity.Remove<Owes>(Entity.Any, RemoveConflict.Allow);  // debt jubilee, even for the debt-free

Use Cases ​

ScenarioExample
Status effects expiringentity.Remove<Burning>()
Equipment unequippedentity.Remove<Sword>(hand)
Buff/debuff endedentity.Remove<SpeedBoost>()
Clearing temporary stateentity.Remove<JustSpawned>()
Breaking relationshipsentity.Remove<Targeting>(enemy)

Constraints ​

  • C must be notnull
  • The component must exist on the entity (throws otherwise)
  • For Link<L>, L must be a reference type (class)

Neofox: comfy Structural Changes

Removing a component is a structural change – it moves the entity to a new archetype. Inside Stream runners, these are deferred until the runner completes.