diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md new file mode 100644 index 0000000..3e96a66 --- /dev/null +++ b/.claude/CLAUDE.md @@ -0,0 +1,82 @@ +playscii - ascii art and game creation tool (v9.18) + +desktop GUI app using SDL2 + OpenGL. NOT a web app, no server component. +originally from https://heptapod.host/jp-lebreton/playscii (mercurial). +we maintain our own git repo. + + +running +------- + just run launch the app (uv run python playscii.py) + just check lint gate (ruff check + format) + just lint ruff check --fix + ruff format + just typecheck ty check (601 errors, legacy code, not in check gate) + just test pytest (no tests yet, not in check gate) + + +project structure +----------------- + all python source lives at the repo root (no src/ layout) + ~50 .py files, flat structure, no packages + + playscii.py main entry point, app init, SDL2/OpenGL setup + art.py art/canvas management, the core data model + ui*.py ~20 UI modules (dialogs, panels, menus, toolbar, etc.) + game_*.py game engine (objects, rooms, world, HUD) + renderable*.py rendering pipeline (sprites, lines, framebuffer) + formats/ import/export handlers (ANS, ATA, BMP, EDSCII, PNG, GIF, TXT) + games/ bundled example games (crawler, fireplace, flood, maze, shmup, etc.) + charsets/ 30+ classic computer character sets (.char + .png) + palettes/ color palette definitions + shaders/ GLSL shader files + artscripts/ art animation scripts (.arsc files) + art/ sample ASCII art (.psci files) + docs/ documentation and design notes + ui/ UI image resources + + +dependencies +------------ + runtime: appdirs, numpy, Pillow, PyOpenGL, PySDL2, packaging + system: libSDL2, libSDL2_mixer (must be installed on the OS) + dev: ruff, pytest + + +gotchas +------- + art scripts and exec(): + art.py imports random at module level with a noqa comment. art scripts + (.arsc files) are loaded via exec() in art.py's scope. they use random + without importing it themselves. do NOT remove that import even though + ruff flags it as unused. same pattern may apply to other "unused" imports + in art.py — check before removing anything. + + pdoc detection: + playscii.py has a contextlib.suppress block that tries to import pdoc. + the import MUST stay inside the suppress block. if it gets moved or + removed, pdoc_available becomes unconditionally True and the help menu + breaks when pdoc isn't installed. + + SDL2 init ordering: + many modules import from playscii.py's namespace or expect SDL2 to be + initialized before they run. import order in playscii.py matters — E402 + is disabled for this reason. + + mutable default arguments: + B006 is disabled. many functions use mutable defaults (lists, dicts). + changing these could alter behavior since some code may rely on the + shared mutable state. do not "fix" these without testing. + + variable naming: + E741 is disabled. single-letter vars (l, x, y, z, i, r, g, b) are + everywhere in the math/rendering/game code. this is intentional. + + +ruff config +----------- + rules: E, F, I, UP, B, SIM + 13 rules are explicitly ignored (see pyproject.toml for rationale) + line-length: 88, formatter handles what it can + + when adding new code, write it clean. the ignored rules are concessions + to legacy code, not a style guide for new work.