NatureGL Islandv1.1.0

Reference

Scenarios and automation

Eleven named viewpoints, each a mode, a camera and a time of day. They're deterministic, which is what the smoke test, the HUD's Viewpoints panel, the docs' media capture and the ?scenario= URL all rely on.

Village pathvillage-dayEye level on the path at 10:12, looking down past the stilt houses to the pier.
Jungle pathjungle-pathThe hill path under the canopy at 09:24, over the village and lagoon.
BeachbeachThe south beach at 11:30: crabs, rowing boats and the pier.
Pierpier-dayDown the length of the pier at 13:00.
Pier at sunsetpier-sunsetSun 2.2° above the sea, south-west of the pier.
Pier at nightpier-night21:24: lamps, lamplight pools on the water, stars.
Boat · cockpitboatAt the helm: windscreen, chart plotter, radar, wheel and throttle.
Boat · chase camboat-chaseThe chase camera at 15:30 with the wake behind the hull.
UnderwaterunderwaterThe humpback and its fish schools over the coral bommies, 7 m down.
Drone · whole islanddrone-islandThe whole island from 700 m out and 420 m up.
Drone · lagoondrone-lagoonThe lagoon, reef patches and pier from 70 m up.

#What a scenario does

game.applyScenario(name) (from src/IslandGame.js):

  1. pauses the clock and sets the time immediately ('sunset' means a sun elevation of 2.2° at azimuth 205°, over the sea);
  2. re-seeds the birds and crabs, sets the sea life to a fixed time and moors the boat at the pier head;
  3. switches mode instantly and places the camera: a walker position and view for walk and swim, a boat position, heading and camera view for boat, a camera position and view for drone;
  4. fires a scenario event.

underwater is computed rather than stored: it finds the whale's position at a fixed time and puts you 21 m off its inshore flank, 7 m down, looking at it.

#The table

NameModeTimeWhat it shows
village-daywalk10:12The village path down to the pier: stilt houses, stalls, fences, path stones, lamps
jungle-pathwalk09:24The hill path through the jungle canopy, over the village and lagoon
beachwalk11:30The south beach with crabs, rowing boats and the pier
pier-daywalk13:00Down the length of the pier
pier-sunsetwalksunsetThe pier at sunset, sun over the sea
pier-nightwalk21:24Lamps, lamplight pools on the water, stars
boatboat (cockpit)12:12Windscreen, chart plotter, radar, wheel and throttle; 40% throttle
boat-chaseboat (chase)15:30The chase camera with the wake; 55% throttle
underwaterswim12:30The humpback with its fish schools over the coral bommies
drone-islanddrone12:00The whole island from 700 m out
drone-lagoondrone11:00The lagoon, reef patches and pier from 70 m up

The definitions are in src/config/scenarios.js; add one there and it appears in the HUD, in window.__pro.presets and in the smoke test.

src/config/scenarios.js
'pier-sunset': {
  label: 'Pier at sunset', mode: 'walk', time: 'sunset',
  at: [70.5, 236], ...look([70.5, 4, 236], [60, 4.2, 330]),
},
boat: {
  label: 'Boat · cockpit', mode: 'boat', view: 'cockpit', time: 12.2,
  boat: [170, 330, -2.35],
},

#The automation contract

demo/main.js exposes window.__pro, the same contract every NatureGL demo uses:

demo/main.js
window.__pro = {
  ready: false,                          // true after the first frame rendered
  system: game,                          // the IslandGame
  presets: Object.keys(SCENARIOS),       // the eleven scenario names
  qualities: Object.keys(QUALITY_LEVELS),// ['low', 'medium', 'high', 'ultra']
  applyPreset: name => game.applyScenario(name),
  setQuality: level => game.setQuality(level),
  rain: on => game.rain.toggle(on),      // island extra
};

Open the page with ?smoke for automation: the start card is not shown and no scenario is applied at load.

Through __pro.system a script can reach everything else. The docs' videos, for example, hold keys by adding them to game.input.down, so the real controllers do the driving:

js
const g = window.__pro.system;
g.input.down.add('KeyW');     // walk, throttle up or fly forward, depending on the mode
// …
g.input.down.clear();

#The smoke test

bash
npm test                                   # every scenario
node scripts/smoke.mjs --presets beach,boat --quality low --settle 1500 --headed

scripts/smoke.mjs starts a Vite dev server on a free port, opens demo/?smoke at 1280×720 in Chromium on the real GPU (--use-angle=metal), waits for __pro.ready, then for every scenario:

  1. calls __pro.applyPreset(name);
  2. waits for the settle time (2 s by default);
  3. counts frames for 2 s to get the fps;
  4. saves test-results/<name>.png.

It prints the renderer string, any warnings, and the min, median and max fps. It exits non-zero on any page error, console error or HTTP error (except a missing favicon).

#Other scripts

ScriptDoes
node scripts/shot.mjs [--presets a,b] [--quality q] [--eval js] [--out dir]Screenshots scenarios to test-results/shots/ without the error gate
node scripts/play-test.mjsDrives the real input path with key presses: walks the pier, boards the boat, throttles and steers, switches to the chase camera, leaves, flies the drone, lands, swims and dives. Screenshots each step to test-results/play/.