In our last post on creating the game architecture for our high level classes, we discussed a number of design decisions about our game. While the details will be important, almost all games have the same basic structure, so I thought we’d get started on creating that in parallel with our creative process.
Usually, I build out the skeletal structure as I’m doing the creative process details. As a reminder, here is our structure:
Main.lua in Corona SDK
In Lua, everything starts in your main.lua file. Most people will probably put a lot of logic and variables in this. We use the main.lua file strictly to launch our application and leave the rest of the logic up to the Game Controller, which we’ll create a file for called GameController.lua.
This is all we have in the main.lua file. It simply declares a function, and then adds an event listener that gets system messages for when the application starts, exits, suspends and resumes. For each of these states, we either save or load the data. For example, if we were in the middle of a battle and our game gets sent to the background, we’ll need to save the current state of the application to a file so that we can resume in the same place, even if the app quits completely. These might be things like current health, time, which enemies are still active, etc. When the application resumes again, we reload this data and we’ll check it later in the code to see what our state was, so we can handle the loading of that screen, just as if we never left.
If the application starts up, and there is no data, that means it is the first time we’ve launched our application. We call a special function in GameController.lua called firstLaunch() to handle this. You could put this logic in the GameController’s main function to make main.lua even simpler if you wanted but by testing for nil, we can handle it differently if your game had different needs.
This first launch function might include a quick tutorial overlay to introduce the player to our game. Always after that, we save the data so the next time the app starts, data will be loaded in and firstLaunch() won’t be called. First launch may do other things like setting up and writing settings files, but we’ll want to separate out the logic for overlays and other things into other functions so that we can reuse them later, if the user wishes to go back through the beginning tutorial. In other words, if the user wants to revisit the tutorial via a menu item, we don’t want to run through all the first launch logic like creating settings files, user names, etc. We’ll simply want to call something like showTutorial() in order to bring that feature up. It’s important we separate out these steps for later use in the app. You never know what you’ll end up reusing or accessing from another execution path.
Finally, we print out the event.type variable if it is not nil, in case you’re interested in handling additional system events that Corona sends your way. In our case, I’ve simply commented out the print statement but keeping the handling of system events in one place is a good idea. In our case, we’re forwarding the handlers to our GameController since that’s acting as our master controller.
You may have also noticed we made a call to getGameStats() to serialize and deserialize our data. This returns the Game Stats controller that holds all the information about our game including character stats, level stats, scores, and everything else we want to keep. This will talk to our storage controller to read the file information and then put it into a format. We’ll also have a level loader, so we can load things such as those one at a time from storage.