SINGE 3.00 ========== Unreleased API Changes ----------- - --gamedir names the directory holding the games, the .game files and the Singe support folder, so the executable can live anywhere. It becomes the working directory; relative names count from it. The Menu.sh the engine writes there runs the executable by its full path. - Without --datadir the data directory is now data/ in the game directory (2.x wrote beside the game, which may be read only). The menu's Menu.sh no longer needs to pass -d data. - math.randomseed accepts fractional seeds (floored), so 2.x games that seed with os.clock() products run under Lua 5.4. - A script launched by name (or by its directory) runs with its games.dat entry, as the menu would run it: Singe finds the games.dat in the script's directory or up to three above, and applies the entry whose SCRIPT names the script, LEGACY_SPRITE_ARGS included. Options typed on the command line keep their values. Every game in a library therefore behaves the same whether it was started from the menu or from a shell. - The name now expands to "SINGE Is Not a Game Emulator", in the banner, the manual, INSTALL, and the Windows file description. - Framework.singe applies the legacy sprite argument order once even when a game loads it more than once. - lfs.dir, lfs.attributes and lfs.symlinkattributes see inside a packed game (the union of its loose directory, its data overlay and the database), and lfs.mkdir and lfs.rmdir act on its data overlay, so frameworks that list or create their own directories work packed. - Physics. Any scene node can carry a rigid body on Jolt Physics: static, kinematic (follows its node and pushes) or dynamic (drives its node), shaped as a box, sphere, capsule, cylinder, a convex hull of the node's mesh or the mesh's triangles; mass, friction, bounce, velocities, forces and impulses; triggers; hinge, ball and slider joints with limits; a raycast; onCollision and onTrigger callbacks. The world steps at a fixed 60 Hz between animation and rendering and pauses with the game. physicsSet2D keeps bodies in a plane for 2D games, which need no GPU (nodes now exist on every machine, so a Raspberry Pi 3 gets 2D physics without 3D). New calls: body*, joint*, physics*, and the BODY_*, SHAPE_* and JOINT_* constants; see the Physics chapter. Needs SSE4.1 on x86 (2008 and later); the engine's first C++ (one wrapper file and the library), statically linked, no runtime to install. - Soft bodies. softNew makes cloth or a pressure body from a node's mesh (particles from its welded vertices, Jolt's stretch, shear and bend constraints, pressure for balloons) or a rope from the node to a point with a tube mesh the engine makes; they collide with everything rigid and the mesh is rewritten every frame. softPin holds particles in place or to nodes; stiffness, mass, damping and pressure are tunable. meshPlane takes subdivisions; nodeSetMaterial changes a material without the mesh. New calls: soft*, and the SOFT_* constants; see Soft bodies in the Physics chapter. - Ragdolls. ragdollNew derives capsules and swing-twist joints from a skinned model's skeleton; ragdollActivate hands the skeleton to physics from its current pose and the mesh follows the bones as it falls; motors (ragdollSetStrength) pull it back toward that pose; ragdollApplyImpulse shoves a bone; ragdollDeactivate returns it to animation. New calls: ragdoll*; see Ragdolls in the Physics chapter. - Water. bodySetWater fills a static body with water: dynamic bodies inside float, sink and drift by Jolt's buoyancy against its surface, with drag and a current (bodySetCurrent, bodySetBuoyancy per body); players swim in it (playerIsSwimming, playerSetSwim, three-axis playerMove); a buoyant hull with vehicleNew(node, VEHICLE_BOAT) gets a propeller and a rudder (vehicleSetThrust, vehicleSetRudder). - Vehicles. A dynamic body becomes a car, a motorcycle or a tank on Jolt's vehicle constraint: wheels are nodes the engine poses (spin, steer, suspension), the script drives with throttle, steering, brake and hand brake, and engine, gears, suspension, steering, brakes and anti-roll bars are tunable. Motorcycles lean and balance with a spring scaled to the chassis; tanks pivot on the spot. New calls: vehicle*, and the VEHICLE_* constants; see Vehicles in the Physics chapter. - Point lights inside geometry. A bulb in a closed room, under a shade or inside a cabinet now shadows correctly: cube faces render depth two-sided so closed meshes cast from inside, every shadow tap picks its own cube face so the seams along the cube edges are gone, the depth range fits the casters round the light instead of the scene centre, the bias grows with distance and grazing angle, and each face draws only what it can see. nodeSetShadow excuses a mesh from casting. - Character controller. playerNew puts Jolt's CharacterVirtual on a node, as a capsule or any convex bodyNew shape: it walks where playerMove says, climbs steps, slides along walls, refuses steep slopes, falls, jumps from the ground, rides kinematic platforms and shoves light dynamic bodies; onCollision and onTrigger report it like a body. Works in 2D worlds as a platformer character, with tolerances scaled to the shape. New calls: player*; see Players in the Physics chapter. - Linear lighting. The scene is lit in linear light on a 16-bit float target and brought to the screen by a post pass with an exposure control (sceneSetExposure, in stops) and a tone curve (sceneSetTonemap: TONEMAP_NEUTRAL, TONEMAP_ACES, TONEMAP_NONE). Colours given as 0-255 are sRGB and decoded on the way in; textures are sampled as sRGB; bright light compresses instead of clipping. Specular highlights are GGX with Fresnel, so roughness and metallic behave as they do in glTF viewers. Existing scenes look a little different: the same numbers now mean what they mean everywhere else. - GUI. Menus, HUDs and option pages can be RmlUi documents: HTML-like RML styled by CSS-like RCSS, with layout, text wrapping, nine-slice panels from the game's own artwork, transitions, animations, form controls and a focus model a gamepad can drive. guiNew(width, height) makes a GUI rendered to its own texture every frame; guiLoad puts a document in it (names through the vfs like spriteLoad, so packed games work), with guiShow, guiHide and guiClose; guiDraw composites it over the overlay in overlay coordinates (through the Sinden border and the overscan scale like the overlay itself), and materialSetGui shows it on a material in the scene, where sceneProbeGui gives the GUI and pixel under an overlay point. guiSetInput routes the mouse and light gun, keys, typed text (SDL text input runs while a field has focus) and a pad's switches (directions as arrows, ACTION_1 as Return, ACTION_2 as Escape) to a GUI; what an element uses never reaches onInputPressed or onKeyPressed, and the rest falls through as before. guiSetHandler calls a Lua function for an element's click, change or submit; guiGetValue and guiSetValue read and write a control's value or an element's inner RML; guiLoadFont adds a face for every GUI. RmlUi's own Lua API runs on the game's state: rmlui.contexts["gui0"] and its documents, a document's