• Content count

  • Joined

  • Last visited

About Fenris_Wolf

  • Rank

Contact Methods

  • Website URL

Profile Information

  • Gender
  • Interests
    coding and gunning down the undead
  1. Jessie is using libstdc++6.20, which uses CXXABI_1.3.8 For CXXABI_1.3.9 libstdc++6.21 is required. Debian Stretch is using libstdc++6.22 I haven't tried the vehicle test build and have no experience with MX (my machines run pure deb), but it looks like they've been using backports to update some of the packages and they don't seem to provide a handy list on the website. My advice would be manually in a terminal check what libstdc++6 is installed: ls /usr/lib/x86_64-linux-gnu/libstdc++.so.6* Without knowing what all that distro has done and backported (or knowing whats in their repos) I shouldn't really give advice on upgrading lbstdc++, it might be worth checking with their support forums
  2. This tutorial assumes you know the very basics of Lua: what a variable is, and how to assign one. what a function is, and how to call one and pass variables to it. what a table is, and how to declare one. It is dedicated to modders new to Lua, and is a general tutorial on Lua... not specific to modding PZ. Variables and function scope: This seems to be one of the more overlooked aspect I've noticed in mods, and is EXTREMELY important for efficient and fast code. There are 2 scopes: global and local. * Global variables can be accessed by any part of the code, from any function, in any file, and are declared like: * Local variables can only be accessed from the file (or function) that they are declared in. The more variables declared, the longer its going to take to find any specific one. Think of it like a phonebook... if you need to look up a number and that book has 1000 different numbers in it, it will take longer to find the one you want. Ideally you only want the book to contain numbers your actually planning on calling. One of the reasons Lua is used as a language for a lot of games is due to its speed. One of the reasons its fast is because by default it doesn't pollute the global space with unneeded stuff. The most important thing to remember: ALL VARIABLES ARE GLOBAL BY DEFAULT UNLESS DECLARED LOCAL. This is often overlooked. If we wanted to make sure a variable can not be accessed outside the file or function (thus not polluting the global namespace), we declare it like this: local modName = "My new mod" If we wanted a to declare this in a function printModInfo instead: function printModInfo() local modName = "My new mod" print(modName) end Had we left out the 'local' key word there, modName reverts to global, and can now be accessed anywhere. Not only is it bad for performance, it also runs the risk of accidentally over writing another variable...if someone else's mod used the same variable name in the global namespace. Lets assume we actually want modName to be global, as well as modInfo, modAuthor and modVersion, so we can access them from other files in the mod. We could declare them all global but why pollute the global space more then we have to? We're better off sticking them in a global table: MyModData = { modName = "My new mod", modInfo = "My description", modAuthor = "Me!", modVersion = 1.0 } print(MyModData.modName) It may not seem like we've saved much, only adding 1 item into the global space instead of 4, but it adds up. Tables are important for organizing and separating data. This same concept applies to functions, they can exist in the global or local space, and are assumed global unless declared with the local keyword. They can also be declared in 2 styles: -- global function printModInfo() ... end printModInfo = function() ... end -- local local function printModInfo() ... end local printModInfo = function() ... end You may have noticed the second style there actually creates a function but assigns it to a variable name, this is perfectly valid and can be a handy trick: function printModInfoStyle1() ... end function printModInfoStyle2() ... end printModInfo = printModInfoStyle1 we can reassign printModInfo to Style1 or Style2, depending on some condition and call it later simply as printModInfo() Lets say you want to add a Event that triggers on keypress: local function someFunction(key) ... end Events.OnKeyPressed.Add(someFunction) Remember to declare that function local, its not getting called from anywhere else. Actually, since its only getting passed to Events.OnKeyPressed.Add, and not even getting called locally, you can shortcut and skip polluting the local space as well: Events.OnKeyPressed.Add(function(key) ... end) Some coders may disagree with that last example, but remember the trick to writing efficient Lua is to keep the scope as small as possible, since we'll never need that function again, there is no point assigning it a name. If you create a number of functions, and the only code that calls those functions exists within the same file, be sure to make them local. The same thing I said above about sticking global variables into a table to avoid namespace pollution also applies to functions. If all those functions you declared you need to access elsewhere, put them in a table: MyModFunc = { functionNo1 = function() ... end, functionNo2 = function() ... end, functionNo3 = function() ... end, } MyModFunc.functionNo4 = function() ... end -- this works too This isn't related to global/local scope, but is often the most confusing (and annoying) part for new Lua coders so worth mentioning. Functions inside tables can actually be declared and accessed 2 ways: MyModFunc = { } function MyModFunc.functionNo1() ... end function MyModFunc:functionNo2() ... end and calling them as: MyModFunc.functionNo1() MyModFunc:functionNo2() Notice the use of : in functionNo2 instead of the . The first style is a normal function, and behaves exactly like you'd expect. The second style is technically called a 'method', it will pass a variable named 'self' to the function. In this case 'self' is the table MyModFunc. The functionNo2 method is basically doing this: function MyModFunc.functionNo2(self) ... end MyModFunc.functionNo2(MyModFunc) Now that all that is sorted out, here's a additional scoping trick... functions can be created inside other functions: local functionNo1() local myVariable = "some text" local functionNo2 = function() print(myVariable) end return functionNo2 end local result = functionNo1() result() -- prints "some text" this calls the first function, which returns the second, the second (now in the variable 'result') is called, and prints "some text" While the above bit of code itself not overly useful, it demonstrates a few points: functions inside functions, and variables are inherited from the above scope (even locals) and can be used after their scope has ended.