Something went wrong. Try again.
a Bluesky client for PICO-8 picosky.vinnymac.dev
pico-8 simulation bluesky games
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170# picosky - common development tasks. Source lives in src/ (src/*.lua modules +# src/cart.p8, which #includes them and holds the gfx/label/sfx/music data). The# root picosky.p8 / picosky*.js are BUILD OUTPUT, generated by `make build`.# `make` or `make help` lists targets. Override any variable on the command line,# e.g. `make build PICO8=/usr/bin/pico8` or `make serve PORT=9000`.
# --- config ------------------------------------------------------------------PICO8 ?= $(HOME)/.local/pico-8/pico8P8HOME ?= /tmp/p8homeSHRINKO8 ?= python3 tools/shrinko8/shrinko8.py# Tokens are picosky's binding budget (~90%); chars (~30%) and compressed (~55%)# have headroom. --focus-tokens trades a little compressed size for ~140 fewer# tokens per cart, so the .p8/.js outputs (and `count`) use it. The .p8.png# targets stay on the default (compressed-focused) minify - their limit is the# compressed ROM size, not tokens.MINIFY ?= --minify --focus-tokens# CART = source cart (#includes src/*.lua + holds the gfx/sfx/music data).# OUT = built standalone demo cart (BUILD OUTPUT). Inline `#` comments are kept# verbatim in Make values, so these are on their own lines (CART/OUT are file# prerequisites below - trailing whitespace would break the rules).CART ?= src/cart.p8SRC := $(wildcard src/*.lua)OUT ?= picosky.p8EXPORT ?= picosky.jsDEMO_EXPORT ?= picosky-demo.jsZIP ?= /tmp/pico8.zipPORT ?= 8080HEADLESS_ENV = SDL_VIDEODRIVER=dummy SDL_AUDIODRIVER=dummy
.DEFAULT_GOAL := help
# --- help --------------------------------------------------------------------.PHONY: helphelp: ## Show this help @grep -E '^[a-zA-Z0-9_-]+:.*?## ' $(MAKEFILE_LIST) \ | awk 'BEGIN{FS=":.*?## "}{printf " \033[36m%-14s\033[0m %s\n",$$1,$$2}'
# --- dev loop ----------------------------------------------------------------.PHONY: serveserve: ## Static dev server on 127.0.0.1:8080 (LAN=1 to expose on network, HOST= to pick interface) PORT=$(PORT) node serve.js $(if $(LAN),--lan,) $(if $(HOST),--host=$(HOST),)
# --- cart build --------------------------------------------------------------# Source is src/cart.p8 (#includes src/*.lua + the gfx/sfx/music data). Two web# carts come from it: shrinko8 minifies and sets the per-cart ONLINE flag (online# = real client; demo = self-contained lua mock feed, no js data bridge), then# headless PICO-8 exports each to JS. The root picosky.p8 is BUILD OUTPUT too -# the minified standalone demo cart (online can't run without the js bridge).$(OUT): $(CART) $(SRC) $(SHRINKO8) $(CART) $(OUT) $(MINIFY) --const ONLINE false @echo "built $(OUT) (standalone demo cart)"
$(EXPORT): $(CART) $(SRC) @mkdir -p build $(P8HOME) $(SHRINKO8) $(CART) build/online.p8 $(MINIFY) --const ONLINE true cd build && $(HEADLESS_ENV) $(PICO8) -home $(P8HOME) online.p8 -export "picosky.html" cp build/$(EXPORT) $(EXPORT) @echo "built $(EXPORT) (online)"
$(DEMO_EXPORT): $(CART) $(SRC) @mkdir -p build $(P8HOME) $(SHRINKO8) $(CART) build/demo.p8 $(MINIFY) --const ONLINE false cd build && $(HEADLESS_ENV) $(PICO8) -home $(P8HOME) demo.p8 -export "picosky-demo.html" cp build/$(DEMO_EXPORT) $(DEMO_EXPORT) @echo "built $(DEMO_EXPORT) (demo)"
.PHONY: build build-online build-demo cartcart: $(OUT) ## Build the standalone demo cart -> picosky.p8build-online: $(EXPORT) ## Export the online cart -> picosky.jsbuild-demo: $(DEMO_EXPORT) ## Export the demo cart -> picosky-demo.jsbuild: $(OUT) build-online build-demo ## Build root cart + export both web carts
# --- asset generation --------------------------------------------------------.PHONY: avatarsavatars: ## Re-fetch + bake real Bluesky avatars into __gfx__ node tools/fetch-avatars.js python3 tools/bake-avatars.py
.PHONY: imagesimages: ## Convert fox + npmx source images to PICO-8 hex strings (paste output into actions.lua) @echo "fox_hex:"; .venv/bin/python3 tools/gen-image.py tools/fox-reference.png @echo "npmx_hex:"; .venv/bin/python3 tools/gen-image.py tools/npmx-logo.png
.PHONY: iconsicons: ## Inject stats (reply/repost/heart 8-10) + footer (compose/refresh/quote 12-14) icons into __gfx__ python3 tools/gen_icons.py $(CART)
.PHONY: labellabel: ## Regenerate the cart __label__ from its butterfly sprite python3 tools/gen_label.py $(CART)
.PHONY: web-iconsweb-icons: ## Regenerate favicons, app icons + Open Graph card from the page logo python3 tools/gen_web_icons.py
# --- .p8.png exports (BBS / Splore) ------------------------------------------.PHONY: pngpng: ## Build picosky.p8.png (demo+online, compressed ≤ 100%) $(SHRINKO8) $(CART) picosky.p8.png -f png --minify --title "A BLUESKY CLIENT FOR PICO-8" --title "made by vinnymac ♥"
.PHONY: png-onlinepng-online: ## Build picosky-online.p8.png (ONLINE=true, strips demo block) $(SHRINKO8) $(CART) picosky-online.p8.png -f png --minify --const ONLINE true
# --- code checks (shrinko8) --------------------------------------------------# Lint runs on the readable source (the only place its warnings are meaningful);# count runs on the minified per-cart builds - the budgets that actually ship..PHONY: lintlint: ## Lint the cart source $(SHRINKO8) $(CART) --lint
.PHONY: countcount: ## Token / char / compressed budgets of the shipped carts (online + demo) @mkdir -p build @echo "online:"; $(SHRINKO8) $(CART) build/online-count.p8 $(MINIFY) --const ONLINE true --count @echo "demo:"; $(SHRINKO8) $(CART) build/demo-count.p8 $(MINIFY) --const ONLINE false --count
.PHONY: validatevalidate: lint count ## Lint source + budget-check the shipped carts (the gate)
# --- deploy ------------------------------------------------------------------DIST ?= dist
.PHONY: distdist: build ## 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 og.png $(DIST)/ cp picosky.js picosky-demo.js picosky-comms.js picosky-firehose.js picosky-shim.js $(DIST)/ cp client-metadata.json $(DIST)/ cp -r favicons fonts vendor $(DIST)/ @[ -f _headers ] && cp _headers $(DIST)/ || true
.PHONY: deploydeploy: dist ## Build + deploy to Cloudflare Pages (requires wrangler auth) npx wrangler pages deploy $(DIST) --project-name picosky --commit-dirty=true
.PHONY: ci-distci-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 og.png $(DIST)/ cp picosky.js picosky-demo.js picosky-comms.js picosky-firehose.js picosky-shim.js $(DIST)/ cp client-metadata.json $(DIST)/ cp -r favicons fonts vendor $(DIST)/ @[ -f _headers ] && cp _headers $(DIST)/ || true
.PHONY: ci-deployci-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 picosky --branch=main --commit-dirty=true
# --- setup / housekeeping ----------------------------------------------------.PHONY: install-pico8install-pico8: ## Install PICO-8 from /tmp/pico8.zip (override ZIP=) @test -f $(ZIP) || { echo "missing $(ZIP) (set ZIP=path)"; exit 1; } mkdir -p $(HOME)/.local/pico-8 $(HOME)/.local/bin /tmp/pico-8-extract unzip -o -q $(ZIP) -d /tmp/pico-8-extract cp -f /tmp/pico-8-extract/pico-8/pico8 /tmp/pico-8-extract/pico-8/pico8.dat $(HOME)/.local/pico-8/ chmod +x $(HOME)/.local/pico-8/pico8 ln -sf $(HOME)/.local/pico-8/pico8 $(HOME)/.local/bin/pico8 @echo "installed: $(PICO8)"
.PHONY: setupsetup: ## Clone shrinko8 into tools/ (needed for lint/count/validate/build) git clone --depth=1 https://github.com/thisismypassport/shrinko8.git tools/shrinko8
.PHONY: cleanclean: ## Remove generated exports + build/ intermediates (keeps the built picosky.p8) rm -rf build picosky.js picosky.html picosky-demo.js picosky-demo.html picosky.p8.png picosky-online.p8.png