# npicomx - dev tasks. Source lives in src/ (src/*.lua modules + src/cart.p8, which # #includes them and holds the gfx/map/sfx data). `make` builds the shippable cart to # ./npicomx.p8 (minified, debug-stripped, self-contained). Override vars on the CLI, # e.g. `make web PICO8=/usr/bin/pico8` or `make serve PORT=9000`. # --- config ------------------------------------------------------------------ PICO8 ?= $(HOME)/.local/pico-8/pico8 P8HOME ?= /tmp/p8home-npicomx SHRINKO8 ?= python3 tools/shrinko8/shrinko8.py MINIFY ?= --minify -ot # -ot/--focus-tokens: merges successive assigns etc. (~113 tok) CART ?= src/cart.p8 # source cart (#includes src/*.lua + data sections) OUT ?= npicomx.p8 # built, shippable cart (this is a BUILD OUTPUT) EXPORT ?= npicomx.js HTML ?= npicomx.html PORT ?= 8128 HEADLESS_ENV = SDL_VIDEODRIVER=dummy SDL_AUDIODRIVER=dummy .DEFAULT_GOAL := build # --- build ------------------------------------------------------------------- # shrinko8 expands the #includes in src/cart.p8, minifies, const-folds away the debug # tour (`--const dbg false`), and writes the single self-contained cart to ./npicomx.p8. .PHONY: build build: ## Build src/cart.p8 -> npicomx.p8 (minified, debug-stripped, self-contained) $(SHRINKO8) $(CART) $(OUT) $(MINIFY) --const dbg false @echo "built $(OUT)" # --- code checks (shrinko8) -------------------------------------------------- # Lint/count read the SOURCE; count minifies first so the budget is the one that ships. .PHONY: lint lint: ## Lint the cart source (implicit game-state globals + the `t` math-param convention are by design; the unused-var lint still runs) $(SHRINKO8) $(CART) --lint --no-lint-undefined --no-lint-duplicate-global .PHONY: count count: ## Token / char / compressed budgets of the shipped (minified) cart @mkdir -p build $(SHRINKO8) $(CART) build/count.p8 $(MINIFY) --const dbg false --count .PHONY: validate validate: lint count ## Lint source + budget-check the minified cart (the gate) # --- .p8.png export (BBS / Splore) ------------------------------------------- .PHONY: png png: build ## Build npicomx.p8.png (for Splore / BBS); needs Pillow $(SHRINKO8) $(OUT) npicomx.p8.png -f png --title "npmx inspired game for PICO-8" --title "made by vinnymac ♥" .PHONY: web-icons web-icons: ## Regenerate favicons, app icons + Open Graph card from the ./ npicomx wordmark; needs Pillow python3 tools/gen_web_icons.py .PHONY: gen-label gen-label: ## Regenerate the 128x128 cart label ("./ npicomx" wordmark) in src/cart.p8; needs Pillow python3 tools/gen_label.py # --- web export -------------------------------------------------------------- # Drive headless PICO-8 to export the JS runtime from the built cart. `-export` writes # npicomx.html + npicomx.js; we use only npicomx.js - the custom index.html loads it. .PHONY: web web: build ## Export the JS web runtime -> npicomx.js (loaded by index.html) @mkdir -p $(P8HOME) $(HEADLESS_ENV) $(PICO8) -home $(P8HOME) $(OUT) -export "$(HTML)" @echo "built $(EXPORT) - open index.html (via make serve)" # --- preview ----------------------------------------------------------------- .PHONY: serve serve: ## Dev server to preview index.html (LAN=1 to expose; HOST= / PORT= to change; needs `make web` first) PORT=$(PORT) node serve.js $(if $(LAN),--lan,) $(if $(HOST),--host=$(HOST),) # --- screenshot (headless verification) -------------------------------------- # Runs the built cart under a dummy SDL driver. PICO-8 only writes a screenshot when the # cart calls extcmd("screenshot") (gated behind the dbg flag - only the smoke build). .PHONY: screenshot screenshot: build ## Run the built cart headlessly so an extcmd("screenshot") call can capture a PNG @mkdir -p $(P8HOME) -$(HEADLESS_ENV) $(PICO8) -home $(P8HOME) $(OUT) @echo "if the cart called extcmd(\"screenshot\"), look in $(P8HOME)/screenshots" # --- deploy ------------------------------------------------------------------ DIST ?= dist .PHONY: dist dist: web ## Assemble web-only files into dist/ for Cloudflare Pages deploy rm -rf $(DIST) mkdir -p $(DIST) cp index.html sw.js manifest.webmanifest crt.js npicomx.js og.png $(DIST)/ cp -r favicons fonts vendor $(DIST)/ @[ -f _headers ] && cp _headers $(DIST)/ || true .PHONY: deploy deploy: dist ## Build + deploy to Cloudflare Pages (requires wrangler auth) npx wrangler pages deploy $(DIST) --project-name npicomx --commit-dirty=true .PHONY: ci-dist ci-dist: ## Assemble dist/ from committed artifacts (no pico8/python3 required) rm -rf $(DIST) mkdir -p $(DIST) cp index.html sw.js manifest.webmanifest crt.js npicomx.js og.png $(DIST)/ cp -r favicons fonts vendor $(DIST)/ @[ -f _headers ] && cp _headers $(DIST)/ || true .PHONY: ci-deploy ci-deploy: ci-dist ## Deploy committed artifacts to Cloudflare Pages (CI-safe, no pico8 needed) CLOUDFLARE_ACCOUNT_ID=ebbd354a5e5728e183b95c92fbcfb770 npx wrangler pages deploy $(DIST) --project-name npicomx --branch=main --commit-dirty=true # --- help / housekeeping ----------------------------------------------------- .PHONY: help help: ## Show this help @grep -E '^[a-zA-Z0-9_-]+:.*?## ' $(MAKEFILE_LIST) \ | awk 'BEGIN{FS=":.*?## "}{printf " \033[36m%-14s\033[0m %s\n",$$1,$$2}' .PHONY: clean clean: ## Remove generated exports (js/html/.p8.png) + build/ intermediates (keeps npicomx.p8) rm -rf build npicomx.js npicomx.html npicomx.p8.png