• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Luacheck or: How I Learned to Stop Worrying and Use Lua

Status
Not open for further replies.
Level 13
Joined
Nov 7, 2014
Messages
571
Luacheck or: How I Learned to Stop Worrying and Use Lua

Luacheck is a tool for linting and static analysis of Lua code. It can detect a lot of errors at "map build time".

I find the "accessing of undefined global variables" (aka. typos) errors the most helpful. Luacheck can be configured to ignore "new globals" which one should probably do if they want to use Blizzards ~5K of predefined "stuff" (see the attached example 'luacheck.config' file).
 

Attachments

  • luacheck.config.txt
    124.3 KB · Views: 84
Level 12
Joined
Jan 30, 2020
Messages
875
I had hopes when finding your post but it seems useless.

I tried it on my map script, and on the first function it starts throwing errors when they should not be any.
By the way, the default config file for luacheck is ".luacheckrc" not "luacheck.config".

Ok so I used your config file, indeed removing more than 1000 undefined globals warning. But this is still not helping !

Beginning of my script :
Lua:
gg_trg_Lua_Init = nil
function InitGlobals()
end

function EnableBallTriggers(bn)
    EnableTrigger(StoppedBall[bn])
    EnableTrigger(DamagedBall[bn])
    EnableTrigger(KilledBall[bn])
end


function DisableBallTriggers(bn)
    DisableTrigger(StoppedBall[bn])
    DisableTrigger(DamagedBall[bn])
    DisableTrigger(KilledBall[bn])
end


function CleanDestroyBallTriggers(bn)
    DisableBallTriggers(bn)
    DestroyTrigger(StoppedBall[bn])
    DestroyTrigger(DamagedBall[bn])
    DestroyTrigger(KilledBall[bn])
end


function AddEventsBallTriggers(b, bn)
    TriggerRegisterUnitEvent(StoppedBall[bn], b, EVENT_UNIT_ISSUED_ORDER)
    TriggerRegisterUnitEvent(DamagedBall[bn], b, EVENT_UNIT_DAMAGED)
    TriggerRegisterUnitEvent(KilledBall[bn], b, EVENT_UNIT_DEATH)
end

result for this simple part :
Code:
    war3map.lua:1:1: setting non-standard global variable 'gg_trg_Lua_Init'
    war3map.lua:2:10: setting non-standard global variable 'InitGlobals'
    war3map.lua:5:10: setting non-standard global variable 'EnableBallTriggers'
    war3map.lua:6:19: accessing undefined variable 'StoppedBall'
    war3map.lua:7:19: accessing undefined variable 'DamagedBall'
    war3map.lua:8:19: accessing undefined variable 'KilledBall'
    war3map.lua:12:10: setting non-standard global variable 'DisableBallTriggers'
    war3map.lua:13:20: accessing undefined variable 'StoppedBall'
    war3map.lua:14:20: accessing undefined variable 'DamagedBall'
    war3map.lua:15:20: accessing undefined variable 'KilledBall'
    war3map.lua:19:10: setting non-standard global variable 'CleanDestroyBallTriggers'
    war3map.lua:20:5: accessing undefined variable 'DisableBallTriggers'
    war3map.lua:21:20: accessing undefined variable 'StoppedBall'
    war3map.lua:22:20: accessing undefined variable 'DamagedBall'
    war3map.lua:23:20: accessing undefined variable 'KilledBall'
    war3map.lua:27:10: setting non-standard global variable 'AddEventsBallTriggers'
    war3map.lua:28:30: accessing undefined variable 'StoppedBall'
    war3map.lua:29:30: accessing undefined variable 'DamagedBall'
    war3map.lua:30:30: accessing undefined variable 'KilledBall'

It does not take into account the main function that runs first, then does not check if the variables are defined somewhere else.
I bet it cannot even detect when the functions are used as callbacks.


Or am I using this tool the wrong way ?

How would you make it detect the usage of Globals that are not defined at the time its access is actually attempted ?


Has potential, but didn't help me find any real error.
 
Level 13
Joined
Nov 7, 2014
Messages
571
Try declaring your functions with 'local':
Lua:
function my_function()
end
=>
local function my_function()
end

For Blizzard's auto generated global variables you can try adding an ignore pattern in the config file.
Lua:
ignore = {
    'gg_.+', -- don't report access to variables with 'gg_' prefix
}
For Blizzard's auto generated global functions you would probably have to ignore them individually.

You should probably consider writing your Lua scripts outside of the Trigger Editor. That way you won't have to bother with the auto generated stuff.
 
Level 12
Joined
Jan 30, 2020
Messages
875
Well I don't write it in trigger editor, I have enough Lua nightmares like that.

Mind you one should expect to run into these horrible situations when you think you lose control of your script and nothing seems to make sense.

This is typical from converting Jass2 to Lua, as both languages are so different in spite of similar syn taxes in some cases.

the "gg_trg_Lua_Init = nil" you see there is just the trace of the trigger I made in GUI to call my main function when I started the conversion.

Everything else is separated in custom scripts, with each functions doing things in a similar scope. I made this for readability, but I work on my functions in Notepad++ with the included Lua highlighter.


I tried VSCode and it looks amazing, but too confusing for me, and I am so drawn into converting my map and its endless inexplicable issues (often because of variables woes), that I don't have time to learn anything else than how Lua works at the moment.

I know there are ways to completely rewrite functions in Lua, even those created by World Editor on save or even natives I have heard, but I don't know yet how to do that so I try to focus on why the hell basic things like adding a debugging print("ok there") to a function makes the game crash... yes a nightmare.

Anyways, I had hopes this program could run through my map script and find out the Global Variables I try to use without proper initialization, and there seem to be more than I thought. But if it throws an error everytime it finds a global I initialize later in the script, how can this help ?


Sorry I hope I don't sound harsh, I have been working endlessly on this conversion for many days and I start to be a bit tired.


Only positive aspect is I don't suffer from the confinement :D
 
Status
Not open for further replies.
Top