A few months ago, I wrote a post about how to make a game with pygame. Please check out that post first, as it lays the foundation for this one. The game was a sandbox and lacked objectives, but you could collect raw materials, craft, and build things. In this post, we will add an objective to our game that let's the player build toward something.
Before that, we need to ask: what is the point of our game? If you want to make a good game, it should have a single point. For example, Mount and Blade, a great medieval sandbox RPG in an open world, still has a single goal: "advance and develop your character." There are many ways to accomplish this single goal: fighting, trading, tournaments, doing quests, ruling fiefs, founding businesses, raiding. The point of our game is to build structures. Our objective will provide guidelines for each structure to make. We can then add a story or measurement system. "You are a wizard stonemason who, hired to build vaults. You need to get your vault as close as possible to the guideline structure to increase your score."
The mechanic is the actual thing the player does to achieve our objective. The mechanic will be a secondary view where you can press a button and see what the structure should look like, and then you can build it. The clouds we added in part 1 obscure vision and also increased the difficulty a bit.
We are adding to our game...
1- saving so a game can be loaded with prior progress and we can save/load objectives
2- an objective with visualization mechanic to build a specific structure on the map
3- a scoring mechanism to rate the result
First, we are going to add saving to the game. In its most basic form, saving the game state and loading it again involves storing the locations of everything on the screen, our character, and our inventory, and populating these values from this save when we load up the game. So the way I've implemented saving is to make everything in the game world that I want to save a value inside a python dictionary called game_state, then I save this dictionary to a file. Below you can see a video of me saving my game then loading that save.
To save our game, you can press the 's' key, and it will automatically create a file called save-file-DATE.save, which contains all the info needed to reload our game. Whenever we have a new feature we want to be save-able, we make sure it is part of the game_state dictionary in our code, and our function will save it.
We are going to use our save functionality here to make our objective. We are going to make two world states that the player can make. These world states are pretty designs/layouts for our little game. The goal is to get the world as close as possible to this world state. So I will create these states and save my game and then load them into a new mechanic we will call 'future sight.' If we press/hold 'f,' we will see the structure we need to make superimposed onto the map. Below you can see me examining an objective.
You can create your objectives by making a structure then pressing the 'o' key, which will save just the tilemap from the game_state as an objective file. Then to use that as the objective for a level, you have to load it as I did on the command line. Here is the code:
You may notice that we have no way to score the end product. We will create a yellow outline in the objective view (the view that shows our goal structure), and this yellow outline will denote the scoring area. To score our game, we press 'e'. This gives us a score based on how close our structure is to the objective. I updated our function that saves objectives to now save the tilemap and an empty rectangle called scoring_rect. To add a rectangle, you can edit the values in the objective file under the key "scoring_rect." The values are in a list, and there should only be 4 (x, y, width, height of the rectangle). You can open the objective file in any plain text editor and make whatever scoring area you want. Here is a video of me attempting to build this objective then scoring it with our new scoring function. I score it several times, going eventually to a score of 81.
Notice I am constantly checking the objective with 'f' to see what I should be building.
Here is the code:
If you enjoyed this post, be sure to signup for more.