Help me get a better understanding of lua items such as "functions", "variables", "hooks", etc.

I have been dabbling in lua coding for a few weeks now, I’ve watched plenty of online tutorials, and followed several youtube gamemode projects.

However, I still get the feeling that I don’t have a full grasp on what everything actual means. Sure, I can make sense of it through context, but I really don’t feel like I have a hold on what these items of text are at their core.
I have a pretty big ambition to create things with lua right now, and I really don’t want to go much further until I feel like I have a very stable knowledge of the base of lua.

Here’s what I think I understand thus far, but I don’t think all of it’s truly correct:

Please help me get a better view on these things and anything else I haven’t mentioned, because that^ is pretty much the extent of my knowledge right now…
I would greatly appreciate all of your help, I promise I’ll put the knowledge to good use. :slight_smile:

[editline]15th March 2015[/editline]

I’ve also spent a generous number of hours browsing through the GMOD wiki reference. It helps a little, but I think an explanation from another human directly would benefit me much more.

Those are generic programming terms, you should probably start watching an intro to programming series (not gmod specific) if you don’t even know what functions and variables are.

Well, variables are representations of data stored to be called in later expressions and commands. I was just asking if i.e. ply is classified as a variable.

I’m most confused about functions. Some are used to make things happen example: PlayerSpawnAsSpectator, and others are used when things happen example: PlayerConnect.

What logic is that?!

Anyway I’ll take your word for it and go watch some object-oriented tutorials.

PlayerConnect is a hook, idk where you heard otherwise. It does not make things happen, it is called when something happens(when a player connects, obviously)

Though if you typed GM:PlayerConnect, it would be used as a function

For example

function GM:PlayerConnect( ply, ip )
–your code
end
^^ GM:PlayerConnect is a function here, not a hook. Notice the GM:

hook.Add( “PlayerConnect”, “UniqueIdentifier”, function( ply, ip )
–Your code
end )
^^ PlayerConnect is a hook here

Also, to answer your other question, ply is almost always a variable
You could call your function ply if you wanted to, but it would be a weird name and rather unreasonable
Could also cause errors due to conflicting names if you have ply defined elsewhere in the file

Hooks and functions are the same; hooks are just special in that the game calls them for you, instead of you calling them yourself. You can define you own functions, and call them yourself as well.

Much in the same way that variables are abstract representations of data and physical objects, functions are abstract representations of actions and events; they are less tangible, but still exist.

And yes, ply is a variable. It’s a bit more complicated form of a variable, with other variables as properties, but it is still a variable.

As some of the other users above have stated, it would be better in your interest to look up a general programming tutorial or course to learn the basics such as functions. But however i could help explain how functions work in GLua and many other languages.

The hook system in garrysmod lets you ‘hook’ functions to game events. These hooks have their own set of parameters that are passed into the function that you define for it. Hooks are a good way to do something with game events without overriding the original gamemode function, as you can access them from almost anywhere. Hooks and functions however are split between server and client. Only client hooks/functions can be called on client, same with serverside hooks. However, some hooks are shared between serverside and client so you can call them in either context.

Also about libraries, Libraries are just collections of functions pertaining to certain entities or systems. Same with classes

AJ is correct about hooks and libraries, but only partially correct about classes. In OOP (Object Oriented Programming, which we can spoof in lua), a class is a template for an object that contains functions which can be called to manipulate the object’s instance (self). AJ was correct about these methods being stored on a table, but it’s a metatable that you can’t manipulate completely like a table.

I agree with everyone else when they say to watch generic programming tutorials.

Here is a copy of my post where I explain fairly well classes and hooks in GLua:
(I can’t quote it because the thread is locked, so have this link.)

I’m pretty sure everyone covered this, but again… A function and hook are the same. A variable can store a reference to anything, even functions. You can create functions many different ways. Lua is a language of tables, everything is stored in a table, even global variables and functions.

Think of hooks, or functions, that get called when an event happens as a broadcast receiver. These are implemented to make modifying the game easier. Functions that make things happen help us simplify problems, think of these as building blocks; they reduce the amount of code we need to write, they also reduce repetition ( I always create a function out of code when I re-use something more than once or twice )…

I have a few examples, and some starter docs that may help… So, you can create your own hooks.
Example, there is no PlayerDroppedWeapon or CanPlayerDropWeapon hooks, but these can be quite useful to have.

  • CanPlayerDropWeapon will be a hook.Call ( This broadcasts out looking for any hook.Adds that use CanPlayerDropWeapon to see if the behavior will be modified [ think: Can the player drop the weapon, or not? ] before calling the main function [ default behavior; many are left blank ] – note, if you use hook.Add to modify behavior, only use return for your specific behavior, don’t do else return false; end just because it looks nice because that will prevent all other hook.Adds and the main function from running at all )…

  • PlayerDroppedWeapon will be called after the player successfully dropped the weapon.

The only way we can add this behavior is by redirecting ( rewrite ) a function in the Player Meta-Table - META_PLAYER = FindMetaTable( “Player” ); - DropWeapon… Since we’re adding new behavior and we want to preserve the old behavior we need to create a variable that references the original function so we can use the original function when we over-write it. This needs to be auto-refresh compatible ( meaning it needs to be global variable set like this: var = var || original_function; – or something we set 1 time such as if ( !META_PLAYER.__DropWeapon ) then META_PLAYER.__DropWeapon = META_PLAYER.DropWeapon; end – and this method can be used interchangeably; some prefer one way, others pefer another way…

3 files… Now, I also add additional behavior so the default function I define for function GM:PlayerDroppedWeapon( … ); is to unlink the data ( this is part of another data / networking system so private data belonging to the weapon is known by the player holding it and no one else because no one else needs it )

I chose to use: __META_PLAYER_DROP_WEAPON as the reference to the original function ( I’ll be changing this next update to my dev-base to keep it internal with the player meta-table )…

This is the file that changes the logic… Notice I create the reference and used the data = data || original_function; method of preserving the original function… The first thing I do is hook.Call CanPlayerDropWeapon so that I can prevent the weapon being dropped ( by not calling the original function ) if a hook.Add or the main GM function for the hook returns false ( which means do not allow drop ). If drop is allowed, I proceed to call the original function ( and because we have a reference to the function via . when the function was created using : [ where self is inferred ] I need to add self as the first variable [ which is the player ] to preserve the original functionality even though the only argument is the weapon, more on this later… I then call a second hook, which informs any code that needs to be informed when the player dropped the weapon successfully. The networking:CallHook is part of my networking system which simply calls the same hook on the client as a notification so if client-side code needs to know anything about the weapon drop, it can be done since this is a server-side function…

Since the GM: function needs to exist if we call a hook on GAMEMODE table, and because I needed default behavior for it… I added this with data ( normally, override functions are empty ). debug.print is part of a debugging system that lets you enable / disable debug output based on category. The data:Unlink is part of the system I mentioned earlier…

CanPlayerDropWeapon I added a few things that come into play with my dev_base ( a lot will be moved into libraries soon ) but it prevents a weapon from being dropped if it is invalid, it also, by default, prevents weapons from being dropped if the SWEP:Holster function prevent it from being holstered ( to allow default behavior ), then I check to see if the weapon class is listed in the un-droppable weapons table ( such as physgun, admin baton, etc… ) and if all of those pass I return true to allow dropping the weapon. Now, any hook.Add can return true or false to override this entire default function…

I hope that provides some insight in terms of why we use hooks and why some functions do tasks while others are “rang” / broadcasted.

Always test and develop code using SRCDS: Setting up a Local Development SRCDS

Here are some beginner docs:

https://dl.dropboxusercontent.com/u/26074909/tutoring/tables/quick_intro_to_tables.lua.html

https://dl.dropboxusercontent.com/u/26074909/tutoring/functions/function_naming.lua.html

https://dl.dropboxusercontent.com/u/26074909/tutoring/strings/string_concatenation.lua.html

https://dl.dropboxusercontent.com/u/26074909/tutoring/logic/ternary_operations.lua.html

https://dl.dropboxusercontent.com/u/26074909/tutoring/time/understanding_time%20and_basic_time_calculations.lua.html

Generalized tips ( many simple mistakes cost in terms of running-cost [ performance ] ): https://dl.dropboxusercontent.com/u/26074909/tutoring/optimization/_generalized_optimization_guide.lua.html

https://dl.dropboxusercontent.com/u/26074909/tutoring/includes/file_only_works_on_autorefresh_possible_reasons.lua.html

HUD
https://dl.dropboxusercontent.com/u/26074909/tutoring/hud/proper_hud_creation.lua.html

https://dl.dropboxusercontent.com/u/26074909/tutoring/hud/understanding_hardcoding_of_screensizes.lua.html

https://dl.dropboxusercontent.com/u/26074909/tutoring/hud/basic_healthbar.lua.html

[ NOTE ] Remove .html to view / copy .Lua …

Additional help:

I have written over 500 tutorials and completed “systems” in Lua for Garry’s Mod. I tutor for negotiable rates / free / donations, and answer questions one on one for free / donations; feel free to add me on Steam if you need some guidance. Here are some resources to help you get started:

Generalized Lua Help ( Links to Wikis, Answers the question of “Where do I post a simple question or DarkRP Specific question”, links to other resources compiled by forum members )
https://dl.dropboxusercontent.com/u/26074909/tutoring/___welcome_docs/_welcome_general_lua_learning.lua.html

Useful Programs ( SteamCMD, Autosizer, Desktops, Process Explorer ) and Notepad++ Upgrades
https://dl.dropboxusercontent.com/u/26074909/tutoring/___welcome_docs/_welcome_useful_programs_and_notepadpp_upgrades.lua.html

I think if you really want to get a grasp on the terms, you should be thinking of them as simply as possible. Instead of referring to variables as “representations of data stored to be called in later expressions and commands”, just call it a name (or identifier) for a value. This isn’t a test for your bachelors in computer science. You don’t need to use that jargon casually.