Manage project code

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
MadByte
Party member
Posts: 533
Joined: Fri May 03, 2013 6:42 pm
Location: Braunschweig, Germany

Manage project code

Post 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 :)
User avatar
Hexenhammer
Party member
Posts: 175
Joined: Sun Feb 17, 2013 8:19 am

Re: Manage project code

Post 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 = {}
User avatar
Inny
Party member
Posts: 652
Joined: Fri Jan 30, 2009 3:41 am
Location: New York

Re: Manage project code

Post 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.
User avatar
MadByte
Party member
Posts: 533
Joined: Fri May 03, 2013 6:42 pm
Location: Braunschweig, Germany

Re: Manage project code

Post 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
User avatar
Inny
Party member
Posts: 652
Joined: Fri Jan 30, 2009 3:41 am
Location: New York

Re: Manage project code

Post 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.
User avatar
MadByte
Party member
Posts: 533
Joined: Fri May 03, 2013 6:42 pm
Location: Braunschweig, Germany

Re: Manage project code

Post 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.
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Google [Bot] and 2 guests