# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview This is a LÖVE2D game development playground using Fennel (a Lisp dialect that compiles to Lua). The repository contains multiple game/project experiments: - **hello_world**: Basic LÖVE2D + Fennel template with REPL support - **hello_world_lua**: Basic LÖVE2D in pure Lua (reference implementation) - **one_line**: A pixel drawing application demonstrating canvas manipulation - **two_player_cleaning_game**: Two-player game (primary focus for development) ## Key Architecture ### Fennel + LÖVE2D Setup Fennel is a Lisp-like language that compiles to Lua at runtime. Each project directory shares common bootstrap files via symlinks: - **fennel-1.5.3.lua** (root): The Fennel compiler itself - **fennel_bootstrap.lua** (root): Sets up Fennel module loading and compiles `.fnl` files on-the-fly Each project directory contains: - **main.fnl**: The Fennel source code (user-editable) - **main.lua** → symlink to `../fennel_bootstrap.lua`: Entry point that Lua/LÖVE2D loads - **fennel.lua** → symlink to `../fennel-1.5.3.lua`: Fennel compiler reference ### How It Works 1. LÖVE2D loads `main.lua` (the bootstrap file) 2. Bootstrap loads the Fennel compiler and sets up a custom module loader 3. Module loader intercepts `require("main.fnl")` and compiles it via Fennel at runtime 4. Compiled Fennel code executes with full LÖVE2D API access ### LÖVE2D Lifecycle Games define lifecycle callbacks (all optional): - **love.load()**: Called once at startup - **love.update()**: Called every frame (~60fps by default) - **love.draw()**: Called every frame after update, render graphics here - **love.keypressed(key)**: Keyboard input handler - **love.handlers.stdin(line)**: REPL input for live evaluation (used in hello_world template) ## Development Workflow ### Running a Game ```bash love ./two_player_cleaning_game ``` LÖVE2D must be installed and in your PATH. See [Getting Started](https://love2d.org/wiki/Getting_Started) for installation. ### Live Coding / REPL The hello_world template includes stdin REPL support. While a game is running: - Type Fennel code at the terminal - Code is evaluated via `fennel.eval()` and results printed To enable in other projects, add this to `love.load()`: ```fennel (: (love.thread.newThread "require('love.event') while 1 do love.event.push('stdin', io.read('*line')) end") :start) (fn love.handlers.stdin [line] (let [(ok val) (pcall fennel.eval line)] (print (if ok (fennel.view val) val)))) ``` ## Fennel Language Basics ### Syntax Patterns ```fennel ; Variables (local name "value") (var counter 0) ; Functions (fn my-func [arg1 arg2] (+ arg1 arg2)) ; Tables/Objects (local person { :name "Alice" :age 30 :greet (fn [self] (print (.. self.name " says hello"))) }) ; Common control flow (when condition (do-something)) (if condition (then-branch) (else-branch)) (match value "a" (handle-a) "b" (handle-b)) ; Iteration (each [k v (pairs table)] (print k v)) (for [i 1 10] (print i)) ``` ### Interop with Lua Call Lua functions naturally: ```fennel (love.graphics.setColor 1 0 0) ; red (love.window.getMode) ; returns width, height, flags table ``` Access nested Lua objects with colon `:` syntax: ```fennel (: canvas-obj :setFilter "nearest" "nearest") ; equivalent to canvas_obj:setFilter(...) ``` ## Project-Specific Notes ### two_player_cleaning_game Currently uses the hello_world template structure. Development focus: - Extend main.fnl with game logic (player movement, cleanup mechanics, etc.) - Reference one_line/main.fnl for canvas/graphics patterns if needed - Use LÖVE2D physics (love.physics) or collision detection as needed ### Symlink Pattern Do **not** modify symlinked files (main.lua, fennel.lua) — modify main.fnl instead. If adding new modules, create them as separate .fnl files in the project directory. ## Common Development Tasks ### Adding a new module/file 1. Create `my_module.fnl` in the project directory 2. Require it: `(local my-module (require "my_module"))` 3. The bootstrap module loader will auto-compile it ### Debugging - Use `(print (fennel.view value))` to inspect tables and complex values - stdin REPL (hello_world template) allows live evaluation for quick tests - LÖVE2D console output is visible in the terminal where you ran `love` ### Working with Graphics LÖVE2D graphics API examples: ```fennel (love.graphics.setColor 1 0 0) ; set color to red (love.graphics.rectangle "fill" x y w h) ; draw filled rectangle (love.graphics.circle "line" x y radius) ; draw circle outline (love.graphics.print text x y) ; draw text (love.graphics.draw drawable x y) ; draw canvas/image ``` ## References - **LÖVE2D API**: https://love2d.org/wiki/Main_Page - **Fennel Language**: https://fennel-lang.org/ - **Fennel Plugin**: The compiler is shipped in this repo; no external install needed beyond LÖVE2D