diff --git a/.donotrelease/BUILDS/Binaries/prepackaged binaries b/.donotrelease/BUILDS/Binaries/prepackaged binaries new file mode 100644 index 0000000..e69de29 diff --git a/.donotrelease/BUILDS/LOVE/standalone love files b/.donotrelease/BUILDS/LOVE/standalone love files new file mode 100644 index 0000000..e69de29 diff --git a/.donotrelease/RESOURCES/hq assets here b/.donotrelease/RESOURCES/hq assets here new file mode 100644 index 0000000..e69de29 diff --git a/.luarc.json b/.luarc.json new file mode 100644 index 0000000..b2acbb2 --- /dev/null +++ b/.luarc.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://raw.githubusercontent.com/sumneko/vscode-lua/master/setting/schema.json", + "runtime.version": "LuaJIT", + "diagnostics.globals": [ + "love" + ], + "workspace.library": [ + "${3rd}/love2d/library" + ], + "workspace.checkThirdParty": false +} \ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..f03953d --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,5 @@ +{ + "recommendations": + ["tomblind.local-lua-debugger-vscode", + "sumneko.lua",] +} diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..f9b3759 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,28 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "type": "lua-local", + "request": "launch", + "name": "Debug", + "program": { + "command": "love" + }, + "args": [ + ".", + "debug" + ], + }, + { + "type": "lua-local", + "request": "launch", + "name": "Release", + "program": { + "command": "love" + }, + "args": [ + ".", + ], + }, + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..a156b19 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,12 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Build with LÖVE-Build", + "type": "shell", + "command": "love-build", // Path to Love-build + "args": [".main.lua"], + "group": "build", + } + ] +} \ No newline at end of file diff --git a/assets/icon.png b/assets/icon.png new file mode 100644 index 0000000..086bbac Binary files /dev/null and b/assets/icon.png differ diff --git a/build.lua b/build.lua new file mode 100644 index 0000000..a451794 --- /dev/null +++ b/build.lua @@ -0,0 +1,17 @@ +return { + -- basic settings: + name = 'Jeopardy', -- name of the game for your executable + developer = 'Ryan Ward', -- dev name used in metadata of the file + output = 'bin', -- output location for your game, defaults to $SAVE_DIRECTORY + version = '1.0.2', -- 'version' of your game, used to name the folder in output + love = '11.5', -- version of LÖVE to use, must match github releases + ignore = {'bin', 'love', 'server_test', '.gitignore', '.gitmodules', 'build.lua', 'login_dialog.yaml', 'package.bat', 'README.md'}, -- folders/files to ignore in your project + icon = 'assets/icon.png', -- 256x256px PNG icon for game, will be converted for you + + -- optional settings: + use32bit = false, -- set true to build windows 32-bit as well as 64-bit + identifier = 'net.ddns.epicknex.jeopardy', -- macos team identifier, defaults to game.developer.name + libs = {}, + hooks = {}, + platforms = {'windows', --[['macos', 'linux', 'steamdeck']]} -- set if you only want to build for a specific platform +} \ No newline at end of file diff --git a/gui b/gui index fa06733..79ad2b8 160000 --- a/gui +++ b/gui @@ -1 +1 @@ -Subproject commit fa0673374761b2602c9bc6dd053d943a76fd9f31 +Subproject commit 79ad2b839b4e7138ea4babedbe4acf35e735991b diff --git a/login_dialog.yaml b/login_dialog.yaml deleted file mode 100644 index 71324cf..0000000 --- a/login_dialog.yaml +++ /dev/null @@ -1,59 +0,0 @@ -# login_dialog.yaml -type: frame -x: 0 -y: 0 -scale-size: [0.4, 0.25] -scale-pos: [0.3, 0.2] -color: "#1e1e2e" -border-color: "#4a4a6a" -roundness: 12 - -children: - - type: label - text: "Sign In" - x: 0 - y: 20 - scale-size: [1.0, 0.0] - h: 48 - align: center - font: 28 - text-color: "#cdd6f4" - - - type: textbox - x: 30 - y: 90 - scale-size: [0.85, 0.0] - h: 36 - text: "" - color: "#313244" - border-color: "#6c7086" - text-color: "#cdd6f4" - font: 14 - on-return: "focusPassword" - - - type: textbox - x: 30 - y: 140 - scale-size: [0.85, 0.0] - h: 36 - text: "" - color: "#313244" - border-color: "#6c7086" - text-color: "#cdd6f4" - font: 14 - on-return: "submitLogin" - - - type: button - text: "Log In" - align: "center" - fit-font: true - x: 30 - y: 200 - scale-size: [0.2, 0.0] - h: 40 - color: "#89b4fa" - text-color: "#1e1e2e" - roundness: 8 - on-pressed: "submitLogin" - on-enter: "highlightButton" - on-exit: "unhighlightButton" \ No newline at end of file diff --git a/main.lua b/main.lua index 8b57cb6..62617f7 100644 --- a/main.lua +++ b/main.lua @@ -49,12 +49,16 @@ local old = multi.error multi.error = function(self, err) loadLog:error("Error: %s", err) + loadLog:error(debug.traceback()) love.quit() end function love.load() loadLog:info("Starting Jeopardy Game") loadLog:debug("Setting game identity to jeopardy") + for i,v in ipairs(color.listColors(showAllColors)) do + loadLog:debug("Indexed color %s",v) + end love.filesystem.setIdentity("jeopardy") loadLog:trace("Creating save directory") success = love.filesystem.createDirectory("") diff --git a/menus/board.lua b/menus/board.lua index 4f611aa..7fee5f5 100644 --- a/menus/board.lua +++ b/menus/board.lua @@ -28,21 +28,18 @@ local boardLog = log:child("board") boardLog:debug("Creating resize fonts handler") local function resizeFonts() -- Use multi-threading to improve performance - multi:newThread(function() - -- Introduce a small delay to avoid too many iterations at once - thread.skip(2) - -- Iterate over each element in the 'manage' table - for i = 1, #manage do - local elem = manage[i] + thread.skip(2) + -- Iterate over each element in the 'manage' table + for i = 1, #manage do + local elem = manage[i] - -- Check if the current element has a centerFont property - if elem.centerFont then - -- Adjust font size and re-center the text - elem:fitFont(nil, nil, {scale = 2/3}) - elem:centerFont() - end + -- Check if the current element has a centerFont property + if elem.centerFont then + -- Adjust font size and re-center the text + elem:fitFont(nil, nil, {scale = 2/3}) + elem:centerFont() end - end) + end end gui.Events.OnResized(resizeFonts) @@ -239,17 +236,12 @@ function Menu(frame, path) label.color = color.bg label.textColor = color.status_font label:setRoundness(20,20,60) - - boardUpdater:newThread(function() - local test = function() - return label.text ~= "" - end - while true do - thread.hold(test) - label:centerFont() - label:fitFont(nil, nil, {scale = 2/3}) - end - end) + local updateLabel = function() + label:fitFont(nil, nil, {scale = 2/3}) + label:centerFont() + end + boardUpdater:newThread(updateLabel) + gui.Events.OnResized(updateLabel) local data = loader:new(path) board, question, dailydouble = qframe:newFrame(), qframe:newFrame(), qframe:newImageLabel("assets/images/double.jpg") @@ -409,7 +401,7 @@ function Menu(frame, path) boardUpdater:newThread("QuestionUpdater",function() while true do template.update(dt) - thread.yield() + thread.sleep(.1) if self.text == "" then return end end end) @@ -460,19 +452,33 @@ end function ScoreBoard(frame, x, y, w, h, sx, sy, sw, sh) -- Colors - local C_BG_PANEL = color.new("#1a1a2e") - local C_BG_HEADER = color.new("#16213e") - local C_ACCENT = color.new("#e94560") - local C_ROW_TOP = color.new("#1c2641") - local C_ROW_NORM = color.new("#121226") - local C_BORDER_TOP = color.new("#323c6e") - local C_BORDER_NRM = color.new("#1c1c37") - local C_BAR_EMPTY = color.new("#232341") - local C_TEXT_MUTED = color.new("#786e96") - local C_WHITE = color.new("#ffffff") - local C_GOLD = color.new("#ffd700") - local C_SILVER = color.new("#C0C0C0") - local C_BRONZE = color.new("#cd7f32") + color.indexColor("scoreboard_panel_bg", "#1a1a2e") + color.indexColor("scoreboard_header_bg", "#16213e") + color.indexColor("scoreboard_accent_color", "#e94560") + color.indexColor("scoreboard_row_top_bg", "#1c2641") + color.indexColor("scoreboard_row_norm_bg", "#121226") + color.indexColor("scoreboard_border_top_color", "#323c6e") + color.indexColor("scoreboard_border_nrm_color", "#1c1c37") + color.indexColor("scoreboard_bar_empty_color", "#232341") + color.indexColor("scoreboard_text_muted_color", "#786e96") + color.indexColor("scoreboard_pure_white", "#ffffff") + color.indexColor("scoreboard_precious_gold", "#ffd700") + color.indexColor("scoreboard_precious_silver", "#C0C0C0") + color.indexColor("scoreboard_precious_bronze", "#cd7f32") + + local C_BG_PANEL = color.scoreboard_panel_bg + local C_BG_HEADER = color.scoreboard_header_bg + local C_ACCENT = color.scoreboard_accent_color + local C_ROW_TOP = color.scoreboard_row_top_bg + local C_ROW_NORM = color.scoreboard_row_norm_bg + local C_BORDER_TOP = color.scoreboard_border_top_color + local C_BORDER_NRM = color.scoreboard_border_nrm_color + local C_BAR_EMPTY = color.scoreboard_bar_empty_color + local C_TEXT_MUTED = color.scoreboard_text_muted_color + local C_WHITE = color.scoreboard_pure_white + local C_GOLD = color.scoreboard_precious_gold + local C_SILVER = color.scoreboard_precious_silver + local C_BRONZE = color.scoreboard_precious_bronze -- Config stuff local LEADER_HEIGHT_SCALE = .06 @@ -572,14 +578,13 @@ function ScoreBoard(frame, x, y, w, h, sx, sy, sw, sh) remove_player:setFont(20) remove_player.align = gui.ALIGN_CENTER local embededWatch = {remove_player} - scoreUpdater:newThread(function() - while true do - thread.sleep(.01) - for i,v in pairs(embededWatch) do - v:centerFont() - end + + gui.Events.OnMousePressed(boardUpdater:newFunction(function() + for i,v in pairs(embededWatch) do + v:centerFont() + v:centerFont() end - end) + end)) local function embedTextEdit(reference, default, but_text, callback) reference.color = C_BORDER_NRM diff --git a/menus/title.lua b/menus/title.lua index a9d1008..388ebe4 100644 --- a/menus/title.lua +++ b/menus/title.lua @@ -80,7 +80,8 @@ function Menu(frame) end end) - quit:OnReleased(function() + quit:OnReleased(function(self, x, y) + print("Quit Pressed",x,y,self:getAbsolutes()) titleLog:debug("Quit button pressed") local f = frame:newFrame() f:fullFrame() diff --git a/templates/whatis.lua b/templates/whatis.lua index 5107de6..6a5458d 100644 --- a/templates/whatis.lua +++ b/templates/whatis.lua @@ -32,10 +32,11 @@ local function index(window, q, callback) end, },correct,wrong,skip) label:setFont(60) + -- label:centerFont() end local function update(dt) -- time in seconds that has passed since - label:centerFont() + end return { diff --git a/test_logger.lua b/test_logger.lua deleted file mode 100644 index ff10c74..0000000 --- a/test_logger.lua +++ /dev/null @@ -1,197 +0,0 @@ ---- test_logger.lua — Demonstrates and tests all logger.lua features - --- Adjust path if needed -package.path = "./?.lua;" .. package.path -local Logger = require("utils/logger") - -local PASS = 0 -local FAIL = 0 - -local function test(label, cond) - if cond then - print(string.format(" [PASS] %s", label)) - PASS = PASS + 1 - else - io.stderr:write(string.format(" [FAIL] %s\n", label)) - FAIL = FAIL + 1 - end -end - -print("━━━ logger.lua test suite ━━━\n") - --- ── 1. Basic levels ──────────────────────────────────────────────────────── -print("▶ 1. Basic level output (INFO+)") -do - local handler, get, clear = Logger.handlers.MemoryHandler() - local log = Logger.new("basic", { level = Logger.LEVELS.INFO, handlers = { handler } }) - - log:trace("should be filtered") - log:debug("should be filtered") - log:info("hello %s", "world") - log:warn("disk %d%%", 90) - log:error("boom") - log:fatal("catastrophe") - - local records = get() - test("TRACE filtered", records[1].level == Logger.LEVELS.INFO) - test("INFO captured", records[1].message == "hello world") - test("WARN captured", records[2].message == "disk 90%") - test("ERROR captured", records[3].level == Logger.LEVELS.ERROR) - test("FATAL captured", records[4].level == Logger.LEVELS.FATAL) - test("exactly 4 records", #records == 4) -end - --- ── 2. Level filtering ───────────────────────────────────────────────────── -print("\n▶ 2. Dynamic level changes") -do - local handler, get = Logger.handlers.MemoryHandler() - local log = Logger.new("dyn", { handlers = { handler } }) - - log:set_level(Logger.LEVELS.DEBUG) - log:debug("visible") - log:set_level(Logger.LEVELS.ERROR) - log:info("invisible") - log:error("visible again") - - local records = get() - test("DEBUG visible at DEBUG level", records[1].message == "visible") - test("INFO invisible at ERROR level", records[2].message == "visible again") - test("total 2 records", #records == 2) -end - --- ── 3. is_enabled ────────────────────────────────────────────────────────── -print("\n▶ 3. is_enabled()") -do - local log = Logger.new("enabled", { level = Logger.LEVELS.WARN }) - test("WARN enabled", log:is_enabled(Logger.LEVELS.WARN)) - test("INFO disabled", not log:is_enabled(Logger.LEVELS.INFO)) - test("ERROR enabled", log:is_enabled(Logger.LEVELS.ERROR)) -end - --- ── 4. Custom format ─────────────────────────────────────────────────────── -print("\n▶ 4. Custom format string") -do - local handler, get = Logger.handlers.MemoryHandler() - local log = Logger.new("fmt", { - format = "{level}|{name}|{message}", - handlers = { handler }, - }) - log:info("hi") - local f = get()[1].formatted - test("contains level", f:find("INFO") ~= nil) - test("contains name", f:find("fmt") ~= nil) - test("contains message", f:find("hi") ~= nil) - test("pipe separator", f:find("|") ~= nil) -end - --- ── 5. Filters ───────────────────────────────────────────────────────────── -print("\n▶ 5. Custom filter") -do - local handler, get = Logger.handlers.MemoryHandler() - local log = Logger.new("filter", { level = Logger.LEVELS.DEBUG, handlers = { handler } }) - - -- only pass records whose message contains "keep" - log:add_filter(function(rec) return rec.message:find("keep") ~= nil end) - - log:info("drop this") - log:info("keep this") - log:warn("also drop") - log:debug("keep me too") - - local records = get() - test("only 'keep' records pass", #records == 2) - test("first kept record", records[1].message == "keep this") - test("second kept record", records[2].message == "keep me too") -end - --- ── 6. Multiple handlers ─────────────────────────────────────────────────── -print("\n▶ 6. Multiple handlers") -do - local h1, get1 = Logger.handlers.MemoryHandler() - local h2, get2 = Logger.handlers.MemoryHandler() - local log = Logger.new("multi", { handlers = { h1 } }) - log:add_handler(h2) - - log:info("broadcast") - - test("handler1 received", #get1() == 1) - test("handler2 received", #get2() == 1) - test("same message", get1()[1].message == get2()[1].message) -end - --- ── 7. Child loggers ─────────────────────────────────────────────────────── -print("\n▶ 7. Child loggers") -do - local handler, get = Logger.handlers.MemoryHandler() - local parent = Logger.new("app", { handlers = { handler } }) - local child = parent:child("db") - - parent:info("parent message") - child:info("child message") - - local records = get() - test("parent name", records[1].name == "app") - test("child name", records[2].name == "app.db") - test("child shares handler", #records == 2) -end - --- ── 8. Logger.get() registry ────────────────────────────────────────────── -print("\n▶ 8. Logger.get() registry") -do - local a = Logger.get("svc.auth") - local b = Logger.get("svc.auth") - test("same instance returned", a == b) - - local c = Logger.get("svc.payments") - test("different names differ", a ~= c) -end - --- ── 9. Format with no args ──────────────────────────────────────────────── -print("\n▶ 9. Message with no format args") -do - local handler, get = Logger.handlers.MemoryHandler() - local log = Logger.new("noargs", { handlers = { handler } }) - log:info("plain string, no args") - test("plain string works", get()[1].message == "plain string, no args") -end - --- ── 10. FileHandler ─────────────────────────────────────────────────────── -print("\n▶ 10. FileHandler") -do - local path = "test_logger_output.log" - os.remove(path) - - local fh = Logger.handlers.FileHandler({ path = path }) - local log = Logger.new("file", { handlers = { fh } }) - log:info("written to file") - log:warn("second line") - - local f = io.open(path) - local content = f and f:read("*a") or "" - if f then f:close() end - - test("file created", content ~= "") - test("INFO line present", content:find("written to file") ~= nil) - test("WARN line present", content:find("second line") ~= nil) - test("two newlines", select(2, content:gsub("\n","")) == 2) -end - --- ── 11. Console handler (visual) ────────────────────────────────────────── -print("\n▶ 11. ConsoleHandler — visual check (colours enabled)") -do - local log = Logger.new("visual", { - level = Logger.LEVELS.TRACE, - handlers = { Logger.handlers.ConsoleHandler({ colours = true }) }, - }) - log:trace("trace message") - log:debug("debug message") - log:info ("info message") - log:warn ("warn message") - log:error("error message") - log:fatal("fatal message") - test("no crash", true) -end - --- ── Summary ──────────────────────────────────────────────────────────────── -print(string.format("\n━━━ Results: %d passed, %d failed ━━━", PASS, FAIL)) -if FAIL > 0 then os.exit(1) end diff --git a/test_logger_output.log b/test_logger_output.log deleted file mode 100644 index ba3c7e8..0000000 --- a/test_logger_output.log +++ /dev/null @@ -1,2 +0,0 @@ -[2026-06-08 19:40:49] [INFO ] [file] written to file -[2026-06-08 19:40:49] [WARN ] [file] second line