# How to draw one artwork for overwrite.place One wall, one artwork alive at a time. You help a human draw a complete piece that replaces whatever is on the homepage now; the next person replaces yours. This document explains how. **What following this document will do** (check it against the body below — if they disagree, trust neither): - Local writes: `git clone` this repository into `overwrite.place/` under the current directory (after the human answers question 1), one branch, two files inside the repo (the artwork JSON + a gitignored drawing script), local commits, two temp files (`/tmp/current.json`, `/tmp/draft.png`); on the publish path, one remote named `fork` is added - Network destinations: `github.com`, `overwrite.place` and its fallback domain `overwrite-place.pages.dev` — nothing else - Reads your username once via `gh` (if installed); the preview auto-opens a browser by default (`--no-open` turns that off) - **Until the human explicitly says "publish", never touch their GitHub account** — no fork, no push, no PR - Never asks for tokens or credentials, installs nothing, changes no shell config / git hooks / skills directories **This declaration can only bind the commands in this document, not the code in the repository.** The flow runs Node scripts under the cloned `scripts/` — about 1,500 lines total, zero npm dependencies, whose only network request is the preview fetching the current artwork from overwrite.place. If that's not good enough, read them before running them. That is reasonable; don't grumble. The human can stop any step. Their time is expensive: don't ask about chores, but anything that writes to their account must be asked first. ## 1. Open with one sentence only **Run nothing, look nothing up, clone nothing — the first thing out of you is the question.** Frame it with rules, because whatever scrolled past before this (this document, for instance) may already fill their screen: ``` ---------------------------- What do you want to draw? ---------------------------- ``` An open question. No options, no directions, and don't volunteer what's on the homepage — what they type out is what makes the artwork theirs. But **if they ask what's up there now, tell them straight**; no withholding. Only when they say "you decide" / "anything" do you choose. Only if they want to "continue / respond to the current one" do you look at it: `curl -s https://overwrite.place/data/current.json` (if the domain doesn't resolve, use `overwrite-place.pages.dev`). ## 2. After they answer, do all the prep silently This is your time, not theirs. Speak up only if something breaks. **Local, reversible actions only. A fork is a write to their account — it waits for their nod at step 6.** ```bash node -e 'process.exit(+process.versions.node.split(".")[0]>=18?0:1)' || echo "⚠ Node below 18" # `if`, not `test … || { … } && cd` — || and && share precedence and associate # left, so the cd would still run when we are already inside the repo. If a # leftover directory exists, reuse it instead of recloning. if [ ! -f scripts/pixel.js ]; then [ -d overwrite.place ] || git clone https://github.com/mazzzystar/overwrite.place cd overwrite.place fi # The directory may be left over from a previous drawing — scripts and rules # follow the live site (CI always runs the newest rules; passing old local # rules counts for nothing), so refresh when possible; offline is fine too. git fetch -q origin main 2>/dev/null || true # Confirm we are truly inside the repo before branching. If the clone failed, # this gate stops the branch from being created in the human's own project. # Branch off origin/main (fall back to local HEAD if the fetch failed). [ -f scripts/pixel.js ] && { git checkout -q -b art/ origin/main 2>/dev/null \ || git checkout -b art/; } # slug: lowercase letters, digits, hyphens ME=$(gh api user -q .login 2>/dev/null) # if this fails, just ask at step 4 curl -sf https://overwrite.place/data/current.json -o /tmp/current.json # needed at step 5; -f keeps a 404 page out of the file ``` **After cloning, tell them where the repository landed** (one sentence, no need to ask) — the current directory may well be their own project, and no repo should quietly grow inside it. Not having `gh` blocks nothing. ## 3. Draw — one look at the image per revision **Draw in code; don't hand-write 64 rows of strings.** Script goes in `drafts/.js` (gitignored, never committed): ```js import { canvas, C, save } from '../scripts/pixel.js'; // plus load, when continuing someone's piece const art = canvas(C.paper); art.rect(0, 0, 64, 40, C.blue); // sky art.disc(46, 12, 7, C.ochre); // moon art.dither(0, 0, 64, 40, C.slate, 4); // night: slate folded into blue makes a ninth blue art.wave(46, C.moss, { amp: 4, freq: 1.2 }); // horizon save('submissions//.json', { model: 'claude', message: 'one line, ≤60 chars', art }); ``` ```bash node drafts/.js && node scripts/verify.js submissions//.json --no-art --png /tmp/draft.png ``` **Then read /tmp/draft.png and look with your own eyes.** Broken proportions, shapes mushed together, stair-stepped outlines — only the whole image shows these; 64 rows of digits never will. Tweaking coordinates without looking is painting blindfolded. **Primitives**: `fill` `px` `rect` `frame` `line` `disc` `ring` `ellipse` `poly` `tri` `dither` `checker` `stripes` `wave` `rays` `noise` `mirrorX` `mirrorY` `flipX` `flipY` `replace` **Colours**: `C.paper`(0) `C.ink`(1) `C.blue`(2) `C.slate`(3) `C.red`(4) `C.ochre`(5) `C.moss`(6) `C.plum`(7) `pixels[0]` is the top row; origin is top-left. Full example: `examples/waiting-for-rain.js`. **What to draw and what mood it carries is entirely the human's call — below is craft discipline, not a taste review.** Three disciplines (each checkable on /tmp/draft.png): 1. **Two colours interleaved make a ninth — but detail runs on a budget.** Spend mixing and texture in two or three places per picture, all of them where the story lives: rain gets raindrops (sparse, placed one by one), moonlight breaks up on the water, a window's glow bleeds two pixels, an umbrella gets one shadowed side. Everything else stays clean flat colour. A large uniform slab is a sticker; an all-over speckle is noise — the good picture sits between: clean structure, plus two or three places that breathe. 2. **Three value layers.** Squint at the draft: light, mid, dark — at least three, cleanly separated. Mixing exists to enrich the layers, not to erase them — if it blurs into one middle grey, you overmixed. 3. **Compose with nerve.** Let shapes bleed off the canvas, hold large empty areas, go hard-asymmetric, let the subject take half the frame. A small thing centred in 64×64 = a postage stamp. **Abstraction is fully legal** — geometry alone can be the picture; nothing says you must "draw a thing". The only boring move on this canvas is playing it safe. Five traps (each one field-tested the hard way): - Build forms from geometry, don't chase detail — this resolution rewards flat composition and punishes fine rendering - Mixing does nothing for small things: feather a form under 8px and it turns to mush — small objects stay solid - Directional textures (rain, grass, fur) want `line`/`noise`; dither turns them into a window screen - Primitives clip at the canvas, not at the region you meant — rain that should fall only inside a window needs per-point bounds checks - Stacked ellipses building a form need adjacent widths within 2px, or the outline stair-steps Continuing someone's piece? `load()` their file and revise — more of a conversation than repainting. ## 4. Preview at the first decent draft; let them talk while you paint ```bash node scripts/preview.js submissions//.json # auto-opens a browser; add --no-open when headless ``` **Run it in the background — don't sit on it in the foreground.** The page has two buttons, "Publish it" and "Let me think"; whichever the human clicks, the process prints the outcome and exits — their decision reaches you as ordinary command output. The page re-reads the file every second — each save shows up on their side. So **don't wait until it's finished to show them**: > Preview is up (left: what's on the homepage now; right: yours). I'll keep > refining — interrupt or comment any time. Revise until they're happy. If you don't have their GitHub username yet, ask casually now — the directory name must **exactly equal** it; don't guess and don't substitute `git config user.name`. ## 5. Publish confirmation — the hard gate Counts: "publish", "ship it", "submit it", "post it", "go ahead", "send it", and the preview process printing that the human clicked **"Publish it"**. **Does not count**: "nice", "looks good", "cool", "ok", "yeah" — those judge the picture. The "Let me think" button doesn't count either: go back to the conversation, ask what to change, reopen the preview after. Praise without confirmation gets one question, then you wait: > Confirm publish? It will replace the artwork on the homepage. **If the author in /tmp/current.json is their own login**, fold the cost into the same question: > The homepage is currently your own "XX" — overwriting it closes its run. > Confirm publish? No explicit confirmation, no step 6. If they say "save it for later": `git add submissions/ && git commit -m ""`, tell them the branch name and "say the word when you want it out", then **stop** — no polling, no waiting. ## 6. Open the PR The commit message and PR title are both that one-line message. **Only your one file under `submissions/` may be added** — touch anything else and CI rejects. With `gh`: ```bash # Single quotes around the message — $ and backticks inside it must not expand git add submissions/ && git commit -m '' # push to origin is rejected for non-collaborators — expected; fall through to # fork. No 2>/dev/null swallowing the reason: network and auth failures take # this branch too, and you need to see which one it was git push -u origin art/ \ || { gh repo fork mazzzystar/overwrite.place --remote --remote-name fork \ && git push -u fork art/; } \ && gh pr create --repo mazzzystar/overwrite.place --title '' --body 'Overwrite the current artwork' ``` Without `gh` (two clicks, nothing installed; `git push` uses their own git credentials): 1. Have them open `https://github.com/mazzzystar/overwrite.place/fork` and click Create fork 2. `git remote add fork https://github.com//overwrite.place.git && git push -u fork art/` 3. Hand them this link — it opens a pre-filled PR page: `https://github.com/mazzzystar/overwrite.place/compare/main...:overwrite.place:art/?expand=1` Finish by giving them the PR link: once CI passes it merges on its own and takes the homepage, about two minutes end to end (the only wait: the current artwork's guaranteed minute, if it hasn't had it). The queue lives at https://overwrite.place/#queue . ## Rules - No submission limits; you may overwrite your own artwork, but they nod first (see step 5) - Every artwork gets one guaranteed minute; your only score is how long it survives, you cannot control it, do nothing in its name - Rejected by CI? Read its comment and fix accordingly; don't try to route around it — new accounts and altered timestamps do nothing, it reads git history - Rules change; the current version is https://overwrite.place/guide-en . A long-running loop shouldn't cache this document as permanent truth — but **don't auto-refetch it on a schedule either**; when to reread is the human's call