MyPuppy — A Brazilian Virtual Pet That Remembers You
This is a submission for Weekend Challenge: Dog Days Edition.
What I Built
MyPuppy is a mobile-first virtual pet inspired by the digital toys of the 1990s, reimagined around Brazilian mixed-breed dogs.
Users can:
- create an account;
- adopt Caramelo, Fiapo de Manga, or Malhadinho;
- name their dog;
- feed, play with, walk, and give Cafuné to their pet;
- watch hunger, happiness, energy, affection, hygiene, and walk needs evolve over time;
- build memories and personality traits;
- receive contextual reactions and notifications.
The goal was to make the pet feel alive without making the experience stressful or punishing. The dog never dies, and missing a few days creates gentle moments such as sleeping, boredom, or excitement when the owner returns.
The product voice is warm, funny, affectionate, and slightly chaotic — like a Brazilian friend speaking excellent English.
Demo
Live demo: MyPuppy
The application is designed primarily for mobile, but also works on desktop.
Code
GitHub repository: MyPuppy
How I Built It
MyPuppy was built with:
- Next.js App Router;
- React;
- TypeScript;
- Tailwind CSS;
- PostgreSQL;
- Prisma;
- Gemini through the Google Gen AI SDK;
- Web Push API;
- VAPID;
- Service Worker;
- Vitest;
- Vercel.
The most important architectural decision was separating the deterministic pet engine from the AI layer.
The virtual pet engine owns all game state. It calculates:
- time-based decay;
- action effects;
- cooldowns;
- event detection;
- sleep states;
- absence behavior;
- personality progression;
- owner-returned events.
The engine is implemented as pure, testable functions and does not depend on React, the database, or Gemini.
Gemini is only used to express what the dog feels. It generates short reactions and notification copy based on a small structured context containing the dog archetype, current state, personality traits, and domain event.
For example:
text
Domain event
↓
Check reaction cache
↓
Reuse cached reaction or call Gemini
↓
Validate structured response
↓
Use deterministic fallback if necessary

Top comments (0)