Page 1 of 1

Manage project code

Posted: Mon Jun 17, 2013 11:01 pm
by MadByte
Hi!

I'm currently trying to set up a basic code construct to use in future game projects and I want to make sure
the code isn't extremly inefficient, that's why I ask you guys.
craftedCode.love
Is anything completely against every rule or something ? ( maybe the world.lua )
Are there any things which could be easily optimized with minmal changes?

I know that's a very wide ranged topic but anyway - what do you think?
I would be very thankful for any help on that :)

Re: Manage project code

Posted: Mon Jun 17, 2013 11:52 pm
by Hexenhammer
The most important thing is to organize you code into modules instead of randomly stuffing the global namespace like you do currently:

http://lua-users.org/wiki/ModulesTutorial

Don't use globals in general unless you have a damn good excuse i.e. your variable declarations should almost all start with "local" e.g.

Code: Select all

local world = {}
not

Code: Select all

world = {}

Re: Manage project code

Posted: Tue Jun 18, 2013 1:24 am
by Inny
Actually, it's not bad putting your game code into the global table, but it is very important to be modularized if you do so. For instance, lets say you have a file called "sprites.lua" and in it you have "Player" and "Enemy", define them like so:

Code: Select all

sprites = {}
sprites.Player = your_implementation_here
sprites.Enemy = likewise
Others go the step further, and move the sprites into a folder called "sprites" and give them each their own file. If you have "library code" which is code that's not at all specific to your game and can be used for lots of things, then you want to make the table that you put all of your functions in as local, and then return that table at the bottom of the file, as Hexenhammer demonstrated.

Basically, you want the top of other files to have one of these lines:

Code: Select all

require 'sprites' -- if you put them into a global table

local sprites = require 'sprites' -- if you return it as a table

local Player = require 'sprites.player'
local Enemy = require 'sprites.enemy' -- if you split them out into multiple files.

Re: Manage project code

Posted: Tue Jun 18, 2013 3:52 pm
by MadByte
Well, I tried it and it does work on the first try - pretty simple! Thanks for the tips :)
Inny wrote:Actually, it's not bad putting your game code into the global table, but it is very important to be modularized if you do so. For instance, lets say you have a file called "sprites.lua" and in it you have "Player" and "Enemy", define them like so:

Code: Select all

sprites = {}
sprites.Player = your_implementation_here
sprites.Enemy = likewise
I guess if I already load them local on top of the i.e game.lua this way doesn't make much sense anymore?

Code: Select all

local world = require'src.world'
local player = require'src.player'

local game = {}
local World
local Player


function game:enter()
	World = world.new()
	Player = player.new(200, 200)
	World:add( Player )
end
What about put the requires into the init function of a gamestate, is there any advantage on doing that ?
I mean they are now already local & shouldn't pollute the global namespace anymore.

And one other question, what do you think about loading all entities and objects with a world class by looping through them everytime as I
currently do? This might be a bit heavy on the performance but it seems to be much more comfortable to organize things like that.
Or is there any similar way to archive this which does look better in the performance aspect.

Code: Select all

function world:add( entity )
	table.insert( self.entities, entity )
end


function world:update(dt)
	for i, v in ipairs( self.entities ) do
		if not v.removed then
			v:update(dt)
		else
			table.remove( self.entities, i )
		end
	end
end

Re: Manage project code

Posted: Tue Jun 18, 2013 5:09 pm
by Inny
MadByte wrote:I guess if I already load them local on top of the i.e game.lua this way doesn't make much sense anymore?

Code: Select all

local world = require'src.world'
local player = require'src.player'

local game = {}
local World
local Player

function game:enter()
	World = world.new()
	Player = player.new(200, 200)
	World:add( Player )
end
What about put the requires into the init function of a gamestate, is there any advantage on doing that ?
I mean they are now already local & shouldn't pollute the global namespace anymore.
The way the require function works is that it'll only load the file once, and whatever is returned from that file is reused every other time you try to require it. So, if you move the requires into the game:enter function, it'll pretty much behave the same without a performance impact. If anything, it'd probably make your game startup faster, but take slightly longer the first time it switches to a new gamestate.

A side note though, Lua's rules on scoping are slightly different then what you're thinking. When you write local, you've created a bound scoped variable, not a global variable. By putting the results of require calls into a local variable, it's only available to the file where you did so, or if you do it in the game:enter function, it'll only be available there. If you need it available everywhere, then consider making it global, which means you'd either require it main.lua and put it in a global variable, i.e. no local keyword, or don't use the local keyword in the file where you defined the module. Again, if it's your own gamespecific code, then it's fine, it's your global state. If you're writing libraries for others, then the global state isn't yours so don't do it that way.
MadByte wrote: And one other question, what do you think about loading all entities and objects with a world class by looping through them everytime as I
currently do? This might be a bit heavy on the performance but it seems to be much more comfortable to organize things like that.
Or is there any similar way to archive this which does look better in the performance aspect.
I'm not sure what you're getting at here. If you're talking about writing code like this: player = require('src.player').new(), that might get very messy.

Re: Manage project code

Posted: Tue Jun 18, 2013 5:27 pm
by MadByte
Inny wrote: I'm not sure what you're getting at here. If you're talking about writing code like this: player = require('src.player').new(), that might get very messy.
No no :D never mind, thanks for the help.