paperlab 0.8.0 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +57 -30
- package/dist/{FxPostPass-V6YDK4H2.js → FxPostPass-ACFSHY3S.js} +4 -4
- package/dist/FxPostPass-ACFSHY3S.js.map +1 -0
- package/dist/{chunk-232SU3AQ.js → chunk-BIFUJCUA.js} +2 -2
- package/dist/{chunk-232SU3AQ.js.map → chunk-BIFUJCUA.js.map} +1 -1
- package/dist/{chunk-SVWWC5UL.js → chunk-LUKNPQ3S.js} +16 -17
- package/dist/chunk-LUKNPQ3S.js.map +1 -0
- package/dist/{chunk-7WOGU2D4.js → chunk-S74YZAXE.js} +2 -2
- package/dist/chunk-S74YZAXE.js.map +1 -0
- package/dist/{damageContract-nF1fgK7P.d.cts → damageContract-9RC4egJg.d.cts} +2 -2
- package/dist/{damageContract-nF1fgK7P.d.ts → damageContract-9RC4egJg.d.ts} +2 -2
- package/dist/fx.cjs +20 -20
- package/dist/fx.cjs.map +1 -1
- package/dist/fx.d.cts +42 -44
- package/dist/fx.d.ts +42 -44
- package/dist/fx.js +21 -21
- package/dist/fx.js.map +1 -1
- package/dist/index.cjs +22 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +6 -6
- package/dist/index.js.map +1 -1
- package/dist/{slots-D_EE8GXn.d.cts → slots-DbJQfwVd.d.cts} +1 -1
- package/dist/{slots-D_EE8GXn.d.ts → slots-DbJQfwVd.d.ts} +1 -1
- package/dist/stage.cjs +23 -24
- package/dist/stage.cjs.map +1 -1
- package/dist/stage.d.cts +1 -1
- package/dist/stage.d.ts +1 -1
- package/dist/stage.js +12 -12
- package/dist/stage.js.map +1 -1
- package/package.json +5 -5
- package/dist/FxPostPass-V6YDK4H2.js.map +0 -1
- package/dist/chunk-7WOGU2D4.js.map +0 -1
- package/dist/chunk-SVWWC5UL.js.map +0 -1
package/dist/fx.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { D as DamageSource } from './damageContract-
|
|
2
|
-
export { a as DAMAGE_CHANNELS, b as DAMAGE_LOOK_DEFAULTS, c as DamageLook } from './damageContract-
|
|
1
|
+
import { D as DamageSource } from './damageContract-9RC4egJg.cjs';
|
|
2
|
+
export { a as DAMAGE_CHANNELS, b as DAMAGE_LOOK_DEFAULTS, c as DamageLook } from './damageContract-9RC4egJg.cjs';
|
|
3
3
|
import * as react from 'react';
|
|
4
4
|
import { ReactNode } from 'react';
|
|
5
5
|
import * as THREE from 'three';
|
|
@@ -366,7 +366,7 @@ declare const particlePresets: {
|
|
|
366
366
|
* caught the bug in the version before this one. That version said "the hot
|
|
367
367
|
* end is now ~5.6, well over the bloom threshold" — and 5.6 was an ABSOLUTE
|
|
368
368
|
* luminance, while paper white under `window` is 1.6. So the hottest spark
|
|
369
|
-
* in the frame was **3.5× paper, under the
|
|
369
|
+
* in the frame was **3.5× paper, under the 4× floor**, and its
|
|
370
370
|
* own comment said otherwise. A number that cannot be compared to anything
|
|
371
371
|
* is a number nobody can check.
|
|
372
372
|
*
|
|
@@ -540,8 +540,8 @@ interface FireEmitterOptions {
|
|
|
540
540
|
};
|
|
541
541
|
}
|
|
542
542
|
/**
|
|
543
|
-
* How much each kind leaves the front, per texel per second —
|
|
544
|
-
* the lab
|
|
543
|
+
* How much each kind leaves the front, per texel per second — the tune made in
|
|
544
|
+
* the lab, which the lab starts from and `/hands` inherits.
|
|
545
545
|
*
|
|
546
546
|
* The simulator's smoke is the main smoke of a burning sheet, since it is the
|
|
547
547
|
* same fluid the flames are made of; these sprite puffs, once switched off
|
|
@@ -576,8 +576,8 @@ declare class FireEmitter {
|
|
|
576
576
|
}
|
|
577
577
|
|
|
578
578
|
/**
|
|
579
|
-
* The pool, drawn — three kinds, three ways, because
|
|
580
|
-
* particles are three different things
|
|
579
|
+
* The pool, drawn — three kinds, three ways, because a fire's three
|
|
580
|
+
* particles are three different things.
|
|
581
581
|
*
|
|
582
582
|
* - **Embers** are light, moving fast: quads STRETCHED along their own
|
|
583
583
|
* screen-space velocity into streaks, a bright head and a fading tail,
|
|
@@ -655,21 +655,21 @@ interface FxQualitySettings {
|
|
|
655
655
|
* Bloom is a blur, and a blur at half resolution is a quarter of the
|
|
656
656
|
* fill-rate for a glow that is soft anyway — the cheapest thing a phone
|
|
657
657
|
* can give up that still leaves every zone and every flame on screen
|
|
658
|
-
* (
|
|
658
|
+
* (tiers thin post quality, never what is shown). Read by
|
|
659
659
|
* `FxPost`.
|
|
660
660
|
*/
|
|
661
661
|
bloomScale: number;
|
|
662
662
|
/**
|
|
663
|
-
* The most flames standing at once.
|
|
663
|
+
* The most flames standing at once. It was 8 / 16 / 32; a ring
|
|
664
664
|
* of fire that is dense in clusters and broken by gaps needs more tongues
|
|
665
|
-
* than that
|
|
666
|
-
*
|
|
665
|
+
* than that (a living, uneven ring, never a crown), so it is
|
|
666
|
+
* 16 / 36 / 64. Every tier has real flames; a phone
|
|
667
667
|
* gets fewer tongues, never the cheap version.
|
|
668
668
|
* Read by `FxFlames`.
|
|
669
669
|
*/
|
|
670
670
|
flames: number;
|
|
671
671
|
/**
|
|
672
|
-
* The most of each particle kind in the air at once
|
|
672
|
+
* The most of each particle kind in the air at once, inside the
|
|
673
673
|
* `particles` budget. Read by `FireEmitter` through its `caps` option.
|
|
674
674
|
*/
|
|
675
675
|
caps: {
|
|
@@ -681,7 +681,7 @@ interface FxQualitySettings {
|
|
|
681
681
|
* Heat haze strength in pixels at 1080p; 0 turns it off. Read by `FxPost`.
|
|
682
682
|
*
|
|
683
683
|
* High tier only, and half what it was. It was 3.8 px on two tiers against
|
|
684
|
-
*
|
|
684
|
+
* the 1–3 wanted, and invisible in every capture at either — a few pixels of
|
|
685
685
|
* wobble reads as nothing while the fluid beside it is moving. It is also
|
|
686
686
|
* still driven from `flameAnchors`, which is where the SPRITE flames stand,
|
|
687
687
|
* not where the fluid actually burns; until it reads the fluid's own heat
|
|
@@ -731,7 +731,7 @@ interface FxPostProps {
|
|
|
731
731
|
threshold?: number;
|
|
732
732
|
/**
|
|
733
733
|
* The burning field, and where its sheet is — for the heat haze above its
|
|
734
|
-
* flames and the frame's warm grade as it grows
|
|
734
|
+
* flames and the frame's warm grade as it grows. Leave both out and
|
|
735
735
|
* the pass is bloom and the tone curve alone.
|
|
736
736
|
*/
|
|
737
737
|
field?: DamageField;
|
|
@@ -762,7 +762,7 @@ declare function FxPost(props: FxPostProps): react.JSX.Element;
|
|
|
762
762
|
* were identical: most presets are safe from 0.8–0.9, `studio` from 1.1, and
|
|
763
763
|
* `window` — the brightest — only from 1.6. The brightest preset has to set
|
|
764
764
|
* this, because a threshold that lets paper bloom under any preset brings back
|
|
765
|
-
* the painted-glow failure of
|
|
765
|
+
* the painted-glow failure of the first fire.
|
|
766
766
|
*
|
|
767
767
|
* Re-measure it with `pnpm test:fire-look` if a preset's lighting changes.
|
|
768
768
|
*/
|
|
@@ -775,14 +775,14 @@ declare const PAPER_WHITE = 1.6;
|
|
|
775
775
|
* the number survives: it is not "3.6", it is "clear of the brightest paper".
|
|
776
776
|
*
|
|
777
777
|
* **Do not lower it to make fire bloom.** That is the wrong end of the
|
|
778
|
-
* problem, and
|
|
778
|
+
* problem, and a visual review that found the fluid's flames under it said so:
|
|
779
779
|
* `window`'s paper blooms from 1.6, so lowering the threshold blooms paper,
|
|
780
780
|
* which is the painted glow again. Raise what the fire EMITS.
|
|
781
781
|
*/
|
|
782
782
|
declare const FX_BLOOM_THRESHOLD: number;
|
|
783
783
|
/**
|
|
784
784
|
* What the spec asks a glowing part of a fire to reach, in multiples of paper
|
|
785
|
-
* white
|
|
785
|
+
* white. The band `emission.test.ts` holds every emitter to.
|
|
786
786
|
*/
|
|
787
787
|
declare const FIRE_GLOW: readonly [4, 8];
|
|
788
788
|
/** One sRGB channel (0..1) to linear. The transfer function, not a gamma. */
|
|
@@ -845,8 +845,8 @@ declare const FIRE_SOOT_SCALE = 3;
|
|
|
845
845
|
* multiplier on whatever clears the threshold, so its right value depends
|
|
846
846
|
* entirely on how much fire is authored above it. With a core authored to
|
|
847
847
|
* over-expose, 0.55 was the most the black stage could take; the flame of
|
|
848
|
-
* {@link FIRE_ZONES}
|
|
849
|
-
* threshold, and 1.25 is
|
|
848
|
+
* {@link FIRE_ZONES} authors none of it past the
|
|
849
|
+
* threshold, and 1.25 is the tune for it. `pnpm test:fire-budget` holds the
|
|
850
850
|
* stage black and the paper unbloomed whatever this is set to.
|
|
851
851
|
*/
|
|
852
852
|
declare const FX_BLOOM = 1.25;
|
|
@@ -882,7 +882,7 @@ declare const FX_BLOOM = 1.25;
|
|
|
882
882
|
* both ways. Above it, a flame keeps its light in a bright room but loses its
|
|
883
883
|
* colour to the tone curve; below it, the colour holds, and a flame drawn
|
|
884
884
|
* opaque risks reading as a decal on the sheet rather than as light. The
|
|
885
|
-
* defaults sit below it
|
|
885
|
+
* defaults sit below it, with the bloom carrying the glow.
|
|
886
886
|
*/
|
|
887
887
|
interface FireZones {
|
|
888
888
|
root: {
|
|
@@ -913,7 +913,7 @@ type FireZonesInput = {
|
|
|
913
913
|
[Z in keyof FireZones]?: Partial<FireZones[Z]>;
|
|
914
914
|
};
|
|
915
915
|
/**
|
|
916
|
-
*
|
|
916
|
+
* The tune made in `/fx-lab`, and the source of truth for how a
|
|
917
917
|
* flame looks: the lab starts from it and `/hands` inherits it. A gentler
|
|
918
918
|
* flame than the one it replaced — every zone sits under the bloom threshold,
|
|
919
919
|
* so its glow comes from the bloom's strength ({@link FX_BLOOM}) spreading
|
|
@@ -938,9 +938,9 @@ interface AfterglowOptions {
|
|
|
938
938
|
/**
|
|
939
939
|
* The embers a burn leaves behind, drawn over the field it came from.
|
|
940
940
|
*
|
|
941
|
-
*
|
|
941
|
+
* Smoulder: after the flames, glowing spots
|
|
942
942
|
* crawl along the edge, flare on a breath, and go out one by one over
|
|
943
|
-
* seconds
|
|
943
|
+
* seconds. The field cannot do this, and it is not a tuning problem:
|
|
944
944
|
* a burn blown out loses its heat in a fraction of a second — below ignition
|
|
945
945
|
* everywhere or it recovers — so its own heat channel has nothing left to
|
|
946
946
|
* smoulder with.
|
|
@@ -954,7 +954,7 @@ interface AfterglowOptions {
|
|
|
954
954
|
* breath flares what is left.
|
|
955
955
|
*
|
|
956
956
|
* Only the sheet reads it. Flames and the fire light read the FIELD, so the
|
|
957
|
-
* flames die with the gas
|
|
957
|
+
* flames die with the gas while the edge keeps glowing; the physics
|
|
958
958
|
* reads char, saturation and presence, which pass through untouched.
|
|
959
959
|
*/
|
|
960
960
|
declare class Afterglow implements DamageSource {
|
|
@@ -977,7 +977,7 @@ declare class Afterglow implements DamageSource {
|
|
|
977
977
|
get smouldering(): boolean;
|
|
978
978
|
/**
|
|
979
979
|
* Advance by `dt`, after the field has stepped. `blow` is the breath on the
|
|
980
|
-
* sheet, 0..1: it flares what is left (
|
|
980
|
+
* sheet, 0..1: it flares what is left ("on smoulder: beads flare,
|
|
981
981
|
* then fade").
|
|
982
982
|
*/
|
|
983
983
|
step(dt: number, blow?: number): void;
|
|
@@ -994,7 +994,7 @@ interface FxFlamesProps {
|
|
|
994
994
|
quality?: FxQualityTier;
|
|
995
995
|
/**
|
|
996
996
|
* The air, world units a second — pass the particle pool's `wind`, which is
|
|
997
|
-
* read every frame. Flames lean away from it and shorten
|
|
997
|
+
* read every frame. Flames lean away from it and shorten.
|
|
998
998
|
*/
|
|
999
999
|
wind?: readonly [number, number, number];
|
|
1000
1000
|
}
|
|
@@ -1002,8 +1002,8 @@ interface FxFlamesProps {
|
|
|
1002
1002
|
* The flames of a burn: separate tongues of burning gas, standing just off
|
|
1003
1003
|
* the char, rising straight up whatever the sheet is doing.
|
|
1004
1004
|
*
|
|
1005
|
-
*
|
|
1006
|
-
* camera about WORLD up — never the sheet's normal
|
|
1005
|
+
* Each tongue is a quad that turns to face the
|
|
1006
|
+
* camera about WORLD up — never the sheet's normal — so a flame on a
|
|
1007
1007
|
* sheet held flat still rises to the ceiling. The shader is upward-scrolling,
|
|
1008
1008
|
* domain-warped noise inside a teardrop, coloured on the flame's own
|
|
1009
1009
|
* blackbody ramp: a dim indigo root, a yellow-white core, orange edges and
|
|
@@ -1042,8 +1042,8 @@ declare function FxWisps({ glow, field, locate, wind }: FxWispsProps): react.JSX
|
|
|
1042
1042
|
|
|
1043
1043
|
/**
|
|
1044
1044
|
* The fire simulator's controls — by the names, and at the defaults, of the
|
|
1045
|
-
* fluid-fire tool
|
|
1046
|
-
* & turbulence), so the lab's panel reads like
|
|
1045
|
+
* fluid-fire tool it was modelled on (Emission, Combustion, Fuel & air, Motion
|
|
1046
|
+
* & turbulence), so the lab's panel reads like that one.
|
|
1047
1047
|
*
|
|
1048
1048
|
* The numbers are the panel's, not the solver's. `solverUniforms` is the one
|
|
1049
1049
|
* place they are turned into this solver's units — world units (a default
|
|
@@ -1102,8 +1102,7 @@ interface FireFluidParams {
|
|
|
1102
1102
|
smokeAfter: number;
|
|
1103
1103
|
}
|
|
1104
1104
|
/**
|
|
1105
|
-
* The defaults — the panel's names, at the values
|
|
1106
|
-
* 2026-09-12. No turbulence of its own: the motion comes from vorticity,
|
|
1105
|
+
* The defaults — the panel's names, at the values tuned in the lab. No turbulence of its own: the motion comes from vorticity,
|
|
1107
1106
|
* the radial impulse and the uneven rim that feeds it.
|
|
1108
1107
|
*/
|
|
1109
1108
|
declare const fireFluidDefaults: FireFluidParams;
|
|
@@ -1327,7 +1326,7 @@ interface FxFireLightProps {
|
|
|
1327
1326
|
shadows?: boolean;
|
|
1328
1327
|
}
|
|
1329
1328
|
/**
|
|
1330
|
-
* Fire is a light source
|
|
1329
|
+
* Fire is a light source. A fire that changes nothing around it
|
|
1331
1330
|
* looks pasted on.
|
|
1332
1331
|
*
|
|
1333
1332
|
* One warm point light for each place the fire is gathered — up to
|
|
@@ -1345,7 +1344,7 @@ interface FxFireLightProps {
|
|
|
1345
1344
|
*
|
|
1346
1345
|
* And one dimmer light on the FAR side of the sheet, at the fire as a whole,
|
|
1347
1346
|
* for translucency: paper is thin, and a fire in front of it glows through to
|
|
1348
|
-
* the back
|
|
1347
|
+
* the back. The sheet's own material lights its back face from whatever
|
|
1349
1348
|
* is behind it.
|
|
1350
1349
|
*
|
|
1351
1350
|
* Every light is mounted all the time and only its intensity changes, so a
|
|
@@ -1355,7 +1354,7 @@ interface FxFireLightProps {
|
|
|
1355
1354
|
declare function FxFireLight({ field, locate, gain, shadows }: FxFireLightProps): react.JSX.Element;
|
|
1356
1355
|
/**
|
|
1357
1356
|
* Light per unit of front length; the front runs to ~0.045 at a burn's peak.
|
|
1358
|
-
*
|
|
1357
|
+
* Tuned in `/fx-lab` (it was 42).
|
|
1359
1358
|
*/
|
|
1360
1359
|
declare const FIRE_LIGHT_GAIN = 26;
|
|
1361
1360
|
|
|
@@ -1392,8 +1391,7 @@ interface FxMatchFlameProps {
|
|
|
1392
1391
|
};
|
|
1393
1392
|
}
|
|
1394
1393
|
/**
|
|
1395
|
-
* A match, held:
|
|
1396
|
-
* flame's to draw.
|
|
1394
|
+
* A match, held: the parts of it that are the flame's to draw.
|
|
1397
1395
|
*
|
|
1398
1396
|
* - **Arming.** Friction building: a few tiny sparks and a warm point that
|
|
1399
1397
|
* grows at the pinch. A pinch released early (a flick) fizzles — nothing
|
|
@@ -1407,7 +1405,7 @@ interface FxMatchFlameProps {
|
|
|
1407
1405
|
* - **Blown.** It leans away and flickers hard; when the page says it has
|
|
1408
1406
|
* gone out, it leaves a soft puff behind.
|
|
1409
1407
|
* - **Light.** It lights the sheet warm before anything scorches — bringing
|
|
1410
|
-
* the flame near the paper is the first thing people notice
|
|
1408
|
+
* the flame near the paper is the first thing people notice.
|
|
1411
1409
|
*
|
|
1412
1410
|
* It owns its own clock and its own handful of particles: nothing here is
|
|
1413
1411
|
* part of a burn anyone replays.
|
|
@@ -1417,7 +1415,7 @@ declare function FxMatchFlame({ match }: FxMatchFlameProps): react.JSX.Element;
|
|
|
1417
1415
|
/**
|
|
1418
1416
|
* Where a burn's flames stand, read off the field.
|
|
1419
1417
|
*
|
|
1420
|
-
*
|
|
1418
|
+
* Paper does not burn, the gas does. Heat
|
|
1421
1419
|
* cooks the cellulose into gas, which burns just ABOVE the surface, rooted
|
|
1422
1420
|
* over the char right behind the ember line — so a flame belongs on the edge
|
|
1423
1421
|
* of the hole, where it is hot, and nowhere else. Where the heat has gone
|
|
@@ -1435,7 +1433,7 @@ interface FlameAnchor {
|
|
|
1435
1433
|
x: number;
|
|
1436
1434
|
y: number;
|
|
1437
1435
|
z: number;
|
|
1438
|
-
/** World units. 10–40 mm at A4
|
|
1436
|
+
/** World units. 10–40 mm at A4, scaled by heat and by which rim it is on. */
|
|
1439
1437
|
height: number;
|
|
1440
1438
|
width: number;
|
|
1441
1439
|
/** Stable while the cell burns, so a flame keeps its own flicker frame to frame. */
|
|
@@ -1472,7 +1470,7 @@ declare function flameAnchors(field: DamageField, locate: SurfaceLocator, max: n
|
|
|
1472
1470
|
/**
|
|
1473
1471
|
* How much a flame has puffed up at a moment — the same function the flame
|
|
1474
1472
|
* shader runs, so the fire light flickers WITH the flames rather than beside
|
|
1475
|
-
* them
|
|
1473
|
+
* them. Value noise, 10–15 Hz, seeded per flame: neighbours never move
|
|
1476
1474
|
* in step, and nothing is a sine.
|
|
1477
1475
|
*/
|
|
1478
1476
|
declare function flamePuff(seed: number, time: number): number;
|
|
@@ -1795,13 +1793,13 @@ declare class FireSound {
|
|
|
1795
1793
|
update(dt: number, stats: FieldStats, at?: SoundAt | null): void;
|
|
1796
1794
|
/**
|
|
1797
1795
|
* A match struck: the scratch of the head across the box, then the hiss of
|
|
1798
|
-
* it flaring as the head burns off
|
|
1796
|
+
* it flaring as the head burns off. Two bursts of the shared
|
|
1799
1797
|
* noise, one bright and short, one breathier and longer.
|
|
1800
1798
|
*/
|
|
1801
1799
|
strike(): void;
|
|
1802
|
-
/** Blown out: a soft, low breath of noise
|
|
1800
|
+
/** Blown out: a soft, low breath of noise. */
|
|
1803
1801
|
puff(): void;
|
|
1804
|
-
/** One ember popping in the air — a tiny click on the frame it flashes
|
|
1802
|
+
/** One ember popping in the air — a tiny click on the frame it flashes. */
|
|
1805
1803
|
pop(): void;
|
|
1806
1804
|
/** Silence, now — the flame blown out, or the page going away. */
|
|
1807
1805
|
stop(): void;
|
package/dist/fx.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { D as DamageSource } from './damageContract-
|
|
2
|
-
export { a as DAMAGE_CHANNELS, b as DAMAGE_LOOK_DEFAULTS, c as DamageLook } from './damageContract-
|
|
1
|
+
import { D as DamageSource } from './damageContract-9RC4egJg.js';
|
|
2
|
+
export { a as DAMAGE_CHANNELS, b as DAMAGE_LOOK_DEFAULTS, c as DamageLook } from './damageContract-9RC4egJg.js';
|
|
3
3
|
import * as react from 'react';
|
|
4
4
|
import { ReactNode } from 'react';
|
|
5
5
|
import * as THREE from 'three';
|
|
@@ -366,7 +366,7 @@ declare const particlePresets: {
|
|
|
366
366
|
* caught the bug in the version before this one. That version said "the hot
|
|
367
367
|
* end is now ~5.6, well over the bloom threshold" — and 5.6 was an ABSOLUTE
|
|
368
368
|
* luminance, while paper white under `window` is 1.6. So the hottest spark
|
|
369
|
-
* in the frame was **3.5× paper, under the
|
|
369
|
+
* in the frame was **3.5× paper, under the 4× floor**, and its
|
|
370
370
|
* own comment said otherwise. A number that cannot be compared to anything
|
|
371
371
|
* is a number nobody can check.
|
|
372
372
|
*
|
|
@@ -540,8 +540,8 @@ interface FireEmitterOptions {
|
|
|
540
540
|
};
|
|
541
541
|
}
|
|
542
542
|
/**
|
|
543
|
-
* How much each kind leaves the front, per texel per second —
|
|
544
|
-
* the lab
|
|
543
|
+
* How much each kind leaves the front, per texel per second — the tune made in
|
|
544
|
+
* the lab, which the lab starts from and `/hands` inherits.
|
|
545
545
|
*
|
|
546
546
|
* The simulator's smoke is the main smoke of a burning sheet, since it is the
|
|
547
547
|
* same fluid the flames are made of; these sprite puffs, once switched off
|
|
@@ -576,8 +576,8 @@ declare class FireEmitter {
|
|
|
576
576
|
}
|
|
577
577
|
|
|
578
578
|
/**
|
|
579
|
-
* The pool, drawn — three kinds, three ways, because
|
|
580
|
-
* particles are three different things
|
|
579
|
+
* The pool, drawn — three kinds, three ways, because a fire's three
|
|
580
|
+
* particles are three different things.
|
|
581
581
|
*
|
|
582
582
|
* - **Embers** are light, moving fast: quads STRETCHED along their own
|
|
583
583
|
* screen-space velocity into streaks, a bright head and a fading tail,
|
|
@@ -655,21 +655,21 @@ interface FxQualitySettings {
|
|
|
655
655
|
* Bloom is a blur, and a blur at half resolution is a quarter of the
|
|
656
656
|
* fill-rate for a glow that is soft anyway — the cheapest thing a phone
|
|
657
657
|
* can give up that still leaves every zone and every flame on screen
|
|
658
|
-
* (
|
|
658
|
+
* (tiers thin post quality, never what is shown). Read by
|
|
659
659
|
* `FxPost`.
|
|
660
660
|
*/
|
|
661
661
|
bloomScale: number;
|
|
662
662
|
/**
|
|
663
|
-
* The most flames standing at once.
|
|
663
|
+
* The most flames standing at once. It was 8 / 16 / 32; a ring
|
|
664
664
|
* of fire that is dense in clusters and broken by gaps needs more tongues
|
|
665
|
-
* than that
|
|
666
|
-
*
|
|
665
|
+
* than that (a living, uneven ring, never a crown), so it is
|
|
666
|
+
* 16 / 36 / 64. Every tier has real flames; a phone
|
|
667
667
|
* gets fewer tongues, never the cheap version.
|
|
668
668
|
* Read by `FxFlames`.
|
|
669
669
|
*/
|
|
670
670
|
flames: number;
|
|
671
671
|
/**
|
|
672
|
-
* The most of each particle kind in the air at once
|
|
672
|
+
* The most of each particle kind in the air at once, inside the
|
|
673
673
|
* `particles` budget. Read by `FireEmitter` through its `caps` option.
|
|
674
674
|
*/
|
|
675
675
|
caps: {
|
|
@@ -681,7 +681,7 @@ interface FxQualitySettings {
|
|
|
681
681
|
* Heat haze strength in pixels at 1080p; 0 turns it off. Read by `FxPost`.
|
|
682
682
|
*
|
|
683
683
|
* High tier only, and half what it was. It was 3.8 px on two tiers against
|
|
684
|
-
*
|
|
684
|
+
* the 1–3 wanted, and invisible in every capture at either — a few pixels of
|
|
685
685
|
* wobble reads as nothing while the fluid beside it is moving. It is also
|
|
686
686
|
* still driven from `flameAnchors`, which is where the SPRITE flames stand,
|
|
687
687
|
* not where the fluid actually burns; until it reads the fluid's own heat
|
|
@@ -731,7 +731,7 @@ interface FxPostProps {
|
|
|
731
731
|
threshold?: number;
|
|
732
732
|
/**
|
|
733
733
|
* The burning field, and where its sheet is — for the heat haze above its
|
|
734
|
-
* flames and the frame's warm grade as it grows
|
|
734
|
+
* flames and the frame's warm grade as it grows. Leave both out and
|
|
735
735
|
* the pass is bloom and the tone curve alone.
|
|
736
736
|
*/
|
|
737
737
|
field?: DamageField;
|
|
@@ -762,7 +762,7 @@ declare function FxPost(props: FxPostProps): react.JSX.Element;
|
|
|
762
762
|
* were identical: most presets are safe from 0.8–0.9, `studio` from 1.1, and
|
|
763
763
|
* `window` — the brightest — only from 1.6. The brightest preset has to set
|
|
764
764
|
* this, because a threshold that lets paper bloom under any preset brings back
|
|
765
|
-
* the painted-glow failure of
|
|
765
|
+
* the painted-glow failure of the first fire.
|
|
766
766
|
*
|
|
767
767
|
* Re-measure it with `pnpm test:fire-look` if a preset's lighting changes.
|
|
768
768
|
*/
|
|
@@ -775,14 +775,14 @@ declare const PAPER_WHITE = 1.6;
|
|
|
775
775
|
* the number survives: it is not "3.6", it is "clear of the brightest paper".
|
|
776
776
|
*
|
|
777
777
|
* **Do not lower it to make fire bloom.** That is the wrong end of the
|
|
778
|
-
* problem, and
|
|
778
|
+
* problem, and a visual review that found the fluid's flames under it said so:
|
|
779
779
|
* `window`'s paper blooms from 1.6, so lowering the threshold blooms paper,
|
|
780
780
|
* which is the painted glow again. Raise what the fire EMITS.
|
|
781
781
|
*/
|
|
782
782
|
declare const FX_BLOOM_THRESHOLD: number;
|
|
783
783
|
/**
|
|
784
784
|
* What the spec asks a glowing part of a fire to reach, in multiples of paper
|
|
785
|
-
* white
|
|
785
|
+
* white. The band `emission.test.ts` holds every emitter to.
|
|
786
786
|
*/
|
|
787
787
|
declare const FIRE_GLOW: readonly [4, 8];
|
|
788
788
|
/** One sRGB channel (0..1) to linear. The transfer function, not a gamma. */
|
|
@@ -845,8 +845,8 @@ declare const FIRE_SOOT_SCALE = 3;
|
|
|
845
845
|
* multiplier on whatever clears the threshold, so its right value depends
|
|
846
846
|
* entirely on how much fire is authored above it. With a core authored to
|
|
847
847
|
* over-expose, 0.55 was the most the black stage could take; the flame of
|
|
848
|
-
* {@link FIRE_ZONES}
|
|
849
|
-
* threshold, and 1.25 is
|
|
848
|
+
* {@link FIRE_ZONES} authors none of it past the
|
|
849
|
+
* threshold, and 1.25 is the tune for it. `pnpm test:fire-budget` holds the
|
|
850
850
|
* stage black and the paper unbloomed whatever this is set to.
|
|
851
851
|
*/
|
|
852
852
|
declare const FX_BLOOM = 1.25;
|
|
@@ -882,7 +882,7 @@ declare const FX_BLOOM = 1.25;
|
|
|
882
882
|
* both ways. Above it, a flame keeps its light in a bright room but loses its
|
|
883
883
|
* colour to the tone curve; below it, the colour holds, and a flame drawn
|
|
884
884
|
* opaque risks reading as a decal on the sheet rather than as light. The
|
|
885
|
-
* defaults sit below it
|
|
885
|
+
* defaults sit below it, with the bloom carrying the glow.
|
|
886
886
|
*/
|
|
887
887
|
interface FireZones {
|
|
888
888
|
root: {
|
|
@@ -913,7 +913,7 @@ type FireZonesInput = {
|
|
|
913
913
|
[Z in keyof FireZones]?: Partial<FireZones[Z]>;
|
|
914
914
|
};
|
|
915
915
|
/**
|
|
916
|
-
*
|
|
916
|
+
* The tune made in `/fx-lab`, and the source of truth for how a
|
|
917
917
|
* flame looks: the lab starts from it and `/hands` inherits it. A gentler
|
|
918
918
|
* flame than the one it replaced — every zone sits under the bloom threshold,
|
|
919
919
|
* so its glow comes from the bloom's strength ({@link FX_BLOOM}) spreading
|
|
@@ -938,9 +938,9 @@ interface AfterglowOptions {
|
|
|
938
938
|
/**
|
|
939
939
|
* The embers a burn leaves behind, drawn over the field it came from.
|
|
940
940
|
*
|
|
941
|
-
*
|
|
941
|
+
* Smoulder: after the flames, glowing spots
|
|
942
942
|
* crawl along the edge, flare on a breath, and go out one by one over
|
|
943
|
-
* seconds
|
|
943
|
+
* seconds. The field cannot do this, and it is not a tuning problem:
|
|
944
944
|
* a burn blown out loses its heat in a fraction of a second — below ignition
|
|
945
945
|
* everywhere or it recovers — so its own heat channel has nothing left to
|
|
946
946
|
* smoulder with.
|
|
@@ -954,7 +954,7 @@ interface AfterglowOptions {
|
|
|
954
954
|
* breath flares what is left.
|
|
955
955
|
*
|
|
956
956
|
* Only the sheet reads it. Flames and the fire light read the FIELD, so the
|
|
957
|
-
* flames die with the gas
|
|
957
|
+
* flames die with the gas while the edge keeps glowing; the physics
|
|
958
958
|
* reads char, saturation and presence, which pass through untouched.
|
|
959
959
|
*/
|
|
960
960
|
declare class Afterglow implements DamageSource {
|
|
@@ -977,7 +977,7 @@ declare class Afterglow implements DamageSource {
|
|
|
977
977
|
get smouldering(): boolean;
|
|
978
978
|
/**
|
|
979
979
|
* Advance by `dt`, after the field has stepped. `blow` is the breath on the
|
|
980
|
-
* sheet, 0..1: it flares what is left (
|
|
980
|
+
* sheet, 0..1: it flares what is left ("on smoulder: beads flare,
|
|
981
981
|
* then fade").
|
|
982
982
|
*/
|
|
983
983
|
step(dt: number, blow?: number): void;
|
|
@@ -994,7 +994,7 @@ interface FxFlamesProps {
|
|
|
994
994
|
quality?: FxQualityTier;
|
|
995
995
|
/**
|
|
996
996
|
* The air, world units a second — pass the particle pool's `wind`, which is
|
|
997
|
-
* read every frame. Flames lean away from it and shorten
|
|
997
|
+
* read every frame. Flames lean away from it and shorten.
|
|
998
998
|
*/
|
|
999
999
|
wind?: readonly [number, number, number];
|
|
1000
1000
|
}
|
|
@@ -1002,8 +1002,8 @@ interface FxFlamesProps {
|
|
|
1002
1002
|
* The flames of a burn: separate tongues of burning gas, standing just off
|
|
1003
1003
|
* the char, rising straight up whatever the sheet is doing.
|
|
1004
1004
|
*
|
|
1005
|
-
*
|
|
1006
|
-
* camera about WORLD up — never the sheet's normal
|
|
1005
|
+
* Each tongue is a quad that turns to face the
|
|
1006
|
+
* camera about WORLD up — never the sheet's normal — so a flame on a
|
|
1007
1007
|
* sheet held flat still rises to the ceiling. The shader is upward-scrolling,
|
|
1008
1008
|
* domain-warped noise inside a teardrop, coloured on the flame's own
|
|
1009
1009
|
* blackbody ramp: a dim indigo root, a yellow-white core, orange edges and
|
|
@@ -1042,8 +1042,8 @@ declare function FxWisps({ glow, field, locate, wind }: FxWispsProps): react.JSX
|
|
|
1042
1042
|
|
|
1043
1043
|
/**
|
|
1044
1044
|
* The fire simulator's controls — by the names, and at the defaults, of the
|
|
1045
|
-
* fluid-fire tool
|
|
1046
|
-
* & turbulence), so the lab's panel reads like
|
|
1045
|
+
* fluid-fire tool it was modelled on (Emission, Combustion, Fuel & air, Motion
|
|
1046
|
+
* & turbulence), so the lab's panel reads like that one.
|
|
1047
1047
|
*
|
|
1048
1048
|
* The numbers are the panel's, not the solver's. `solverUniforms` is the one
|
|
1049
1049
|
* place they are turned into this solver's units — world units (a default
|
|
@@ -1102,8 +1102,7 @@ interface FireFluidParams {
|
|
|
1102
1102
|
smokeAfter: number;
|
|
1103
1103
|
}
|
|
1104
1104
|
/**
|
|
1105
|
-
* The defaults — the panel's names, at the values
|
|
1106
|
-
* 2026-09-12. No turbulence of its own: the motion comes from vorticity,
|
|
1105
|
+
* The defaults — the panel's names, at the values tuned in the lab. No turbulence of its own: the motion comes from vorticity,
|
|
1107
1106
|
* the radial impulse and the uneven rim that feeds it.
|
|
1108
1107
|
*/
|
|
1109
1108
|
declare const fireFluidDefaults: FireFluidParams;
|
|
@@ -1327,7 +1326,7 @@ interface FxFireLightProps {
|
|
|
1327
1326
|
shadows?: boolean;
|
|
1328
1327
|
}
|
|
1329
1328
|
/**
|
|
1330
|
-
* Fire is a light source
|
|
1329
|
+
* Fire is a light source. A fire that changes nothing around it
|
|
1331
1330
|
* looks pasted on.
|
|
1332
1331
|
*
|
|
1333
1332
|
* One warm point light for each place the fire is gathered — up to
|
|
@@ -1345,7 +1344,7 @@ interface FxFireLightProps {
|
|
|
1345
1344
|
*
|
|
1346
1345
|
* And one dimmer light on the FAR side of the sheet, at the fire as a whole,
|
|
1347
1346
|
* for translucency: paper is thin, and a fire in front of it glows through to
|
|
1348
|
-
* the back
|
|
1347
|
+
* the back. The sheet's own material lights its back face from whatever
|
|
1349
1348
|
* is behind it.
|
|
1350
1349
|
*
|
|
1351
1350
|
* Every light is mounted all the time and only its intensity changes, so a
|
|
@@ -1355,7 +1354,7 @@ interface FxFireLightProps {
|
|
|
1355
1354
|
declare function FxFireLight({ field, locate, gain, shadows }: FxFireLightProps): react.JSX.Element;
|
|
1356
1355
|
/**
|
|
1357
1356
|
* Light per unit of front length; the front runs to ~0.045 at a burn's peak.
|
|
1358
|
-
*
|
|
1357
|
+
* Tuned in `/fx-lab` (it was 42).
|
|
1359
1358
|
*/
|
|
1360
1359
|
declare const FIRE_LIGHT_GAIN = 26;
|
|
1361
1360
|
|
|
@@ -1392,8 +1391,7 @@ interface FxMatchFlameProps {
|
|
|
1392
1391
|
};
|
|
1393
1392
|
}
|
|
1394
1393
|
/**
|
|
1395
|
-
* A match, held:
|
|
1396
|
-
* flame's to draw.
|
|
1394
|
+
* A match, held: the parts of it that are the flame's to draw.
|
|
1397
1395
|
*
|
|
1398
1396
|
* - **Arming.** Friction building: a few tiny sparks and a warm point that
|
|
1399
1397
|
* grows at the pinch. A pinch released early (a flick) fizzles — nothing
|
|
@@ -1407,7 +1405,7 @@ interface FxMatchFlameProps {
|
|
|
1407
1405
|
* - **Blown.** It leans away and flickers hard; when the page says it has
|
|
1408
1406
|
* gone out, it leaves a soft puff behind.
|
|
1409
1407
|
* - **Light.** It lights the sheet warm before anything scorches — bringing
|
|
1410
|
-
* the flame near the paper is the first thing people notice
|
|
1408
|
+
* the flame near the paper is the first thing people notice.
|
|
1411
1409
|
*
|
|
1412
1410
|
* It owns its own clock and its own handful of particles: nothing here is
|
|
1413
1411
|
* part of a burn anyone replays.
|
|
@@ -1417,7 +1415,7 @@ declare function FxMatchFlame({ match }: FxMatchFlameProps): react.JSX.Element;
|
|
|
1417
1415
|
/**
|
|
1418
1416
|
* Where a burn's flames stand, read off the field.
|
|
1419
1417
|
*
|
|
1420
|
-
*
|
|
1418
|
+
* Paper does not burn, the gas does. Heat
|
|
1421
1419
|
* cooks the cellulose into gas, which burns just ABOVE the surface, rooted
|
|
1422
1420
|
* over the char right behind the ember line — so a flame belongs on the edge
|
|
1423
1421
|
* of the hole, where it is hot, and nowhere else. Where the heat has gone
|
|
@@ -1435,7 +1433,7 @@ interface FlameAnchor {
|
|
|
1435
1433
|
x: number;
|
|
1436
1434
|
y: number;
|
|
1437
1435
|
z: number;
|
|
1438
|
-
/** World units. 10–40 mm at A4
|
|
1436
|
+
/** World units. 10–40 mm at A4, scaled by heat and by which rim it is on. */
|
|
1439
1437
|
height: number;
|
|
1440
1438
|
width: number;
|
|
1441
1439
|
/** Stable while the cell burns, so a flame keeps its own flicker frame to frame. */
|
|
@@ -1472,7 +1470,7 @@ declare function flameAnchors(field: DamageField, locate: SurfaceLocator, max: n
|
|
|
1472
1470
|
/**
|
|
1473
1471
|
* How much a flame has puffed up at a moment — the same function the flame
|
|
1474
1472
|
* shader runs, so the fire light flickers WITH the flames rather than beside
|
|
1475
|
-
* them
|
|
1473
|
+
* them. Value noise, 10–15 Hz, seeded per flame: neighbours never move
|
|
1476
1474
|
* in step, and nothing is a sine.
|
|
1477
1475
|
*/
|
|
1478
1476
|
declare function flamePuff(seed: number, time: number): number;
|
|
@@ -1795,13 +1793,13 @@ declare class FireSound {
|
|
|
1795
1793
|
update(dt: number, stats: FieldStats, at?: SoundAt | null): void;
|
|
1796
1794
|
/**
|
|
1797
1795
|
* A match struck: the scratch of the head across the box, then the hiss of
|
|
1798
|
-
* it flaring as the head burns off
|
|
1796
|
+
* it flaring as the head burns off. Two bursts of the shared
|
|
1799
1797
|
* noise, one bright and short, one breathier and longer.
|
|
1800
1798
|
*/
|
|
1801
1799
|
strike(): void;
|
|
1802
|
-
/** Blown out: a soft, low breath of noise
|
|
1800
|
+
/** Blown out: a soft, low breath of noise. */
|
|
1803
1801
|
puff(): void;
|
|
1804
|
-
/** One ember popping in the air — a tiny click on the frame it flashes
|
|
1802
|
+
/** One ember popping in the air — a tiny click on the frame it flashes. */
|
|
1805
1803
|
pop(): void;
|
|
1806
1804
|
/** Silence, now — the flame blown out, or the page going away. */
|
|
1807
1805
|
stop(): void;
|