Overview
Toast Town is a browser-based game built using Vite and served via Docker containers, hosted at breadtoasting.com/toasttown/. The project aims to create an interactive 3D town where players can explore, interact with characters, and engage in mini-games. The town layout is designed around radial symmetry, with eight compass-point exits branching off from the main plaza.
Background
The concept of Toast Town was born out of a desire to give Bread Boi, the mascot character, a vibrant and interactive environment to inhabit. The game features various buildings such as the Yogurt Cafe, Avocado Court, Gary's Comics, and Toast Threads, each with its own unique mini-games. Additionally, there are generic "toastfolk" wandering around the town, and future zones like the Forest and Beach are planned.
How It Works
Development Setup
The project uses Vite for development, which allows for fast hot-reloading during coding sessions. The build process involves a multi-stage Docker container: a Node.js environment to compile the code, followed by an Nginx Alpine container for serving the final assets.
# Example Dockerfile snippet
FROM node:16 as builder
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install --production=false
COPY . .
RUN yarn build
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
Building the Game
The game is built using three.js, a JavaScript library for 3D graphics. The development environment includes a Vite server that compiles and serves the code in real-time.
# Example command to start the Vite dev server
vite
Debugging Techniques
One of the more challenging aspects was debugging runtime errors. Syntax errors are caught at build time, but other issues like missing imports or incorrect API usage can only be detected during runtime. These issues cause scenes to get stuck in a solid brown overlay, making it difficult to pinpoint the exact issue.
To debug these problems, I developed a pattern where I would run scene construction headlessly in a plain Node container with stubbed browser globals (like document and localStorage). This allowed me to get stack traces and accurately identify the source of the error.
Bug Fixes
A critical bug was found during the code audit: the save-file merge function was re-running its migration logic at every level of recursion, causing the save data size to triple with each page reload. Empirically, this led from 8KB to 22MB in four reloads, eventually breaking browser localStorage limits and silently failing for real players.
This bug, along with several smaller issues like missable checkpoints and a spamming quest-toast, were documented and handed off as an ordered fix list.
Results
Toast Town is now live at breadtoasting.com/toasttown/. The game includes the following features:
- Yogurt Cafe: A 4-lane note-highway rhythm game with a fully self-contained WebAudio synth soundtrack.
- Avocado Court: An outdoor basketball shootout minigame, along with a Rec Center for future expansion.
- Gary's Comics: A timed genre-sorting mini-game where players must sort comics before the clock runs out.
- Toast Threads: A clothing shop where players can buy and equip hats and ties.
Additionally, there are generic "toastfolk" wandering around the town, and future zones like the Forest and Beach are in development. The town layout is designed with radial symmetry to maintain a clean aesthetic.
Lessons Learned
- Radial Symmetry Layout: Designing the town square with eight compass-point exits ensures a balanced and organized layout.
- Code Audit Importance: Regular code audits can help catch critical bugs early, preventing silent failures in production.
- Headless Debugging: Running headlessly in Node containers can provide valuable stack traces for runtime errors.
The project also has a detailed roadmap for future development, including multiplayer functionality, additional zones, and more advanced features like day/night cycles and seasons.
Conclusion
Building Toast Town was an engaging and challenging endeavor that required careful planning and attention to detail. The combination of Vite, three.js, and Docker provided a robust development environment, while the project's roadmap ensures there is always something new to work on.