Love2d
Use this skill when writing, reviewing, debugging, or refactoring LÖVE / Love2D 11.x game code. Apply correct love.load/love.update/love.draw responsibilities, dt-based updates, asset loading and caching rules, input event vs continuous input handling, love.filesystem save behavior, conf.lua settings, graphics state hygiene, LÖVE 11.x color ranges, screen scaling, dev-only helpers, optional web preview cautions, and release-safe practices for AI coding agents.From its SKILL.md
npx -y skills add Omori0219/love2d-game-dev-skills --skill love2dAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
11.5 KB, ~2.6k tokens by cl100k_base, as published. Nobody here has run it
LÖVE / Love2D 11.x Game Development Skill
Use this skill to produce conservative, maintainable LÖVE / Love2D game code for AI-assisted development. The default target is LÖVE 11.x. As of 2026-05-06, LÖVE 11.5 is used as the reference release unless the project states otherwise.
This skill assumes Lua code should also follow a LuaJIT / Lua 5.1-compatible style. When available, pair it with the lua-luajit skill for language-level rules such as local scoping, module shape, :/. syntax, and avoidance of Lua 5.2+ assumptions.
Scope
This skill covers:
- LÖVE callback responsibilities:
love.load,love.update(dt),love.draw, input callbacks, resize/focus/quit callbacks. - LÖVE 11.x API conventions that AI agents often get wrong.
- Game-loop hygiene: state updates in
update, drawing indraw, time-based movement viadt. - Asset lifecycle: images, fonts, audio, shaders, canvases, and other LÖVE objects.
- Input handling: continuous input versus one-shot events and text input.
- Filesystem and configuration:
conf.lua,love.filesystem, save identity, release checks. - Screen scaling and resize-aware layout for desktop and mobile-sized windows.
- Development-only helpers such as debug overlays, screenshots, and hot reload.
- Optional web-preview cautions for love.js-style browser builds.
- Small-to-medium Love2D game code, examples, reviews, and bug fixes.
This skill does not cover:
- A mandatory game architecture for every project.
- Steam publishing strategy, store assets, marketing, or business decisions.
- Full API documentation. Use the official LÖVE wiki/reference as the source of truth.
- Heavy engine/framework layers such as ECS unless the project already uses them.
- Mandatory dependencies such as push.lua, love.js, Tailscale, or bundled fonts.
- Platform deployment guides for App Store, Steam, or console release workflows.
- Official endorsement by OpenAI, Anthropic, LuaJIT, Lua, or the LÖVE / Love2D project.
When the project already has a working style, preserve it first, then apply this skill as safety guardrails.
Operating Principles
When writing or changing Love2D code:
- Identify the target LÖVE version first. Prefer
conf.lua'st.versionor project docs. If unknown, assume LÖVE 11.x and avoid old 0.10-era APIs. - Preserve existing structure. Inspect current
main.lua, modules, state management, asset loading, and naming before changing anything. - Make the smallest safe change. Avoid broad rewrites unless the user explicitly asks for a refactor.
- Keep the game loop clean. Load/setup once, update state over time, draw current state.
- Do not invent assets. If an image, font, or audio file is not present, use a clear placeholder strategy or mention the missing asset.
- Prefer explicit, beginner-friendly code. Avoid clever metaprogramming, hidden globals, and large framework abstractions unless already used.
- Report runtime assumptions honestly. If you cannot run
love ., say so and provide manual checks.
Non-Negotiable Rules
1. Keep love.load for initialization
Use love.load for one-time setup:
- Initial game state.
- Loading or constructing images, fonts, audio sources, shaders, canvases, and other reusable LÖVE objects.
- Initializing modules and asset caches.
- Setting initial window, audio, and input state when needed.
Do not put per-frame gameplay logic in love.load.
2. Keep love.update(dt) for game-state updates
Use love.update(dt) for:
- Player/enemy movement.
- Timers, cooldowns, animation state, particles, physics/world updates.
- Collision checks and game-state transitions.
- Continuous input polling such as
love.keyboard.isDown.
Treat dt as seconds since the previous update. Movement speeds should normally be expressed as units-per-second and multiplied by dt.
When a long pause or focus change could cause a huge simulation jump, clamp dt locally, for example in the game update layer, without hiding the fact that it is a stability guard.
3. Keep love.draw for drawing only
Use love.draw to render the current state. Avoid changing game state in draw.
Do not do these in love.draw:
- Create images, fonts, audio sources, shaders, canvases, or other reusable objects.
- Move entities, advance timers, spawn enemies, resolve collisions, or change scenes.
- Generate random gameplay outcomes.
- Save files or perform expensive filesystem work.
Small local calculations for layout are acceptable when they do not mutate game state.
4. Do not load assets every frame
Never call constructors such as love.graphics.newImage, love.graphics.newFont, love.audio.newSource, or shader/canvas constructors inside a per-frame path unless the user explicitly requests dynamic asset creation and a cache/lifetime policy is provided.
Prefer:
- Load once in
love.load, or - Use an explicit asset cache module that loads on first request and reuses the object afterward.
For audio, prefer:
staticfor short sound effects.streamfor longer music or ambience.Source:clone()for playing overlapping copies of the same short sound effect.
5. Use LÖVE 11.x color ranges
For LÖVE 11.x, color components are numbers in the 0..1 range. Do not write old 0..255 color values unless the project has a compatibility helper that converts them.
Correct examples conceptually:
- White:
1, 1, 1, 1 - Half-transparent black:
0, 0, 0, 0.5 - Red:
1, 0, 0, 1
If reviewing old snippets using values like 255, 255, 255, flag them as likely pre-11.0 style.
6. Separate continuous input, one-shot input, and text input
Use the right input path:
- Continuous movement or held actions: poll
love.keyboard.isDownor related APIs inlove.update(dt). - One-shot actions: use
love.keypressed,love.mousepressed,love.gamepadpressed, etc. - Text entry: use
love.textinputfor typed text, notlove.keypressed. - IME composition: account for
love.texteditedwhen implementing serious text input.
Do not implement menu selection or shooting as repeated every-frame events unless that is the intended behavior.
7. Keep graphics state controlled
LÖVE graphics state persists until changed, and transformations last until love.draw exits or until restored via love.graphics.pop.
When changing graphics state:
- Use
love.graphics.push()/love.graphics.pop()around transforms. - Restore or explicitly set color before drawing images or UI that should not inherit tints.
- Restore canvas, shader, scissor, stencil, blend mode, and font when the local drawing block changes them.
- Prefer local draw helpers that leave graphics state predictable.
8. Use love.filesystem for game saves
For save data, settings, replays, and user files, use love.filesystem unless the project has a deliberate platform-specific reason not to.
Rules:
- Set a stable save identity via
conf.lua(t.identity) or an explicit initialization call. - Write save files through
love.filesystem.write/append/createDirectory. - Read through
love.filesystem.read/getInfo/lines. - Avoid raw
io.openfor normal game saves because it is less portable across packaged builds and platforms.
9. Treat conf.lua as part of the project contract
When creating or reviewing a Love2D project, check whether conf.lua exists.
Use it for:
t.versionmatching the intended LÖVE version.t.identityfor save directory naming.- Window title, size, resizable/fullscreen flags, icon, and high-DPI choice.
- Disabling unused modules only when the project really does not use them.
Do not disable modules casually. love.filesystem and love are mandatory, and some modules depend on others.
10. Keep main.lua small enough to understand
For anything beyond a tiny prototype, avoid putting every system into main.lua.
Prefer small modules for:
- Game/state manager.
- Assets.
- Input.
- Player/enemy/bullets/entities.
- UI/HUD.
- Save data.
- Debug overlay.
Use table-returning modules and explicit require calls. Do not introduce a large architecture rewrite when a small helper module solves the problem.
11. Avoid unsafe environment APIs unless explicitly requested
Do not introduce these casually in a Love2D game:
os.execute, shell calls, or platform-dependent file paths.- Arbitrary
load/loadstringfrom user-controlled data. - Debug-library hacks.
- Raw binary/native libraries or FFI.
If the user requests one, keep the risk narrow and explain portability/security implications.
Review Checklist
Before giving a final answer for Love2D code, check:
- Is the target LÖVE version clear? If not, did you assume 11.x conservatively?
- Are assets loaded once or cached, not recreated every frame?
- Is all time-based movement/timer logic using
dtappropriately? - Does
love.drawavoid mutating gameplay state? - Are graphics state changes localized and restored?
- Are color values valid for LÖVE 11.x (
0..1)? - Is input split correctly between polling, events, and text input?
- Are saves using
love.filesystemwith a stable identity? - Does
conf.luamatch the project and avoid casual module disabling? - Are resize, high-DPI, or virtual-canvas assumptions explicit when layout depends on them?
- Are debug overlays, screenshots, hot reload, and web-preview helpers kept out of release behavior?
- Did the change avoid unnecessary architecture rewrites?
- Did the code remain LuaJIT / Lua 5.1-compatible?
When More Detail Is Needed
Load these references only when relevant:
references/version-and-scope.md— LÖVE version assumptions and compatibility boundaries.references/callback-rules.md— callback responsibilities and game loop rules.references/asset-lifecycle.md— images, fonts, audio, shaders, canvases, and caching.references/input-and-time.md— input callbacks, polling,dt, timers, and fixed-step cautions.references/filesystem-and-config.md—conf.lua, save identity, and filesystem practices.references/graphics-and-release-checklist.md— graphics state, colors, DPI, and release review.references/screen-scaling.md— virtual canvas, resize, high-DPI, and optional scaling-library cautions.references/dev-workflow.md— debug overlay, screenshot, hot reload, and development-only key handling.references/web-preview.md— optional browser preview cautions, fonts, COOP/COEP, and love.js-style runtime differences.references/common-pitfalls.md— common AI-generated Love2D mistakes.references/review-checklist.md— detailed review procedure.references/sources.md— official and reference sources used to build this skill.examples/— small example files showing recommended patterns.
Response Style
When using this skill:
- For implementation tasks: make the change, then briefly mention key Love2D assumptions.
- For review tasks: list concrete issues first, grouped by severity.
- For debugging tasks: identify the likely callback/API/lifecycle cause before proposing broad changes.
- Keep answers practical. Do not give a full Love2D tutorial unless the user asks for one.
- Use the user's language for explanations; preserve the project's existing comment language.
What ships with it: 26 files
44.7 KB alongside SKILL.md
agents/
- openai.yaml252 B
docs/
- installation.md1.4 KB
evals/
- manual-eval.md2.7 KB
examples/
references/
- asset-lifecycle.md1.9 KB
- callback-rules.md2.0 KB
- common-pitfalls.md2.2 KB
- dev-workflow.md3.3 KB
- filesystem-and-config.md1.7 KB
- graphics-and-release-checklist.md1.9 KB
- input-and-time.md1.7 KB
- review-checklist.md1.7 KB
- screen-scaling.md3.4 KB
- sources.md2.3 KB
- version-and-scope.md1.3 KB
- web-preview.md2.8 KB
- CHANGELOG.md1017 B
- CONTRIBUTING.md1.1 KB
- .gitignore50 B
- LICENSE1.1 KB
- README.md5.7 KB