Virtual Plant Simulator: Learning State Through a Plant That Could Mutate
Neglect is easier to simulate than growth. That was the interesting part. Instead of modeling a plant getting bigger, I modeled what happens when nothing happens, then tied that to a simple state machine driven by time.
This was a small learning project. Around a hundred lines total. One page, a few images, a timer, and a button. But it forced me to think about interaction as state instead of scattered DOM changes.
Building Around Time
The core mechanic was a counter that increments every second. At 20 seconds the plant wilts. At 40 it mutates. Watering resets the counter and returns the plant to a healthy state. That was the whole loop.
What made it interesting was not the thresholds themselves but organizing the code so the timer logic, plant updates, and click handling were separate functions. That was one of the first times separation of concerns felt practical instead of theoretical.
I also liked how much feedback came from small details. CSS transitions on image swaps made state changes feel less abrupt. That was a tiny detail, but it changed how the project felt.
A Small Project With Real Decisions
Even in something simple, choices show up.
- Use a single neglect counter instead of tracking multiple plant conditions
- Keep thresholds hardcoded so the logic stayed easy to reason about
- Use vanilla JavaScript only, which made every state change explicit
The hardcoded thresholds were intentional at the time. Configurable values would have been cleaner, but fixed values made debugging easier while learning.
What Did Not Work Well
The biggest limitation was persistence. Refresh the browser and the plant forgets everything. That broke the illusion immediately. localStorage would have made it feel more alive.
The interaction was also too narrow. Watering was the only action. Once the state transitions worked, I could have added sunlight, growth stages, or competing variables instead of a single neglect timer.
I also used a basic boolean plus counter for state tracking. It worked, but looking back I would probably model the plant as a more explicit finite state machine. That would have scaled better.
What It Taught Me
This project was one of the first times I saw simple systems become interesting through rules, not complexity. A few thresholds and a timer produced behavior that felt responsive.
It also taught me that even toy projects expose engineering habits. Naming functions well matters. Separating responsibilities matters. Handling edge cases matters, even when the whole codebase fits on one screen.
It was not a big project. It was a first pass at thinking in systems.
Sometimes a mutated plant and fifty lines of JavaScript are enough.