Inspiration The hackathon theme was time and every initial idea we had felt too obvious and not as creative. A clock. A timer. A visualization. We kept asking ourselves "what if time wasn't something you observed, but something you had to defend?" That question led us to TIMEKEEPER. We wanted the theme to feel immersive— not illustrated, but with high stakes. The idea of real historical events being physically destroyed unless you intervened made time feel urgent in a way no dashboard or animation could.

What it does TIMEKEEPER is a real-time spacetime simulation game. Asteroids carrying real historical events hurl toward Earth — 1969, the Moon landing. 44 BC, Julius Caesar. 1440, the printing press. You place deflector lines on screen to bend each asteroid's path using gravity. One line deflects one asteroid, then disappears. Let an asteroid through and that year is erased from the timeline at the top of the screen — struck through in red, gone from history. The game spans five levels covering five eras of human history, from the Ancient World to the present. Each level introduces harder asteroid types: armored ones that survive the first hit and rocket forward when their shell breaks, spiralers that orbit inward in a tightening circle, splitters that fracture into two pieces when struck, and chargers that start slow and accelerate until nothing can stop them. Level five has no basic asteroids at all — only the hardest variants.

How we built it The entire game is a single Python file built on pygame with no game engine. Every system is hand-rolled. Asteroid movement uses vector steering math applied every frame so every enemy continuously homes toward Earth — none of them fly past if you don't intervene. The deflection system uses line-circle intersection geometry to detect barrier hits, then reflects the velocity vector off the barrier's surface normal. The spacetime grid is a live gravitational field visualization calculated in real time. Earth itself is rendered once to an offscreen surface using layered ellipses, continent blobs, ice caps, and an atmospheric halo — then blitted each frame for performance. The five levels each have their own historical event sets, spawn rates, and asteroid type pools defined in a clean data structure at the top of the file.

Challenges we ran into The hardest technical problem was making all asteroids reliably hit Earth without intervention. Early versions had asteroids that would curve past Earth or spiral off-screen, which broke the core tension of the game — if the player doesn't need to act, there's no game. We solved this by adding a per-frame steering force toward Earth on top of each asteroid's existing velocity, so every asteroid continuously corrects its path. Tuning that steering strength against spawn speed to make the game feel threatening but fair took significant iteration. The armored asteroid behavior was also tricky — getting it to absorb the first hit, visually crack, then dramatically speed up rather than slow down required carefully separating the hit detection from the velocity calculation.

Accomplishments that we're proud of The timeline system ended up being one of our favorite things in the project. Years glow amber when their asteroid is incoming, turn green when saved, and strike through red when lost. At the end of each level you see the full record — which events survived and which were erased. It transforms what could have been a generic score screen into something that actually feels meaningful. We're also proud of the asteroid variety — each type has its own movement logic, visual identity, and interaction rules that reinforce its personality. The charger's fading orange trail, the splitter's crack lines, the armored asteroid's shattering shield ring — all of it communicates gameplay information while also just looking good.

What we learned We learned that game feel comes almost entirely from small physics decisions. The difference between an asteroid that feels threatening and one that feels annoying is a few lines of steering math. We also learned that building constraints into your design — one deflector line at a time, no shooting, no respawning — forces more interesting player decisions than systems with unlimited options. On the technical side, we got much better at pygame surface management and understanding when to cache renders versus recalculate them each frame.

What's next for TIMEKEEPER We want to add a global leaderboard that tracks which historical events players worldwide are worst at saving — so you can see that 79 AD (Pompeii) has a 94% erasure rate and 1969 (the Moon landing) has only a 12% one. We also want to add a sandbox mode where players can set up their own historical timeline, choose which events to defend, and share scenarios with others. Multiplayer is on the table too — one player placing deflectors while another controls the asteroid spawn rate. And we'd like to expand to more eras, more asteroid types, and eventually a procedurally generated endless mode where history just keeps coming.

Share this project:

Updates