love2d-core

Structure and debug a LÖVE (Love2D) game in Lua: the love.load/update/draw loop, delta-time movement, input, and screen states. Use when building a LÖVE 11.x game (main.lua, conf.lua, .love).

By gamedev-skills · 1,924 installs

npx skills add gamedev-skills/awesome-gamedev-agent-skills --skill love2d-core

Source repository · Upstream listing

LÖVE (Love2D) Core Set up and debug the foundation of a LÖVE game in Lua: the callback loop, frame rate independent movement, input, and screen states. Targets LÖVE 11.5 . When to use Use when starting a LÖVE game, wiring up main.lua / conf.lua , or fixing the core loop, movement that runs at the wrong speed, input handling, or screen switching. Use when the workspace has main.lua calling love. , a conf.lua , or a .love file. When not to use: Lua language questions unrelated to LÖVE; physics bodies/joints (LÖVE uses Box2D via love.physics — a separate concern); shader code ( love.graphics GLSL is its own topic). For cross engine save/load patterns, use save systems . Core workflow 1. Confirm the entry points. A LÖVE game runs main.lua ; it should define love.load() (one time setup), love.update(dt) (state), and love.draw() (rendering). Window/version setup goes in conf.lua (run before modules load). 2. Pin the version. Set t.version = "11.5" in conf.lua so LÖVE warns on mismatch. 3. Drive all motion by dt (delta time, in seconds) so speed is frame rate independent. 4. Handle input two ways: polled ( love.keyboard.isDown in update , for held keys) and event ( love.keypressed callback, for discrete presses). 5. Manage screens (menu, game, pause) with a small state stack rather than a pile of if flags — see Patterns and references/state stack.md . 6. Run and observe. Launch with love . from the project folder; verify the window, motion speed, and input on screen before assuming it works. Patterns 1. main.lua skeleton (the callback loop + input) 2. Frame rate independence (the single most common bug) 3. conf.lua (window + version; runs before main.lua ) 4. Color is 0–1 in LÖVE 11.x (not 0–255) 5. Screen states (brief — full manager in references) Pitfalls Speed varies with FPS → you forgot dt . Every per frame change to position, timers, or animation must be scaled by dt . love.conf placed in main.lua → it silently does nothing. It must live in conf.lua , which LÖVE runs before loading modules. Colors washed out or invisible → you used 0–255 values. 11.x does not rescale them; every channel above 1 draws at full intensity, so setColor(128, 234, 255) comes out plain white and an alpha of 128 is fully opaque. Use 0–1 floats or love.math.colorFromBytes (11.3+). Everything tinted after one setColor → color is global and persists across draws. Reset with love.graphics.setColor(1, 1, 1) before drawing text/images you want untinted. Holding a key fires love.keypressed only once → key repeat is off by default. Call love.keyboard.setKeyRepeat(true) (e.g. for text fields or menu scrolling); the repeats then arrive with the third argument isrepeat set, so a jump handler can ignore them. Releases go to love.keyreleased(key) . References For a complete push/pop screen state manager (menu → game → pause, with delegated callbacks), read references/state stack.md . Related skills save systems — saving/loading game state (engine agnostic). input systems — rebindable, multi device input architecture. pygame core / phaser core — the same loop concepts in other lightweight engines.