-- The long tail (FORGE.md milestone 7), in 2D: a sprite sheet's frames stepped by state, a -- grid of tiles drawn from a sheet, and MIDI notes reaching the rules as an event. dofile("Forge/AuthorCompile.singe") local font = fontLoad("Singe/FreeSansBold.ttf", 18) fontSelect(font) fontQuality(FONT_QUALITY_BLENDED) dofile(authorBuild("testScripts/author/tail.game", singeGetDataPath() .. "tail.singe")) local gameUpdate = onOverlayUpdate local frames = 0 local seen = {} local leftSeen = {} local shots = 0 function onOverlayUpdate() local runner = authorEntity("runner") local t = authorTime() frames = frames + 1 if frames == 2 then authorKeyDown(0, SCANCODE.RIGHT.value) elseif frames == 45 then authorKeyUp(0, SCANCODE.RIGHT.value) authorKeyDown(0, SCANCODE.LEFT.value) elseif frames == 60 then authorMidi(0x90, 60, 100) authorMidi(0x91, 64, 90) authorMidi(0x80, 60, 0) end if frames > 48 then leftSeen[runner.vars.frame] = true else seen[runner.vars.frame] = true end local r = gameUpdate() colorForeground(255, 255, 255, 255) fontPrint(12, 450, string.format("authored long tail, %.1fs, frame %d, %s", t, runner.vars.frame, runner.vars.state)) if (shots == 0 and frames == 20) or (shots == 1 and frames == 70) then shots = shots + 1 singeScreenshot() end if frames > 90 then local distinct = 0 for _ in pairs(seen) do distinct = distinct + 1 end local floor = authorEntity("floor") local w, h = authorSize(floor) debugPrint(string.format("TAIL RESULT frames=%d state=%s score=%d notes=%d grid=%dx%d", distinct, runner.vars.state, AUTHOR_VARS.score, AUTHOR_VARS.notes, w, h)) if distinct < 3 then debugPrint("TAIL FAIL the walk cycle did not step through its frames") end local leftOnly = true for frame in pairs(leftSeen) do if frame > 2 then leftOnly = false end end debugPrint("TAIL facing left used only the walkLeft frames: " .. tostring(leftOnly)) local spinner = authorEntity("spinner") debugPrint(string.format("TAIL the spinner began at 45 and is at %.0f degrees; the fire has an emitter: %s", spinner.vars.angle, tostring(authorEntity("fire").emitter ~= nil))) if spinner.vars.angle < 100 then debugPrint("TAIL FAIL the spinner did not turn") end local problems = authorCheck({ types = { thing = { look = { kind = "box", widthh = 3 }, behaviours = { { kind = "drift", vxx = 1 } } } }, rooms = { { name = "r", entities = {} } }, rules = { { on = "pressed", keyy = "A" } } }) debugPrint("TAIL the checker names " .. #problems .. " misspelt fields: " .. table.concat(problems, " | ")) if #problems ~= 3 then debugPrint("TAIL FAIL expected three misspellings to be named") end if not leftOnly then debugPrint("TAIL FAIL facing left drew frames outside walkLeft") end if AUTHOR_VARS.score ~= 10 or AUTHOR_VARS.notes ~= 2 then debugPrint("TAIL FAIL the notes were not counted: score " .. AUTHOR_VARS.score .. " notes " .. AUTHOR_VARS.notes) end if w ~= 160 or h ~= 96 then debugPrint("TAIL FAIL the grid is not 5 by 3 tiles of 32") end singeQuit() end return r end