Assignment 3 - Once More Unto the Frontier
This assignment will get your Procedural Generation and Utility skills in top-shape!
It will do so in one of the world's most premier environments in the strategy game space: Andrew Forney's Nano Nations -- a civilization-lite game of my own creation! (for rules and other details, consult the lecture slides)
(PS, that wasn't my high score and did not start from the far more generous starting conditions for the game at launch)
As you complete your assignment, you may be asked to make additions to your Report or Recordings, which will be artifacts you generate alongside your programmatic component. These requirements are tagged in purple boxes like this one so don't miss them!
For any written response, you should collect your answers in a single PDF that clearly indicates which answers pertain to which questions from the spec.
For any recorded / video response, you should upload a video to a hosting service like YouTube, Vimeo, Box, etc. and include a link in your report.
Important: for any video resource, ensure that you can access it without being logged into your account before submitting!
Motivation
There are 2 chief tasks associated with this problem space:
1. For complex environments in which traditional planners may be overwhelmed, utility-based agents stand to make for dynamic NPC gameplay without having to worry about all of the individual control flow attached to decisions from a top-down perspective.
2. For creating interesting, diverse maps in these settings (that aren't simply some randomized patchwork pastiche of tile types), we will practice some generative techniques.
Solution Skeleton
Start with the solution skeleton in-hand!
Inside, there is a rather large codebase, only parts of which you'll need to complete the assignment:
/Scripts/AI/Agent.csis where you will complete your work guiding the utility-based agent in Problem 1 below./Scripts/WorldGen/WorldGenerator.csis where you will complete the procedural map generation in Problem 2 below.
Once open in the Unity Hub, ensure that you can open the NanoNationFirstSeed scene and that all assets are visible.
This project uses the following FREE asset packs (credit to their creators):
Important: Use Unity Version 6000.0.38f1 for this assignment (you should be prompted to download it when loading into your editor).
Specifications
Let's start by just getting familiar with the codebase, pieces of which have been demonstrated during lecture.
Begin by opening the
NanoNationsFirstSeedscene, click on the GameManager Game Object in the Hierarchy, and ensure that the "Is Agent Enabled" checkbox is UNCHECKED. This will allow you, the human, to play the game and remember the rules.Once you have played a game (or enough to remind yourself of the rules), go back to the GameManager Game Object and click the "Is Agent Enabled" checkbox. Run the scene, and observe that the player no long has control, but is instead controlled by the agent defined in Agent.cs. It's not very good. In fact, it only places 1 random building per day for which it has resources, and currently lacks any sort of connection to the game objectives. You'll fix this.
-
Take a dive into the code and review the files introduced during the lectures, paying attention to the following:
AI/Agent.cs: observe how the agent currently manages its FirstDay (to choose a Castle starting location) and NewDay (to place as many buildings as it wishes, though in the current implementation, only picks a random building for which it has resources per day) methods. These will be the chief methods in which you will make changes to the Agent player. You should also make note of the other provided helper methods that can be used to determine if buildings can be placed in desired locations, how to actually register the desired building at a location, etc.WorldGen/WorldGenerator.cs: observe the GenerateWorld method, whose sole job is to create the grid of tile types that will compose the game map. At present, these are chosen randomly from the available tiles. You will change this so that the procedural generation is done more naturally and demonstrate your ability to use Noise-based generation effectively.
[CharlemAIn]
Goal: create an automated player of NanoNations who, on randomly generated tileset maps, consistently scores 2500 points or higher from the game's default starting settings (i.e., the default starting resources, 100 days, standard building costs, etc.).
And yes, the problem name is a riff on Charlemagne (the emperor, not the rapper), AI edition, as you must now enhance the lacking strategy of our AI player of Nano Nations.
You will likely need to focus on transforming two of the agent's currently pretty random choices into more informed, utility-based, more carefully planned operations:
FirstDay: consider scanning the entire grid in some way that finds a reasonable spot for your castle based on some utility definition.
NewDay: consider some utility function that scores the frontier locations by building type. You may also want to incorporate strategies from the lecture, like giving your agent motivations that may even be sensitive to the current day or resources. Some sort of depth-limited expectimax may also be appropriate, but is entirely up to you!
Once you have settled on a version of your agent that you are pleased with, detail your strategy for the FirstDay and NewDay methods in your report. Include images to demonstrate your agent's strategy (e.g., images of 2-3 adjacent days demonstrating its planning / priorities / motivations).
Finally, include a video of your agent passing the score threshold on a random map with Day Duration set to 0.1.
Note: when testing your agent, you can set the Day Duration on the GameController object to something like 0.1 to view games completed nearly instantaneously.
BONUS: All agents will be tested on a randomly generated map with some unknown seed -- the team whose agent achieves the highest score will obtain a +4 bonus on this assignment score!
[Perlin, Mapout]
Goal: create a non-randomized version of the WorldGenerator that uses Perlin Noise to create more natural landscapes with less patchwork tile types!
This will involve several steps:
First, create a new SerializableField for the WorldGenerator class to be able to choose between two generation modes: Random (its present behavior) and Perlin (which you will design).
When Perlin is selected, you should be able to configure other SerializableFields for properties like scale, number of octaves, etc. You may draw inspiration from the NoiseVisualizer project demo'd in class, and which is available under the Materials tab of the course site.
The bulk of the work will be in determining how Perlin Noise generated over an area the same dimensionality as the game board can map to the assignment of tile types. You'll want to introduce new methods to do this translation -- this is where the fun is! (Hint: instead of the noise mapping to height like we saw in Minecraft, think of it somehow mapping to the tile types -- remember that Perlin values should be between 0 and 1!).
Once you have figured out this mapping, use your new WorldGenerator with the Perlin setting on to generate worlds with the following qualities (hint: you may need additional configuration options like new SerializableFields to select between biome-types like the following):
Grasslands = large amounts of grass with frequent spots of dirt and the occasional snowy zones. There should be almost no desert, and water in small lakes.
Desert Riverlands = large rivers surrounded by desert. Snow tiles are rare, and there are only spots of grass and dirt.
Arboreal Snow = large lakes surrounded by dirt tiles, mostly snow elsewhere with the occasional grass tile. Almost no desert.
In your report, detail how you went about mapping Perlin Noise to the tile types, and include example maps generated for each of the map biome types above.
In your report, include a link to a video showing how your AI agent plays on the new, modified terrain types (it's OK if they don't perform as well). Discuss your findings, why they behave the way you expected or didn't expect.
Congratulations! You are gods of creation following this exercise -- but don't worry, you get to rest on the last day.
Grading
Your submission will be graded on successful completion and report on all Problems listed above. Each are weighted equally.
Since some portions leave some room for creativity / interpretation, feel free to reach out if you have questions of whether or not your approach meets the stated spec.
BONUS: All agents will be tested on a randomly generated map with some unknown seed -- the team whose agent achieves the highest score will obtain a +4 bonus on this assignment score!
Submission
You will be submitting your assignments through GitHub Classroom!
What
Complete all requested sections of the skeleton above AND finalize your report in a /doc/ subdirectory as shown in the skeleton before
pushing your finished project to your GitHub Classroom repo.
How
To clone this assignment (if you need a refresher), consult the guide here:
To submit this assignment:
Simply push your final, submission copy to the GitHub Classroom repository associated with your account.
Place your name(s) at the top of *all modified* files AND in the accompanying
readmefile.