singe/testScripts/README.md

70 lines
16 KiB
Markdown

# Test scripts
The Lua scripts used to verify the 3D scene and physics work, one per stage
of PLAN.md sections 18 and 19, with everything they load: the Khronos
Duck, Fox, BoxAnimated, AnimatedMorphCube and Sponza sample models under Models/, Box.png and crate.png. The
disc and the font are the engine's own, addressed as
Singe/menuBackground.mkv and Singe/FreeSansBold.ttf like any engine
asset. This directory is a complete Singe game directory. Run one from the singe directory with
.builddir/Singe-v3.00-Linux-x86_64 -w -d data -v Singe/menuBackground.mkv testScripts/scene6.singe
(scene12 and scene20 have no disc: give them -C 720x480 instead of -v)
or pack it (singe --pack testScripts testScripts.game) and run an entry
with --entry N (the numbers follow games.dat). Every script takes a
screenshot or two and quits by itself; the results are in screenshots/.
| Script | Entry | Stage | What it shows |
|-----------------|-------|-------|------------------------------------------------------------|
| scenetest.singe | 1 | 18.1 | The 3D layer: a translucent colour over the disc, text on top |
| scene2.singe | 2 | 18.2 | Primitives, materials, lights, camera, sceneProject label |
| scene3.singe | 3 | 18.3 | glTF models: two Ducks, BoxAnimated, loose and packed |
| scene4.singe | 4 | 18.4 | Node animation at three speeds, one paused |
| scene5.singe | 5 | 18.5 | Skinning: three Foxes in Survey, Walk and Run |
| scene6.singe | 6 | 18.6 | The disc and a loaded video as materials, sceneUnproject |
| scene7.singe | 7 | 18.6b | Shadows: sun, sun and spot together, a point light inside |
| scene8.singe | 8 | 18 | An arcade cabinet from primitives with the disc on screen |
| scene9.singe | 9 | 19.2 | Physics: a crate stack, a ball, a kinematic paddle |
| scene10.singe | 10 | 19.3 | Physics: a trigger volume, collision callbacks, a raycast pick |
| scene11.singe | 11 | 19.4 | Physics: a hull down a ramp, a mesh torus, hinge, ball and slider joints |
| scene12.singe | 12 | 19.6 | 2D physics drawn with sprites; runs with no GPU (SDL_GPU_DRIVER=nothing) |
| scene13.singe | 13 | 18.8 | Morph targets: the AnimatedMorphCube, animated and driven from script |
| scene14.singe | 14 | - | The solid tangram dragon (Models/DragonModel.glb, a copy of assets/DragonModel.glb) turning under a sun with shadows |
| scene15.singe | 15 | - | The Singe logotype as solid letters (Models/SingeText.glb, a copy of assets/SingeText.glb) turning under a sun with shadows |
| scene16.singe | 16 | - | The dragon perched on the logotype, both models under one parent node, turning together |
| scene17.singe | 17 | 20.1 | 2D particles: fireworks, a smoke trail, sparks off a 2D physics ball; runs with SDL_GPU_DRIVER=nothing |
| scene18.singe | 18 | 20.2 | 3D particles: torch flame and smoke on a post, a fountain, dust, over the disc with shadows |
| scene19.singe | 19 | 21.1 | Character controller: the Fox on a course of stairs, a ramp, a jump, a crate, a wall and a steep slope |
| scene20.singe | 20 | 21.2 | Character controller in 2D: a sprite platformer (gap, step, wall, ledge); runs with SDL_GPU_DRIVER=nothing and -C 720x480 |
| scene21.singe | 21 | 22.1 | Point-light shadows inside geometry: a bulb under a shade and a bulb in a cage, in a closed room of outward-facing boxes, inside and outside views |
| scene22.singe | 22 | 23.1 | Vehicles: a car from primitives on a ramp track, driven by a scripted route with a chase camera |
| scene23.singe | 23 | 23.2 | Vehicles: a tank that pivots and climbs, and a motorcycle that leans through a turn |
| scene24.singe | 24 | 24.1 | Water: a pool and a river; crates float, sink and drift, the Fox swims across, a raft drives |
| scene25.singe | 25 | 25.1 | Ragdolls: a running Fox crumples at a wall, one falls down stairs, one lies under motor strength |
| scene26.singe | 26 | 26.1 | Soft bodies: a flag, a sheet catching a crate, a swinging rope, a balloon |
| scene27.singe | 27 | - | The Khronos Sponza atrium (Models/Sponza.glb, 18 MB: textures compressed to KTX2 with util/compressTextures.py --etc1s, then packed with util/packGlb.py; 99 MB of texture memory instead of 393 MB) under a sun with cascaded shadows, lit from above by a sky (sky.png) in place of a flat ambient, fog down the nave, the ACES tone curve, six braziers with flame, smoke and dust particles, each crackling in place (crackle.wav from util/makeCrackle.py); no disc, -x 1280 -y 720 -C 1280x720 (screenshots/sponza-nave, -atrium, -gallery and -columns.png are the four stops at 2560x1920) |
| scene28.singe | 28 | - | Materials: roughness and metallic sphere rows before a brick wall with normal, emissive and metallic-roughness maps (brick*.png), each stop a different exposure and tone curve; no disc, -x 1280 -y 720 -C 1280x720 |
| scene29.singe | 29 | - | Animation blending: a Fox crossfading Walk to Run, one walking with Survey on a layer masked to its neck, one easing out of a ragdoll into Survey; no disc, -x 1280 -y 720 -C 1280x720 |
| scene30.singe | 30 | - | Sky and fog: the dragon on its plate and metal spheres under an equirectangular sky (sky.png from util/makeSky.py) lighting the scene, fog down an avenue of posts; no disc, -x 1280 -y 720 -C 1280x720 |
| scene31.singe | 31 | - | Culling and instancing: 400 dragons on a plain, the overlay reporting sceneGetStats and the frame time at four stops; no disc, -x 1280 -y 720 -C 1280x720 |
| scene32.singe | 32 | - | Bloom and views: a monitor showing a security camera's view of the Fox, a rear-view panel from a camera on the Fox, a lamp glowing with bloom, a name tag and icon billboarded over the Fox and a fixed text sign; no disc, -x 1280 -y 720 -C 1280x720 |
| scene33.singe | 33 | - | Navigation: a mesh baked from Sponza's geometry, the path along the nave marked with posts, six Foxes wandering between random points as crowd agents; no disc, -x 1280 -y 720 -C 1280x720 |
| scene34.singe | 34 | - | Terrain: hills from hills.png (util/makeHills.py) with a tiled brick texture from a KTX2 file (brick.ktx2), the dragon placed by terrainGetHeight, crates tumbling on the height field body; no disc, -x 1280 -y 720 -C 1280x720 |
| scene35.singe | 35 | - | Physics debug drawing: physicsSetDebug(DEBUG_ALL + DEBUG_STATIC) over crates, a ball, a hinged bar and a walking player, a ray cast drawn with lineDraw and the baked navigation mesh with navDraw; no disc, -x 1280 -y 720 -C 1280x720 |
| scene36.singe | 36 | 45.1 | GUI over the disc: an RmlUi document (scene36.rml, scene36.rcss over the shipped Singe/gui.rcss) in a GUI the size of the overlay, composited with guiDraw; a nine slice panel from crate.png, a scrolling list, a progress bar animated from RCSS, and a line rewritten each frame with guiSetValue |
| scene37.singe | 37 | 45.2 | GUI on a material: the scene36 document on scene6's arcade monitor through materialSetGui (unlit), a glass ball in front, and the same GUI drawn small over the overlay with guiDraw |
| scene38.singe | 38 | 45.3 | GUI input: a form (text field, slider, select, checkbox, buttons) in a GUI that takes input, guiSetHandler callbacks for click and change, guiSetValue and guiGetValue on the fields; headless it presses Start through RmlUi's Lua API |
| scene39.singe | 39 | 45.4 | GUI pointed at: sceneProbeGui asked for the GUI pixel under the projected corners and centre of the 3D monitor (must match the GUI's corners) and under a point off it (nil); the same probe routes the mouse and light gun to a GUI on a surface |
| scene40.singe | 40 | 46.1 | GUI clip masks: scene40.rml over the disc with a rounded list (border-radius, overflow-y auto) whose rows are clipped to the corners, a panel rotated 8 degrees with overflow hidden and a block larger than it inside, and a rounded child inside a rounded parent (nested masks); the list scrolls through RmlUi's Lua API between the two screenshots |
| scene41.singe | 41 | 46.2 | GUI layers: scene41.rml over the disc with two overlapping opaque squares under filter: opacity(0.5) (the overlap must stay as light as the rest) beside the same pair under the opacity property (it darkens), a panel cut out by mask-image: image(maskFade.png), a group inside a group, and a box-shadow without blur that RmlUi renders through a layer saved as a texture; the script drops the group to opacity(0.25) between the two screenshots |
| scene42.singe | 42 | 46.3 | GUI filters: scene42.rml over the disc with a panel under filter: blur(6dp), text under drop-shadow, a row of squares through grayscale, sepia, invert, hue-rotate(90deg) and saturate(3) beside an unfiltered one, a panel with a soft box-shadow, and a panel under blur(40dp) (the downscaled path); guiGetStats() printed at each screenshot, and both blurs narrowed through RmlUi's Lua API between the two |
| scene43.singe | 43 | 46.4 | GUI gradients: scene43.rml over the disc with a three-stop linear-gradient panel, a radial-gradient disc, a conic-gradient wheel (its starting angle turned through RmlUi's Lua API between the two screenshots), a repeating-linear-gradient stripe, a twenty-stop gradient that trips the sixteen-stop warning once, and the shipped theme's gradient panel, buttons and progress bar |
| scene44.singe | 44 | 47 | Hypseus extensions over the disc: strip.png (five 32x32 frames) through spriteLoadFrames and the three spriteDrawFrame forms side by side (an out of range frame draws frame 1, a still ignores the frame), the sheet as an ordinary animation under spriteSetFrame and spriteDraw, vldpFocusArea on the middle of the frame (frame 60) then off (80), vldpSetMonochrome and overlaySetMonochrome on (90) then off (110), and a status line with vldpGetScale, spriteFrameWidth/Height, vldpGetYUVPixel beside vldpGetPixel and controllerIsValid(0); screenshots at 30, 70, 100 and 120 |
| scene45.singe | 45 | 48.1 | Hypseus parity shims: setOverlaySize preset 1 (the disc, 720x480), 2 (half, 360x240), 4 with a size (640x400), 3 (360x240), 4 with another size (320x240), 4 with none (ignored, still 320x240) and an unrecognised 9 (half again), then setOverlayResolution as the alias of overlaySetResolution (480x320), each redrawn and shot at its new size; setOverlayLinearScale true (170) then false (190) over checker.png, which the window scales four times up; musicLoad/musicPlay/musicStop/musicIsPlaying/musicSetVolume/musicUnload over tone.ogg (a 440 Hz sine); and a status line with scoreBezelGetState (the score panel is left off here; scene47 drives it), rewriteStatus, ratioGetX/Y and musicIsPlaying; screenshots at 20, 40, 60, 80, 100, 120, 140, 160, 180, 200 and 245 |
| scene46.singe | 46 | 48.2 | The video rectangle over the disc inside a Sinden border (`-g '10 5'`): a frame around the very edge of the picture, magenta corner ticks and a cyan crosshair a quarter of the way in, stepped through vldpSetScale 50, 25 and 100 and vldpSetRotate 90, 180, 270 and 0 with a screenshot at each; run three times, plain and with `--shiftx -40 --shifty -40` and `--shiftx 40 --shifty 40`, for the shifted stops, which show only once the scale factor has left room to move in |
| scene47.singe | 47 | 48.3 | Bezels over the disc: cabinet artwork (testScripts/bezels/cabinet.png, 1280x800, with a deliberately off centre 800x500 cutout at 200,120 declared in cabinet.cfg and a yellow ring painted just outside it) with the picture landing exactly in the cutout, a GUI (scene47.rml) drawn on the artwork's left pillar with guiDrawScreen, and the score panel stepped through scoreBezelEnable, credits, two scores, two lives, setOverlayOnTop, scoreBezelClear and a value that lights it again; run five times, plain, with `--bezelflip` (the artwork's corner brackets then cover the picture, and setOverlayOnTop puts the overlay back over them), with `-g '10 5'` (the Sinden border goes to the window's edge), with `-g '10 5' --sindenedge video` (and back around the picture), and with no `--bezel` at all |
| scene48.singe | 48 | 48.4 | User options and the settings file over the disc: a status page of everything a script can see of the new configuration -- `getFValue()`, `ratioGetX()`/`ratioGetY()`, `soundGetVolume()`, `vldpGetScale()`, `controllerIsValid(0)`, `mouseHowMany()` and `singeWantsCrosshairs()` -- with a six colour ramp in the overlay beside the disc, which stays in colour while `--monochrome` greys the disc, and one `controllerDoRumble` so the trace records the step `--haptic` left of it; run plain, with a `settings.cfg` setting several options and the command line overriding one of them, and with `--monochrome`, `--startsilent`, `--altaudio`, `--idleexit`, `--nogamepad` and `--screen 1` |
| scene49.singe | 49 | 48.5 | Input over the disc: every device the engine can see on one page -- the four gamepad slots with the name, the six axis values and the fifteen button states of whatever is in each, the mice ManyMouse found with their names, the last mouse position and how many times `SWITCH_MOUSE_DISCONNECT` has fired, the keyboard mode, and the switches the mappings are currently letting through -- with `DEAD_ZONE`, `TRIGGER_THRESHOLD` (raw and as a per cent of full travel) and `joyMouseIsEnabled()` across the top. The phases are timed on the wall clock (shots at 2, 6, 10 and 16 seconds, quitting at 18) so a device can be attached, pressed and unplugged while it runs; the LD_PRELOAD harness in the scratchpad drives an SDL virtual joystick through exactly that. Run plain, with `--joymouse --js_range 20`, with `--gamepad_reorder 10`, with `--trigger_threshold 99.5`, with `--mapjoysticks=false`, with `--manymouse --absolutes_only`, with a `gamecontrollerdb.txt` beside it, and with a `controls.cfg` setting `DEAD_ZONES` |
| scene50.singe | 50 | 48.6 | Subtitles and the disc picture over the disc: `testScripts/subtitles.srt` (four cues, one of them two lines and one carrying a `<bracket>` and an `&` that must reach the screen as text) parsed into disc frames at the disc's own frame rate and shown through the shipped `Singe/subtitle.rml`, with `testScripts/broken.srt` refused (`srtLoad` answers false and loads nothing); the disc searched to a known frame before every shot so a cue is read off the disc's frame number and not the wall clock; `srtPosition` at 15 and 80 per cent; `overlayBanner` taking the cue's place for thirty drawn frames and then giving it back; `srtEnable` off and on; `srtClear`; `vldpSetLuma` at 0, 8, 4 and off; `vldpSetBlend` on, off and together with the luma; and `vldpFlash`, asked for and shot in the same tick because it lasts one drawn frame. 23 screenshots |
| scene51.singe | 51 | 48.6 | Sprites, in-memory assets and music over the disc: `spriteRotateFrame` turning frames 1 to 4 of `testScripts/arrows.png` (a four frame strip whose arrows have a white notch, so a rotation is readable) at 0, 45, 135 and 225 degrees, drawn by `spriteDrawRotatedFrame` plain, at 1.5 and at 2 by 0.75, beside the same frame through `spriteDrawFrame` which ignores both; `spriteScale` before a rotation, so the pair honours the sprite's own scale; an out of range frame falling back to frame 1; `spriteDrawGrid` taking three rectangles out of the same file loaded as one wide still and a fourth out of a sprite `spriteLoadData` built from the file's bytes; `spriteGetFrames` on all three; `controllerHowMany`; `setOverlayOpacity` at 96 and back to 255; and the music family over `testScripts/tune.mp3` (six seconds of 330 Hz, so the built-in mp3 decoder is exercised) -- play looping, `musicSetVolume` at 128 and 16, `soundSetVolume` at 8 with a `soundLoadData` sound played through it to show the two volumes do not move each other, pause, resume, a 250 ms fade out, a play once and an unload. 16 screenshots |