Better Fire+ is built as an event-driven, time-sliced simulation engine for Minecraft Bedrock Edition (Script API @minecraft/server v2.9.0). It simulates thermodynamics, heat radiation, material reactions, container inventory protection, and structural collapse.


1. Directory & File Structure

The add-on codebase is located in behavior_packs/better_fire/scripts/:

scripts/
├── main.js         # Entry point & event listeners
├── config.js       # Configuration defaults, persistence & difficulty modes
├── rules.js        # Rule engine matrix & heat source registries
├── heat.js         # In-memory heat tracking map & cooling iterations
├── effects.js      # Container snapshot/restore, item spilling & audio/particles
├── simulation.js   # Spatial scanning, thermal math, raycasting & collapse queue
├── commands.js     # Custom command registry (/bf:) & /scriptevent listener
└── i18n.js         # RawMessage localization formatter

2. Execution Lifecycle & Event Sequence

The add-on follows a strict initialization and tick lifecycle:

[Server Boot]
      │
      ├──> system.beforeEvents.startup
      │         │
      │         └──> registerCommands(init) [Registers /bf:fire & /bf:firefeature]
      │
      └──> world.afterEvents.worldLoad
                │
                ├──> loadConfig() [Restores settings from world dynamic properties]
                ├──> registerScriptEvents() [Listens for /scriptevent bf:*]
                └──> startSimulation() [Schedules simulation generator job]

1. Early Registration Phase (system.beforeEvents.startup)

2. World Load Phase (world.afterEvents.worldLoad)


3. Asynchronous Time-Sliced Simulation Loop (system.runJob)

To prevent server lag or tick spikes in large worlds, the simulation loop uses ES6 Generators (function*) distributed via system.runJob(...):

export function startSimulation() {
  stopSimulation();
  simulationJob = system.runJob(simulationLoop());
}

function* simulationLoop() {
  while (CONFIG.enabled) {
    yield* processThermalCycle();
    yield* waitTicks(CONFIG.cycleTicks); // Default: 20 ticks = 1 second
  }
}