Conjurations grow into the world, wrapped in glowing swirls
Nothing appears fully-formed anymore. Summoned creatures and conjured terrain volumes scale up from a sliver, bottom-anchored, as if growing out of the floor. Conjured SOLIDS — walls, firewalls, stone, and yes, illusion walls for whoever they fool — RISE: while growing, the rays pass over them so the room behind stays visible, and the renderer draws the young face climbing bottom-up with violet swirls running across it, solidifying as it tops out. Every creation also blooms the shimmer at its cell. The growth is driven through the fx channel, so the director's slate applies: things grow only once the camera faces them. Two camera notes squared away en route: the slate-setter read back the state it had just written, registering itself as its own dependency (an update-depth ping-pong under fast stepping) — locals now; and a reel whose FINAL step strides into a corner gets one more turn after the walk lands, to a view worth ending on. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
cd9ce9fddf
commit
285c91b2c8
@@ -20,7 +20,15 @@ export type FpFx =
|
||||
rise?: number }
|
||||
| { id: number; kind: "flash"; color: string; peak: number; t0: number; dur: number }
|
||||
| { id: number; kind: "shake"; mag: number; t0: number; dur: number }
|
||||
| { id: number; kind: "door"; edge: string; t0: number; dur: number };
|
||||
| { id: number; kind: "door"; edge: string; t0: number; dur: number }
|
||||
| { id: number; kind: "grow"; slot: "solid" | "sprite"; key: string; t0: number; dur: number };
|
||||
|
||||
/** Eased growth 0..1 for a conjuration's rise. */
|
||||
export function growProgress(p: number): number {
|
||||
if (p <= 0) return 0.01;
|
||||
if (p >= 1) return 1;
|
||||
return Math.max(0.01, p * p * (3 - 2 * p));
|
||||
}
|
||||
|
||||
/** How far open an animated door stands at progress p: swings open,
|
||||
* holds for the crossing, swings shut. */
|
||||
@@ -144,11 +152,34 @@ export function fpFxForEvents(
|
||||
}
|
||||
}
|
||||
}
|
||||
if (e.type === "wallCreated" && "edge" in e) {
|
||||
// Stone conjured from nothing: dust where it rises.
|
||||
const at = edgeMid((e as { edge: { cell: { x: number; y: number }; side: "N" | "E" | "S" | "W" } }).edge.cell,
|
||||
(e as { edge: { side: "N" | "E" | "S" | "W" } }).edge.side);
|
||||
out.push({ fx: { id: nextId++, kind: "impact", art: "rubble", at, t0: 0, dur: 550 }, delay: 0 });
|
||||
if ((e.type === "wallCreated" || e.type === "firewallCreated" || e.type === "illusionWallCreated") && "edge" in e) {
|
||||
// Conjured from nothing: the edge RISES from the floor, wrapped in
|
||||
// dust and shimmer. (An illusion rises too — for the deceived, it
|
||||
// is a wall in every way.)
|
||||
const edge = (e as { edge: { cell: { x: number; y: number }; side: "N" | "E" | "S" | "W" } }).edge;
|
||||
const key = edgeKey(edge.cell, edge.side);
|
||||
out.push({ fx: { id: nextId++, kind: "grow", slot: "solid", key, t0: 0, dur: 750 }, delay: 0 });
|
||||
const at = edgeMid(edge.cell, edge.side);
|
||||
if (e.type === "wallCreated") {
|
||||
out.push({ fx: { id: nextId++, kind: "impact", art: "rubble", at, t0: 0, dur: 550 }, delay: 0 });
|
||||
}
|
||||
out.push({ fx: { id: nextId++, kind: "impact", art: "shimmer", at, t0: 0, dur: 750 }, delay: 0 });
|
||||
}
|
||||
if (e.type === "creatureCreated" && "at" in e) {
|
||||
const at = (e as { at: { x: number; y: number } }).at;
|
||||
const cid = (e as { creatureId: string }).creatureId;
|
||||
out.push({ fx: { id: nextId++, kind: "grow", slot: "sprite", key: cid, t0: 0, dur: 750 }, delay: 0 });
|
||||
out.push({ fx: { id: nextId++, kind: "impact", art: "shimmer", at: { x: at.x + 0.5, y: at.y + 0.5 }, t0: 0, dur: 750 }, delay: 0 });
|
||||
}
|
||||
if (e.type === "squareFilled" && "cell" in e) {
|
||||
const cell = (e as { cell: { x: number; y: number } }).cell;
|
||||
const kind = (e as { kind: string }).kind;
|
||||
const cellK = `${cell.x},${cell.y}`;
|
||||
out.push({
|
||||
fx: { id: nextId++, kind: "grow", slot: kind === "stone" ? "solid" : "sprite", key: cellK, t0: 0, dur: 750 },
|
||||
delay: 0,
|
||||
});
|
||||
out.push({ fx: { id: nextId++, kind: "impact", art: "shimmer", at: { x: cell.x + 0.5, y: cell.y + 0.5 }, t0: 0, dur: 750 }, delay: 0 });
|
||||
}
|
||||
if (e.type === "sectorRotated" || e.type === "sectorRelocated") {
|
||||
// The maze ITSELF moves: the whole world flashes violet and heaves.
|
||||
|
||||
Reference in New Issue
Block a user