-- Forge: a game's own vocabulary. The description names a file of looks, behaviours, -- conditions, and actions that this game alone knows; the editor offers them while the game is -- open and forgets them when it closes; the compiler checks against them; the built game -- loads them and plays by them. FORGE_LIBRARY = true dofile("Forge/Forge.singe") local font = fontLoad("Singe/FreeSansBold.ttf", 18) fontSelect(font) fontQuality(FONT_QUALITY_BLENDED) local work = singeGetDataPath() .. "vocab.forge" -- The editor: the vocabulary is there while the game is open, and gone when it is closed. authorCopy("testScripts/author/vocab.forge", work) authorCopy("testScripts/author/vocab.singe", singeGetDataPath() .. "vocab.singe") if not forgeBegin(work) then debugPrint("VOCAB FAIL the editor could not open the game") end if AUTHOR.behaviours.bob and AUTHOR.conditions.bobbing and AUTHOR.actions.setBob then debugPrint("VOCAB the editor knows the game's own bob, bobbing, and setBob") else debugPrint("VOCAB FAIL the editor did not load the game's vocabulary") end local built = forgeBuild(singeGetDataPath() .. "vocabGame.singe") local file = built and io.open(singeGetDataPath() .. "vocabGame.singe", "r") local text = file and file:read("a") or "" if file then file:close() end if text:find('authorVocabulary("vocab.singe")', 1, true) then debugPrint("VOCAB the built game loads the vocabulary") else debugPrint("VOCAB FAIL the built game does not name the vocabulary") end forgeClose() if AUTHOR.behaviours.bob or AUTHOR.conditions.bobbing or AUTHOR.actions.setBob then debugPrint("VOCAB FAIL closing the game did not forget its vocabulary") else debugPrint("VOCAB closing the game forgot its vocabulary") end -- The game: built and played, the buoy bobs and the rules use the game's own words. dofile(singeGetDataPath() .. "vocabGame.singe") local gameUpdate = onOverlayUpdate local frames = 0 local lowest = 1000 local highest = 0 local lowest2 = 1000 local highest2 = 0 function onOverlayUpdate() frames = frames + 1 local r = gameUpdate() local buoy = authorEntity("buoy") local rock = authorEntity("rock") local _, by = authorPosition(buoy) local _, ry = authorPosition(rock) if frames <= 90 then lowest = math.min(lowest, by) highest = math.max(highest, by) elseif frames > 92 then lowest2 = math.min(lowest2, by) highest2 = math.max(highest2, by) end if frames == 91 then authorKeyDown(0, SCANCODE.SPACE.value) elseif frames == 60 then singeScreenshot() elseif frames == 180 then debugPrint(string.format("VOCAB RESULT buoy %.0f..%.0f then %.0f..%.0f, rock at %.0f, seen %d frames bobbing", lowest, highest, lowest2, highest2, ry, AUTHOR_VARS.seen)) if (highest - lowest) < 60 or (highest - lowest) > 82 then debugPrint("VOCAB FAIL the buoy did not bob 40 either way") end if (highest2 - lowest2) < 150 then debugPrint("VOCAB FAIL setBob did not raise the bob to 100") end if math.abs(ry - 240) > 1 then debugPrint("VOCAB FAIL the rock moved") end if AUTHOR_VARS.seen < 170 then debugPrint("VOCAB FAIL the bobbing condition was not true every frame") end singeQuit() end return r end