Need advice on splitting program into multiple files

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Post Reply
SpencerBeige
Prole
Posts: 1
Joined: Wed Aug 05, 2020 11:40 pm

Need advice on splitting program into multiple files

Post by SpencerBeige »

Hi,

I'm just starting out with Love2D, and before now I've never worked with multiple lua files in one program, so I need a bit of advice.

I understand that the most common use of separated files is for OOP. However, I'm currently working on a set of functions that manage the window / screen, and I wanted them to all be in their own file (window.lua). Because I want to use these functions and tables outside of this file, none of them can be local. I don't know exactly why, but I've seen online that making everything global is bad practice.

The only solution I can think of is to throw all of these functions/tables into a table, then load the file using require(). But I can't believe that this is the best solution - it makes everything really messy and confusing.

Does anyone know of a better solution?

Thanks
User avatar
gilzoide
Prole
Posts: 5
Joined: Fri Jun 19, 2020 2:19 am

Re: Need advice on splitting program into multiple files

Post by gilzoide »

Some of the things about globals are that:
  • they may be accidentally accessed or overriden, for example if you give it a generic name like "object" or "image" that is easy to be misused
  • if it's a table with too many variables/state inside, it's easy to introduce subtle bugs, like if you forget to reset one variable when resetting your game, then everything gets weird,
  • globals usually make debugging (and writing automated tests) more cumbersome, as they are implicit dependencies to your code.
This all depends on how you're using them, and this is actually more of a problem when developing libraries to be used by others (including yourself). For an end application, like a LÖVE game, where you have all the control of what is going on, it is perfectly fine to rely on globals. Globals are one of the tools Lua give you, and every tool has it's usage.

So usually writing a separate file with functions and other variables have 2 ways to go (or 3, you can mix locally defined modules with globals at any time):

Code: Select all

-- 1) declare functions and variables as globals in "window.lua". Give obvious names to avoid name clashes in your code
window_width = 800
window_height = 600

function close_window()
    -- ...
end

-- then on "main.lua" or elsewhere
require "window"  -- this will load the globals

function somewhere_in_code()
    print(string.format("window is %dx%d", window_width, window_height))
    close_window()
end

Code: Select all

-- 2) declare functions and variables in a local table in "window.lua" and return it. As defined as locals, there is no name clash issues
local window = {}

window.width = 800
window.height = 600

function window.close()
    -- ...
end

return window

-- then on "main.lua" or elsewhere
local window = require "window"  -- get "window.lua" result in a local "window" variable
window = require "window"  -- or get "window.lua" result in a global "window" variable

function somewhere_in_code()
    print(string.format("window is %dx%d", window.width, window.height))
    window.close()
end
Explicit code is usually easier to understand and less error prone, because you don't need to search the entire project code to find out what a "window" would be. Notice that it may be initialized as a table, but nothing stops you from assigning a number to it afterwards. This may not be a problem for small projects, but as soon as you have more files, It may become more confusing to have everything declared globally rather than explicitly required. When using globals, I'd suggest to give your variables and functions obviously unique names. They don't have to be big, for example "deg2rad" is most likely a function for transforming angles between degrees and radians (if it is not, this is a really bad and confusing name).

(As a side note, separate files is about organizing code. Code in general, including OOP, usually makes more sense when well organized)
User avatar
pgimeno
Party member
Posts: 3550
Joined: Sun Oct 18, 2015 2:58 pm

Re: Need advice on splitting program into multiple files

Post by pgimeno »

I am of the "avoid globals as much as possible" school. It's easier to read a file if it's self-contained instead of invoking variables that may be defined elsewhere. If there's an initialization problem, it's more difficult to track.

Having globals also makes it more difficult to find variables that should be local but you've forgotten to make local, which have the potential of causing bugs.

SpencerBeige wrote: Wed Aug 05, 2020 11:53 pmThe only solution I can think of is to throw all of these functions/tables into a table, then load the file using require(). But I can't believe that this is the best solution - it makes everything really messy and confusing.
Why messy and confusing? That's what Löve does, for example. Do you consider the Löve API messy and confusing? It has only 1 global as far as I know, and everything else is inside that. I'd call that clean and organized, not messy and confusing.

I agree with gilzoide that separate files is about organizing code, by the way.
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Bing [Bot] and 91 guests