116 lines
4.1 KiB
Text
116 lines
4.1 KiB
Text
-- A Forge release is standalone (FORGE.md).
|
|
--
|
|
-- Building it is half the test; the half that matters is that the result runs somewhere Forge has
|
|
-- never been. The runtime a compiled game loads is Singe/Author.singe, which whatever Singe the
|
|
-- player has will have extracted -- but a game should not change behaviour because the engine under
|
|
-- it moved on, so a release carries its own copy and loads that instead.
|
|
FORGE_LIBRARY = true
|
|
dofile("Forge/Forge.singe")
|
|
|
|
local font = fontLoad("Singe/FreeSansBold.ttf", 15)
|
|
local out = singeGetDataPath()
|
|
local work = out .. "release.forge"
|
|
local dest = out .. "Released"
|
|
|
|
fontSelect(font)
|
|
fontQuality(FONT_QUALITY_BLENDED)
|
|
overlaySetResolution(720, 480)
|
|
|
|
local source = assert(io.open("testScripts/author/platformer.forge", "r"))
|
|
local copy = assert(io.open(work, "w"))
|
|
|
|
-- With credits, so the release can be checked for them: the fields go to games.dat, the notes to
|
|
-- CREDITS.txt, and the licence file travels with the game.
|
|
copy:write((source:read("a"):gsub("(\n\ttitle%s*=[^\n]*\n)", "%1\tcredits = { developer = \"Test Developer\", year = 1983, notes = { \"Original game: Test Author\", \"Converted by: Test Porter\" }, licenses = { \"LICENSE.txt\" } },\n", 1)))
|
|
source:close()
|
|
copy:close()
|
|
copy = assert(io.open(out .. "LICENSE.txt", "w"))
|
|
copy:write("A licence the release must carry.\n")
|
|
copy:close()
|
|
|
|
if not forgeBegin(work) then
|
|
debugPrint("RELEASE FAIL could not open " .. work)
|
|
singeQuit()
|
|
end
|
|
|
|
local frames = 0
|
|
local stage = 0
|
|
|
|
|
|
local function step()
|
|
if stage == 1 then
|
|
local folder = forgeExport(dest, "Platformer")
|
|
|
|
debugPrint("RELEASE built into " .. tostring(folder))
|
|
|
|
elseif stage == 2 then
|
|
-- Everything a standalone game needs has to be there.
|
|
for _, name in ipairs({ "Platformer.singe", "Author.singe", "games.dat", "Platformer.forge" }) do
|
|
local f = io.open(dest .. "/" .. name, "r")
|
|
|
|
if f == nil then
|
|
debugPrint("RELEASE FAIL missing " .. name)
|
|
else
|
|
f:close()
|
|
end
|
|
end
|
|
debugPrint("RELEASE all four files present")
|
|
|
|
elseif stage == 3 then
|
|
-- And it must load its own runtime, not the engine's.
|
|
local text = assert(io.open(dest .. "/Platformer.singe", "r")):read("a")
|
|
|
|
if text:find('dofile%(here %.%. "Author%.singe"%)') and text:find('debug%.getinfo') then
|
|
debugPrint("RELEASE the game finds its own directory and loads the runtime there")
|
|
elseif text:find('Singe/Author%.singe') then
|
|
debugPrint("RELEASE FAIL the game still loads the engine's runtime, which no longer ships")
|
|
else
|
|
debugPrint("RELEASE FAIL the game does not load a runtime at all")
|
|
end
|
|
|
|
elseif stage == 4 then
|
|
-- The original author's credits: in games.dat for the menu, the notes in CREDITS.txt, and
|
|
-- the licence beside the game.
|
|
local dat = assert(io.open(dest .. "/games.dat", "r")):read("a")
|
|
local credits = io.open(dest .. "/CREDITS.txt", "r")
|
|
local licence = io.open(dest .. "/LICENSE.txt", "r")
|
|
local notes = credits and credits:read("a") or ""
|
|
|
|
if credits then
|
|
credits:close()
|
|
end
|
|
if licence then
|
|
licence:close()
|
|
end
|
|
if dat:find('DEVELOPER = "Test Developer"', 1, true) and dat:find("YEAR = 1983", 1, true) and notes:find("Original game: Test Author", 1, true) and (licence ~= nil) then
|
|
debugPrint("RELEASE the credits travel: games.dat, CREDITS.txt, and the licence")
|
|
else
|
|
debugPrint("RELEASE FAIL credits missing from the release")
|
|
end
|
|
|
|
elseif stage == 5 then
|
|
-- Whether it truly stands alone cannot be answered from in here: DIR is the directory of
|
|
-- the script the engine was *launched* with, so a game reached by dofile would look for the
|
|
-- runtime beside this scene instead of beside itself. A released game is the main script,
|
|
-- which is a different run of the engine. harness/verify.sh launches it with
|
|
-- Singe/Author.singe moved aside and checks it still runs.
|
|
debugPrint("RELEASE RESULT done")
|
|
end
|
|
end
|
|
|
|
|
|
function onOverlayUpdate()
|
|
frames = frames + 1
|
|
if frames % 14 == 0 and stage < 6 then
|
|
stage = stage + 1
|
|
step()
|
|
end
|
|
if frames == 20 or frames == 70 then
|
|
singeScreenshot()
|
|
end
|
|
if frames > 90 then
|
|
singeQuit()
|
|
end
|
|
|
|
return OVERLAY_UPDATED
|
|
end
|