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.
