Skip to content

PlayPets developer guide ​

Overview and audience ​

PlayPets is a pet app whose pets play on the desktop and in the yard window. You connect an AI to a friend to chat with it, and friends react while a coding agent works. It is a Tauri v2 app: the page is web code with no build tool (src/), and the backend is Rust (src-tauri/). It runs on macOS, Windows and Linux.

This guide is the entry point for people who change the code, build integrations, or handle releases. How to use the app is in the user guide on the site and in the repository README. These documents also appear as is under the site's "Developers" tab. The contribution process (PRs, check order) is in CONTRIBUTING. AI agents and review bots working in the repository read AGENTS.md, a short version of these rules.

Key concepts ​

  • One app, two windows: There is the yard window (the main window) and a transparent desktop window, one per monitor. Both windows only draw the state the backend holds.
  • Commands and notifications: The page calls the backend through a single window.playPets.<command>(). When state changes, the backend sends the new state (change) to every window, and sends one-off happenings as events (event).
  • Pets and friends: A pet is a character file (pet.json plus a sprite sheet, in the Codex pet format). A friend is a pet invited into the yard. Each friend has a name, a personality, a size and an AI connection.
  • AI connection: Optional for ordinary movement, games, gardening and collecting; it gives a friend AI conversation. Claude Code and Codex use their signed-in CLIs; subscription allowances and any paid extra usage apply, and API-key CLI sign-in can incur separate charges. Ollama and OpenAI-compatible servers use HTTP. Local models need no hosted inference fees; remote services use their provider’s billing. API keys saved by PlayPets live only in the OS secure storage.
  • Agent integration: Running the app executable as playpets hook … or playpets mcp runs it in CLI mode with no window, and it sends status to the running app through a local HTTP bridge. Node.js is not needed.
  • Strings tables: Sentences shown to people live in two tables, one for the page and one for the backend, in Korean, English, Japanese and Simplified Chinese. Code uses only keys.
  • Lock rule and page redraws: The backend never waits on the main thread while holding the state lock. The page redraws often only while something moves. These two rules exist to prevent freezes and battery drain.

Area map ​

Go to a document based on what you want to know.

What you want to knowDocument
Getting the repo, running tests and starting the app for the first timeSet up a development environment and run the app
Root settings, directory ownership, generated files and common maintenance commandsRepository layout and tooling
How the app is built and what calls whatArchitecture: PlayPets app
How coding agents reach the app; CLI, HTTP and MCP specsArchitecture: coding agent integration
Adding a backend command the page can callAdd a backend command the page calls
Adding, hiding or reordering community discovery linksAdd or change a discovery site
Adding a selectable indoor or outdoor placeAdd a place for friends
Adding a fish, a bug, a flower or a gift, a drawing or an effect, or changing the sceneryAdd to the yard
Reproducing seasonal, game, collection and audio review fixturesVisual review
Setting up once: the updater key, the GitHub repository, secrets, the Homebrew tap, winget, signing accountsSet up the repository, keys and store accounts
Releasing a new version and distribution channelsRelease a new version
Changing the site (intro, user guide, version pages)Edit and check the website
Changing the site addressChange the site address
Adding a language the app speaksAdd a language
Where to look first when stuckTroubleshooting guide

These are the standards to follow. Read the one for an area before changing it.

AreaStandard
Page modules, stylesStandard: Page code structure
Backend concurrencyStandard: Backend locks and threads
Strings and translationStandard: Multilingual strings
Draw loops, animation, overlayStandard: Page and backend performance
TestsStandard: Testing
Branches, commits, what never goes in, historyStandard: Commits, branches and history
Signing keys, tokens, certificatesStandard: Managing signing keys and secrets
Pet filesStandard: Pet file format

These are the procedures for outages and incidents.

SituationProcedure
Updater signing key lost or leakedThe updater signing key is lost or leaked

Getting started ​

If you are new, read in this order.

  1. Follow Set up a development environment and run the app to get the tests passing and start the app.
  2. Read the diagram and data flow in Architecture: PlayPets app. Find which component the part you want to change belongs to.
  3. Read the standard for the area you are changing (the standards table above). Page changes almost always involve Page code structure and Multilingual strings; backend changes almost always involve Backend locks and threads.
  4. Test in the check order in CONTRIBUTING and open a PR. Add one line to CHANGELOG.md for any change users can see.

Deep dives and reference ​

Decision records: why the structure is the way it is. The standards point to them as their basis.

For the remaining publication steps, use the first public release hand-off. Local checks and signed upgrade testing are separate gates.

Design records and research

Records are dated and not rewritten; when two disagree, the later one holds. The five records of 2026-10-11 and 2026-10-12 consolidate that period's design work (decision).

Repository automation

FileWhat it does
.github/workflows/build.ymlbuild job: lint, test, build and E2E on five environments. site job: builds the site, so a dead link fails the PR. Runs for every push to main and every PR
.github/workflows/release.ymlBuilds every environment from a version tag into a release draft
.github/workflows/distribute.ymlwinget manifest and Homebrew cask from a published release
.github/workflows/pages.ymlBuilds and publishes GitHub Pages when its source or shared inputs change on main
website/The VitePress site. Developer docs are copied from docs/ at build time
packaging/Local distribution builds (macOS dmg; Linux and Windows through Docker)
scripts/Icon generation, release, distribution file generation, CPU measurement, site preparation, screen capture, mascot pets

Common commands

CommandWhat it does
npm testRust unit tests and page tests
npm run checkLint, unit tests and site build; run E2E separately
npm run test:js / test:rustFocused Node / Rust tests
npm run build:app / startBuild the normal native executable / run that existing build
npm run assets:auditCheck image dimensions and references; save an inventory under ignored scratch/asset-audit/
npm run lint / npm run formatCheck / tidy code layout (rustfmt, clippy, Oxlint, Biome)
npm run test:e2eReal-app E2E
npm run measureCPU measurement in five states (macOS, Linux)
npm run site:dev / site:buildSite dev server / build (includes dead link check)
npm run shots -- x.y.zReal-app screenshots in every app language (macOS)
npm run ogRedraw the four share cards (website/public/og.png in English, og-ko.png, og-ja.png, og-zh-hans.png) and the README banner
npm run artRedraw the installer art: the macOS disk image background (packaging/macos/dmg-background.png), the Windows installer's sidebar and header (packaging/windows/nsis-*.bmp), and the English screenshots Linux software centers show (website/public/listing/en/, from the current captures). Where each is used is set in src-tauri/tauri.conf.json (bundle.macOS.dmg, bundle.windows.nsis, bundle.linux) and packaging/linux/app.playpets.metainfo.xml
npm run dist:mac, dist:windows, dist:linuxLocal distribution files (release/<platform>/)
npm run release -- x.y.zRelease commit and tag
npm run iconsEvery icon from assets/icon.png

Frequently asked questions ​

Can I change Windows code without checking it on Windows? You can check that it compiles with npm run dist:windows (Docker), and the CI Windows runner runs E2E. For things you only learn by running, like window behavior, say in the PR description that it needs checking.

Why does the page have no bundler? The browser reads the page's ES modules as they are. With no build step, the file you edit is the file that runs, and tests enforce the module rules instead. The full reasoning is in the decision "Page modules run nothing on import…".

Do I need a signing key to develop? No. Tests, E2E and local distribution builds all run without keys. Keys are used only in CI when a maintainer releases.

How do I change a string? For a sentence on the page, edit src/core/strings/<language>.js; for a backend sentence, edit src-tauri/src/i18n/<language>.rs. Change every language together (the Korean file is the reference). The rules are in the Multilingual strings standard.

Free and open source under the MIT license. Not affiliated with OpenAI; Codex is a trademark of OpenAI.