Chemistry · class
ParcelStore
Explained in Chemistry.
class ParcelStoreimport { ParcelStore } from '@driftengine/chemistry';Constructor
new
constructor(substances: SubstanceRegistry, species?: import("../index.ts").SpeciesRegistry)| Parameter | Type | Description |
|---|---|---|
substances | SubstanceRegistry | |
species? | import("../index.ts").SpeciesRegistry |
Accessors
| Name | Type | Description |
|---|---|---|
countget | number | Handles ever issued, live or not. A destroyed parcel still occupies its index. |
substanceCountget | number | How many substances this store's registry holds. fingerprintChemistry covers all of them. |
Methods
spawn
spawn(spec: ParcelSpec): number| Parameter | Type | Description |
|---|---|---|
spec | ParcelSpec |
areaOf
areaOf(parcel: number): numberm², what the environment touches. Zero means the caller has not said, and conduction refuses.
| Parameter | Type | Description |
|---|---|---|
parcel | number |
destroy
destroy(parcel: number): void| Parameter | Type | Description |
|---|---|---|
parcel | number |
alive
alive(parcel: number): boolean| Parameter | Type | Description |
|---|---|---|
parcel | number |
substanceOf
substanceOf(parcel: number): number| Parameter | Type | Description |
|---|---|---|
parcel | number |
massOf
massOf(parcel: number): number| Parameter | Type | Description |
|---|---|---|
parcel | number |
volumeOf
volumeOf(parcel: number): numberm³, from mass and the substance's density. Shrinks as mass leaves, which is why a log burns down.
| Parameter | Type | Description |
|---|---|---|
parcel | number |
shellCount
shellCount(parcel: number): numberShells resolved right now, which a level-of-detail tier may have reduced.
| Parameter | Type | Description |
|---|---|---|
parcel | number |
More
Everything that walks a parcel's depth reads this rather than the substance's declared count, so
a Distant log is one shell everywhere at once and nothing has to be told which tier it is at.
declaredShellsOf
declaredShellsOf(parcel: number): numberWhat the substance asked for, which is the resolution Hero restores to.
| Parameter | Type | Description |
|---|---|---|
parcel | number |
tierOf
tierOf(parcel: number): Tier| Parameter | Type | Description |
|---|---|---|
parcel | number |
cadenceOf
cadenceOf(parcel: number): numberTicks between updates at this parcel's tier. §14's cadence column.
| Parameter | Type | Description |
|---|---|---|
parcel | number |
substepsOf
substepsOf(parcel: number): numberThe most sub-steps a reaction solve will take at this parcel's tier.
| Parameter | Type | Description |
|---|---|---|
parcel | number |
setTier
setTier(parcel: number, tier: Tier): voidMove a parcel to a tier, conserving mass, every element and enthalpy exactly.
| Parameter | Type | Description |
|---|---|---|
parcel | number | |
tier | Tier |
More
§14: "a tier change does not lose or gain mass or energy... which is the property that makes
the LOD safe to apply to a burning object mid-burn." Shells are equal-mass by construction, so a
fold is a proportional redistribution — target j takes source shells [j·n/m, (j+1)·n/m),
splitting one where the ratio is not an integer — and the targets come out equal-mass too.
What it loses is the profile inside a fold, which is the point of a tier: two shells at 400 K and 300 K become one at their mass-weighted mean, and going back up hands each of them the same mean. Resolution in depth is what a distant object gives away.
enthalpyOf
enthalpyOf(parcel: number): numberTotal joules held across every shell, not joules per kilogram.
| Parameter | Type | Description |
|---|---|---|
parcel | number |
shellEnthalpyOf
shellEnthalpyOf(parcel: number, shell: number): number| Parameter | Type | Description |
|---|---|---|
parcel | number | |
shell | number |
shellTemperatureOf
shellTemperatureOf(parcel: number, shell: number): numberThe temperature of one shell, K. Shell 0 is the surface and the last is the core.
| Parameter | Type | Description |
|---|---|---|
parcel | number | |
shell | number |
More
surfaceTemperatureOf is what decides ignition and coreTemperatureOf is what decides
doneness, and the gap between them is the whole reason shells exist.
surfaceTemperatureOf
surfaceTemperatureOf(parcel: number): number| Parameter | Type | Description |
|---|---|---|
parcel | number |
coreTemperatureOf
coreTemperatureOf(parcel: number): number| Parameter | Type | Description |
|---|---|---|
parcel | number |
positionX
positionX(parcel: number): number| Parameter | Type | Description |
|---|---|---|
parcel | number |
positionY
positionY(parcel: number): number| Parameter | Type | Description |
|---|---|---|
parcel | number |
positionZ
positionZ(parcel: number): number| Parameter | Type | Description |
|---|---|---|
parcel | number |
move
move(parcel: number, x: number, y: number, z: number): void| Parameter | Type | Description |
|---|---|---|
parcel | number | |
x | number | |
y | number | |
z | number |
temperatureOf
temperatureOf(parcel: number): numberThe temperature this parcel would have if it were stirred, K.
| Parameter | Type | Description |
|---|---|---|
parcel | number |
More
A read rather than a stored field, and that is the design. Nothing writes a temperature except
setTemperature, which writes the enthalpy that produces one — so a parcel on a plateau simply
does not move, and no code anywhere had to know a plateau exists.
The temperature of the total enthalpy, not the mean of the shell temperatures. The two differ wherever the curve bends, and only this one has the property that matters: heat in, temperature out, with nothing lost between them.
addHeat
addHeat(parcel: number, joules: number): voidJoules in, spread evenly through the depth. Negative cools. A microwave, or a stirred pot.
| Parameter | Type | Description |
|---|---|---|
parcel | number | |
joules | number |
addSurfaceHeat
addSurfaceHeat(parcel: number, joules: number): voidJoules into shell 0 alone, which is what a flux from outside actually does.
| Parameter | Type | Description |
|---|---|---|
parcel | number | |
joules | number |
More
Every radiative, convective and contact term in CH-5 lands here. The difference between this
and addHeat is the difference between a log in front of a fire and a log in an oven.
conduct
conduct(parcel: number, dt: number): voidConduct heat inward one step of dt seconds.
| Parameter | Type | Description |
|---|---|---|
parcel | number | |
dt | number |
More
Conserves this parcel's total enthalpy exactly — the arithmetic is in conduction.ts and so is
the reason.
setTemperature
setTemperature(parcel: number, temperature: number): voidForce a temperature by writing the enthalpy that produces it.
| Parameter | Type | Description |
|---|---|---|
parcel | number | |
temperature | number |
More
For authoring and for tests. Not for a tick: it discards whatever enthalpy the parcel held, so a boiling parcel set to its own boiling point loses however much of the plateau it had crossed, and the energy budget does not close across the call.
setShellTemperature
setShellTemperature(parcel: number, shell: number, temperature: number): voidForce one shell's temperature. Authoring and tests only, for the reason above.
| Parameter | Type | Description |
|---|---|---|
parcel | number | |
shell | number | |
temperature | number |
speciesMassOf
speciesMassOf(parcel: number, shell: number, species: number): numberKilograms of one species in one shell. Zero where the substance cannot hold it at all.
| Parameter | Type | Description |
|---|---|---|
parcel | number | |
shell | number | |
species | number |
parcelSpeciesMass
parcelSpeciesMass(parcel: number, species: number): numberThe same, summed over every shell.
| Parameter | Type | Description |
|---|---|---|
parcel | number | |
species | number |
shellMassOf
shellMassOf(parcel: number, shell: number): numberKilograms in one shell, summed over its species. Invariant under reaction.
| Parameter | Type | Description |
|---|---|---|
parcel | number | |
shell | number |
elementTotalsOf
elementTotalsOf(parcel: number, out: Float64Array): voidMoles of each element this parcel holds. Writes into out, allocates nothing.
| Parameter | Type | Description |
|---|---|---|
parcel | number | |
out | Float64Array |
chemicalEnergyOf
chemicalEnergyOf(parcel: number): numberEnergy locked in this parcel's chemical bonds, J.
| Parameter | Type | Description |
|---|---|---|
parcel | number |
More
Neither this nor the thermal enthalpy is conserved on its own — a reaction moves energy between
them. Their sum is, exactly, because the same number is added to one and taken from the
other in reactShell.
react
react(parcel: number, dt: number, transportFactor?: number): voidRun this parcel's reactions in every shell for dt seconds.
| Parameter | Type | Description |
|---|---|---|
parcel | number | |
dt | number | |
transportFactor? | number |
sleeping
sleeping(parcel: number): booleanWhether this parcel is being skipped entirely.
| Parameter | Type | Description |
|---|---|---|
parcel | number |
More
§14's thermal quiescence, and the vocabulary is deliberately Track B's. A cold stone floor is a
thousand of these and costs a bounded scan.
wake
wake(parcel: number): voidWake it, and reset the count that would put it back.
| Parameter | Type | Description |
|---|---|---|
parcel | number |
More
Called by everything that could change what a parcel is: heat arriving, water poured on, mass added, a contact, or a source coming within range. Cheap enough — a flag and an integer — that a caller never has to decide whether it is worth it.
settle
settle(parcel: number): booleanDecide whether this parcel is still enough to sleep, and put it to sleep if it has been for long enough. Returns whether it is now asleep.
| Parameter | Type | Description |
|---|---|---|
parcel | number |
More
A burning or smouldering parcel never sleeps, whatever its numbers say. A steady flame is a steady parcel by every measure here, and sleeping one would put out a fire by optimising it.
accrue
accrue(parcel: number, dt: number): numberSeconds this parcel is owed by its cadence, and whether its turn has come.
| Parameter | Type | Description |
|---|---|---|
parcel | number | |
dt | number |
More
A Far parcel is stepped every fourth tick with four ticks of dt, so the same seconds are
integrated either way — which is what makes a cadence conserving for free rather than by care.
burning
burning(parcel: number): booleanWhether a flame stands over this parcel.
| Parameter | Type | Description |
|---|---|---|
parcel | number |
smouldering
smouldering(parcel: number): booleanWhether its char is glowing, which needs no flame and far less oxygen.
| Parameter | Type | Description |
|---|---|---|
parcel | number |
piloted
piloted(parcel: number): booleanWhether a pilot is present this tick.
| Parameter | Type | Description |
|---|---|---|
parcel | number |
ignite
ignite(parcel: number): voidSupply a pilot for one tick. This does not start a fire, and §11 is why.
| Parameter | Type | Description |
|---|---|---|
parcel | number |
More
Ignition is five conditions, and a pilot is one of them. Holding a match to wet wood does exactly nothing here, which is correct and is the API telling the truth about what a match is.
douse
douse(parcel: number): voidPut the flame out. Embers survive, which is the point — see §12.
| Parameter | Type | Description |
|---|---|---|
parcel | number |
setBurning
setBurning(parcel: number, burning: boolean): void| Parameter | Type | Description |
|---|---|---|
parcel | number | |
burning | boolean |
setSmouldering
setSmouldering(parcel: number, smouldering: boolean): void| Parameter | Type | Description |
|---|---|---|
parcel | number | |
smouldering | boolean |
clearPilot
clearPilot(parcel: number): void| Parameter | Type | Description |
|---|---|---|
parcel | number |
massFluxOf
massFluxOf(parcel: number): numberkg/(m²·s) of gas leaving the surface, all of it.
| Parameter | Type | Description |
|---|---|---|
parcel | number |
fuelFluxOf
fuelFluxOf(parcel: number): numberAnd of the part of it that can burn — which is the criterion ignition turns on.
| Parameter | Type | Description |
|---|---|---|
parcel | number |
More
The two differ by exactly what a wet log gives off. Steam leaving a surface counts toward diluting the mixture above it and not toward feeding it, which is why 60% moisture stops a log catching in front of a fire that lights a seasoned one in eighty seconds.
setMassFlux
setMassFlux(parcel: number, total: number, fuel: number): void| Parameter | Type | Description |
|---|---|---|
parcel | number | |
total | number | |
fuel | number |
heatReleaseOf
heatReleaseOf(parcel: number): numberWatts the reactions released last step: positive exothermic, negative endothermic.
| Parameter | Type | Description |
|---|---|---|
parcel | number |
More
A fire's size is its heat release rate, which is what every figure in the design is quoted against and is not the temperature. A pyrolysing surface reads negative here while it is gasifying, which is right and is why a flame has to keep feeding heat back to sustain one.
moistureOf
moistureOf(parcel: number): numberKilograms of water per kilogram of dry matter — the dry basis, which is how it is quoted.
| Parameter | Type | Description |
|---|---|---|
parcel | number |
More
"12% moisture content" means twelve kilograms of water per hundred of dry wood, and
wetComposition folded that into a wet-basis 0.107 to store it. Undoing the same conversion
here is what makes a script comparing against the 0.25 that decides whether a log is worth
burning read the quantity the author wrote.
Ice counts as water. A frozen log is not a dry one.
parcelPhaseOf
parcelPhaseOf(parcel: number): numberPHASE_SOLID, PHASE_LIQUID, PHASE_GAS, or PHASE_MIXED where no one of them dominates.
| Parameter | Type | Description |
|---|---|---|
parcel | number |
More
Mixed is a real answer rather than a failure to decide: wet wood is wood and water at once, and calling it either would be a lie a consumer would then draw.
wetnessOf
wetnessOf(parcel: number): numberKilograms of free water on the surface, per square metre of it.
| Parameter | Type | Description |
|---|---|---|
parcel | number |
More
Free, meaning beyond what the material holds as its own moisture, and that distinction is the whole reading. A seasoned oak log carries 12% water on a dry basis and is not glossy; a log somebody threw a bucket over is. Reporting the shell's total water would make the two identical and every piece of wood in a scene look rained on.
Derived rather than a column, because wet puts real water in the surface shell rather than
setting a flag — so §17's wet-film roughness reads a quantity the boiling reaction is
simultaneously consuming, which is what makes drying visible.
wettable
wettable(parcel: number): booleanWhether this parcel's substance can hold liquid water, which is what wet asks of it.
| Parameter | Type | Description |
|---|---|---|
parcel | number |
More
A caller pouring rain over everything asks first: wet refuses a material with no water in its
model, and refusing is right, but a loop over every parcel in the rain had no way to tell an
iron nail from a log before it was told.
wet
wet(parcel: number, kilograms: number): voidPour water on it: liquid water into the surface shell, where the boiling reaction will find it.
| Parameter | Type | Description |
|---|---|---|
parcel | number | |
kilograms | number |
More
Not a flag, and that is the whole point. The heat sink §12 describes is the same
2.44 MJ/kg every other drop of water in this model carries, so a doused fire goes out for the
reason a real one does and a light sprinkling on a hot ember does not.
Refused, naming the substance, where that substance cannot hold water at all — which means it declares no reaction that touches it. Silently doing nothing would make "I poured a bucket on it" and "this material has no water in its model" indistinguishable.
dry
dry(parcel: number, kilograms: number): voidTake surface water away: a cloth, a hot dry pan, or wind. Never below what is there.
| Parameter | Type | Description |
|---|---|---|
parcel | number | |
kilograms | number |
charDepthOf
charDepthOf(parcel: number): numberMetres of char measured inward from the surface.
| Parameter | Type | Description |
|---|---|---|
parcel | number |
More
The shells that are mostly carbon, summed by their own thickness. A shell counts once it is past half char, which is a threshold on a continuum and is said out loud: a finer answer needs a char front within a shell, which is a sub-shell quantity this model does not carry.
structuralIntegrityOf
structuralIntegrityOf(parcel: number): numberHow much of this parcel is still load-bearing, 1 down to 0.
| Parameter | Type | Description |
|---|---|---|
parcel | number |
More
§18 refuses structural failure in writing and this is the refusal reporting. A beam whose
char depth has eaten a fraction of its thickness has lost that fraction of its strength, and
what happens next — a joint releasing, a body splitting, a building coming down — belongs to
whoever owns the solver. This package writes the scalar, emits an event at a threshold, and
breaks nothing.
mix
mix(from: number, into: number): voidPour from into into; from is consumed. Mass, elements and enthalpy all conserved exactly.
| Parameter | Type | Description |
|---|---|---|
from | number | |
into | number |
More
Both must be the same substance, and two that are not are refused naming both. Two substances are two species sets and two shell counts, so mixing them would silently discard whichever set was narrower — and a stew is not a substance change. What a consumer combining two genuinely different materials wants is a third substance that is the mixture, authored as one.
addShellHeat
addShellHeat(parcel: number, shell: number, joules: number): voidJoules into one named shell.
| Parameter | Type | Description |
|---|---|---|
parcel | number | |
shell | number | |
joules | number |
More
The difference between this and addSurfaceHeat is a microwave and an oven: one deposits where
the field penetrates to, the other at the surface. Nothing here decides which is physical.
surfaceHeatCapacityOf
surfaceHeatCapacityOf(parcel: number): numberJoules per kelvin of the surface shell, from what it is made of right now.
| Parameter | Type | Description |
|---|---|---|
parcel | number |
More
What every explicit surface term has to be bounded against. A flux times an area times a
step is joules, and joules into a small enough shell is an arbitrarily large temperature change
— so a term that does not know this number cannot tell the difference between heating something
and destroying it. ChemistryWorld uses it to stop a radiative or convective step carrying a
surface past the thing driving it.
appearanceOf
appearanceOf(parcel: number): AppearanceModel | nullWhat this parcel's substance looks like, or null where nobody said.
| Parameter | Type | Description |
|---|---|---|
parcel | number |
charFractionOf
charFractionOf(parcel: number): numberShare of this parcel's mass that is char, 0..1.
| Parameter | Type | Description |
|---|---|---|
parcel | number |
addSpeciesMass
addSpeciesMass(parcel: number, shell: number, species: number, kilograms: number): voidAdd (or with a negative value, remove) mass of one species in one shell.
| Parameter | Type | Description |
|---|---|---|
parcel | number | |
shell | number | |
species | number | |
kilograms | number |
substanceDigestOf
substanceDigestOf(substance: number): numberA number standing for what a registered substance is, for the fingerprint.
| Parameter | Type | Description |
|---|---|---|
substance | number |
More
Its density, porosity, emissivity, shell count and the species it can hold — enough that two
libraries differing anywhere disagree here, and cheap enough to compute once a tick. §15 asks
for the registry to be covered because two worlds with different substances are different
worlds, and a replay crossing them should say so rather than diverge later.
speciesSetOf
speciesSetOf(substance: number): Int32ArrayGlobal species indices this parcel's substance can hold.
| Parameter | Type | Description |
|---|---|---|
substance | number |
idOfSpecies
idOfSpecies(species: number): string| Parameter | Type | Description |
|---|---|---|
species | number |
phaseOf
phaseOf(species: number): number| Parameter | Type | Description |
|---|---|---|
species | number |
emissivityOf
emissivityOf(parcel: number): number| Parameter | Type | Description |
|---|---|---|
parcel | number |
ignitionOf
ignitionOf(substance: number): IgnitionModel | nullWhen this parcel's substance catches, or null where nobody said it does.
| Parameter | Type | Description |
|---|---|---|
substance | number |
porosityOf
porosityOf(parcel: number): number| Parameter | Type | Description |
|---|---|---|
parcel | number |
conductivityOf
conductivityOf(parcel: number, temperature: number): numberW/(m·K) at a temperature, or zero where the substance never said.
| Parameter | Type | Description |
|---|---|---|
parcel | number | |
temperature | number |
shellDepthOf
shellDepthOf(parcel: number, shell: number): numberMetres from the outside of shell shell to the inside of it.
| Parameter | Type | Description |
|---|---|---|
parcel | number | |
shell | number |