Skip to content

feat(pets): add the dog as a first-class pet and rename to pixelpets - #21

Merged
JOhnsonKC201 merged 2 commits into
mainfrom
feat/pixelpets-dog
Jul 30, 2026
Merged

feat(pets): add the dog as a first-class pet and rename to pixelpets#21
JOhnsonKC201 merged 2 commits into
mainfrom
feat/pixelpets-dog

Conversation

@JOhnsonKC201

Copy link
Copy Markdown
Owner

What this does

The app hosts either a cat or a dog now, switchable from the tray (Pet → Cat / Dog) without a restart. Each species keeps its own coat choice, so switching back and forth never loses your pick.

The dog is not a recoloured cat

src/dog-sprite.js is its own composer set with canine geometry:

  • a muzzle that protrudes past the skull line (a cat is flat-faced at this size, and this is the single cue that stops it reading as one)
  • ears that hang or perk per breed (floppy, long, semi-perk, big, rose, round)
  • a broader chest, a real neck, and short legs on the dwarf breeds
  • a smaller head relative to the body than the cat's; an oversized round skull is what made the first pass read as a meerkat

14 breeds ship, and their markings are coat structures rather than palette swaps: spots (Dalmatian), saddle (German Shepherd), tricolour (Beagle), mask (Husky), merle (Aussie), patch (Border Collie), curly rim (Poodle).

Internal edges are carved to . so outlineHalo() traces them, which is the only way the jaw line, ear seams and toe splits survive on solid coats like the Black Lab.

Poses

Five, each the canine answer to the cat's rather than a reuse of it:

Cat Dog
hunting crouch play bow (chest down, rump up, tail flagged)
loaf nose-to-tail curl (a ring, with the tail wrapped over the paws)
rear-up bat beg (up on the haunches, front paws dangling)
keyboard knead keyboard lean, snout over the keys

Behaviour

  • Fetch. The tray throws a tennis ball; it arcs and bounces under gravity, the dog sprints after it, picks it up, carries it back to its home corner, drops it, then wags and pants.
  • A tail that wags from the base, with breed-specific shape (curl / plume / feather / stub / straight) and a rate and amplitude that ride the mood. Cats get their existing slow rolling S-curve.
  • Panting with a lolling tongue after exertion, tied to the zoomies band.
  • Whiskers suppressed for dogs. A dog with cat whiskers reads as a cat in a dog costume.

Implementation notes

  • The active species rewrites the shared PATTERNS / PATTERN_BUILD / TABBY tables in place, so the tray, settings window, custom coats and contact sheet keep working with no knowledge that a second species exists. That kept the diff to the renderer small.
  • Face features are now composed after markings. A solid marking was burying the Beagle's eye in the curl pose; the new tests caught it.
  • scripts/pet-sheet.js renders every breed x pose to a PNG with no Electron and no canvas dependency, for visual QA (npm run sheet:dog). Reading grid code cannot tell you whether a silhouette actually reads as a dog.

Rename

Product and package are now pixelpets. appId, AppUserModelId and the tmpdir state paths deliberately keep the old identifier: changing them orphans existing installs' settings and would break the identity of the in-flight winget package (JOhnsonKC201.pixelcat, microsoft/winget-pkgs#407879). The GitHub repo name is likewise unchanged, since renaming it would break the release asset URLs that PR points at.

Test plan

  • npm test - 27 pass, 0 fail (7 new tests covering breed/build/tail integrity, palette completeness, every breed x every pose composing with a visible body/eye/nose/outline, muzzle-below-eyes geometry, dwarf leg length, and species-registry agreement)
  • npm run lint - clean across src/, scripts/pet-sheet.js, tests/
  • npm run test:boot - green
  • Visual QA via npm run sheet:dog across all 14 breeds and 5 poses
  • Manual pass on a real desktop: tray species switch, fetch round trip, wag rates across mood bands

The app hosts either a cat or a dog now, switchable from the tray without a
restart. Each species keeps its own coat choice so switching back and forth
never loses your pick.

The dog is not a recoloured cat. src/dog-sprite.js is its own composer set with
canine geometry: a muzzle that protrudes past the skull line, ears that hang or
perk per breed, a broader chest, a real neck, and short legs on the dwarf
breeds. 14 breeds ship, and their markings are coat structures rather than
palette swaps (spots, saddle, tricolour, mask, merle, patch, curly rim).

Five poses, each the canine answer to the cat's rather than a reuse of it:
  sit, play bow (vs the hunting crouch), keyboard lean, nose-to-tail curl
  (vs the loaf), and beg (vs the rear-up bat).

Behaviour:
  - fetch: the tray throws a tennis ball, it arcs and bounces under gravity, the
    dog sprints after it, carries it home, drops it, then wags and pants
  - a tail that wags from the base with breed-specific shape (curl/plume/
    feather/stub/straight) and a rate that rides the mood
  - panting with a lolling tongue after exertion
  - whiskers are suppressed for dogs; they read as a cat in a dog costume

Implementation notes:
  - the active species rewrites the shared PATTERNS/PATTERN_BUILD/TABBY tables
    in place, so the tray, settings, themes and contact sheet keep working with
    no knowledge that a second species exists
  - face features are composed after markings; a solid marking was burying the
    beagle's eye in the curl pose, which the new tests caught
  - scripts/pet-sheet.js renders every breed x pose to a PNG with no Electron
    and no canvas dependency, for visual QA (npm run sheet:dog)

Renamed the product and package to pixelpets. appId, AppUserModelId and the
tmpdir state paths deliberately keep the old identifier: changing them orphans
existing installs' settings and would break the in-flight winget package
identity.

27 tests pass, lint clean, boot check green.
@vercel

vercel Bot commented Jul 29, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
pixelcat Ready Ready Preview, Comment Jul 29, 2026 7:36am

The tray could already switch pets, but the settings window still listed cat
coats regardless of species and wrote every pick to `pattern`. It now:

  - offers a Pet dropdown (Cat / Dog)
  - swaps the list to the 14 breeds and relabels "Coat" to "Breed" for a dog
  - writes to `dogPattern` vs `pattern` so each species keeps its own choice
  - renders a live dog preview, whiskerless, via the canine composer

Custom coats stay cat-only: they are built from the cat's geometry, so offering
them for a dog would compose a cat silhouette in a dog's palette.

site/cat-preview.js re-ported to match, per the drift guard in site-sync.test.js.
drawDog is inert there because the site bundle has no canine composer, which the
`typeof composeSitDog` guard already handles.
@JOhnsonKC201
JOhnsonKC201 merged commit 784d54d into main Jul 30, 2026
4 checks passed
@JOhnsonKC201
JOhnsonKC201 deleted the feat/pixelpets-dog branch July 30, 2026 03:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant