menu_bookDocumentation

Prop Component: Procedural Components, Damage System, Gib Spawning, and DamageInfo Patterns

calendar_today May 4, 2026 schedule ~2 min read person patrickjr verified 50

Prop Component: Procedural Physics, Gibs, Damage, and Network Patterns

The Prop component is a high-level s&box component that automatically creates ModelRenderer, ModelCollider, and Rigidbody components based on the assigned model. These are "procedural" components — they are not saved to disk and are recreated on enable.

How Procedural Components Work

Prop maintains a ProceduralComponents list (marked [Property, Hide]). When enabled (and not a proxy), it calls ClearProcedurals() then UpdateComponents() to recreate the renderer and physics components. These components have ComponentFlags.NotSaved behavior — they are not serialized.
CSHARP
// Prop automatically creates these based on the model:
// - ModelRenderer or SkinnedModelRenderer (if model has bones)
// - ModelCollider (static or dynamic)
// - Rigidbody (if model has single physics part)
// - ModelPhysics (if model has multiple physics parts = ragdoll)

Damage System

Prop implements Component.IDamageable:
CSHARP
[Sync] public float Health { get; set; }
[Sync] public bool IsOnFire { get; protected set; }
[Sync] public GameObject LastAttacker { get; set; }

public void OnDamage( in DamageInfo damage )
{
    LastAttacker = damage.Attacker;
    if ( IsProxy ) return;  // only owner processes damage

    Health -= damage.Damage;
    if ( Health <= 0 ) Kill();
}

Key pattern: if ( IsProxy ) return — only the owner/host processes damage. The Health property is [Sync] so all clients see the current health.

Gib Spawning Pattern

CSHARP
[Rpc.Broadcast( NetFlags.OwnerOnly )]
public void NetworkCreateGibs()
{
    CreateGibs();
}

Gibs are spawned via [Rpc.Broadcast( NetFlags.OwnerOnly )] — only the owner can trigger this, but it runs on all clients. Client-only gibs (debris) are tagged "debris", "clientside" and not network-spawned.

DamageInfo

DamageInfo is a class (not struct) so it can be subclassed for custom damage types:
CSHARP
var damage = new DamageInfo( 50f, attackerGo, weaponGo )
{
    Position = hitPosition,
    Origin = shooterEyePos,
    Shape = hitShape,
    Hitbox = hitbox
};
damage.Tags.Add( "bullet" );

// Apply to a component implementing IDamageable
target.Components.Get<Component.IDamageable>()?.OnDamage( damage );

Explosion Pattern

When a prop breaks and is explosive, it clones an explosion prefab and configures it via RunEvent:

CSHARP
go.RunEvent<RadiusDamage>( x =>
{
    x.Radius = radius;
    x.DamageAmount = damage;
    x.Attacker = LastAttacker;
    x.DamageTags?.Add( "explosion" );
}, FindMode.EverythingInSelfAndDescendants );

This is a common s&box pattern: clone a prefab, configure components via RunEvent, then enable and network-spawn it.

Was this helpful?