Inspiration
- With the theme of Sport, our minds immediately jumped to the World Cup. It's taking the world by storm and we are no different so it seemed the logical route of our focus.
- Furthermore, we all have a keen interest in the chance side of things, not knowing which team has the upper hand and simply relying on analysis or previous data, it seemed very logical and well themed to our needs.
What it does
- Our application takes pre-existing probabilities for a team win or draw for each of the current games in waiting and uses these as a starting point. From there we used votes from the user to dynamically alter these chances in real time. Each vote for either team to win or both to draw, altered the visible percentages to now be based around the public vote on who they believe would win or draw.
- Another api we have utilised updates the teams and probabilities once matches are played so once the final game comes around only that one will then be visible on the site.
How we built it
- The first stage was of course planning which we used Trello as it was a good and efficient way of listing all of our requirements and being able to order them, list any and all relevant information while also having the ability to clearly label who was working on what and when each step was completed.
- The second stage was of course our execution stage where the group was split between the front and back end with a priority on making it user friendly and visually appealing.
- For our front end we wanted it to be simple yet elegant while also retaining the style of football itself.
- The backend focused primarily on our database reliance and ensuring that it worked from the offset so it was our first major step to creating the project as a whole. Once that was complete, our focus shifted towards our api and the necessary logic to create our vision.
Challenges we ran into
- Two halves of the team, two mental models. The frontend was built 3-way (with a Draw button) while the backend was first built 2-way — they didn't fit together. We stopped, agreed that football itself is the source of truth (group games can draw, knockouts can't), and redesigned the backend around a per-match stage so both sides finally spoke the same language.
- Percentages that lie. Naive rounding made splits add up to 99% or 101%. We fixed it with largest-remainder rounding so a prediction is always exactly 100%.
- The "first vote = 100%" problem. On an empty database, one vote made a match look 100% certain. We seed baseline votes so the crowd prediction has believable inertia from the very first load.
- Team permissions. Our repo owner was an org admin and the rest of us were contributors, so we adopted a clean fork-and-pull-request workflow to ship safely without stepping on each other.
- Free-tier cold starts. Render's free instance sleeps when idle; we added a /health endpoint to warm it before demoing.
Accomplishments that we're proud of
- Zero-Dependency 3D: A stunning, rich-textured 3D rotating football built with 100% pure CSS — no WebGL or Three.js bloat.
- A drift-proof prediction engine: Predictions are always derived fresh from raw votes and always sum to exactly 100% — no stale cached percentages, no race conditions.
- Football-accurate, not generic: The engine knows a knockout can't end in a draw and adapts outcomes per match — enforced all the way down to the database.
- Verified, not vibes: We proved the backend works with 9 unit tests and 20 end-to-end assertions against a real MongoDB, plus live smoke tests against the deployed API.
- Full-stack, shipped in a day: From an empty repo to a live, CORS-secured API on Render, a seeded Atlas database, and a Cloudflare Pages frontend talking to it end-to-end.
What we learned
- Agree on the data model first. The single biggest slowdown was frontend and backend diverging; a five-minute contract up front would have saved hours.
- Verify end-to-end, don't assume. Running the real API against a real database surfaced issues (unseeded DB, wrong API URL) that unit tests alone never would.
- Simple beats clever. An append-only vote log recomputed on read is trivially correct and concurrency-safe — no locks, no counters, no drift.
- The platform can do more than you think. A convincing 3D football fell out of pure CSS.
What's next for Voteball
- Live-updating predictions via polling/WebSockets so the crowd split moves on screen without a refresh.
- Real fixtures, auto-synced from a live World Cup data feed instead of hardcoded matches.
- Accounts + one-vote-per-user, and a post-match reveal that scores how accurate the crowd (and each fan) was.
- Smarter aggregation — recency-weighted or outlier-trimmed averages to resist vote spam during a live demo.
- More of the tournament — full group + knockout coverage, and richer stats per match.
Built With
- cloudflare
- css3
- express.js
- github
- html5
- javascript
- mongodb
- mongoose
- node.js
- radix
- render
- trello
- tsparticles
Log in or sign up for Devpost to join the conversation.