When I make a toy app for my own learning, I start small and add one feature at a time, each time figuring out some new piece about the framework or language I’m working in.
There’s a point in adding features where they start to make each other harder. One time I made a Cat Diary, and then I let the cats mark some entries public so other cats could see them, and then I let them delete entries. But then I had to stop them from deleting other cats’ entries. Feature interaction crops up so fast!
I’m trying to keep it simple, to focus on each new concept or experiment. I thought “one at a time” was the simplest I could achieve, but it isn’t simple enough.
A friend of mine has a different habit, and I think his might be better. Eric Evans is learning about game development by making a tiny multiplayer game. He made the simplest game he could think of: join a room, land in a small green square, and be a capsule. Move with the arrow keys, bump into each other and into the single tree.
Technically a landscape, technically multiplayer. The game is called “Yur It.”
Once he got this working, he started adding features. Like that yellow dot above my head, that’s a feature. That yellow dot transfers to another player when I catch them, because then they’re “It,” see. He learned about collision detection.
He added a first-person point of view, learning about camera placement and angles and more things.
Oh and there’s jumping, which had an unexpected consequence: if you stand by the wall, and I jump on your head, then I can jump onto the wall. From there I can leap over the side and fall forever into the abyss.
Also there’s changing facial expressions 😉 . There’s hand-rolled observability (sending events to Honeycomb). There’s a “jetpack” that lets you get on top of the tree!
Each of those features exists… in its own version of the game.
Eric forks the repository each time, and adds the new feature to the base game. That way, the learning is not complicated by feature interaction.
Keep your experiments separate.Eric Evans
I now think this is a superior process for learning a new framework, programming style, whatever we’re focused on.
Add features one at a time—not as a series, but on alternate timelines. With version control, we have this superpower.
Sometimes we do combine features, afterward. Like he cut-and-pasted the change-facial-expressions code into the observability fork, so that we could add traces that showed why each expression change happened. At that time, we got to focus on the combination of changing expressions and observing events. The interaction has its own learning, separate from each feature individually.
In real work, the lesson from this is: sometimes, play around with implementing a feature, learn something, and then throw that code away. Try implementing it a different way—not thoroughly each time, but enough to learn something. Then when you implement it for real, you can lean on a breadth of understanding.
Adding features gets harder as you go, because each one comes with the unwritten requirement: “…and everything else still works.” Free yourself of that constraint when you can!