Tech Discussion: Simulating Fire That Feels Real



In Firesafe Friend, fire isn’t just a visual effect—it’s a core gameplay system. It simulates how fire behaves across different house parts and materials, and teaches players how critical fire safety upgrades can be during a wildfire.
To support that, I designed a data-driven fire system in Unity, built to handle material variance, localized spread, and performance-friendly simulation across dozens of burnable objects.
How It Works
Every burnable object in the scene has a Combustible MonoBehaviour that handles logic. Fire properties are stored in a separate ScriptableObject (CombustibleInfo), giving us clean separation between logic and configuration.
public class FF_BaseCombustibleInfo : ScriptableObject
{
public string partID;
public float durability; // how long the part can resist fire
public float flammability; //chance to ignite when near flames
public Sprite icon;
public MaterialClass materialClass; //a clear, intuitive label for how fire-resistant it is
[TextArea]
public string description;
}
This lets us easily tweak multiple fire profiles for different materials—wood, metal, brick, etc.— and apply them to any prefab without modifying code.
Heat-Based Spread System
Fire doesn’t spread automatically. Each Combustible tracks its own heat level over time. If the object is near one or more burning neighbors, it begins accumulating heat.
If currentHeat >= heatThreshold
, the object ignites.
public virtual void AddHeat(float amount)
{
if (heat > heatThreshold && !isOverHeated)
{
TryIgnite();
isOverHeated = true;
return;
}
heat += amount;
}
public virtual void TryIgnite()
{
if (isOnFire) return;
float fireCatchChance = CalculateFireCatchChance(flammability);
if (UnityEngine.Random.value < fireCatchChance)
{
StartCoroutine(IgniteWithDelay());
}
}
protected virtual IEnumerator IgniteWithDelay()
{
yield return new WaitForSeconds(durability / 10 + baseBurnTime);
isOnFire = true;
burnTimer = durability / flammability + baseBurnTime;
StartCoroutine(Burn());
}
That means:
-
Fire spreads faster between F-rated, flammable parts
-
Upgraded A-rated parts can hold off fire, slow the spread, or even stop it
This lets players watch a fire travel across a structure in ways that feel natural—and avoidable with the right upgrades.
Fire Lifecycle & Stages
All combustibles track their own fire lifecycle using a BurnStage
enum:
enum BurnStage {
BeforeIgniting,
Igniting,
Burning,
BurnedOut
}
The burn logic is driven by a coroutine:
protected virtual IEnumerator Burn()
{
BurnStage = BurnStage.Igniting;
while (isOnFire)
{
burnTimer -= Time.deltaTime;
if (burnTimer / startBurnTimer <= 0.25f) BurnStage = BurnStage.BurnedOut;
else if (burnTimer / startBurnTimer <= 0.75f) BurnStage = BurnStage.Burning;
yield return null;
}
}
Each stage triggers events (OnIgnite, OnBurning, OnBurnedOut
) which are used for visual FX, state transitions, and interaction logic.
Spreading Fire Across House Parts
BaseHousePartObject
extends the base fire logic and introduces neighbor-aware spread using house graph data. When a part starts burning, it begins trying to ignite nearby parts:
private IEnumerator SpreadFireToNeighbour()
{
while (isOnFire)
{
foreach (var neighbor in houseGraph.GetNeighbors(houseNode))
{
float distance = Vector3.Distance(transform.position, neighbor.transform.position);
float delay = Mathf.Clamp(distance * 0.5f, 1f, 5f);
yield return new WaitForSeconds(delay);
neighbor.housePart?.TryIgnite();
}
yield return new WaitForSeconds(10f);
}
}
This gives us localized, structure-based fire propagation—and makes upgraded materials valuable not just for the part itself, but for slowing down fire spread in general.
Visual Feedback & Destruction
The system handles real-time visual transitions through material color changes, VFX, and mesh replacement:
-
Burning parts slowly lerp to a
burntColor
-
Burned parts are visually replaced with a
burntModel
mesh -
Fire VFX are spawned and animated along the object’s height
private void HandleBurning()
{
if (burntModel && burntMesh == null)
{
burntMesh = Instantiate(burntModel, transform);
burntMesh.material = mesh.material;
mesh.gameObject.SetActive(false);
}
}
When a part is destroyed, it gets disabled or removed entirely, and the house’s burnedWeight
is updated to reflect progress.
Wildfire Minigames Collection
A collection of minigames to help people develop preparedness and resilience to wildfire
Status | Released |
Authors | Wildfire UCSC, Yiyang Lu |
Genre | Simulation |
Tags | minigames, wildfire |
More posts
- Art Direction: Why We Chose a Stylized, Low-Poly Look for Our Wildfire Games7 hours ago
- From Workshop to Production – Turning Community Stories into Playable Scenario...1 day ago
- Critical Interdisciplinarity2 days ago
- When Good Ideas Go—Iterating with Communities and Experts3 days ago
- Concept Chunking: a Minigames Approach to Tackle Complex Topics in Game Design3 days ago
- Building Empathy Through Storytelling and Role-Play4 days ago
- Multiplayer, Cooperation, and Discussion5 days ago
- Autonomy and Agency vs Gamification5 days ago
- The "Serious" Side of Serious Games: Staying True to Life6 days ago
Leave a comment
Log in with itch.io to leave a comment.