Mario Level Generation

Procedural content generation is the use of algorithms (procedures) to create novel, and sometimes customized, game content from scratch. Examples of PCG include generation of levels, maps, tree, cityscapes, weapons, monsters, and quests. PCG is often used as a design-time tool to roughly sketch out level content to be refined by human designers. PCG can also be done at run-time to incorporate individual player differences such as skills or preferences. In this project, we look at run-time PCG to create Mario Bros. game levels customized to individual players’ play styles. This includes (a) learning a model of the player’s play style, and (b) using the model to create a custom level. Fortunately, the first part is already done for you. You must focus on designing and implementing algorithms that use the player information to create something that will evaluate well.

This project will be using the 2011 IEEE Super Mario Bros. Competition infrastructure (Level Generation Track). The description of the competition and some documentation can be found there.

You will write a procedural content generator in the provided Mario Bros. game engine that optimizes level content for different types of players such as those who like to jump, like to collect coins, or like to kill enemies. You will implement a genetic algorithm to tune the layout of the Mario Bros. level.


What you need to know

The Mario Bros. engine is written in Java. You will find the source code in the src/ directory.

You will modify MyLevel.java, MyDNA.java, and MyLevelGenerator.java to implement a genetic algorithm in order to satisfy a variety of "player profiles". Each player profile is an evaluation function focused on a specific type of potential player. You are provided with four player profiles:

Each evaluation function for each player profile returns a value between 0-1 (inclusive) to demonstrate how much that player profile "likes" a given level.

dk.itu.mario.engine.level.DNA:

This object contains the chromosome representation used by the genetic algorithm. It represents an individual in the population. This is an abstract base class for MyDNA.

Member variables:

Member functions:

dk.itu.mario.engine.level.MyDNA:

This is a specific version of DNA that will be used for your Mario level generation implementation. You must complete this class. You may choose to use the default string-based representation or add new member variables and functions as necessary.

dk.itu.mario.engine.level.MyLevel:

This object places the blocks of the level. It converts a MyDNA object into a structure that can be rendered. In genetic algorithm terms, MyDNA is the genotype and MyLevel is the phenotype, the organisms that manifests when the chromosome is activated.

In addition, this class contains a number of extra functions that show examples of how to create complicated level structures.

dk.itu.mario.engine.level.generator.MyLevelGenerator:

This class implements the genetic algorithm. The basic structure of the genetic algorithm is given, but the details remain to be completed.

See instructions for the functions in MyLevelGenerator that need to be completed.


Instructions

You must implement a genetic algorithm that produces level content that is "liked" by different player profiles as given by the three evaluation functions, Scrooge, Killer, and Jumper.

Step 1: Acquire and install Apache Ant (http://ant.apache.org/).

Step 2: In the homework7 directory, build the game engine:

Step 3: Modify the following files: homework7/src/dk/itu/mario/engine/level/MyDNA.java, homework7/src/dk/itu/mario/engine/level/MyLevel.java, and homework7/src/dk/itu/mario/engine/level/generator/MyLevelGenerator.java. Complete the following functions:

MyDNA:

You can create new member variables and functions as necessary to give the genotype representation the complexity needed to represent Super Mario Bros. levels. At a minimum, you will want to define a string symbol language that represents level elements that can be produced by MyLevel.

MyLevel:

If the genotype uses a default chromosome string, then create() parses the string and translates elements in the string into setBlock() calls. You may make any new member functions or member variables necessary.

MyLevelGenerator:

Step 4: Run your level generator from the homework7 directory:

To run the codebase, you must first compile any changes you've made with the command "ant" in the parent directory. Then, if the code compiled correctly, you can run the game by calling:

With the four player profiles you have access to:

When you run the application, an image (output_image.png) will be generated in the parent directory which shows the entire generated level. It will also drop a Java GUI window which allows you to play through the level using the arrow keys, 'a' to run, and space bar to jump.

If you die 3 times, Mario will respawn at the top of the screen and fly, allowing you to see the entire level.


Grading


Hints

Make sure that MyLevel.create() is linear time, or close to it. It will need to be called to turn a genotype into phenotype every time an individual is created (via mutation or crossover) and evaluated.

You may wish to create member variables in MyGenerateLevel to keep track of the global fitness of the population and how it has changed over time. You can use this to terminate the search if the search is approach an asymptote or if the global fitness (or max fitness) hasn't changed in a while.


Submission

To submit your solution, upload your modified MyDNA.java, MyLevel.java, and MyLevelGenerator.java.

DO NOT upload the entire game engine.