forge/CHANGELOG
2026-10-06 16:57:52 -05:00

241 lines
14 KiB
Text

FORGE 1.00
==========
Unreleased
New Features
------------
- Forge is a project of its own, apart from Singe. ./build.sh renders the
book and packs Forge.game with whichever Singe binary it is pointed at,
and testScripts/run.sh runs Forge's tests against the same binary. Forge
needs Singe 3.00 or later.
- A Forge game says who made it. The game's form has credits fields --
developer, publisher, year, platform, genre, creator, source, and
description -- and a release writes them into its games.dat, where the menu
shows them. Notes go into a CREDITS.txt beside the game, and licence
files named in the credits travel with it. A port of an existing game gets
its original author's credits filled in from the original's own games.dat
and script header.
- A game can be sent to the master service for review from Forge. Shift+P
in the editor exports, packs, and uploads it; an upload is not in the catalogue
until it has been reviewed, and Forge shows where each version of yours
stands. Behind it: singePack(directory, database) packs a game from
a script exactly as --pack does, and the network layer can send a request
body straight from a file, so a game is never held in memory whole.
- Forge gives every description a permanent GAME_ID the first time it is saved
and writes it into the games.dat it exports, so a Forge game can be
published and updated.
- Forge can judge a shot by the picture rather than by a hitbox. lightSensor
is a behaviour of the framework now, the way a home laserdisc gun works: a
spot on the picture flashes on the frames a target is shown, and a shot is
good when the picture under the gun changes the way the spot does. It began
as five games' own vocabulary and was general all along, so it moved in, and
those five name no vocabulary of their own any more. pictureAt came with it,
a condition any rule can ask -- is the picture at this point bright, dark, or
neither -- for a flash hidden in a game's own video, a colour cue, or a lamp
in a scene; a game with no disc reads dark everywhere. Both are in the
book's vocabulary tables, which are generated from the manifest, and scene
100 covers them.
- Publishing from Forge writes a new file beside the old one and releases
the old copy only once the new one is in place, so an interrupted write
cannot lose either.
- Forge has tutorials: ten sittings at the front of Forge.pdf, each
ending with a game that plays, with the kit of pictures, sounds, a clip,
and a model they use packed in Forge.game, and the finished description
of each in the chooser. Each tutorial's scene presses the keys the text
names and checks the result, so the book cannot drift from the editor.
On the way the editor gained the game's own form (title, players, vars,
verbs, layers, and each layer's parameters), the digits as panel keys,
DELETE to empty a field, X to release a game with every file it names,
a file picker that keeps an unset field unset, and a panel that steps
aside while a polygon is drawn. What an entity is made from is now a
type, not a kind: types = { hero = ... } in a description, type = "hero"
on an entity and in an event's filter, and the Types panel. Forge's
launcher takes every key (MODE_FULL), so ENTER and TAB reach it, and
its panel's rows and fields take clicks. A value is edited in place:
it starts selected, so typing replaces it, and the arrows put a caret
into it. A field whose values are a fixed set opens a dropdown of them
-- true and false, the scancodes, the switches, the looks, the events,
the words a parameter takes, the game's own types, rooms, entities,
states, tracks, and nodes -- opened on the value it has, under its own
row, upward when there is no room below. The panel's list and fields
box scroll, with bars, and keep the chosen row in view. The game's
name at the top of the panel, or a press on empty canvas, brings the
game's own form back. A waves track (W in the tracks) spawns a type
by count and interval at a moment, a disc frame, or a rail camera's
stop, from an entity or a list of them in turn, or at a point; and
soundDone says when a clip playSound or a sound behaviour started has
ended. Ports of the test library began (FORGE.md section 14): the
five light gun games of the VHS era are Forge descriptions written by
a porting script, and play the same as the emulator under
the same inputs (testScripts/ports/). On the way: a lightSensor
behaviour, a pointer behaviour, fonts and anchors on the text look,
sprites drawn in copies, discPlay and discPause, pointerX and pointerY
in expressions, an event belonging to the room it happened in, and a
built game finding files beside its description. A game can bring a
vocabulary of its own: a description names a file of Lua
(vocabulary = "Vocabulary.singe") that adds looks, behaviours,
conditions, actions, layers, or events to the manifest for that game
alone; the editor loads it when the game opens and forgets it when
the game closes, the compiler checks against it, and the built game
carries it into a release. Their light sensor lives in one now,
beside those five games, and not in Forge. The Hypseus library's
eleven Karis Framework 3.32b titles are ported by the same converter, which
finds the framework where a game keeps it and notes its version; the
rest of that library is surveyed in FORGE.md 14.9. A branch on the
branching track can want its move mashed (mash = 6) or held (hold =
20). The seven Kimmy Script Engine titles are ported by the same
converter and a kimmy behaviour that
plays that engine's loop, and play as their originals do (FORGE.md
14.11).
util/forgePorts.py
assembles the ported games into a project folder of their own
(~/claude/singePorts), one game to a folder with its description, the
compiled port, the runtime, its files, and a games.dat. A description is a
.forge file now (it was .game, which is the packed release's, and the
chooser had to sniff which was which). The seventeen KarisFramework
games are ported too: util/forgePortKaris.lua reads a game's own
script, and the qte behaviour plays the framework's loop over the
framework's tables, running the game's script and add-ons in a shim;
every one plays as its original under the same driver. Flat
bodies are the size their looks are drawn at (they were half), and a
platformer stands on its point.
- A game can be described rather than written. Forge/Author.singe and
Forge/AuthorCompile.singe take a table of layers, entities, behaviours
and rules and compile it into an ordinary Singe game: the rules become
real Lua, so nothing walks a table every frame and the result can be
read and edited by hand. There is no notion of genre in it -- a game
declares which of the engine's layers it uses, and that is the whole
difference between a platformer and a quick-time event over video. The
vocabulary of conditions and actions is declared in a table rather than
built into the compiler, so new kinds of game are entries rather than
releases, and the "lua" action is the deliberate way out when a rule
needs something the vocabulary cannot say. See the manual.
- Forge runs as a game rather than only as a library: started from the
menu it opens on a chooser (its own descriptions, a new game from a
starter, a copy of anything dropped into its directory), the keys, the
mouse and the pad reach the editor, P saves, builds and plays what is on
screen and comes back to it, and ESC closes or leaves. Entities can be
added, duplicated, deleted and typed field by field -- position, look,
behaviours and their parameters, all from the manifest -- and renaming
one renames it in every rule. Conditions and actions are picked from
the vocabulary with their help beside them, rules reorder, a rule's
note is editable, and U undoes forty steps. The compiler loads the
runtime from Forge/, where it lives, so it no longer fails looking for
a Singe/Author.singe that never shipped.
- An editor for those descriptions, Forge, which is itself
a Singe game: the canvas is the same overlay at the same coordinates the
game will be played in, so what is placed is what is seen. Entity list
and details are an RmlUi document, the canvas beside them is drawn into
the overlay and picked the way a light gun game picks a target, and the
two compose because a button is offered to the GUI first while pointer
motion is never consumed. A description survives a round trip through
it: load, save, load again, and it compiles to the same game. Forge is
distributed on its own and no part of it ships inside Singe -- not the
editor, not the compiler, not the runtime. A game Forge builds carries
its own copy of that runtime, so it runs on a machine that has never had
Forge on it and cannot change behaviour because the engine moved on.
- A game released from Forge is standalone. forgeExport writes the
compiled script, a games.dat, the description it came from and a copy of
the runtime into a directory of its own, taken out of Forge. --pack turns
that directory into a .game. The game locates its own directory with
debug.getinfo rather than trusting DIR, which names the directory of the
script the engine was launched with -- not this one when a game is reached
by dofile.
- The editor edits rules, not only entity positions: Tab swaps the panel
between the entities and the event sheet, the selected rule opens in
place with its conditions and actions under it, and conditions and
actions are added from the same manifest the compiler reads, so the rule
editor needs no change when the vocabulary grows. It is driven by keys
as well as the pointer, which is how the bundled menu has always worked
and what a cabinet needs. ENTER types a value into the selected
condition or action and moves to its next one, ESC puts it back; a
number typed in comes back a number.
- Forge's description format is new (FORGE.md section 4): kinds with
instances, rooms that remember themselves, rules triggered by events
(collisions between kinds, hits, deaths, timers, disc frames) as well as
every frame, vars and states on every instance, expressions where a
number goes, any-of groups, timers, sound, a HUD document bound to vars,
actions that take time run as coroutines, and hitbox tracks keyed to
disc frames or time. A shoot-em-up and a light gun game over video
prove it (testScripts/author, scenes 58 and 59). The editor gained
kinds, rooms, event pickers, and a timeline that scrubs the disc's video
under the cursor (scene 60). Nothing of the first slice's format loads;
it was never released.
- Forge builds 3D games (FORGE.md section 5): a scene3d layer, model,
mesh, light, billboard, and text looks, the character controller moving
relative to a camera that is fixed, follows, orbits, sits in first
person, or rides a rail of points with stops, enemies that seek, an
animator playing a clip per state, targets with zones on named bones so
a gun's ray says which part it hit, ragdolls on death, bodies and
triggers. A rail shooter in the manner of House of the Dead and a 3D
platformer prove it (scenes 61 and 62), and the editor shows a 3D room
as the scene itself under an orbiting camera (scene 63).
- Forge builds adventure games (FORGE.md section 6): rooms that remember
themselves, walk areas baked to a navigation mesh in a painted room or
a modelled one, hotspots, a verb line and a text parser with the most
specific rule winning, an inventory, dialogue trees, cut-scenes across
rooms with fades, depth sorting and scaling, and whole-game saves. The
same rules run a two-room adventure in 2D and in 3D (scenes 64 and 65).
- Forge builds racing games and tower defences (FORGE.md section 7):
vehicles on the engine's vehicle physics with an opponent that drives a
track on its own, walkers that follow a target or patrol a lane, turrets
that fire at what is in range, instances placed by a click on the floor,
thrust, and hinge, ball, and slider joints (scenes 66 and 67).
- Forge builds branching video games and carries the arcade plumbing
(FORGE.md section 8): windows on the disc that want a move, with the
disc sent to a success or a failure clip, the score bezel mirroring the
game's vars, coins, continues, a results card with the best score kept,
and scores sent to the master service's board (scene 68).
- Forge's editor gained a search in every picker, a file picker for any
field that names a file, polygon drawing for walk areas and hotspot
outlines, a dialogue outline panel, and play-from-this-room (FORGE.md
section 9, scene 69).
- Forge's long tail (FORGE.md section 10): sprite sheets stepped by
state, tile maps from a sheet, MIDI notes as events, water that bodies
float in, boats under their propellers, and soft bodies (scenes 70 and
71). Every kind of game in FORGE.md's catalogue now has its vocabulary.
- Forge's sprites turn (a var, a spin behaviour, or a projectile aiming
along its flight), a particles look streams from an instance, the
checker names misspelt fields, and 2D particle bursts are drawn at all
(they never had been).
- Forge builds painted rooms in 3D with occluders, and its 3D viewport
gained axis gizmos with a turn handle; entities carry a rotation, and
a sprite faces left through a frame range of its own (FORGE.md section
12, scenes 70, 79, and 80).
- Forge's catalogue is written out (FORGE.md section 11): a first-person
shooter, breakout, a maze, third-person action, a space shooter, a
rhythm game, and bowling join the samples (scenes 72 to 78), and what
they found is fixed: a gun's ray passes through what is not a target,
events raised while the first room is built reach the rules, and a
rule on a key or a room can run once per instance of a kind.
- Forge has its own manual, docs/Forge.adoc, built to Forge.html and
Forge.pdf beside the Singe manual; the engine's manual keeps a pointer.
The build packs Forge.game itself, with the manual and four samples
that need no art inside, and Forge's first run copies Forge.pdf out to
its data directory and says where.
R redoes what U undid, forty steps deep.