Page 1 of 2

Game Design in Love with Lua

Posted: Fri Nov 06, 2015 2:34 am
by tsteinholz
So i'm sort-of new to lua and love, I have a background in object-oriented programming languages (c++, java, etc). I don't really have experience in dynamic scripting languages where you don't have variable types etc. In my head I want to structure my game like levels with polymorphism and some type of interface or header...

ex:

Level_
|- Intro
|
|- Level 1
|
|- etc....

The closest I can come to this in Lua is using the middleclass lib (https://github.com/kikito/middleclass) which i am learning (sort-of, keep running into issues here and there, nothing specific). In Lua would it make sense to just have a folder of lua files that have the same methods and have a variable set to one of those files and just call the method assuming the variable has that method? Would this be unsafe or possible?

Please give me some advice / examples on how to structure a multi level game if my method is flawed (not really confident in it)

Re: Game Design in Love with Lua

Posted: Fri Nov 06, 2015 4:39 pm
by CaptainMaelstrom
Pretty hard to say without knowing more about what kind of game you want to make. Many games create multiple levels just by storing information in variables:

Code: Select all

level1 = {
	name = "Big Bad Dungeon"
	size = {w = 1200, h = 800},
	tiles = {
		{0, 0, 1, 1, 1, 0, 0},
		{0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0},
		{1, 1, 1, 1, 1, 1, 1},
		{1, 1, 1, 1, 1, 1, 1}
	},
}

level2 = {
	name = "Tower of Evil"
	size = {w = 600, h = 1000},
	tiles = {
		{0, 0, 0, 0},
		{0, 0, 1, 1},
		{0, 0, 0, 0},
		{0, 1, 0, 0},
		{0, 0, 0, 0},
		{0, 0, 1, 0},
		{0, 1, 0, 0}
	},
}
The game then chooses a level variable and draws the tiles according to the level's "tiles" variable. Once your game is playable with one level, it's typically not too hard to figure out how to make more levels playable. Just copy and paste code, then change some variables (typically). If you want to do more complicated stuff, the forum can probably help but you'll have to be more specific.

Re: Game Design in Love with Lua

Posted: Fri Nov 06, 2015 5:23 pm
by Tesselode
It sounds like you want to do gamestates? Is that right at all?

Re: Game Design in Love with Lua

Posted: Fri Nov 06, 2015 8:56 pm
by tsteinholz
Tesselode wrote:It sounds like you want to do gamestates? Is that right at all?
I don't know, I want to create a story game and use a level type system so each level I load in then play. So i'd have a main menu scene, level 1 scene, game end scene etc. I just want my main.lua to be able to switch in between them and load them all up and play them. Would game states really be useful for levels in a large game?

Re: Game Design in Love with Lua

Posted: Fri Nov 06, 2015 8:59 pm
by tsteinholz
CaptainMaelstrom wrote:Many games create multiple levels just by storing information in variables.
This might be the way to go, just that method seems a little foreign to me because I am so used to C/C++ and I have little to no experience in dynamic languages like lua (besides auto in cpp lol).

I think something similar to this might be the way to go, but i don't know for sure yet.

Re: Game Design in Love with Lua

Posted: Fri Nov 06, 2015 10:18 pm
by Teraku
You can store each level in a separate file (or all levels in one separate file) and simply require the file when necessary. If you call require like a function you can pretty much pass in any string, even dynamically generated ones or variables containing strings.

Re: Game Design in Love with Lua

Posted: Sat Nov 07, 2015 2:26 am
by Jasoco
For levels, instead of require I use local tempLevel = love.filesystem.load(filename)() then run through the tempLevel table and handle things accordingly. Or store it in a less local table instead. Either way, as long as you delete the old level table data completely when loading a new one you're fine.

Re: Game Design in Love with Lua

Posted: Sat Nov 07, 2015 2:59 am
by undef
tsteinholz wrote:Would game states really be useful for levels in a large game?
Yes and even necessary if you don't want to loose your sanity, in my opinion.

I've recently did this:

Code: Select all

-- state.lua

 -- this is a function that takes the name of a file, including it's path
 -- and returns the environment of the values defined within.
 -- This environment is table containing everything that was in the lua file
function loadState( filename )
	-- first we create an empty environment with an index metamethod on the
	-- global environment.
	-- That way you can read variables from the global environment, as long
	-- as the variable isn't defined in our new environment.
	-- This is useful to gain access to functions like print and also ensures
	-- that no variables in the global environment are overwritten.
	local env = setmetatable( {}, { __index = _G } )
	-- we load the file as a function
	local ffunc = love.filesystem.load( filename )
	-- checking if everything went right
	if not ffunc then  error( err )  end
	-- we set the environment of our new function to our new environment.
	setfenv( ffunc, env )
	-- we execute the function to populate the environment with the files contents
	ffunc()
	return env
end

states = {} -- this is the table that holds all your environments
-- iterating over a directory containing all our state scripts and then
-- assigning their environments to our states table indexed under the
-- files name with no suffixes.
-- (The way it is done here it only looks for filenames without
-- spaces or special characters.)
for _, v in pairs( love.filesystem.getDirectoryItems"states" ) do
	local name = v:match"^(%w+).lua$"
	if name then
		states[name] = loadState( "states/" .. v )
		-- states["title"] = loadState( "states/title.lua" )
	end
end

-- The function to change the state of the program.
-- Unless noInit is given, the states init function is executed.
function setState( newState, noInit )
	state = states[newState]
	if not noInit then
		state.init()
	end
end
setState"title"

That way you would just have this in your main.lua:

Code: Select all

require"state"

function love.update( dt )
	state.update( dt )
end

function love.draw()
	state.draw()
end

And have single files for every state you have that look like this:

Code: Select all

function init()
    -- stuff to be called when you initially set this state
end

function update( dt )
    -- updating stuff
end

function draw()
    -- drawing stuff
end
Then just call setState from your current state to change the state.

In case you want to access something from another state, you can do it through the global environment.
For example if you want to use the same font as the one from the title screen in the menu you can do this:

Code: Select all

-- menu.lua

function draw()
    love.graphics.setFont( states.title.font )
end
Of course this technique can be nested and you can create a table of substates in one of your states,
for instance if you want to load up the levels of your game.
(This way you can set an index metamethod to your game state, to have access to functions and variables
that are required by all levels - like hud drawing functions etc.)

I hope this helps.

Maybe you don't understand how all of this works yet, if so - I really recommend reading up on the stuff that
might seem alien to you, especially metatables.
Lua is very flexible, and if you don't know Lua well you're likely to programm in an unnecessarily complicated way.
Even though your code will work it will be much harder to maintain, so if you invest a little time upfront to learn about Lua's strengths
it will pay off in the future.

Re: Game Design in Love with Lua

Posted: Sat Nov 07, 2015 7:35 am
by tsteinholz
@undef I think that might be the way to go, defiantly sounds efficient with some modifications here and there for my specific purpose. I appreciate it.

Re: Game Design in Love with Lua

Posted: Sat Nov 07, 2015 2:42 pm
by undef
You're very welcome. :)