@idle-screens/saver-metaquarium 0.19.1 → 0.20.0

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 CHANGED
@@ -82,9 +82,9 @@ never changes because a dependency was bumped.
82
82
  | Param | Type | Default | Description |
83
83
  |-------|------|---------|-------------|
84
84
  | fishCount | number | 1 | Visible fish, 1–24 (step). Default 1 = hero mode; the pool grows on demand and never shrinks |
85
- | fishUrl | string | `ipfs://…/fish_257_….glb` | GLB model URL, single-breed mode (`ipfs://` supported; the playground overrides to a local asset) |
85
+ | fishUrl | string | `ipfs://…/fish_257_….glb` | GLB model URL, single-breed mode: `ipfs://`, `https://assets.idlescreens.com/`, or a URL on the page's own origin (the playground overrides to a local asset). Any other host is refused, logged once, and the default fish swims instead |
86
86
  | fishMix | string | `""` | Mixed population DSL: `id[:count][@style][*size]` comma-separated (`*size` 0.25–4 scales that token over its breed's length), catalog ids or breed aliases (`"257:2,100:1"`, `"457:3@hover,257:6@school"`), plus the bundled creatures (`shark crab dori glowfish babyfish hackerfish blowfish starfish octopus`, ids 601–606 and 608–610: species, so a count is copies; bundled in the package, see `breeds/README.md`; a crab walks the seabed and climbs rocks on its own legs, `src/crab.ts`; a starfish crawls it and stands up to wave, `src/starfish.ts`; an octopus crawls it, jets off and parachutes down, and watches you with level pupils, `src/octopus.ts`). A minted id is an INDIVIDUAL — no id twice in a scene. Non-empty overrides fishUrl + fishCount; counts absolute, tier-capped |
87
- | dracoPath | string | `""` | Where the Draco decoder lives (most Metaquarium models are Draco-compressed). Empty = the copy shipped beside this package |
87
+ | dracoPath | string | `""` | Where the Draco decoder lives (most Metaquarium models are Draco-compressed). Empty = the copy shipped beside this package. It runs as script, so only a path on the page's own origin (or under the shipped copy) is used; anything else falls back to the shipped copy and is logged once |
88
88
 
89
89
  ### Motion
90
90
 
@@ -2926,18 +2926,24 @@ var PARAM_DOCS = {
2926
2926
  cameraAzimuth: "Orbit bearing in degrees. 0 looks at the village from the front.",
2927
2927
  cameraElevation: "Degrees above the floor. 8\u201315 is eye level with the fish; 40+ looks down on a castle.",
2928
2928
  cameraDistance: "Distance from the tank centre. 80 is a close-up, 170\u2013220 a village, 300+ a landmark.",
2929
- shot: "A named framing: `orbit` (default), `hero` (three-quarter), `front` (level, long lens), `low` (among the plants, looking up), `top` (the floor as a map), `surface` (the water's underside), `macro` (close on the nearest landmark). Azimuth and autoRotate turn it; distance scales it.",
2929
+ shot: "A named framing: `orbit` (default), `hero` (three-quarter), `front` (level, long lens), `low` (among the plants, looking up), `top` (the floor as a map), `surface` (the water's underside), `macro` (close on the nearest landmark), `cast` (frames the mix's first three wherever they swim). Azimuth and autoRotate turn it; distance scales it.",
2930
+ shotBlend: "Seconds a change of `shot` takes (0 = a cut): the camera moves to the new framing, eased.",
2930
2931
  cameraFollow: "Ride with one fish (cast slot, 0 = first); -1 is the orbit camera. Orbit params are ignored while following. Pair with `followSpot` on the same slot for a spotlit chase.",
2931
2932
  followAngle: "Where round the followed fish the chase camera stands, degrees: 0 behind (default), 90 beside, 180 in front looking back at its face.",
2932
2933
  followDistance: "How far behind the followed fish the camera rides (40\u201370 is a chase). Under ~18 it is the fish's eye and the fish is hidden; a floor walker (Dot, crab, octopus, snail, starfish) sees from its own head height.",
2933
2934
  autoRotate: "Turntable speed, degrees/second. 0 holds the shot (stages, vignettes); 1\u20132 is a slow reveal. frame.state.camera.bearing: where it stands now.",
2934
- followAvoid: "Keep the followed fish in view, 0\u20131 (default 0): when something is in the way the chase camera rises over low clutter or pulls in, eased. For long walking takes through a village. No effect in the fish's own eye (followDistance under about 16).",
2935
+ followAvoid: "Keep the followed fish in view, 0\u20131: the chase camera rises over low clutter or pulls in, eased. For walks through a village.",
2936
+ nearFade: "A creature at the lens dissolves instead of being sliced, 0\u20131. The followed fish never fades.",
2935
2937
  // cast
2936
2938
  fishCount: "How many fish when `fishMix` is empty (all are `fishUrl`).",
2937
2939
  finish: "A final full-screen pass: gentle grade, soft vignette, dither against banding, and restrained bloom on high-end devices (0 = none; never on the low tier).",
2938
- fishUrl: "The single model used when `fishMix` is empty. ipfs:// or https.",
2939
- fishMix: "The cast: `id[:count][@style]`, comma-separated: `100:2@drift, 257:1, seahorse:3, shark:1@patrol`. Minted breeds plus bundled creatures: shark crab dori glowfish babyfish hackerfish blowfish starfish octopus snail dot dolphin. Floor walkers keep their own pace (swimSpeed does not hurry them): crab (climbs rocks, forages, pinches, waves), starfish (walks upright too; dances with `starfishDance`), snail (very slow; hides in its shell). `dot` (experimental) is Dot the courier, a box on two legs with a screen face; `dolphin` (experimental) chatters, flips and blows bubbles. Both act out vignette gestures. Overrides fishCount/fishUrl.",
2940
- dracoPath: "Where the Draco decoder lives; leave empty on a channel.",
2940
+ tiltShift: "Tilt-shift, 0\u20131: sharp through the middle, soft above and below, like a model. Mid/high tiers.",
2941
+ depthOfField: "Depth of field, 0\u20131: the subject sharp (followed fish, `cast` leads), the rest soft. High tier.",
2942
+ ambientOcclusion: "Ambient occlusion, 0\u20131: crevices darken. High tier.",
2943
+ highlights: "Bright light rolls off instead of clipping, 0\u20131: a fish in a shaft stays a fish. Bright rooms want it. Mid/high tiers.",
2944
+ fishUrl: "The single model used when `fishMix` is empty: ipfs://, https://assets.idlescreens.com/, or a URL on the page's own origin. Any other host is refused and the default fish swims.",
2945
+ fishMix: "The cast: `id[:count][@style]`, comma-separated: `100:2@drift, 257:1, seahorse:3, shark:1@patrol`. Minted breeds plus bundled creatures: shark crab dori glowfish babyfish hackerfish blowfish starfish octopus snail dot dolphin. Floor walkers keep their own pace (swimSpeed does not hurry them): crab (climbs rocks, forages, pinches, waves), starfish (walks upright too; dances with `starfishDance`), snail (very slow; hides in its shell). `dot` (experimental): Dot the courier, a box on legs with a screen face; `dolphin` (experimental) chatters, flips, blows bubbles, breaches where there is open surface, and in a scene stands on its tail for character beats (talk, nod, bow...). Both act out vignette gestures. Overrides fishCount/fishUrl.",
2946
+ dracoPath: "Where the Draco decoder lives; leave empty on a channel. Only the page's own origin or the shipped copy is used.",
2941
2947
  swimSpeed: "Global swim speed multiplier. 0.4 is contemplative, 1 lively.",
2942
2948
  swimStyle: "How the cast swims unless a fishMix entry says otherwise (`@style`). `auto` picks by breed.",
2943
2949
  pathShape: "The shape of free-swimming paths.",
@@ -2959,10 +2965,14 @@ var PARAM_DOCS = {
2959
2965
  fishAmbient: "The water's light on the fish in lit mode (backs, flanks, bellies, metal plates). Fixes fish reading dark; 0.6\u20131 in bright tanks. Dims with a follow-spot's house lights.",
2960
2966
  fishGlow: "How strongly GLOW- parts of a fish bloom and light their neighbours and the floor.",
2961
2967
  fishMetal: "`on` (default) gives METAL- parts a polished, reflective finish.",
2962
- snailShell: "The snails' shells: `banded` (as drawn), `pearl` (iridescent nacre), `gold`, `glow` (a spiral that breathes light; best at night); `mix` (default), each its own. Lit fish only: flat lighting and the neon look keep the banded coat. frame.state.fish[i].shell says which.",
2963
- starfishDance: "Starfish dance: `aerobics`, a class facing the camera with an instructor, in unison; `freestyle`, each its own move every eight counts; `duet`, couples face to face (basic, sway, twirl, dip, lift), best with `spotRig: 0/#ffd27a*26, 1/#ff8ad0*26`. `off` (default): they crawl and wave on their own. Cast a few (`fishMix: starfish:7`); best with `shot: front`, `autoRotate: 0`, a bright room. The class faces the live camera every frame (a follow camera uses cameraAzimuth).",
2968
+ snailShell: "The snails' shells: `banded` (as drawn), `pearl` (iridescent nacre), `gold`, `glow` (a spiral that breathes light; best at night); `mix` (default), each its own. Lit fish only. frame.state.fish[i].shell says which.",
2969
+ starfishDance: "Starfish dance: `aerobics`, a class facing the camera with an instructor, in unison; `freestyle`, each its own move every eight counts; `duet`, couples face to face, best with `spotRig: 0/#ffd27a*26, 1/#ff8ad0*26`. `off` (default): they crawl and wave on their own. Cast a few (`fishMix: starfish:7`); best with `shot: front`, `autoRotate: 0`, a bright room.",
2964
2970
  danceTempo: "Beats per minute for the starfish dance (60\u2013180, default 128). Glides on the beat.",
2965
2971
  fishLook: "`neon` dresses the bundled creatures (crab, glowfish, shark\u2026) for blacklight: near-black coats, eyes and a crab's mouth glowing a neon of their own. Best in a dark room (abyss, void) with `finish`. `natural` is the default.",
2972
+ fishRim: "A thin edge of the water's light round each fish, 0\u20131 (lit mode): dark fish on dark water. 0.6\u20131 in dark rooms.",
2973
+ fishShadows: "Soft shadows on the ground under the swimmers, 0\u20131: dark near the sand, faint high up.",
2974
+ fishFadeIn: "Seconds an arriving fish takes to dissolve in (0 = it pops in).",
2975
+ sceneryShadows: "Soft shadows under rocks, homes, castle, pyramids, geodes and lamps, 0\u20131, so nothing floats.",
2966
2976
  swimWave: "Fish bend as they swim: a wave runs nose to tail and the body curls into turns (0 = rigid wiggle). Skips the turtle, crab and fish that already have a skeleton; the seahorse gets its own motion instead \u2014 fin, tail and nod.",
2967
2977
  fishAvoid: "Fish make way for each other: a pair about to meet parts a second ahead, the smaller giving more, over or under before round. 1 (default) on, 0 pass-through. `inspect().crowding` counts pairs still touching.",
2968
2978
  eyeLife: "Eyes blink, look, and emote (0 = painted on). Redraws each token's own pixel-grid eye; black and white only.",
@@ -2981,6 +2991,8 @@ var PARAM_DOCS = {
2981
2991
  floorKind: "Floor shape: `auto` follows the environment, `flat`, or terrain `dunes`, `ridges`, `basin`, `shelf` (the town on a terraced plateau), `trench` (a deep channel across the front), `terraces` (tiers behind the town).",
2982
2992
  waterY: "Height of the water ceiling; -1 = the environment's own.",
2983
2993
  rayStrength: "Light shafts from the surface, within device budget: 5 on the high tier, 2 on standard, none on the lowest tier in a room with a water surface (reef, kelp, ice, lagoon; abyss, vent and universe keep 2). Where dropped, perceiveChannel reads room.rayStrength 0.",
2994
+ raySoftness: "Shafts as soft volume, not flat sheets, 0\u20131. 1 for anything cinematic.",
2995
+ floorDetail: "A seabed, not a coloured plane, 0\u20131: ripples, silt, grain; the floor's far edge fades into the fog.",
2984
2996
  caustics: "The dancing net of light from the surface on the floor, rocks, plants and fish (0 = none). Sharp near the top, soft and dim deep down.",
2985
2997
  causticScale: "Size of the caustic cells: below 1 a fine shimmer, above 1 broad slow bands.",
2986
2998
  surfaceMirror: "The surface from below: a window up to the light and a rippling mirror of the tank around it (0 = the plain sheet). Needs reef, kelp, ice or lagoon; pays off on the `surface` and `low` shots. High tier reflects the real tank, mid tier the deep water.",
@@ -2995,26 +3007,27 @@ var PARAM_DOCS = {
2995
3007
  rockDensity: "Faceted boulders, an arch and a back ridge around the crystals.",
2996
3008
  rockVeins: "Crystals bursting out of the rocks: each crown broken open, chips on the rim, a colony of the same crystal growing from the breach. 0 is plain stone.",
2997
3009
  geodeHomes: "Geode houses (0\u20133) in a crescent: a village. Their doors are vignette marks `home1`\u2026, `home1in`\u2026. Capped at 2 on basic/minimal tiers (3 on standard/high); a dropped house takes its homeN/homeNin marks, and indoors there are none.",
3010
+ stoneStyle: "`weathered`: river-grey rocks and homes with silt on top, not dark holes in a lit room. `classic` (default): dark slate.",
2998
3011
  interior: "`geode` sets the whole scene INSIDE a geode home: furniture, chandelier, marks like `table`, `bed`, `door`.",
2999
- floraDensity: "Voxel plants: one tank-wide budget (density \xD7 36/72/108 by tier) shared among crystals and geodes (or six bare spots), so more crystals means sparser gardens. What grows is `floraMix`; empty, the room picks (coral on a reef, kelp in the kelp forest, glow caps in the abyss).",
3000
- geodes: "Wild geodes about the floor (0 = none): split geodes and thunder eggs, amethyst cathedrals, crystal clusters, one mega cavern. They glow and pulse with the crystals (crystalGlow, crystalPulse), take the nearest crystal's mineral, grow flora like a crystal, and wake when a fish comes close.",
3012
+ floraDensity: "Voxel plants: one tank-wide budget (\xD7 36/72/108 by tier) shared among crystals and geodes, so more crystals means sparser gardens. What grows is `floraMix`; empty, the room picks.",
3013
+ geodes: "Wild geodes on the floor (0 = none): split geodes, thunder eggs, cathedrals, clusters, one cavern. They glow and pulse with the crystals, take the nearest crystal's mineral, and wake when a fish comes close.",
3001
3014
  geodeMix: "Which geodes: `kind[:weight]`, comma-separated. geode cathedral cluster cavern (the cavern is one at most).",
3002
3015
  geodeMineral: "What they are made of: amethyst agate celestine citrine carnelian rose emerald quartz smoky. Empty = the mineral nearest in colour to the nearest crystal; `world` = two from the seed; or a list.",
3003
3016
  fountain: "The town square's fountain where the paths meet: `vent` (a hot-vent chimney crusted with crystal, glowing at the mouth) or `geode` (a great geode basin on a plinth). A bubble column, a pebble plaza, a light of its own, and a vignette mark `fountain`.",
3004
- signs: 'Underwater signage, `kind[@place][>target][/#color][*size][:text]`: `plank` on a post, `arrow` pointing at another place, life-`ring` with a plaque, lit `porthole`, glowing `neon` lettering, scrolling `led` board. Each stands beside its place facing the front; with no @place, in the open. Original words only. `plank@gate:"Welcome to the reef", neon@home1/#ff4fa0:OPEN, arrow@hub>gate:Castle`.',
3017
+ signs: 'Signs, `kind[@place][>target][/#color][*size][:text]`: `plank` on a post, `arrow` to another place, life-`ring`, lit `porthole`, `neon` lettering, scrolling `led` board, each beside its place. Original words only. `plank@gate:"Welcome to the reef", neon@home1/#ff4fa0:OPEN, arrow@hub>gate:Castle`.',
3005
3018
  signFlicker: "How unstable the lit signs' power is (neon and LED), 0\u20131, default 0.4: hums, stutters, a dead row for a moment, now and then a reboot. Each sign has its own supply; 0 is steady. Flash-safe at any setting.",
3006
3019
  streetLamps: "Crystal streetlamps along the paths (0 = none, 1 = about 24): slate posts with a crystal crown in their nearest crystal's colour, a halo and light on the floor. Needs paths.",
3007
- townProps: "The village's small things, comma-separated kind[:count][/style]: fence (a yard round every home with a gate; driftwood coral stone crystal, none = each home its own), mailbox (by every gate: post, clam or bottle; vignette marks mailbox1\u2026), bench[:n] (round the fountain or hub; shell stone), sock[:n] (a current sock). Fences and mailboxes need geodeHomes.",
3008
- floorCover: "What the village lays on its floor, comma-separated kind[/style]: lawn (each home's yard; stripes checks), mosaic (a compass rose round the fountain or hub; stone shell glass), mat (at every door; kelp stripe), steps (stepping stones down every walk; slate sand moss, none = the walk's own ground), ripples (the open sand; fine broad). Lawns and mats need geodeHomes, steps need paths, a mosaic needs a fountain, paths or homes. Mats and stones lie only on flat ground.",
3020
+ townProps: "Village props, kind[:count][/style]: fence (a yard per home; driftwood coral stone crystal), mailbox (by each gate: post clam bottle; marks mailbox1\u2026), bench[:n] (shell stone), sock[:n]. Fences and mailboxes need geodeHomes.",
3021
+ floorCover: "What the village lays on its floor, kind[/style]: lawn (yards; stripes checks), mosaic (a compass rose at the hub; stone shell glass), mat (at doors; kelp stripe), steps (down every walk; slate sand moss), ripples (open sand; fine broad). Lawns and mats need geodeHomes, steps need paths. Flat ground only.",
3009
3022
  pyramids: "Pyramids built of cubes like the fish (0 = none, 1 = about a dozen complexes): symmetric stacks, a great pyramid and its queens, the great ones at the back. Flat ground only: use floorKind: flat (none on dunes, ridges or a basin).",
3010
- pyramidMix: "Shapes and stones: `shape|stone[:weight], \u2026`. Shapes giza step bent djoser mayan frame; stones sandstone limestone obsidian jade gold lapis coral crystal nacre basalt, and lit led (white and rainbow) and neon (magenta and cyan), every cube a lamp in the light show. Empty = every shape in the room's stone.",
3023
+ pyramidMix: "Shapes and stones, `shape|stone[:weight], \u2026`: giza step bent djoser mayan frame; sandstone limestone obsidian jade gold lapis coral crystal nacre basalt, and lit led and neon (every cube a lamp). Empty = every shape in the room's stone.",
3011
3024
  pyramidLayout: "field = complexes over the floor; stage = one monumental pyramid in the middle of the camera's orbit (lit if the mix has led or neon, else stone with lit trim), a small one at each side, the field behind. Needs flat ground in the middle.",
3012
- pyramidShow: "The lit pyramids' show (led, neon or trim in pyramidMix): empty or auto = the whole field as one wave through every routine; solo = each its own; a routine (rings beam edges equalizer rainbow twinkle faces rain spiral breathe ripple); or a looping cue sheet `8s:rings, 8s:beam, 16s:equalizer`. Steered live, no rebuild.",
3025
+ pyramidShow: "The lit pyramids' show (led, neon or trim): auto = one wave through every routine; solo = each its own; a routine (rings beam edges equalizer rainbow twinkle faces rain spiral breathe ripple); or cues `8s:rings, 16s:equalizer`. Live, no rebuild.",
3013
3026
  pyramidBpm: "The light show's tempo, 0\u2013140 (0 = free-running): the motion steps on the beat and each beat lifts the lamps a little \u2014 never a flash.",
3014
3027
  geodeLayout: "`field` (default) scatters them; `gallery` lines them up, a row per kind and a column per mineral, the mega geode behind. Frame with cameraDistance 400, elevation ~26, nothing else in the scene.",
3015
3028
  floraLayout: "`garden` (default) grows plants round the crystals; `gallery` plants one of each species in two rows across the front (low before tall). With `floraMix` set, only its species. Frame with `shot: front` or `cameraDistance` ~260.",
3016
3029
  floraPalette: "One colour scheme for the garden: `world` picks a hero hue, a neighbour and an accent from the seed; or give up to six `#rrggbb`. Each colony is pulled most of the way to one of them. Empty = every species its own colours.",
3017
- floraMix: "Which plants: `species[:weight]`, comma-separated: grass tube bulb fan kelp anemone staghorn brain whip barrel shelf seapen clam bubble elder curl pod (giant clam: two at most; elder, a lantern tree: one). Colonies share a colour. `kelp:3, whip, seapen` is a kelp forest; `staghorn:2, brain, anemone:2, clam` a reef. Empty = the room's own garden. Needs floraDensity > 0.",
3030
+ floraMix: "Which plants: `species[:weight]`, comma-separated: grass tube bulb fan kelp anemone staghorn brain whip barrel shelf seapen clam bubble elder curl pod (clam: two at most; elder: one). `kelp:3, whip, seapen` is a kelp forest; `staghorn:2, brain, anemone:2, clam` a reef. Empty = the room's garden. Needs floraDensity.",
3018
3031
  bubbleVents: "Bubbles from chimneys, fissures and crystals.",
3019
3032
  bubbleStyle: "How vent bubbles live: `classic` loops puffs; `live` grows each bubble at the vent, rises it to the surface (if there is one) and pops it, resting the vent now and then. Distant bubbles dim instead of fattening.",
3020
3033
  pearling: "Oxygen pearls on the plants: beads grow on the leaves over half a minute or more, sway with them and let go (0 = none). Needs floraDensity > 0; with no flora there is nothing to pearl on.",
@@ -3076,6 +3089,7 @@ vignette beats separated by |, cues by comma; actors a b c are fish slots 0 1 2
3076
3089
  var NIGHT = { fogColor: "#0a0a1a", fogNear: 120, fogFar: 700 };
3077
3090
  var STAGE = { fogColor: "#01030a", floorColor: "#0a1322", fogNear: 120, fogFar: 650, autoRotate: 0 };
3078
3091
  var ALIVE = { eyeLife: 1 };
3092
+ var CINEMATIC = { highlights: 1, raySoftness: 1, nearFade: 1, finish: 0.6 };
3079
3093
  var RECIPES = [
3080
3094
  {
3081
3095
  id: "geode-harbor",
@@ -3313,7 +3327,7 @@ var RECIPES = [
3313
3327
  {
3314
3328
  id: "reef-characters",
3315
3329
  label: "Reef characters",
3316
- what: "The bundled characters on a coral reef: tangs that look back at you, blowfish that puff up and flirt, an octopus that changes colour and inks, a crab on the floor. A slow orbit.",
3330
+ what: "The bundled characters on a reef: tangs that look back, blowfish that puff and flirt, an octopus that changes colour and inks, a crab. A slow orbit.",
3317
3331
  params: {
3318
3332
  ...ALIVE,
3319
3333
  environment: "reef",
@@ -3338,7 +3352,7 @@ var RECIPES = [
3338
3352
  {
3339
3353
  id: "snail-garden",
3340
3354
  label: "Snail garden",
3341
- what: "Five snails glide a planted floor, low and close: they stop to graze, stretch, look at you, or hide in their shells, a few baby fish overhead.",
3355
+ what: "Five snails glide a planted floor, low and close: they graze, stretch, look at you or hide in their shells; baby fish overhead.",
3342
3356
  params: {
3343
3357
  ...ALIVE,
3344
3358
  environment: "lagoon",
@@ -3356,7 +3370,7 @@ var RECIPES = [
3356
3370
  {
3357
3371
  id: "dot-delivers",
3358
3372
  label: "Dot delivers",
3359
- what: "Dot, the courier, walks from the fountain to a neighbour's door and knocks; a blowfish comes out, they bow and chat, Dot thinks it over, gets the idea, spins for joy and walks home. The camera rides beside it.",
3373
+ what: "Dot the courier walks to a neighbour's door and knocks; a blowfish comes out, they bow and chat, Dot spins for joy and walks home. The camera rides beside it.",
3360
3374
  params: {
3361
3375
  ...ALIVE,
3362
3376
  geodeHomes: 3,
@@ -3389,6 +3403,86 @@ var RECIPES = [
3389
3403
  followDistance: 40,
3390
3404
  followAngle: 140
3391
3405
  }
3406
+ },
3407
+ {
3408
+ id: "reef-cinematic",
3409
+ label: "Reef, cinematic",
3410
+ what: "A small reef cast framed close wherever it swims, in soft shafts, each fish over its shadow. The polished look.",
3411
+ params: {
3412
+ ...ALIVE,
3413
+ ...CINEMATIC,
3414
+ environment: "reef",
3415
+ fishMix: "seaturtle:1@patrol, blowfish:1, octopus:1@bottom, dori:5@school, crab:1",
3416
+ floraDensity: 0.45,
3417
+ marineSnow: 0.3,
3418
+ swimSpeed: 0.6,
3419
+ fishRim: 0.35,
3420
+ fishShadows: 1,
3421
+ sceneryShadows: 1,
3422
+ floorDetail: 0.5,
3423
+ fishAmbient: 0.5,
3424
+ caustics: 0.6,
3425
+ depthOfField: 0.4,
3426
+ ambientOcclusion: 0.8,
3427
+ shot: "cast",
3428
+ cameraElevation: 12,
3429
+ autoRotate: 0.5
3430
+ }
3431
+ },
3432
+ {
3433
+ id: "night-cinematic",
3434
+ label: "Deep night, cinematic",
3435
+ what: "The deep at night: glowfish under jellyfish lanterns, a shark sliding through, every outline rimmed in light.",
3436
+ params: {
3437
+ ...ALIVE,
3438
+ ...CINEMATIC,
3439
+ finish: 0.75,
3440
+ environment: "abyss",
3441
+ fishMix: "glowfish:2@hover, babyfish:1@hover, shark:1@patrol, babyfish:2, hackerfish:1",
3442
+ propMix: "crystal:2@druse/cyan, crystal:1@spire/hotpink",
3443
+ fishLook: "neon",
3444
+ fishGlow: 0.8,
3445
+ fishRim: 0.9,
3446
+ sceneryShadows: 1,
3447
+ marineSnow: 0.5,
3448
+ swimSpeed: 0.5,
3449
+ skyLanterns: 0.6,
3450
+ skyHeight: 0.35,
3451
+ shot: "cast",
3452
+ cameraElevation: 8,
3453
+ autoRotate: 0.4
3454
+ }
3455
+ },
3456
+ {
3457
+ id: "village-cinematic",
3458
+ label: "Village, cinematic",
3459
+ what: "Dot, Puff and Hex meet in a sunlit village of stone homes, seen high through a tilt-shift lens: a model village.",
3460
+ params: {
3461
+ ...ALIVE,
3462
+ ...CINEMATIC,
3463
+ environment: "lagoon",
3464
+ floorKind: "flat",
3465
+ geodeHomes: 3,
3466
+ stoneStyle: "weathered",
3467
+ paths: 0.5,
3468
+ streetLamps: 0.3,
3469
+ floraDensity: 0.12,
3470
+ townProps: "mailbox, fence",
3471
+ fishMix: "dot:1, blowfish:1, hackerfish:1, babyfish:3",
3472
+ swimSpeed: 0.5,
3473
+ marineSnow: 0.25,
3474
+ vignette: "4s: a =home1in, b =home2in, c =home3in | 8s: a >centre, b >centre @a | 6s: a @b talk, b @a nod | 8s: c >centre, a @c, b @c | 9s: a b c circle centre | 8s: a >home1in, b >home2in, c >home3in",
3475
+ fishRim: 0.3,
3476
+ fishShadows: 1,
3477
+ sceneryShadows: 1,
3478
+ floorDetail: 0.6,
3479
+ ambientOcclusion: 0.8,
3480
+ tiltShift: 0.55,
3481
+ shot: "orbit",
3482
+ cameraDistance: 125,
3483
+ cameraElevation: 32,
3484
+ autoRotate: 0.5
3485
+ }
3392
3486
  }
3393
3487
  ];
3394
3488
  var recipe = (id) => RECIPES.find((r) => r.id === id);
@@ -3739,10 +3833,14 @@ var METAQUARIUM_PARAMS = {
3739
3833
  /** Camera distance from tank center, world units. */
3740
3834
  cameraDistance: { type: "number", default: 110, min: 80, max: 400, ease: "smooth" },
3741
3835
  /** A named framing: `orbit` (the classic camera), hero, front, low, top,
3742
- * surface (looking up at the water's underside) or macro (close on the
3743
- * landmark nearest the front). Azimuth and autoRotate still turn it;
3836
+ * surface (looking up at the water's underside), macro (close on the
3837
+ * landmark nearest the front) or cast (the leads — the mix's first three — wherever they swim,
3838
+ * as close as their spread allows). Azimuth and autoRotate still turn it;
3744
3839
  * distance scales it. A change is a cut. */
3745
- shot: { type: "enum", default: "orbit", options: ["orbit", "hero", "front", "low", "top", "surface", "macro"], ease: "step" },
3840
+ shot: { type: "enum", default: "orbit", options: ["orbit", "hero", "front", "low", "top", "surface", "macro", "cast"], ease: "step" },
3841
+ /** Seconds a change of `shot` takes: 0 (default) cuts; above it the camera
3842
+ * moves from the old framing to the new one, eased. */
3843
+ shotBlend: { type: "number", default: 0, min: 0, max: 12, ease: "step" },
3746
3844
  /** Ride with one fish (a cast slot, 0 = first); -1 (default) is the orbit
3747
3845
  * camera. The orbit params are ignored while following. */
3748
3846
  cameraFollow: { type: "number", default: -1, min: -1, max: 23, ease: "step" },
@@ -3843,6 +3941,15 @@ var METAQUARIUM_PARAMS = {
3843
3941
  * same sentinel reason: ramping -1 → 0 would read as FULL strength until it
3844
3942
  * snapped off. */
3845
3943
  rayStrength: { type: "number", default: -1, min: -1, max: 1, ease: "step" },
3944
+ /** Light shafts as light in the water rather than sheets of it: their sides
3945
+ * melt, faint filaments run down them, their feet fade into the floor.
3946
+ * 0 is the classic flat cone. */
3947
+ raySoftness: { type: "number", default: 0, min: 0, max: 1, ease: "smooth" },
3948
+ /** The seabed's detail: sand the current has combed into ripples, broad
3949
+ * patches of silt and grit, a fine grain — and the floor's far edge faded
3950
+ * into the fog, so no rim shows against the background. 0 is the plain
3951
+ * floor. */
3952
+ floorDetail: { type: "number", default: 0, min: 0, max: 1, ease: "smooth" },
3846
3953
  /** Caustics: the net of light a rippled surface throws on the floor, rocks,
3847
3954
  * plants and fish — sharp near the surface, broad and dim deep down,
3848
3955
  * brightest on faces that look up. 0 compiles the stock programs. */
@@ -3949,10 +4056,48 @@ var METAQUARIUM_PARAMS = {
3949
4056
  * their backs, the water around on their flanks, the floor under their
3950
4057
  * bellies — and mirrored in silvered plates. 0 is the studio alone. */
3951
4058
  fishAmbient: { type: "number", default: 0, min: 0, max: 1, ease: "smooth" },
4059
+ /** A thin edge of the water's light round each fish's silhouette (lit
4060
+ * mode), brighter on top: what separates a dark fish from dark water.
4061
+ * 0 is none. */
4062
+ fishRim: { type: "number", default: 0, min: 0, max: 1, ease: "smooth" },
4063
+ /** A soft shadow on the ground under every swimmer: small and dark near
4064
+ * the sand, wide and faint high up — what puts a fish at a height instead
4065
+ * of floating in front of the floor. 0 is none (floor walkers always
4066
+ * have theirs). */
4067
+ fishShadows: { type: "number", default: 0, min: 0, max: 1, ease: "smooth" },
4068
+ /** Seconds a fish takes to dissolve into the water when it first arrives
4069
+ * (its model loads a few seconds into a scene), instead of popping in.
4070
+ * 0 (default) pops. */
4071
+ fishFadeIn: { type: "number", default: 0, min: 0, max: 3, ease: "step" },
4072
+ /** A soft shadow pooled under everything that stands on the floor — rocks,
4073
+ * homes, the castle, pyramids, wild geodes, lamps — so it stands on the
4074
+ * sand instead of floating over it. 0 is none. */
4075
+ sceneryShadows: { type: "number", default: 0, min: 0, max: 1, ease: "smooth" },
4076
+ /** A creature that comes too close to the camera dissolves (an ordered
4077
+ * dither by depth) instead of being cut by the lens: at 1 it is whole
4078
+ * beyond about a fish and a half and gone inside about half that. 0 is off. */
4079
+ nearFade: { type: "number", default: 0, min: 0, max: 1, ease: "smooth" },
3952
4080
  /** The finish: one full-screen pass — a gentle grade, dither against
3953
4081
  * banding, and restrained bloom on high-end devices. 0 draws straight to
3954
4082
  * the screen as before; the low tier never runs it. */
3955
4083
  finish: { type: "number", default: 0, min: 0, max: 1, ease: "smooth" },
4084
+ /** Tilt-shift: in focus through a band across the middle of the frame,
4085
+ * softer above and below — a wide shot of a village reads as a model.
4086
+ * Mid and high tiers. 0 is none. */
4087
+ tiltShift: { type: "number", default: 0, min: 0, max: 1, ease: "smooth" },
4088
+ /** Depth of field: sharp at what the shot is about (the followed fish, or
4089
+ * where the shot aims — `cast`: the leads), softer with distance from it.
4090
+ * High tier only. 0 is none. */
4091
+ depthOfField: { type: "number", default: 0, min: 0, max: 1, ease: "smooth" },
4092
+ /** Ambient occlusion: the water's light reaches less into crevices —
4093
+ * between voxels, under ledges, where a fish meets the sand — from the
4094
+ * frame's own depth. High tier only. 0 is none. */
4095
+ ambientOcclusion: { type: "number", default: 0, min: 0, max: 1, ease: "smooth" },
4096
+ /** Bright light rolls off instead of clipping: shafts, glare and glow that
4097
+ * stack past white ease into it with their hue kept, so a fish in a beam
4098
+ * stays a fish. The brightest seventh of the range is compressed a little.
4099
+ * 0 draws as before; mid and high tiers on WebGL2. */
4100
+ highlights: { type: "number", default: 0, min: 0, max: 1, ease: "smooth" },
3956
4101
  /** Metallic plates read as metal (a generated chrome matcap — reflection
3957
4102
  * with no environment map and no lights). `off` is non-metallic instead —
3958
4103
  * still lit under `fishLighting: 'lit'`; pair with `fishLighting: 'flat'`
@@ -4000,6 +4145,11 @@ var METAQUARIUM_PARAMS = {
4000
4145
  /** How fractured the rocks are: fissure width, forks, and crystals pushing
4001
4146
  * out of the crack. 0 is plain stone. Only matters with `rockDensity`. */
4002
4147
  rockVeins: { type: "number", default: 0.7, min: 0, max: 1, ease: "step" },
4148
+ /** The world's stone — rocks, arches, homes, the castle keep: `classic`,
4149
+ * the dark slate it always was, or `weathered` — river-grey, each facet its
4150
+ * own shade, silt settled on the tops — so stone in a lit room reads as
4151
+ * stone and not as a hole. */
4152
+ stoneStyle: { type: "enum", default: "classic", options: ["classic", "weathered"], ease: "step" },
4003
4153
  geodeHomes: { type: "number", default: 0, min: 0, max: 3, ease: "step" },
4004
4154
  /** A follow-spot: a beam from the rig and a pool of moving caustics on the
4005
4155
  * floor that track ONE fish across the scene like a performer on a stage,
@@ -4392,4 +4542,4 @@ export {
4392
4542
  paramSpaceWith,
4393
4543
  coerceNum
4394
4544
  };
4395
- //# sourceMappingURL=chunk-Y3TSBXXY.js.map
4545
+ //# sourceMappingURL=chunk-IIYEE6GT.js.map