One of the reasons why there are few tutorials on this subject has to do with it’s a very broad topic with many possible solutions. Every developer will want to do things a certain way.
Now keeping this on the most general of terms, how you do this depends on the game you’re building. You can have one (or a few) game.lua files that are data driven. For instance the game I’m currently building is a side-scrolling sci-fi shooter. All levels are basically the same. I use the same code to detect collisions, all that changes are the images I use and some per-enemy AI logic that rotates through the different levels etc. I only have one “game.lua” file. It knows for level 1 to use Enemy 1. For level 2 use Enemy 2 and Boss 2. At this point you can store your game data in their own .lua files that is pretty much just a table.
Here’s an example: – shiptypes.lua
local shipTypes = {} shipTypes[1] = { title = "Fighter Mk I", name = "fighter1", width = 115, height = 46, health = 100, fireSpeed = 300, healthBays = 2, bombBays = 3, guns = 1, buy = 1000, sell = 800 } shipTypes[2] = { title = "Fighter Mk II", name = "fighter2", width = 133, height = 49, health = 125, fireSpeed = 250, healthBays = 2, bombBays = 2, guns = 1, buy = 2000, sell = 1600 } shipTypes[3] = { title = "Fighter Mk III", name = "fighter3", width = 112, height = 58, health = 150, fireSpeed = 200, healthBays = 3, bombBays = 3, guns = 1, buy = 4000, sell = 3200 } shipTypes[4] = { title = "Fighter Mk IV", name = "fighter4", width = 105, height = 72, health = 175, fireSpeed = 300, healthBays = 3, bombBays = 4, guns = 2, buy = 8000, sell = 6400 } shipTypes[5] = { title = "Warrior Mk I", name = "warrior1", width = 137, height = 58, health = 200, fireSpeed = 250, healthBays = 4, bombBays = 5, guns = 2, buy = 12000, sell = 9600 } shipTypes[6] = { title = "Warrior Mk II", name = "warrior2", width = 125, height = 53, health = 225, fireSpeed = 200, healthBays = 4, bombBays = 6, guns = 2, buy = 24000, sell = 19200 } shipTypes[7] = { title = "Warrior Mk III", name = "warrior3", width = 143, height = 53, health = 250, fireSpeed = 300, healthBays = 5, bombBays = 7, guns = 3, buy = 48000, sell = 38400 } shipTypes[8] = { title = "Warrior Mk IV", name = "warrior4", width = 144, height = 64, health = 275, fireSpeed = 250, healthBays = 5, bombBays = 8, guns = 3, buy = 96000, sell = 76800 } return shipTypes
Now where I need this data, I’ll just do:
local shipTypes = require(“shiptypes”)
and I have access to the table. If I’m level 3 and I need ship 5, I can grab the file name for shipTypes[5] and it’s width and height and feed that to a display.newImageRect(). The code is the same regardless of the level.
The opposite side of the spectrum is the game where each level has so much unique art and code that you can’t reuse anything. I did a kids game where each level was it’s own activity. Coloring book here, puzzle there, action activity etc. It had dozens of scenes and I couldn’t use hardly any code from any scene. In this case, I had dozens of very specific .lua files in my project.
You may find you’re game is somewhere in between. In programming there is a principle called “DRY” – Don’t repeat yourself. If you have 20 levels and you repeat the same collision detection function in each and you have to change one due to a bug you have to make that change 20 times. A good programmer will learn how to compartmentalize common code into libraries to minimize these changes. Using Object Oriented Programming principles you can reduce your dependence on writing the same code multiple times.
If you’re building a Candy Crush like game, perhaps you use a single game.lua, create a level1.lua that has the game map in it and the object could have specific code for that level. It’s a matter of your game and how much code is shared with each level on which way to proceed.
Rob