FERRETGame engine over Babylon.js
Ferret

Scenario: a boiler house

A coal fire under a boiler. Steam goes through a throttle to an engine; the engine turns a shaft; the shaft turns a generator; the generator feeds a lamp. Nothing is scripted: the lamp is bright because the pressure is high, and the pressure is high because the fire is hot.

This page shows how capabilities talk to each other, and where the energy goes.

The chain#

StageCapabilityObjectPassed to the next stage by
Fire (a power in watts)nonea numberboiler.step(dt, heat)
Boiler: water and steam, safety valvecombustionBoilerthe engineOnBoiler link
Engine: steam through a throttlelinksengineOnBoilera torque on the shaft
Shaft with a flywheelmachinesDrivetraingen.omega = shaft.omega, drive(shaft, () => gen.torque)
Generator and loadelectricityCircuit, DCMachine, Resistorthe lamp's power

Every arrow is either a link from the links package or two lines of glue: read one side's field, write the other's. The capabilities know nothing about each other. The scene closes the loop.

Building it#

const boiler = new Boiler({ volume: 0.5, water: 200, T: 450, safety: { pressure: 1.2e6, area: 5e-4 } });

const train = new Drivetrain();
const shaft = train.shaft({ name: 'flywheel', J: 20, b: 0.5 });
const engine = engineOnBoiler(boiler, shaft, { area: 3e-5, exhaust: 101325,
                                               work: (p1, p2) => steamWork(p1, p2, 0.15), maxTorque: 500 });

const circuit = new Circuit();
const gen = circuit.add(new DCMachine('G', 'a', '0', 1.0, 0.2));
const lamp = circuit.add(new Resistor('Lamp', 'a', '0', 5));
train.drive(shaft, () => gen.torque);          // the generator loads the shaft

Each step, in this order: heat the boiler (boiler.step(dt, fire)), step the engine link, copy the shaft speed into the generator (gen.omega = shaft.omega), step the drive train, step the circuit. In a game the capabilities and the links capability do this for you.

What to read off#

  • Pressure is set by the fire against the engine's demand for steam and the valve. Open the throttle (a larger area) and the boiler is drawn down; close it and the valve lifts. The valve holds the pressure to within a few percent of its setting.
  • The ledger. Only a small part of the fire's heat reaches the lamp as electricity; a steam engine at 15 % efficiency delivers well under 20 %. The rest leaves with exhaust steam and vented steam. boiler.heatIn, boiler.energyOut, boiler.vented and the engine link's moved say where each joule went. Put them in the links capability's account (cap.account({ name, joules })) and a leak anywhere shows up as a drifting total.
  • The load. A smaller resistance instead of the lamp draws more current, loads the shaft harder and slows it; a short circuit would stall the engine. Put a Fuse in series to protect it.

Making it a game scene#

Show the boiler's pressure and the shaft speed on a gauge. Expose the fire's power as a command (heat.add) so a stoker can feed it. Hand the lamp's circuit node to lampLight (fx).

If the safety valve is blocked (safety.area = 0), the pressure climbs until the drum gives out. Hand that vessel to explosions (detonate({ vessel })), and the boiler explosion every steam age feared is one call.

What to change#

ChangeEffect
Fire doubledthe pressure rises to the valve, the valve vents the excess; more power to the lamp until the engine's torque cap
Throttle closedthe engine stops and the boiler builds pressure to the valve
Smaller generator resistancemore current, more load on the shaft, lower speed
Cold feed water (boiler.feed(kg, T))pressure drops while the cold water is heated
A second consumer on boiler.takethe engine starves and the pressure sags

The complete run, with the numbers it must produce, is in tests/unit/examples/physics-scenarios-boiler-house.test.ts.