A particle is a function of its age, not a thing that is stepped (#73)
game-maker / suite (push) Failing after 4m22s
game-maker / suite (push) Failing after 4m22s
The asset type `particles` is placeable and carries a graph at the same time — `behavior` was the blueprint. Because a continuous emitter gives birth to particle n at time n/rate, the whole field is a function of the clock rather than of the frames: no ring-buffer bookkeeping, exact time jumps, reproducibility as a measurable property. compile.ts follows compileShader's frame but emits JS closures into a Float64Array instead of GLSL, and without eval; a node with two consumers is evaluated once. Drawing is one Pixi ParticleContainer per source, so one draw call. Collision, wind and braking in flight are out for good — that is the price of the formula model, not an omission. The tab count goes from nine to ten, which is exactly the case #84 was built for one day earlier: at 1280 px the row no longer holds every tab, so guard 14b now asks for hidden.length > 0 instead of === 0.
This commit is contained in:
1 parent
f83c568999
commit
0f9e1611d1
39 files changed
+2386
-32
No files matched your search
@@ -0,0 +1,40 @@
|
||||
import type { ParticlesAsset } from '../core/model/Asset';
|
||||
import { compileParticles, type ParticlesBuild, particlesFingerprint } from '../core/particles/compile';
|
||||
|
||||
/**
|
||||
* Compiled particle graphs, one per asset, recompiled when the graph's content changes – the same
|
||||
* contract the `ShaderLibrary` keeps, with a clock of its own so a test can hold particle time
|
||||
* still without freezing the shaders too.
|
||||
*/
|
||||
export class ParticleLibrary {
|
||||
private readonly builds = new Map<string, { fingerprint: string; build: ParticlesBuild }>();
|
||||
/** How often a graph went through the compiler – what the checks read to prove a move did not. */
|
||||
compiles = 0;
|
||||
private readonly started = performance.now();
|
||||
private frozenAt: number | null = null;
|
||||
|
||||
/** Seconds since the library came up – the clock every source's age is measured on. */
|
||||
now(): number {
|
||||
return this.frozenAt ?? (performance.now() - this.started) / 1000;
|
||||
}
|
||||
|
||||
freezeTime(at: number | null): void {
|
||||
this.frozenAt = at;
|
||||
}
|
||||
|
||||
get frozen(): number | null {
|
||||
return this.frozenAt;
|
||||
}
|
||||
|
||||
buildFor(asset: ParticlesAsset): ParticlesBuild {
|
||||
const fingerprint = particlesFingerprint(asset.graph);
|
||||
const cached = this.builds.get(asset.id);
|
||||
if (cached && cached.fingerprint === fingerprint) return cached.build;
|
||||
this.compiles += 1;
|
||||
const build = compileParticles(asset.graph);
|
||||
this.builds.set(asset.id, { fingerprint, build });
|
||||
return build;
|
||||
}
|
||||
}
|
||||
|
||||
export const particleLibrary = new ParticleLibrary();
|
||||
Reference in new issue
Block a user