Why are the players so terrible at football?
These little football players are really, really dumb; they don't just have bad player AI, they have none whatsover. They have no knowledge of the rules of football; they have no awareness of other players; they are incapable of making decisions from moment to moment about what to do. They don't know that they want to score touchdowns or tackle quarterbacks; they just run blindly in variously-sized circles as fast as they variously can, according to what their genes have to say about how they're physically built.
That's the beautiful thing about genetic algorithms: if you set up the rules for rewarding good behavior correctly, you can let a bunch of randomly generated circlular idiots breed for a hundred generations and something resembling football emerges.
The Basic Idea
Genetic algorithms are a way of using the ideas of fitness (as in survival of the fittest) and selection (as in natural selection) to model the behavior of a system in a computer program. By coming up with a way to judge how well a member of a population is doing (a "fitness function") and using the relative fitness of different members of the population to decide who succeeds (that is, survives or successfully mates or doesn't get fired from their football team) and who fails (dies without mating, gets kicked out of the league), we can use only the genes of the more successful members of the population to create new members of the population. As the process repeats, the selection pressure of the environment causes a slow evolution of the overall genetic makeup of the population as successful genes propogate and unsuccessful ones disappear.
Genetic Football runs with that idea in the following way:
- Each simulated football player starts each play facing in a specific direction, runs forward at a specific speed, and curves left or right at a specific rate, all determined by their genetic code.
- Genes are modeled as small numeric values representing things like limb length and strength, torso size, skin pigment, and so on. Players generated at start of a new league have randomly generated genes.
- As a result of their genetically determined behavior, players will perform varyingly well, ideally making tackles and running the ball forward and scoring touchdowns, but possibly just running in circles or backwards or getting sacked. Players get scored after each play on what they did.
- After some number of games, each team will fire some proportion of its worst players, and replace them with new ones, through some mix of cloning an existing player, breeding a new hybrid player from two existing players, and spawing a totally random new player.
- As time passes, low-performing players will be eliminated from the genetic pool while high-performing players will be used as genetic source material for new players, thus passing on their relatively successful football genes.
- Pause — freeze and unfreeze the simulation. Handy for taking a closer look at players and stats.
- Turbo — toggles higher-speed processing of the real-time simulation. How much turbo will actually speed things up depends on your computing device — desktops/laptops will likely see more speed-up than mobile devices.
- Skip Games — cease all visual aspects of the simulation temporarily to process a given number of simulated games as quickly as possible before returning to normal simulation. Very handy for seeing how tweaks to genetic selection and fitness metrics affect a league over the long term.
- # of games to skip — set the total number of games that Skip Games will calculate before returning to normal simulation.
(Note: the page will be essentially unresponsive during the skipping process; how long it lasts will, like with Turbo, depend on the speed of your device, and on how many games you're skipping at a time. Experiment with smaller numbers of games and/or shorter league game lengths to figure out what works for you.)
- Switch roster type — toggle the display of team information in the simulation's drawing canvas between a graphic-centric portrait of each team's players and a stats-centric view with tiny player portraits and detailed career statistics.
Note that none of the League controls will have any effect until the "Start new league" button is pressed.
- # of teams — set the total number of teams in the next league you start.
- players on team — set the number of players per team in the next league you start.
- game length in secs — set the time allotted for each game in the next league you start.
- Start new league — reset the simulation with a newly generated set of teams and players based on the controls above.
* firing strategy
- games between firings — a team will fire its lowest-performing players after it finishes playing this fixed number of games. Lower values will lead to quicker turnover of underperforming players; larger values will give players more of a chance to establish average performance vs. one or two particularly lucky or unlucky outings.
- % of players to fire — when a team fires players, it'll fire this percent (rounded up) of its players, ranked by average per-game performance since being hired. Setting this to 0% will keep team rosters completely static; setting it to 100% will get produce a completely random new team after every firing cycle.
* breeding strategy
The following three proportion controls are taken as a group and divvied up based on the ratio of the three values; they do not need to add up to 100, you can distribute them relative to one another however you prefer. If you set all three to zero, the simulation will default to producing random players during the firing/hiring process.
- proportion of cloning — proportion of newly hired players who will be genetic clones of one of the non-fired team members. (If the team has fired all of its players, a random player will be generated instead of a clone.)
- proportion of mating — proportion of newly hired players who will be the hybrid genetic offspring of a pair of non-fired team members, with each gene consisting at random of either one parent's allele or the other's. (If the team has fired all of or all but one of its players, a random player will be generated instead of a mated hybrid.)
- proportion of random — proportion of newly hired players who will be entirely genetically random.
- mutation rate — the chance that any given gene in a clone or a mated hybrid will differ from the parent's gene. Setting this to 0% will result in perfect cloning/hybrids with no new genetic variations; setting it to 100% will produce essentially random offspring.
Player performance is measured in terms of how often they perform specific tasks in the game; after every play ends, a player's total performance (their "Value" statistic) is recalculated based on their total career statistics multiplied by the corresponding weighting factors below. Changing how much different actions are rewarded can significantly change the kinds of behavior that become dominant over time as players are fired and new players are cloned and mated and mutated. (Normally all of these things would be weighted at least a little bit positively, but setting some to negative might produce some interesting results. It's not like the league can fire you, after all.)
- per yard gained — how much fitness "Value" a player gains (or loses!) for each yard they carry the ball forward while acting as the ballcarrier for their team. Yards lost will be scored as well, with the opposite of this value.
- per QB tackle — Value awarded a player each time they tackle the opposing team's ballcarrier while that opposing player has succeeded in moving past the line of scrimmage (the red line representing where the current play started).
- per QB sack — Value awarded a player each time they successfully perform a sack; that is, when they tackle the opposing team's ballcarrier while that opposing player is still behind the line of scrimmage.
- per TD scored — Value awarded a player each time they, while carrying the ball, move past the goal line and into the opposing team's endzone, scoring a touchdown for their team.
- per safety scored — Value awarded a player each time they successfully sack the opposing team's ballcarrier in the opposing team's own endzone, scoring a safety for their team.
- per point scored — Value awarded a player for in-game points they score for their team. A touchdown earns a team seven points; a safety earns a team two points. (And the ballcarrier who commits a safety by getting tackled or running out of bounds loses two points on his statistical record.) Setting this to 1 would thus increase a players Value by 7 for scoring a touchdown and by 2 for a safety; setting it to 5 would earn them 35 for a TD and 10 for a safety.
Frequently Answered Questions
How did you make this?
Is the source code available? Can I modify this?
The source code is available right here on GitHub! You are welcome to tweak/fork/fiddle with your own copy of it as long as you point clearly to the original work here.
It runs slow or bad or whatever on my phone/computer/WebTV.
I have tested this very little outside of the web environments I use every day; if you're not in Chrome on OSX or Safari on an iPhone 4S, I can't vouch for anything. It will probably run a lot slower on mobile devices than on desktops/laptops. You're welcome to let me know about specific display/performance issues on twitter.
Why don't they ever pass or punt or hand off the ball?
Because those are all a little more complicated to implement than just running the ball every damn time. Perhaps they will be taught to do some of these things in the future!
Who's the QB on each team?
These footballers are very polite, and so they take turns being the ballcarrier. This lets more players on a team get a chance to perform well (or not so well) every game in every statistical category despite the fact that only the ballcarrier can score gained or lost yards or points for touchdowns.
Why doesn't the simulation accurately reflect the rules of American football?
For two reasons:
1. I made a lot of decisions to simplify the simulation compared to real football, in order to keep the implementation from getting overly complicated and to keep the little simulated football games easy to watch. Having quarters and halves, having teams switch directions, having the ball snapped from a center to the QB, tracking dedicated positions at all like center and QB and halfback and so on, applying penalties, are all details that matter more for a serious football simulation than for a genetic algorithms demonstration wearing a football costume, and so they've been streamlined out for this.
2. I don't actually know much about football and so am just wrong about things. Mostly my experience with the sport is reading Jon Bois' Breaking Madden and yelling HUDDLE UP at my cats when I want to pretend that they'd ever respond meaningfully to a verbal command.
Yeah but so why football then?
Because I wanted something fun to look at. I've really enjoyed playing with things like Genetic Cars and have always wanted to try out some related ideas of my own. When I finished my first genetic algorithms experiment, Blurst of Times, I was happy that the idea worked but realized it just wasn't very much fun to watch. What's more fun? Tiny dudes running around doing a thing. And "football" is an easy idea to sell visually in a minimalist way. You don't need to know a ton about it to get the basic idea, and there's something a little bit enchanting about watching little circles push each other around and accidentally pull of the occasional brilliant play.