Phoenix Dodgeball (pic courtesy Tina Aramburu)

With Growing complete, I’ve started prototyping an idea I’ve been kicking around for a while. It’s a fusion of one of my favorite genres (turn-based strategy) and my favorite sports (dodgeball). (If you haven’t seen dodgeball since your elementary school days, you should get reacquainted with the competitive scene; it’s awesome! Here’s a video from my league that demonstrates some high-level play.)

The Concept

Starting Line (pic courtesy of Matthew Wegner) One thing that makes competitive dodgeball so interesting is the concept of “the burden.” Put simply, the burden is an algorithm to determine which side has a responsibility to give up balls in the next play. (The punishment for noncompliance usually involves the burdened team losing all their balls to the other side, which can be fatal against a veteran team.)

What’s fascinating though, is that the burden creates an implicit resolution of play into “turns,” and most high-level strategy gets encapsulated in a turn-based framework. These pseudo-turns consist of 3 main parts:

1. Positioning.
Both teams take control of balls on their respective sides of the court. The defending team typically spreads their balls to the far ends of the court to counter the attacking team.
2. Recalculation of the burden.
(See the pseudocode below for details.)
3. Attack.
The team with the burden forms and executes a plan, which must include putting N balls over the line within a 10-second countdown (where N is determined by the burden calculated in step 2).

Largely this results in match-up formats where the burden is shifted back and forth between the two teams, resulting in… you guessed it! A turn-based strategy game.

When games start to be played in this back-and-forth manner, the key strategic elements become targeting, ball control and defensive readiness. It’s this interplay between the offensive and defensive elements that I’m focusing on, because that’s where I think the truly interesting gameplay decisions are.

The Code

Here is pseudocode for the burden calculation algorithm. The definition of burden I used can be found in Section 9.5 of the Phoenix Dodgeball Competitive League Detailed Rules. (Burden calculation may vary between leagues and rulesets.)

function GetBurden() {

ballsOnLeft, ballsOnRight = CountBallsOnCourt();
leftSidePlayersRemaining = leftTotalPlayers - leftPlayersInQueue;
rightSidePlayersRemaining = rightTotalPlayers - rightPlayersInQueue;

// special rules for burden when 1 player is remaining
if(leftSidePlayersRemaining = 1 and rightSidePlayersRemaining = 1):
DeathmatchMode();
else if(rightSidePlayersRemaining = 1):
return GetLastManStandingBurden(rightSide, ballsOnRight);
else if(leftSidePlayersRemaining = 1):
return GetLastManStandingBurden(leftSide, ballsOnLeft);

// outside of last man standing scenarios,
// burden is determined by number of live players + balls

leftBallsAndPlayers = ballsOnLeft + leftSidePlayersRemaining;
rightBallsAndPlayers = ballsOnRight + rightSidePlayersRemaining;

if(leftBallsAndPlayers = rightBallsAndPlayers):
// when balls are equally divided,
// burden goes to the team that didn't just throw
if(ballsOnLeft = ballsOnRight):
return burdenedSide = !burdenedSide, burdenAmount = 1;
else:
return burdenedSide = GetSideWithMoreBalls(), burdenAmount = 1;
else:
return GetOverallBurden(leftBallsAndPlayers, rightBallsAndPlayers);

}

function GetLastManStandingBurden(sideWithLastMan, ballsOnLastManSide) {

ballsAgainstLastMan = TotalBalls - ballsOnLastManSide;

if(ballsAgainstLastMan >= 2):
return burdenedSide = !sideWithLastMan,
burdenAmount = ballsAgainstLastMan - 1;
else:
return burdenedSide = sideWithLastMan,
burdenAmount = 2 - ballsOnLastManSide;

}

function GetOverallBurden(leftTotalBurden, rightTotalBurden) {

// side is always allowed one ball regardless of burden
burdenedSide = SideWithGreaterTotalBurden(leftTotalBurden, rightTotalBurden)
burdenAmount = minimum of (1/2 Difference between leftTotalBurden and rightTotalBurden) and (TotalBalls - 1);

}

 
It’s not always entirely straightforward to determine who has burden of throw. In the sport, the referees are in charge of keeping track. In my prototype, there’s an evaluation method that runs at the end of a turn to determine if the burdened team has given up their share of the balls (burdenAmount referenced above). Once that condition has complete, both sides are free to end the turn. Calculation of hits then happens synchronously in phases for both sides.

That’s it for now! Keep an eye out; I’ll be posting more about this soon, along with links to the code and maaaybe some primitive builds.

Leave a Reply

Powered by LOVE! ...and Wordpress!

Copyright © 2011 Corey Nolan