- Pet Care
- Behaviors
- Minigames
- In-Game Store
- Locations
- Weather
- Vacations
- Gardening
- Playdates
- Home Comfort
Your pet needs your help to have a healthy, fulfilling, affectionate life.
Your pet has 18 stats which change over time, and they change at different rates.
| Tier | Stats | Change rate |
|---|---|---|
| Rapid | health, fullness, energy, comfort, playfulness, focus | ~Daily |
| Medium | fulfillment, cleanliness, intelligence, maturity, affection | ~Weekly |
| Slow | fitness, serenity | ~Monthly |
| Slowest | courage, loyalty, mischievousness, curiosity, sociability | Very slowly |
All stats sit on a 0-100 scale. Health is never set directly; it's a weighted average of some of the other stats.
To care for your pet, you'll want to:
- keep them well fed with varied meals
- give them affection (pets, scratches, kisses)
- groom them from time to time
- buy them toys and play with them regularly
- gently train their behavior
- play minigames with them
- take them on trips
- and keep their environment interesting with healthy plants
Your pet will help communicate some of these needs through vocalizations. You can also go to the pet stats page to see them all at any time:
Your pet will exhibit various behaviors over time, specifically you'll see them:
sleeping, napping, stretching, kneading, lounging, investigating, observing, chattering, zoomies, vocalizing, self_grooming, being_groomed, hunting, gift_bringing, pacing, sulking, mischief, hiding, training, playing, affection, attention, eating, startled, meandering
After finishing, each behavior transitions to a new behavior. The next behavior is selected based on the pets current needs, which behaviors have been exhibited recently, and a bit of randomness.
By observing your pet's behaviors you can better understand your pet's needs. If they're sulking or vocalizing that they're bored then perhaps you should play with them or show them some affection. If they're looking a bit upset or vocalizing about food then try going to the kitchen to feed them.
Often they'll be lounging around, napping, or just enjoying their environment.
There are several minigames to keep both you and your pet occupied.
Playing these games provides different stat rewards for your pet, depending on the game type. And they provide coins which you can spend at the in-game store to help care for your pet even better.
The rewards for each game are related to the type of game itself. For example, puzzle games are likely to reward intelligence gains. Action games are more likely to provide fitness gains (and probably some energy losses!) Each game is a bit different, and the rewards are also scaled by how long you play and how successful you are in it.
You can earn coins through the minigames, and sometimes your pet will find a few coins randomly when they're in the mood to do a little hunting.
These coins can be spent at the in-game store to help you care for your pet.
At the store you can buy:
- Meals
- Kibble, Cod, Haddock, Trout, Shrimp, Herring, Turkey, Tuna, Salmon, Chicken, Liver, Beef, Lamb
- Snacks
- Carrots, Pumpkin, Treats, Fish Bytes, Eggs, Nuggets, Milk, Chew Sticks, Puree
- Toys
- String, Feather, Yarn Ball, Laser Pointer
- Gardening supplies
- Various sized pots, Seeds (Grass, Fresia, Sunflower, Roses), Spade, Watering Can, Fertilizer
- Care Services
- Professional Grooming, Professional Training
- Vacations
- Trip to the Park, Forest, Aquarium, Beach
Your pet will appreciate variety in their meals and snacks, and they'll be enriched by exposure to new toys and locations. Adding plants to your pet's home, and keeping those plants healthy, will give a big boost to your pet's mood and life!
Within your pet's home there are a few different spaces for them to hang out. They are the:
- Living room
- Bedroom
- Kitchen
- Outside (Back yard)
- Treehouse
Some of these have special perks. For example, playing with your pet outside or in the living room provides more satisfaction than playing with them in the kitchen. Likewise, feeding them in the kitchen gives them a bit more satisfaction from food than feeding them in the bedroom. And going to the bedroom when the pet's energy is low will encourage them to sleep or nap earlier than they would otherwise (and they'll get a bigger energy and comfort boost for sleeping there too!) Lounging outside or in the treehouse or the living room will be a bit more serene for your pet than lounging in the kitchen, etc...
You can choose to take your pet to a different location, and sometimes they'll decide to go to different locations on their own.
Beyond those at-home locations, there are also some external locations such as the park, forest, aquarium, and beach which you can visit with your pet by taking vacations via the store.
There's a dynamic weather system that progresses over time. The weather can be one of: Clear, Cloudy, Overcast, Windy, Rain, Storm, or Snow. These transition from one to another in sensible ways (i.e., an overcast day might clear up or might start to rain.)
From the Forecast page in the game you can see what the weather will likely be for the next few hours and days.
The weather has some effects on your pet. For example, you don't want to let them sit outside in the rain or their comfort will rapidly plummet!
And while you have a chance to see a shooting star or two each night, you might see a forecast for a meteor shower with lots of them!
If you save up some coins you can take your pet on different vacations. Each one will give some different rewards to your pet, like boosting their sense of fulfillment. But don't stay too long! If your pet starts to hint that they're overwhelmed and they want to go home then it's probably time to wrap up the trip.
You can take them to:
- The park
- A forest
- The aquarium
- The beach
Through the store you can buy different gardening related items, such as pots, seeds, tools, and fertilizer. Once you've bought some of those things you can then use the gardening menu to place pots around your different rooms, and you can then plant seeds in them (you can also plant seeds directly into the ground outside.)
Once you have a plant started, you should keep them watered over time to keep them growing. And if you fertilize them as well you can really get them to thrive.
Having healthy plants around will give extra boosts to your pet's satisfaction.
You can access the "Social" menu to let your cat go on playdates with other cats! If two Catode32 devices are near each other and both access the social menu, then they'll broadcast availability to each other and you can start a playdate.
Both cats will appear on both devices, and the pets will interact and build social connections. Cats will start to remember friends they've spent a lot of time with.
The devices will also activate their wireless features whenever the cats are in the outside or treehouse scenes, but in a more subtle way. The cats won't see each other directly, but if one vocalizes while outside then any nearby cats who are also outside in their own yards will hear it and they might chatter back.
Periodically, your device will use wifi to get a sense of the world around it. It will just do a quick scan to see the names of nearby wireless networks and slowly build up a list of "familiar" ones. Once it has learned what networks you spend the most time around your cat will then feel more comfortable and safe around that location. If you travel to unfamiliar places your cat might be a bit more skittish and less comfortable until they spend some time getting familiar with that new space.
The intent is that a pet left at home is calmer, sleeps better, and plays more freely, while a pet taken somewhere unfamiliar becomes more anxious and restless.
- D-pad: Navigate / Move camera
- A: Select/confirm
- B: Back/cancel
- Menu button 1: Global menu options (always the same)
- Menu button 2: Contextual menu options (based on the current scene)
- ESP32-C6 SuperMini OR ESP32-C3 development board
- SSD1306 OLED Display (128x64, I2C)
- 8 Push Buttons for input
mpremoteinstalled (pip install mpremote)
The project supports both ESP32-C6 and ESP32-C3 boards. To configure for your board:
- Open
src/config.py - Set
BOARD_TYPEto either"ESP32-C6"or"ESP32-C3"
# In src/config.py
BOARD_TYPE = "ESP32-C6" # Change to "ESP32-C3" for ESP32-C3 boardChoose the wiring diagram for your board. Each button connects between GPIO pin and GND (internal pull-ups enabled).
Display (I2C):
| Display Pin | ESP32-C6 Pin |
|---|---|
| VCC | 3V3 |
| GND | GND |
| SDA | GPIO4 |
| SCL | GPIO7 |
Buttons:
| Button | GPIO Pin |
|---|---|
| UP | GPIO14 |
| DOWN | GPIO18 |
| LEFT | GPIO20 |
| RIGHT | GPIO19 |
| A | GPIO1 |
| B | GPIO0 |
| MENU1 | GPIO3 |
| MENU2 | GPIO2 |
Display (I2C):
| Display Pin | ESP32-C3 Pin |
|---|---|
| VCC | 3V3 |
| GND | GND |
| SDA | GPIO6 |
| SCL | GPIO7 |
Buttons:
| Button | GPIO Pin |
|---|---|
| UP | GPIO0 |
| DOWN | GPIO1 |
| LEFT | GPIO2 |
| RIGHT | GPIO3 |
| A | GPIO4 |
| B | GPIO5 |
| MENU1 | GPIO10 |
| MENU2 | GPIO11 |
Note: The ESP32-C3 configuration avoids strapping pins (GPIO2, GPIO8, GPIO9) to prevent boot issues.
This project uses custom MicroPython firmware with asset data frozen directly into flash. The sprite/icon data lives in flash rather than RAM, which frees up a significant portion of the ~85KB heap budget. You build the firmware once, flash it, then upload only the game logic.
Install build prerequisites:
brew install cmake ninja dfu-util # macOSClone ESP-IDF and MicroPython into ~/esp/:
mkdir -p ~/esp
# ESP-IDF (required version: v5.5.1)
git clone --recursive https://github.com/espressif/esp-idf.git ~/esp/esp-idf
cd ~/esp/esp-idf && git checkout v5.5.1
git submodule update --init --recursive
./install.sh esp32c6,esp32c3
# MicroPython
git clone https://github.com/micropython/micropython.git ~/esp/micropython
cd ~/esp/micropython
git submodule update --init --recursive
make -C mpy-crossIf you keep ESP-IDF or MicroPython somewhere other than
~/esp/, set theIDF_PATHandMICROPYTHON_DIRenvironment variables before running build scripts.
# Build and flash in one step (auto-detects USB port):
./tools/build_firmware.sh build-flash
# Or specify board and port explicitly:
./tools/build_firmware.sh build-flash esp32c6 /dev/tty.usbmodem1234
./tools/build_firmware.sh build-flash esp32c3This compiles a custom MicroPython binary with all src/assets/ modules frozen in, then flashes bootloader, partition table, and firmware to the device.
Note: Flashing replaces the entire filesystem. Re-run
./upload.shafter flashing to restore game files.
Before uploading, set your board type in src/config.py:
BOARD_TYPE = "ESP32-C6" # or "ESP32-C3"./upload.shThis installs the ssd1306 library, compiles and uploads all game logic. Asset files are not uploaded since they live in the firmware.
For the fastest iteration during development, use the dev.sh script which compiles Python to bytecode and runs via mpremote mount:
./dev.shThis script:
- Compiles all
.pyfiles insrc/to.mpybytecode inbuild/(excludingsrc/assets/) - Converts level files from
levels/into binary format inbuild/platformer_levels/ - Mounts the
build/directory on the device - Runs the game
Asset files are skipped because they are frozen into the firmware. MicroPython resolves frozen modules before the filesystem, so uploading them would be redundant.
Note
Requires mpy-cross (pip install mpy-cross) and mpremote (pip install mpremote).
The device must be running the custom firmware (see Installation). Asset imports will fail on stock MicroPython firmware.
Builds custom MicroPython firmware with asset modules frozen in flash, then optionally flashes it:
./tools/build_firmware.sh # build only, ESP32-C6
./tools/build_firmware.sh build-flash # build and flash, ESP32-C6
./tools/build_firmware.sh build esp32c3 # build only, ESP32-C3
./tools/build_firmware.sh flash esp32c6 /dev/tty.usbmodem1234 # flash with explicit portRe-run this whenever you add new sprite data to src/assets/ (after running tools/convert_bytearrays.py to convert any new bytearray literals to bytes literals first).
Verifies that your hardware is working correctly:
./test_hardware.shThis script:
- Resets the device
- Scans I2C to confirm the display is detected
- Enters an interactive button test (press buttons to see them register, Ctrl+C to exit)
Run this first when setting up a new device or debugging hardware issues.
Deploys the project to the ESP32's flash storage:
./upload.sh [port]This script:
- Installs the
ssd1306library viamip - Compiles all
.pyfiles to.mpybytecode (excludingsrc/assets/, which are frozen in firmware) - Converts level files from
levels/into binary format inbuild/platformer_levels/ - Cleans existing files from the device (preserves
lib/,save.json, andwebrepl_cfg.py) - Uploads compiled
.mpyand.binfiles andboot.pyto the device
Use this when you want the pet to run standalone without a laptop connection.
After uploading, the game starts automatically on power-up or reset.
To enter REPL mode instead: Hold A+B buttons while powering on or pressing reset. This skips auto-run so mpremote can connect.
To manually start the game from REPL:
mpremote
>>> import main
>>> main.main()If you see mpremote.transport.TransportError: could not enter raw repl when running ./dev.sh or other mpremote commands, it means boot.py is on the device and auto-running the game, blocking mpremote from connecting.
To fix this:
Either press A + B while ./dev.sh to interrupt the boot sequence.
Or, to remove the boot.py file so that it doesn't activate:
- Run
mpremoteto connect to the device - Press Ctrl+C to interrupt the running game
- Press Ctrl+B to exit raw REPL and enter friendly REPL
- Remove boot.py:
import os os.remove('boot.py')
- Press Ctrl+X to exit mpremote
Now ./dev.sh should work again.
To watch print() output from a running game without sending Ctrl+C or triggering a reset:
macOS:
screen /dev/cu.usbmodem* 115200Linux:
screen /dev/ttyACM0 115200If the glob doesn't match (or you have multiple devices), find the exact port first:
- macOS:
ls /dev/cu.* - Linux:
ls /dev/ttyACM*orls /dev/ttyUSB*
Press Ctrl+A then K to exit screen.
This is useful after a reboot (e.g. from a context save) breaks an mpremote session; the game is still running and its output is still on the serial port.
It's helpful to open an issue prior to making a PR to allow discussion on the changes.
It's also helpful to keep PRs small and targeted.






