General GLua formatting tips?

I just want some tips on how you guys suggest I format my code to make it look neat and such.

There’s too many for me to say, but I think the lua that comes with gmod looks like shit. There’s spacing everywhere. So much useless spacing. Here’s an example.
[lua]function Register( t, name, derived )

local CurrentGM = gmod.GetGamemode()

if ( CurrentGM ) then

	if ( CurrentGM.FolderName == name ) then
		table.Merge( CurrentGM, t )
		Call( "OnReloaded" );
	end

	if ( CurrentGM.BaseClass && CurrentGM.BaseClass.FolderName == name ) then
		table.Merge( CurrentGM.BaseClass, t )
		Call( "OnReloaded" );
	end

end

if ( name != "base" ) then

	local basetable = Get( derived )
	if ( basetable ) then
		t = table.Inherit( t, basetable )
	else
		Msg( "Warning: Couldn't find derived gamemode (", derived, ")

" )
end

end

GameList[ name ] = t

baseclass.Set( "gamemode_" .. name, t )

end[/lua]
Here’s what I think it should look like.
[lua]function Register(t, name, derived)
local CurrentGM = gmod.GetGamemode()

if (CurrentGM) then
	if (CurrentGM.FolderName == name) then
		table.Merge(CurrentGM, t)
		Call("OnReloaded")
	end

	if (CurrentGM.BaseClass and CurrentGM.BaseClass.FolderName == name) then
		table.Merge(CurrentGM.BaseClass, t)
		Call("OnReloaded")
	end
end

if (name != "base") then
	local basetable = Get(derived)

	if (basetable) then
		t = table.Inherit(t, basetable)
	else
		Msg("Warning: Couldn't find derived gamemode (", derived, ")

")
end
end

GameList[name] = t
baseclass.Set("gamemode_"..name, t)

end[/lua]
That’s just 1 example. The codebase itself is very inconsistent at times as well.

I personally use a style like this to match the Source and GMod codebase while also inflecting my own style that I think looks clean and clear:


-- All caps for metatables
local PLAYER = GetMetaTable( "Player" )

-- n is a prefix for a number of any discriminate type
function PLAYER:EnumIsOne( nEnum )
   -- In-line returns (no useless locals)
   return nEnum == 1
end

-- Hungarian notation
local bVar = false
local iVar = 5

-- No space next to parenthesis for purely numerical arguments
-- Also, there's always a space or another comment before a comment
local vVar = Vector(2, 5, 1)
local vVar2 = Vector(3, 5, 1)
local pPlayer = Entity(1)

RANDOM_ENUM = 1

-- Spaces 
-- No using IsValid unnecessarily: Entity() will never return nil
if ( (not bVar or iVar ~= 5) and vVar:DistToSqr( vVar2 ) <= 1 and pPlayer ~= NULL and pPlayer:HasSpawnFlags( RANDOM_ENUM )) then -- No space for space-parenthesis-parenthesis. Ex. if ( function(5) ) vs. if ( function( variable ))
   local tPlayers = player.GetAll()
   
   for i = 1, #tPlayers do
      print( "Indexed for loops are great for tables that are numerical and continuous!" )
   end
end

Thank you guys. I appreciate the responses.

General style guidelines threads?

Here are some of mine (that I’m shit at following)

Anything available outside of the file it is written in must be documented (in LDoc style)
Documentation of other stuff should be there, but is optional.



local function helperfunc1(something)
    ...
end
local function helperfunc2(something,somethingelse)
    ...
end

--- Does something.
-- This function takes information and does helperfunc1 and helperfunc2 to it in that order
-- @param information The information to process
-- @return The result of helperfunc2
function dosomething(information)
    helperfunc1(#information)
    return helperfunc2(information.wat,information.lol)
end


Do not use glua-specific operators so that non-glua parsers and validators can deal with the code. Goto is justifiably vilified, but as long as you ONLY use it as a replacement for continue it’s not so bad.

Use as many assert()s and error()s as you like. Crash as soon as you know something is wrong.
But don’t expect nothing else to happen after. Don’t be surprised if someone did



local olderr = error
error = function(msg)
    local nmsg = string.format("[Error] %s
%s",msg,debug.traceback()
    print(nmsg)
    logerror(nmsg)
end
YourCode()
error = olderr




    --[[
    -- =============================================================
    -- =========== FOR THE LOVE OF GOD STOP DOING THIS =============
    -- =============================================================
    ]]

--[[
    This will do just fine
]]


When something was written wrong, don’t try to keep hacking onto it, it’ll just be more work when you eventually have to rewrite it. (even if it’s not your fault)

Keep a list of all the places data enters your beautiful, elegant, inner representation from the dirty, filthy, outside world, and validate at these points. Either keep this list in the comments of some main file, or in it’s own separate text file.

Read This
Use ~= over != tho. Be in the habit of using Lua operators.

Hope that will help out somehow.

I have a problem with this.
While I have no problem with line comments, saying they should be limited because they are a sign of code smell seems like you’re just hiding a symptom of a problem. I should think you would prefer that you see as many symptoms of a problem as possible.

Also, what’s the logic in this one?

Kind of trivial to use != over ~= even though other Lua relational ops are used

Whatever works for you and is readable, anything beyond that is subjective. Though if you use spaces in place of tabs you’re a terrible person.

Don’t worry. I’d never do that

[editline]1st September 2016[/editline]

Thank you all for your responses and suggestions!

I think the most important thing is (being readable and) being consistent, most stuff is pretty arbitrary as long as it’s the same throughout an entire project

like Penguin stated, it all comes down to personal preference

this also may be a good link to come back to as well

Whatever you do don’t use the VCmod code base as a style reference

If you’re gonna use your style, please keep it in a readable format.

Little things I advise:

  • When creating variables, space out the equal from the variable name.
  • Keep things in a neat order. If you start an if statement, finish the arguments for it on the same line you started. Basically, don’t have if and then on separate lines.
  • Remain consistant. Don’t use != and ~= in the same thing, pick one and go with it.

not if you do lengthy statements


function GM:ScalePlayerDamage(ply, hitgroup, dmginfo)
		if(
			dmginfo:GetAttacker():IsValid() && 
			dmginfo:GetAttacker():IsPlayer() && 
			dmginfo:GetAttacker():GetActiveWeapon() && 
			dmginfo:GetAttacker():GetActiveWeapon():IsValid() && 
			dmginfo:GetAttacker():GetActiveWeapon():GetClass() == "ptp_shotty"
		) then
			local scale = math.Clamp(math.max(120 / dmginfo:GetAttacker():GetPos():Distance(ply:GetPos()), 0.1), 0, 1);
			dmginfo:ScaleDamage(scale);
		end
	end

Unrelated, but the IsValid check for the attacker and the nil check for the active weapon are useless since IsPlayer handles the first and GetActiveWeapon can’t return nil. Also, localising the attacker and weapon instead of calling the accessor a bunch is better.

don’t care enough to change it, not like it would have any real impact on perfomance anyways

To build off of this, anyone who uses single quotes instead of double quotes should rot in a hell fire. Am I right Stoned? :smug:

[sp]When people don’t realize I was making a joke[/sp]

Single quotes are useful if you want to put a double quote in a string and prefer not to fuck with escape sequences.

I use it for single characters to explicitly show the predicted input/result is a char.

[editline]5th September 2016[/editline]

Minimal performance, but the real gain is cleaner and more concise code.