Skip to content

moonbench/catode32

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

435 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Catode32 - A virtual pet for your ESP32

catstars

spookycat

Pet Features

Pet Care

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:

Stats

Pet Behavior

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.

Behaviors

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.

Minigames

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.

In-Game Store

In-game store

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!

Locations

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.

Weather

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!

Vacations

parkvacation

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

beachvacation

Gardening

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.

Playdates

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.

Home Comfort

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.

Controls

  • 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)

Setup

Hardware Requirements

  • ESP32-C6 SuperMini OR ESP32-C3 development board
  • SSD1306 OLED Display (128x64, I2C)
  • 8 Push Buttons for input

Software Requirements

  • mpremote installed (pip install mpremote)

Board Configuration

The project supports both ESP32-C6 and ESP32-C3 boards. To configure for your board:

  1. Open src/config.py
  2. Set BOARD_TYPE to either "ESP32-C6" or "ESP32-C3"
# In src/config.py
BOARD_TYPE = "ESP32-C6"  # Change to "ESP32-C3" for ESP32-C3 board

Wiring

Choose the wiring diagram for your board. Each button connects between GPIO pin and GND (internal pull-ups enabled).

ESP32-C6 Wiring

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

ESP32-C3 Wiring

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.

Installation

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.

1. Set Up Build Tools (one-time)

Install build prerequisites:

brew install cmake ninja dfu-util   # macOS

Clone 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-cross

If you keep ESP-IDF or MicroPython somewhere other than ~/esp/, set the IDF_PATH and MICROPYTHON_DIR environment variables before running build scripts.

2. Build and Flash Custom Firmware

# 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 esp32c3

This 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.sh after flashing to restore game files.

3. Configure Board Type

Before uploading, set your board type in src/config.py:

BOARD_TYPE = "ESP32-C6"  # or "ESP32-C3"

4. Upload Game Files

./upload.sh

This installs the ssd1306 library, compiles and uploads all game logic. Asset files are not uploaded since they live in the firmware.

Development Workflow

For the fastest iteration during development, use the dev.sh script which compiles Python to bytecode and runs via mpremote mount:

./dev.sh

This script:

  • Compiles all .py files in src/ to .mpy bytecode in build/ (excluding src/assets/)
  • Converts level files from levels/ into binary format in build/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.

Scripts

./tools/build_firmware.sh

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 port

Re-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).

./test_hardware.sh

Verifies that your hardware is working correctly:

./test_hardware.sh

This 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.

./upload.sh

Deploys the project to the ESP32's flash storage:

./upload.sh [port]

This script:

  • Installs the ssd1306 library via mip
  • Compiles all .py files to .mpy bytecode (excluding src/assets/, which are frozen in firmware)
  • Converts level files from levels/ into binary format in build/platformer_levels/
  • Cleans existing files from the device (preserves lib/, save.json, and webrepl_cfg.py)
  • Uploads compiled .mpy and .bin files and boot.py to the device

Use this when you want the pet to run standalone without a laptop connection.

Running the Game

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()

Troubleshooting

"could not enter raw repl" error

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:

  1. Run mpremote to connect to the device
  2. Press Ctrl+C to interrupt the running game
  3. Press Ctrl+B to exit raw REPL and enter friendly REPL
  4. Remove boot.py:
    import os
    os.remove('boot.py')
  5. Press Ctrl+X to exit mpremote

Now ./dev.sh should work again.

Monitoring serial output without interrupting the game

To watch print() output from a running game without sending Ctrl+C or triggering a reset:

macOS:

screen /dev/cu.usbmodem* 115200

Linux:

screen /dev/ttyACM0 115200

If the glob doesn't match (or you have multiple devices), find the exact port first:

  • macOS: ls /dev/cu.*
  • Linux: ls /dev/ttyACM* or ls /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.

Contributing

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.

About

Virtual pet for the ESP32

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors