Skip to content

Latest commit

 

History

History
149 lines (118 loc) · 6.71 KB

File metadata and controls

149 lines (118 loc) · 6.71 KB

Development

Run from source, build an installer, and check visual changes on a project whose output is GPU-composited and cannot be screenshotted.

Requires git and Node 20 or newer.

git clone https://github.com/JOhnsonKC201/pixelpets.git
cd pixelpets
npm install
npm start

Commands

npm start                 # run the app
npm test                  # 200+ tests: config and data migration, poses, interactions,
                          #  audio, focus and quiet hours, mail and calendar, site drift
npm run lint              # eslint over src, tests and scripts (what CI runs)
npm run test:boot         # launch the real app and assert it renders a frame
npm run check:hook        # does the global input hook load on this Electron?
npm run poses:cat         # previews/cat-poses.png (every activity x every coat)
npm run poses:dog         # the same for the Black Lab
npm run frames:import -- <dir>   # import painted PNGs as baked poses
npm run demo:all          # regenerate the README media (hero, gallery, carousel)
npm run hook -- cursor    # print a path-filled agent hook config
npm run icon              # regenerate the tray + app-tile icons

CI runs npm run lint, npm test, and the boot check on Windows and macOS for every push and pull request.

Tip

Windows: npm start leaves a console window open behind the pet. launch-pixelpets.vbs starts the same thing silently, so it works as a desktop shortcut (point one at wscript.exe "<path>\launch-pixelpets.vbs"). It locates the project from its own path, so moving the folder does not break it.

Note

macOS: same commands. On first run, grant Accessibility permission (System Settings > Privacy & Security > Accessibility) so your pet can react to your typing and cursor. Input is only detected, never logged or sent anywhere.

Build a standalone app

npm run pack    # portable build -> dist/win-unpacked/pixelpets.exe (no installer)
npm run dist    # Windows installer -> dist/pixelpets Setup <version>.exe

pack works out of the box. dist (the NSIS installer) needs permission to create symlinks while electron-builder unpacks its bundled signing tools: enable Windows Developer Mode (Settings > Privacy & security > For developers) or run the build once from an Administrator terminal. The native uiohook-napi module ships N-API prebuilds, so npmRebuild is disabled in the build config and no Visual Studio is needed.

macOS: npm run dist:mac (on a Mac) builds a dmg and zip for Apple Silicon and Intel; the release workflow also builds them in CI on every version tag. Builds are ad-hoc signed rather than notarized, so Gatekeeper still asks before the first launch: open it once, then System Settings > Privacy & Security > Open Anyway. The ad-hoc seal matters for more than the warning: macOS keys the Accessibility grant and the Keychain entry to a code signature, so without it both would be thrown away on every update.

macOS beta checklist

The mac port is code-complete but has not been smoke-tested on real hardware. If you own a Mac, running this and opening an issue with whatever you see is the single most useful contribution to the project right now.

  • The overlay shows over all apps and Spaces, including fullscreen.
  • Clicks pass through everywhere except on the pet.
  • The typing reaction works after granting Accessibility.
  • The pet rests on the Dock edge, not the menu bar.
  • The tray menu works in the menu bar.
  • Login launch works.

Visual QA

The overlay is GPU-composited, so ordinary screenshots cannot capture it. Poses are reviewed with a one-command contact sheet instead:

npm run poses:cat

That renders every activity across every coat into one image, bottom-aligned on a shared floor line so silhouettes can be compared down a column. It runs headlessly, with no Electron and no GPU, by loading the overlay's script stack in a vm (scripts/overlay-vm.js) and reading the pose grids back out. That is also what the pose tests drive, so the sheet and the suite are looking at exactly the same sprites.

Single poses preview via:

npx electron . --shot --state=<sit|typing|hunt|loaf|groom|paper|overheat|pet|startle|work|rearup> --pattern=<coat>

Add --at=<ms> to capture an animated pose at a chosen phase (a typing key-press, say): npx electron . --shot --state=typing --at=760. Add --note="<text>" to pin a speech bubble open in the capture, which is how bubble wrapping and screen-edge clamping get checked against a real font rather than only in unit tests: npx electron . --shot --note="a long reminder that has to wrap".

The butterfly has two flags of its own. --bfly forces a visit from the first frame, so npx electron . --shot --bfly --state=rearup --at=1021 frames the rear-up swat with the bug in shot. The catch itself cannot happen in a shot (both pounce triggers stand down under --shot), so --joy pins the victory beat that follows one: happy eyes and a blush the whole time, and the double bounce looping every two seconds (1.4 s of bounce, 0.6 s still), the way --state=done loops its hop. It loops because --at counts from page load while the renderer's clock started earlier, so no single --at lands on a known phase: take two or three captures a few hundred milliseconds apart and one of them is mid-bounce. The "oh!" beat when the bug is first spotted opens on the very first frame, before the capture timer starts, so it is covered by a test rather than a shot.

Painting a pose by hand

Every pose is composed in code, which is why one sit covers 15 coats and a new coat costs nine hex values instead of an art pass. The trade is that changing how the pet looks means editing geometry.

npm run frames:import is the escape hatch: paint a pose against a placeholder palette, import it, and it wins over the composer for exactly the coats you name while everything else keeps composing. Five held poses can be baked (sit, type, loaf, rear, hunt); the six raised-limb activities are parameterised rigs whose limbs sweep through quantised frames, so a still would freeze them.

Palette, naming and the checks the importer runs are in frame-pack.md.

README media

The hero banner, the gallery, and the coat carousel are all rendered from the same sprite geometry by scripts/make-demo-gif.js, in pure Node with no browser or GPU. Regenerate any one with node scripts/make-demo-gif.js <hero|gallery|carousel> [mp4], or all three with npm run demo:all.

Tech

Electron, HTML canvas, Web Audio, uiohook-napi (system-wide keyboard hook), imapflow, and node-ical.