index global 'GM' (a nil value)

I’m writing a gamemode, and moving everything form GAME. to GM. as I only used GAME. because i couldn’t get GM to work, but now I want to know why I have trouble with it.

This is my init.lua for the game-mode:

include( 'shared.lua' )
include( 'sv_config.lua' )
include( 'sv_resources.lua' )
include( 'sv_moduleloader.lua' )

AddCSLuaFile( 'shared.lua' )
AddCSLuaFile( 'cl_init.lua' )

GM.NameFriendly = ""
GM.NameUnfriendly = engine.ActiveGamemode()

GM.Participants = {}
GM.ParticipantData = {}


SERVERLINK:GetServerProperties( function(result)
	GM.Config.ServerID = result[1].data[1].id
end )

And I get this error:

[ERROR] lua/includes/modules/hook.lua:84: gamemodes/mygamemode/gamemode/init.lua:18: attempt to index global 'GM' (a nil value)

Why is GM. a nil value on line 18, but not on lines 9, 10, 12, 13 and 15?

Is there something I’m missing here?

SERVERLINK:GetServerProperties is a function which runs a query and the callback function ( function(result) ) is where GM. is ‘a nil value’.

It’s worth noting, if I then refresh a file ( eg. save the init file again ), the error doesn’t come back. So why is it a nil value only on first load? I would say GM. isn’t accessible, but that’s where it throws me off as it’s accessible on the other lines that are ran first.

Is it because there’s a delay in doing the query, and GM then turns into GAMEMODE? If so, why does GM turn to GAMEMODE and not just stay as GM? And how long is GM accessible for when the game-mode loads?


[editline]17th April 2016[/editline]

So if I initialized a function early on as GM:Start(), if I wanted to call that say 1 minute after the game had started, would I have to do:

function GM:Start()
    print( 'The game has started' )

timer.Simple( 60, function()
end )

[editline]17th April 2016[/editline]

Are you even meant to store your game-mode functions / variables in GM or create your own table like I had before GAME:MyFunction() / GAME.MyVariable?

[editline]17th April 2016[/editline]

Is it common to do GM = GAMEMODE?

SERVERLINK:GetServerProperties( function(result)
GM.Config.ServerID = result[1].data[1].id
end )

This looks like a callback from a MySQL query (tMySQL?). If so, it will probably be called once the gamemode has already loaded, and therefore GM is no longer valid, use GAMEMODE instead for callbacks.

Thanks James, this is what I thought. However why? Why does GM turn into GAMEMODE - I’m assuming there is a reason?

Because this does seem a little messy, to have to declare things as GM before the game-mode has loaded, and then use them as GAMEMODE.

Is it usual to use GM/GAMEMODE to store game-mode variables / functions, or is it MORE usual to use your own table.

It’s a bit confusing, but basically, GM is only defined for the duration that the gamemode files are being loaded, then it gets un-defined. When any function runs, GM has already been un-defined. You can use GAMEMODE, it’s the same thing.

But you can’t use GAMEMODE before the game-mode as initialized :stuck_out_tongue: So basically, initialize all your functions as GM then when you call them in ANYTHING else, then use GAMEMODE…

Do you know why it’s done like this?


So is it safe to do GM = GAMEMODE - would GM just be a reference to GAMEMODE so I could use GM: everywhere?

It’s the exact same thing with entities, ENT is a table that is used to define the entity. After the entity is defined from the table it serves no use so it’s removed and all the stuff you want from ENT is now in “self”

You could also use gmod.GetGamemode() to get the gamemode or GM.

Ah damn ye, so instead of doing GAMEMODE in my functions I can just use self, I didn’t even think of that :confused:

[editline]17th April 2016[/editline]

Ah thanks, that’s useful to know.

I’m not sure if self will work, I was relating it to how GM is no longer valid and that you have to use GAMEMODE

I think self should work actually, since functions are defined using colon. Astute observation!

I’ll give it a go, self would be easier.