Skip to content

Tiny Tech & Dance Battles

subscribe

This year, I helped run Windy City Throwdown V (WCTV) , an annual hip hop dance battle in Chicago. You may have already seen my training journey for this event, but this article will focus on something else: how I built a custom tech stack for the dance battle.

This is a bit absurd, right? I am a non-engineer, yet with the tools available I’m able to build tech that otherwise never would have existed. I like to affectionately call these sorts of projects Tiny Tech: tech for problems that are so niche, that they only become possible with AI bringing the cost of software development close to 0.

After reading this article, I hope you walk away with 3 themes:

  1. Anyone can do what I do - after the event, I often heard, “How did you do this?” or “I wish I could do that”. I’m a glorified SQL monkey with a biology degree - if I can do this, you can too
  2. Lean into your community - life has become increasingly isolating. Building for WCTV was a lovely way to get closer to the Chicago dance community. I used tech to do this, but find your own way to contribute
  3. I’m awesome - what can I say, this is just true

If any of these themes sound interesting to you, I think you’ll like what I have in store. Let’s go!

What is a dance battle?

Dance battles are a way for dancers to showcase their skill, artistry, and story in a competitive environment. You may have already seen battle videos on social media - these clips tend to be incredibly popular! Here are a few examples of amazing dancers doing rounds for House battles:

Flash Haddi

Soma

Danzel

The videos of the rounds above come from different stages within a battle. Most battles have two stages:

Stage 1: Prelims

When you have hundreds of people enter a battle, how do you separate the wheat from the chaff? Prelims let every entrant quickly showcase their skills. You get a predetermined amount of time (like 45s) to dance to music from a DJ. Judges assign scores, deliberate, then select the top X dancers to move onto Top Cut. These rounds are NOT head to head, and are instead done sequentially in order to get through many dancers quickly.

Animation of a dance battle prelim: 16 dancers each take a turn on stage, are ranked, and the top 8 advance to the top cut.

Stage 2: Top Cut

The great dancers who qualified from prelims get to flex their mastery during Top Cut. This involves head-to-head battles where each dancer gets multiple rounds dancing to music. Judges determine winners from each head to head, eventually resulting in an overall winner.

Animation of a 8-dancer single-elimination bracket: each round one dancer per match is chosen at random to advance, until a single winner is crowned.

Given this, dance battles operators need to be able to:

  1. Collect registration information (and payment) from dancers
  2. Organize dancers for Prelims so that they know where they need to be and when
  3. Enable judges to rank which dancers from prelims should qualify for Top Cut
  4. Display who has qualified for Top Cut, then show progress through Top Cut

Getting all of these right is critical in delivering a great battle experience!

Step 1: What is the job to be done?

Now we understand the subject area! But before building anything, I wanted to make sure I understood what Windy City Throwdown specifically needed from a dance battle tool. I interviewed organizers and attendees from last year, and used my own volunteering experience for data.

The main complaint was that the event went WAY too late. There were 4 key problems:

  1. Slow registrations - registrations before the event took longer than expected for 3 reasons:
    • Missing info - the registration form asked many questions, but didn’t have everything we needed, so manual collection was required
    • Many forms - there were also multiple forms, so attendees were confused because they (rightfully) assumed that filling out one form was all that they needed to do
    • Bad incentives - ordering for prelims was determined based on when dancers registered. So dancers would show up early, and delay registration in order to get a later spot in prelims
  2. Slow judging - paper scoring meant judges had to manually compare scores and calculate averages, delaying the process
  3. Slow prelims - dancers only heard who was up next from the MC, so we lost time hunting for them when they were missing
  4. Lack of buffer time - no buffer time was built into the schedule, so every delay above cascaded through the rest of the event

If we could address these root causes, we could deliver a much more delightful experience for battlers and attendees, while reducing strain on organizers.

Step 2: Can we be lazy?

Before even thinking about a tech solution to these problems, we need to ask, “can existing tools do the job?”

I went through each problem from last year, detailed the exact gaps, and determined if existing tools could address them:

Solutions Exist

Novel Problems

I realized that most issues could be addressed with better planning and better use of Google Forms. However, judging and prelims communication still had genuine gaps. These problems were specific to dance battles, so I started searching for any existing solutions.

The first that came to mind was BreakKonnect. BreakKonnect is a platform that helps battle organizers handle the logistics of an event. However, exploring BreakKonnect revealed some serious gaps. The two most critical were that:

  • It didn’t let us add Photo Release forms or Waivers of Liability as part of the registration process, which was required for risk management
  • It didn’t let us import a list of registrants from a CSV — so even if we collected the liability forms and registrations elsewhere, we couldn’t easily import them into BreakKonnect afterwards

As a result, BreakKonnect was not a viable platform for our event.

Unfortunately, we could not be lazy — there was a true need that existing solutions simply couldn’t meet. It was time to build a MVP

Step 3: What is the MVP?

To build the MVP, I needed to sketch out the core (minimum) requirements that were needed. After some deliberation, we determined that the tech needed to let organizers:

  1. Create, edit, and manage multiple different battles - WCTV had 3 separate events with different requirements and needs
  2. Load dancers - take registrations from google forms and import them via a CSV
  3. Operate prelims - communicate who’s currently dancing, who’s up next, and show timers
  4. Handle judge feedback - make it easy for judges to save scores along with notes, in order to make deliberations easy
  5. Operate top cut - after judges decide who makes it to Top Cut, we need to generate and run the bracket
  6. Customize - battles are always different, organizers need to be able to adjust length of rounds, how many people are in top cut, etc.

A good MVP also requires us to detail what is OUT OF SCOPE. This was what I decided was out of scope for this V0:

  • Visual Refinements - backgrounds, photos, animations, etc.
  • Registrations - this would be handled by google forms
  • Payments - this would be handled by EventBrite

Step 4: Let’s Build

Now that we have a direction, let’s start making some simple architecture decisions. First:

  • Platform: Web only — we don’t do anything requiring a native app, and web deployment is much easier than dealing with the App and Play Stores
  • Language: Flutter — I’m using this because I was familiar with the language from previous projects.
  • AI Tools: Claude Code — An AI assistant is a requirement for development nowadays - in the next section, we discuss how I set up my repo to work with Claude

With that, I had everything I needed to get started!

How did I set up my repo?

In order to speed up my product development, I created 3 things first:

plan.md

For my own needs, and to make it easy to work through the list of requirements with Claude, I dictated my MVP requirements to Claude and asked it to add a plan.md to a repo I created. Afterwards, I went in and refined the list of requirements, added details where appropriate, and corrected bad assumptions made by the model.

  • plan.md

Open this article on desktop to see and download these files

CLAUDE.md

Next, I outlined recommendations to Claude about how I wanted it to interact with the repo, and how I wanted to work with it. One of the most important directions I gave was to have separation of logic and UI: it enables much easier testing, since logic changes can be tested quickly by Claude; if a UI change is needed, we know we don’t need to read the logic files at all; and I think this helps make my development cycle more token efficient, as Claude only needs to read the titles of the files to determine if it needs to load all of it or not.

  • CLAUDE.md

Open this article on desktop to see and download these files

UI standards files

Finally, I had Claude create files to store colors, constants, and themes that we would use throughout the codebase. This was a very easy way to have a more polished product, with very little effort. In addition, if I ever wanted to make changes (like color customizations), all I had to do was edit the values in these files.

  • app_colors.dart
  • app_theme.dart
  • app_fonts.dart
  • app_dimensions.dart
  • app_animations.dart

Open this article on desktop to see and download these files

One important aspect not covered here are the CI tests I utilized. The reason I don’t describe these is because I…didn’t write any. At the end of the day, I’m not an engineer - I don’t know what makes for good tests, or what to be adding into here. Instead, I instructed Claude to write its own CI tests, and this seemed to work well enough.

With these first steps completed, I was ready to actually start building. On July 10th, I started iterating through the requirements in the plan.md.

Timeline

Shockingly, I had the MVP ready in about a week, only working part time on the project! Obviously, it was a very rough product, and NOT yet ready for the event, but it was functional. It’s still mind blowing to me what one person is able to do with the tools available today.

The chart below details the PRs that I pushed to the repo over time, along with major milestones.

Daily PR Activity

WCTV0246810Jul 10Jul 17Jul 24Jul 31Aug 7Aug 148146563365241Initial Async ReviewJul 17Final In-Person ReviewAug 9

54 PRs pushed · Jul 10 – Aug 16

Aug 9: final checks at the studio

Step 5: Iteration

After reviewing the MVP with stakeholders, their request was: how can we make this more delightful? It was time to turn the MVP into a Minimum “Lovable” Product. For this stage of development, I focused on 2 major opportunities:

Visual Delight

Dancers are cool as fuck. A tool for dancers should be similarly cool. However, my expertise is not in design, and I have never created displays for public events before. How could I build a delightful experience, while also keeping my limitations in mind?

Therefore, I focused on 3 areas of improvement:

  • Showcasing Dancer Portraits — dancers are cool, so using them is an easy way to make my tool cool. Every battler at the event would get their photo taken, and their portraits would be displayed in the Top Cut brackets
  • Display Customizations — During the day of the event, we should be able to easily update the background, the darkness of the background, text sizes, glow effects, positioning of elements, and other aspects. Then, while we’re actually at the venue, we can adjust the visuals as needed for maximum clarity
  • Animations — simple animation effects (outlines, grow/shrinks, movement) could greatly enhance the quality of the display, so I used 2-3 PRs to add those in

Resiliency

We would be using this tool for a live event with many dancers and attendees. The app may work perfectly when I’m testing it solo under perfect conditions, but how can I ensure it also delivers during the day of the event?

  • First, I ‘idiot-proofed’ the tools for operators — for example, we didn’t want an operator to be able to move onto the next prelims round until the current dancer had finished their timer (keep note of this…it’ll reappear later).

  • I was also worried about wifi being an issue, so I ensured the tool could work locally without wifi (for short periods of time). For judges, I made sure that the tool could also print judging sheets in case we needed a backup plan

The Final(?) Product

So after all of this work, let’s walk through the product, and how it addresses the gaps we outlined in Step 1:

Prelims

My prelims tool lets operators import dancers via CSV, randomize the order for prelims, print off judge sheets (if needed), and start/reset timers for the rounds. In order to ensure dancers always know when they are up, the public display shows the next 5 dancers giving them ample time to go to the prep area.

The operator tool doesn’t look ideal on phones, because it was designed with desktop in mind. However, in a pinch, organizers can use their phones to control the battle!

Public Display
Operator UI

Judging Tools

Once Prelims have started, judges get links to their judging sheets. These sheets let judges see who is currently dancing, save scores, and take notes for future reference. The tool also lets judges jump around in order to revisit notes or adjust scoring.

After all scores are submitted, we automatically determine the dancers who have made it to Top Cut using the top average scores. Judges can then deliberate with each other on any adjustments they want to make.

Judge UI

Top Cut

The Top Cut tool lets the operators customize and run the bracket. There are timers, simple yet engaging animations, and most importantly, photos!

Again, the operator tools were designed with desktop users in mind, but can be used on a phone in a pinch!

Public Display
Operator UI

There’s a lot more behind the scenes in order to enable all this, but this is the fun stuff I wanted to show off!

Show Time

Building the tech was just half the battle — the real question is how did it perform during the event? It’s story time!

Day 1 - Prelims

The first day was TOUGH. I won’t detail everything that we had to do, but let’s just say there were lots of unexpected issues. I was responsible for 4 things:

  • Checking if attendees/battlers had bought tickets for the event
  • Registering attendees/battlers, and making sure we had all the necessary info
  • Importing the list of battlers into my tool after registrations have closed
  • Running: 1v1 Hip Hop Prelims, 3v3 Hip Hop Prelims, and 1v1 Hip Hop Top 28 through Top 16

I want to give a shoutout to my amazing volunteers that helped with Registrations and Tickets. This was NOT easy, and there was so much info that they needed to handle. Taraja, Shosho, Rossa, Toph, Javi, Love, Mia, and Olivia did an amazing job. Thanks to them, this mostly occurred without any issues.

However, two issues came up as soon as we started prelims:

  1. Dancers were missing in my tool — this turned out to be a human mistake. At the end of registration, we needed to check a checkbox to indicate that yes, this person has completed registration and is here to battle. However, we missed this checkbox for a few dancers.
  2. I couldn’t skip forward to the next dancer in prelims — remember how I said I idiot-proofed the tool? For example, I could only click “next dancer” if the timer for the previous dancer was finished. Well, there is also a “reset timer” button. If I click that, then I get blocked from moving onto the next dancer, even if the timer for that dancer had finished and I accidentally clicked the wrong button.

These problems were a MESS. Fixing this required some stiff-arming of the tool to get everything back in order, and the missing dancers had to go at the end and could not be judged using the judge tools I built (thankfully, we had printed off paper for the judges for scoring just in case). I even had to make various edits directly to the database in order to try and handle this, and during the meantime there were some confusing experiences for dancers and attendees.

On top of that, we ran into two more issues after we finished prelims:

  • Judging takes a lot of time — my tooling helped judges save scores, but it takes time for the judges to argue through the ranking, and land on a Top Cut that they feel good about. I could do so much more to help guide judges through the most important questions. For example, after submitting scores, judges should be able to see discrepancies: like dancers that they rated very highly, yet did not make the cut. Or highlight dancers had large variance in scores, so they could focus on deliberating about them. I think a more opinionated tool could reduce the time required for judging substantially
  • Dancer Photos — One of the best decisions we made was to take portraits of the competitors to use them for the Top Cut brackets. One of the worst decisions we made was to not label each picture with the name of the dancer when the photo was taken. It turns out that trying to remember which portrait is which person is a terrible thing to try to do when you have 100+ dancers, with most coming from out of town. This led to lots of delays as we tried to prepare the 1v1 Hip Hop bracket.

All in all, our goal for the event was for it to finish on time. Unfortunately, we ended about 2 hours late. Admittedly, I was quite dejected after this. I had tried so hard to build something that would prevent the delays, yet came up short.

We spent some time cleaning up the studio after everyone left, and I got home around 3:30 am. We had to be awake very early in the morning to prep for Day 2, so I tried (and mostly failed) to fall asleep.

Day 2 - Top Cut

Day 1 was rough. Because I was only able to get about 2 hours of sleep, Day 2 started off rough:

I was just barely holding it together at this point

On the car ride over, I was dreading what might go wrong. I kept running through different scenarios, thinking about all the potential points of failure, and planning out what exactly I would need to do to ensure that the tooling didn’t falter the way that it did on Day 1. I had already fixed some bugs the prior night, and I kept tweaking the code right up until the event started.

Here’s the thing — Day 2 went…perfectly.

I’m being serious — I don’t think there were ANY issues with the tech. We certainly ran into some logistics complexities, but those were independent of the tech. And even with those complexities we actually ended ON TIME!

Here are some pictures where you can see me tinkering away — I was relaxed enough that I could actually enjoy the event (unlike on Day 1)! You can see it on my face (check out the back left of these photos from Alyssa Ramirez )!

Tyler D Creator
Nico Tapz
Nero Da Professor
99
Law
E

Event Retro

In retrospect, I could have been more thoughtful with my testing in order to avoid the problems on Day 1. I’ll end the article with all the various product features I’d want to add to the tool to address its failures before it gets used again.

However, as much as I want to kick myself for these mistakes, the truth is that I can only learn these things by trying (and failing)! After all:

  • I’ve never run an event like this before.
  • I’ve never built tech like this before.
  • I’m not an engineer or designer or PM or a Dance Battle organizer by training.

It turns out that I’m good at learning and good at failing. And damn, the failures from this weekend have taught me a lot.

With this in mind, I do want to celebrate a simple fact: WCTV was a huge improvement over the prior year! This year had 71% more competitors in the largest event: 1v1 Hip Hop (63 → 108), yet we did not run as late as the prior year! Things could have gone better, but I’m so proud of what I built with the team.

I’ll be honest — working on WCTV was fucking hard. There were definitely some moments where I was like, “what the fuck am I doing here”. But, this adventure was very much a reminder that the only things worth doing are the hard things. And doing these hard things is the best way that I can show my love and appreciation of the community here.

post-competition delirium
post-mortem celebration

Tiny Tech Themes

Finally, I want to end the article with a reflection on my Tiny Tech concept. At the end of the day, the tools I built for WCTV only exist because Claude enabled me to build with speed and (sufficient) quality. 5+ years ago, it would take a few engineers to create a solution like this. And 5+ years ago, there’s no way anyone would build this because the need is too niche to support monetization.

With AI removing engineering as a bottleneck for niche problems, all you need is someone with a passion for the particular problem and sufficient grit to learn how to design and architect a solution. In this particular example, all it took was one non-engineer, a $20/month Claude subscription, a Github account, and about 50 PRs.

You may say that, “this isn’t yet feasible for everyone”. And I’d say you’re right - fundamentally, there are three barriers in the way:

  1. Creativity - can you recognize a problem to be solved and think of a way to solve it? Most people don’t get this far
  2. Initiative - if you have a problem, do you care enough to spend time working on this?
  3. Technical Barriers - although I am not an engineer, I still know the basics of building software (Github, PRs, etc). Someone with no experience will still struggle unless they have very high agency and learn what they need

Barrier 1 feels like a fundamental constraint on humans - not everyone is always thinking about how to fix something. However, I think Barriers 2 and 3 will disappear over time. I worked on this project a few months ago, but my hypothesis already seems to be coming true with the launch of Muse. Muse makes the effort required to work (some) problems effectively 0, removing the Initiative barrier.

I think it is only a matter of time until Muse (or other personal assistants) completely remove the Technical barrier as well. Its not hard to conceptualize an agent that is fully able to create a Github repo, author and QA its own PRs, connect to AWS or Firestore or something else for storage, and work continuously over a long period of time in order to build a product for a user. At that point, all that someone has to do is ask for a product, and the tool will be able to provide it.

This is so exciting - we’re gearing up for a Cambrian explosion of tech because anyone is able to build anything for any need in their life. There will, of course, be issues (cybersecurity is going to be a MESS for the next few years). But in the grand arc of humanity, this continues the democratization of knowledge, capability, and intelligence.

Get notified

I've got a lot of cool ideas in the works
no spam, unsubscribe anytime