Scripting Moderators ds1-e Posted February 12, 2019 Scripting Moderators Share Posted February 12, 2019 Hey. I was doing some stuff with tables, and i encountered a problem. So, i have a table with cache data of vehicles, on server-side. I need to change some values, when vehicle got damaged, however i can't use this table on client-side or within onVehicleDamage because there's not attacker parameter, and without it i can't get some additional data. Looking for workarounds or a solution, - maybe create custom event which will be triggered from client (onClientVehicleDamage) -> server (custom function), but i think so it will decrease performance a lot (triggering on every damage of car done by player), or there's a easier way to get this table up-to-date on client-side, without decreasing performance. Link to comment
Moderators IIYAMA Posted February 12, 2019 Moderators Share Posted February 12, 2019 @majqq The answer to that depends for 95% on what your endpoint needs. Enough context is essential for coding with responsibility. Link to comment
Scripting Moderators ds1-e Posted February 12, 2019 Author Scripting Moderators Share Posted February 12, 2019 (edited) 39 minutes ago, IIYAMA said: @majqq The answer to that depends for 95% on what your endpoint needs. Enough context is essential for coding with responsibility. Well i need to change some data which is server-sided, using client-side event, onClientVehicleDamage. + The data on server-side in table, should be updated when player damage a vehicle. (this should be synced for all the players) Edited February 12, 2019 by majqq Link to comment
aka Blue Posted February 12, 2019 Share Posted February 12, 2019 ¿Why you don't make the table shared and manipule it with shared functions? I think it should work. Link to comment
Moderators IIYAMA Posted February 12, 2019 Moderators Share Posted February 12, 2019 57 minutes ago, majqq said: Well i need to change some data which is server-sided, using client-side event, onClientVehicleDamage. + The data on server-side in table, should be updated when player damage a vehicle. (this should be synced for all the players) 58 minutes ago, majqq said: (this should be synced for all the players) Oke, Is there more to it? Because this is not enough to pick the right method. For example: Response time? Delay in between? Network bandwidth limit? Parameters? Is it used for visuals only or has it also influence on gameplay directly? Which players do need to receive this information immediately? Which ones later? (Which ones not? > Players that join later or that are far away.) 1 Link to comment
Scripting Moderators ds1-e Posted February 12, 2019 Author Scripting Moderators Share Posted February 12, 2019 1 hour ago, aka Blue said: ¿Why you don't make the table shared and manipule it with shared functions? I think it should work. -- shared vehiclesCacheData = { armorPoints = {}, } -- server -- checking data, returns good values. addCommandHandler("data", function(plr, command) local vehicle = getPedOccupiedVehicle(plr) if not vehicle then outputChatBox("You need to be in vehicle to get data.", plr) return end local parent = getElementData(vehicle, "core:parent") if parent and vehicle then outputChatBox("Data [1]: "..vehiclesCacheData.armorPoints[parent], plr) --outputDebugString("Parent: "..tostring(parent)) end end) -- adding data, somewhere in function vehiclesCacheData.armorPoints[carCol] = 17 * 100 -- client -- checking data, returns error or nil. addCommandHandler("data2", function(plr, command) local veh = getPedOccupiedVehicle(getLocalPlayer()) local parent = getElementData(veh, "core:parent") outputChatBox(vehiclesCacheData[parent].armorPoints) -- this will show error - attempt to index field '?' (a nil value) --outputChatBox(vehiclesCacheData.armorPoints[parent]) -- this will show nil end) I tried, it doesn't wanna work, seems like server/client have separate "shared" tables. 54 minutes ago, IIYAMA said: Oke, Is there more to it? Because this is not enough to pick the right method. For example: Response time? Delay in between? Network bandwidth limit? Parameters? Is it used for visuals only or has it also influence on gameplay directly? Which players do need to receive this information immediately? Which ones later? (Which ones not? > Players that join later or that are far away.) Well, i decided to switch from using elementData to tables, everything should be okay, i wouldn't need to write this topic if just onVehicleDamage would have attacker parameter. So: - Efficient, at all, i had some problems with elementData, i'm sure that this thing was responsible for jumping bars of "vehicle armor", but that's by the way. - Less what can be, but i still should care for performance at all. - I can't you answer about it, no clue. - What parameters you mean? - It's one of the important things, not a visual thing only. - What will be best solution for it? To make it works fast, and efficiently. It shouldn't sync for players that aren't logged in, only for players in game. Link to comment
Moderators IIYAMA Posted February 12, 2019 Moderators Share Posted February 12, 2019 2 hours ago, majqq said: Well, i decided to switch from using elementData to tables, everything should be okay, i wouldn't need to write this topic if just onVehicleDamage would have attacker parameter. So: - Efficient, at all, i had some problems with elementData, i'm sure that this thing was responsible for jumping bars of "vehicle armor", but that's by the way. - Less what can be, but i still should care for performance at all. - I can't you answer about it, no clue. - What parameters you mean? - It's one of the important things, not a visual thing only. - What will be best solution for it? To make it works fast, and efficiently. It shouldn't sync for players that aren't logged in, only for players in game. - With parameters I mean the arguments you want to use there. - There are no shared tables. I recommend to first try to use the clean way. Sync with triggerEvents, so that you do not destroy other players their network usage directly. (of course this can still happen) Buffer up to at least 200ms. Check if latent events are fast enough for your target group. If your players have bad internet, then it might be possible that the information never gets send... Latent events will only send information when the network isn't blocked. This means that position and orientation of players should be more accurate while sending information. Element data usage will increase when the player count increases, so test it before you use that type instead. Untested code local damageToSync = {} local syncVehicleDamageTimer local function syncVehicleDamage () syncVehicleDamageTimer = nil -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- triggerServerEvent("syncVehicleDamage", resourceRoot, damageToSync) -- -- or -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- triggerLatentServerEvent("syncVehicleDamage", resourceRoot, damageToSync) -- It will improve the gameplay. >>> BUT this will work ONLY fine if your target players have fast internet. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- damageToSync = {} -- reset table end addEventHandler("onClientVehicleDamage", root, function (attacker, weapon, loss) if isElementSyncer(source) and attacker and getElementType(attacker) == "player" and loss > 0 then -- register vehicle local vehicleDamageTable = damageToSync[source] if not vehicleDamageTable then vehicleDamageTable = {} damageToSync[source] = vehicleDamageTable end -- register attacker + loss of vehicle vehicleDamageTable[attacker] = (vehicleDamageTable[attacker] or 0) + loss -- start sync delay if not syncVehicleDamageTimer then syncVehicleDamageTimer = setTimer(syncVehicleDamage, 200, 1) end end end) The table structure. --[[ -- table structure -- local damageToSync = { [vehicle] = { [attacker] = loss, [attacker] = loss } [vehicle] = { [attacker] = loss, [attacker] = loss } } ]] 1 Link to comment
Scripting Moderators ds1-e Posted February 13, 2019 Author Scripting Moderators Share Posted February 13, 2019 38 minutes ago, IIYAMA said: - With parameters I mean the arguments you want to use there. - There are no shared tables. I recommend to first try to use the clean way. Sync with triggerEvents, so that you do not destroy other players their network usage directly. (of course this can still happen) Buffer up to at least 200ms. Check if latent events are fast enough for your target group. If your players have bad internet, then it might be possible that the information never gets send... Latent events will only send information when the network isn't blocked. This means that position and orientation of players should be more accurate while sending information. Element data usage will increase when the player count increases, so test it before you use that type instead. Untested code local damageToSync = {} local syncVehicleDamageTimer local function syncVehicleDamage () syncVehicleDamageTimer = nil -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- triggerServerEvent("syncVehicleDamage", resourceRoot, damageToSync) -- -- or -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- triggerLatentServerEvent("syncVehicleDamage", resourceRoot, damageToSync) -- It will improve the gameplay. >>> BUT this will work ONLY fine if your target players have fast internet. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- damageToSync = {} -- reset table end addEventHandler("onClientVehicleDamage", root, function (attacker, weapon, loss) if isElementSyncer(source) and attacker and getElementType(attacker) == "player" and loss > 0 then -- register vehicle local vehicleDamageTable = damageToSync[source] if not vehicleDamageTable then vehicleDamageTable = {} damageToSync[source] = vehicleDamageTable end -- register attacker + loss of vehicle vehicleDamageTable[attacker] = (vehicleDamageTable[attacker] or 0) + loss -- start sync delay if not syncVehicleDamageTimer then syncVehicleDamageTimer = setTimer(syncVehicleDamage, 200, 1) end end end) The table structure. --[[ -- table structure -- local damageToSync = { [vehicle] = { [attacker] = loss, [attacker] = loss } [vehicle] = { [attacker] = loss, [attacker] = loss } } ]] Wow, that's awesome. But this will not hurt server when triggering it all the time onClientVehicleDamage? Another question related to it, i will need to get this server-side table when player damage a car (there's a some kind of interface which shows actual armor bar of car), should i make it with triggerClientEvent or there's a better way? About code above, didn't test it yet. Link to comment
Moderators IIYAMA Posted February 13, 2019 Moderators Share Posted February 13, 2019 (edited) It will hurt the sender a bit. But only if he or she has terrible internet. And you can always increase the buffer/delay time. (Remember to test the latent version for your target group) When you are going to send information back it will also hurt the receiver without doubts. But you can use an even bigger delay for players that are far away. So only the players that are closeby should actually receive data immediately. On the other hand elementdata could save you some data for closeby players. The usage require less data, but the target players are not control able. So if there are 500 players in your server, then I do not recommended it. You should test both ways. It is a paradox I know... Why not set elementdata clientside? Because players will overwrite the data from each other. It is something the server should manage. Who is your target group by the way? @majqq Edited February 13, 2019 by IIYAMA 1 Link to comment
Scripting Moderators ds1-e Posted February 13, 2019 Author Scripting Moderators Share Posted February 13, 2019 (edited) 8 hours ago, IIYAMA said: It will hurt the sender a bit. But only if he or she has terrible internet. And you can always increase the buffer/delay time. (Remember to test the latent version for your target group) When you are going to send information back it will also hurt the receiver without doubts. But you can use an even bigger delay for players that are far away. So only the players that are closeby should actually receive data immediately. On the other hand elementdata could save you some data for closeby players. The usage require less data, but the target players are not control able. So if there are 500 players in your server, then I do not recommended it. You should test both ways. It is a paradox I know... Why not set elementdata clientside? Because players will overwrite the data from each other. It is something the server should manage. Who is your target group by the way? @majqq I had already experience with elementData, on 40~ players, let's say was around 15 cars shooting to themselves, and the value of each car armor was done on elementData. There was also one elementData which was responsible for player blood. About my players. I have server in EU, a lot of EU players (they have very small ping 40-60 +/-), and some RU/UA/KZ players (they have ping around 100-120~). I am targeting in making optimisations in everything which changing very frequently (i think it's good to change it from elementData to table), this is one of 3 things, which also change frequently, i just want to see results, which tables can give me. And about this interface, i should send update of this table whenever vehicle got damage? Edited February 13, 2019 by majqq 1 Link to comment
Moderators IIYAMA Posted February 13, 2019 Moderators Share Posted February 13, 2019 (edited) 38 minutes ago, majqq said: . And about this interface, i should send update of this table whenever vehicle got damage? Yes, I can't explain it better than this: Client (see my example) Trigger: When vehicle damage Condition: You must be the syncer of the vehicle. Actions: - Save updates for the table. (Not a new version of the main table) - Start the buffer timer. 200ms?(if not running already) In case of firedamage or a minigun you will be preventing a trigger event that is send every frame. --------------- Trigger: When the buffer timer is finished. Action: Send the table updates to the server. _______________ _______________ _______________ Server Trigger: When there is an update from the client. Condition: If a player is closer to the vehicle than 300+ units, do action 1 for him. Else do action 2 for him. Action 1: Send a (latent) trigger event to the selected person. Action 2: Save this message in a table. Start a personal buffer timer for him. This table could contain similar types of updates from different vehicles. The data should contain is a reference to the player and to the vehicle. Which you can use to pick the right and latest update for the player. (Also here start the buffer timer only when it is not running for the selected person) -------------- Trigger: When the personal buffer timer is finished.(action 2) Action: Send the table new table to the client. Edited February 13, 2019 by IIYAMA 1 Link to comment
Scripting Moderators ds1-e Posted February 15, 2019 Author Scripting Moderators Share Posted February 15, 2019 On 13/02/2019 at 17:49, IIYAMA said: Yes, I can't explain it better than this: Client (see my example) Trigger: When vehicle damage Condition: You must be the syncer of the vehicle. Actions: - Save updates for the table. (Not a new version of the main table) - Start the buffer timer. 200ms?(if not running already) In case of firedamage or a minigun you will be preventing a trigger event that is send every frame. --------------- Trigger: When the buffer timer is finished. Action: Send the table updates to the server. _______________ _______________ _______________ Server Trigger: When there is an update from the client. Condition: If a player is closer to the vehicle than 300+ units, do action 1 for him. Else do action 2 for him. Action 1: Send a (latent) trigger event to the selected person. Action 2: Save this message in a table. Start a personal buffer timer for him. This table could contain similar types of updates from different vehicles. The data should contain is a reference to the player and to the vehicle. Which you can use to pick the right and latest update for the player. (Also here start the buffer timer only when it is not running for the selected person) -------------- Trigger: When the personal buffer timer is finished.(action 2) Action: Send the table new table to the client. Thanks, but can you help me one more time? I don't want create other topic for it, and question it's related with tables. How can i send this table from server-side within triggerClientEvent, and then create same, just with other title? Or copy everything what it contains? table = { first = {}, second = {}, } Link to comment
Moderators IIYAMA Posted February 15, 2019 Moderators Share Posted February 15, 2019 (edited) Clientside local thisTable = {} addEvent("update-------") addEventHandler("update-------", resourceRoot, function (index, data) thisTable[index] = data end, false) Serverside local thisTable = {} function updateTable (target, index, data) thisTable[index] = data triggerLatentClientEvent(target, "update-------", resourceRoot, index, data) end updateTable(target, "index", {"data"}) -- all players updateTable(getElementsByType("player"), "index", {"data"}) -- all players updateTable(getRandomPlayer(), "index", {"data"}) -- just a single player updateTable({getRandomPlayer()}, "index", {"data"}) -- just a single player Keep in mind that when testing this code, it is important to mind "when/timing?" + "triggerClientEvent/communication". As in this example the client hasn't loaded it's scripts yet. Adjust it to your needs. @majqq Edited February 15, 2019 by IIYAMA 1 Link to comment
Scripting Moderators ds1-e Posted March 8, 2019 Author Scripting Moderators Share Posted March 8, 2019 On 15/02/2019 at 12:24, IIYAMA said: Clientside local thisTable = {} addEvent("update-------") addEventHandler("update-------", resourceRoot, function (index, data) thisTable[index] = data end, false) Serverside local thisTable = {} function updateTable (target, index, data) thisTable[index] = data triggerLatentClientEvent(target, "update-------", resourceRoot, index, data) end updateTable(target, "index", {"data"}) -- all players updateTable(getElementsByType("player"), "index", {"data"}) -- all players updateTable(getRandomPlayer(), "index", {"data"}) -- just a single player updateTable({getRandomPlayer()}, "index", {"data"}) -- just a single player Keep in mind that when testing this code, it is important to mind "when/timing?" + "triggerClientEvent/communication". As in this example the client hasn't loaded it's scripts yet. Adjust it to your needs. @majqq Hey, @IIYAMA i am glad about to say that your code works perfectly. I did some changes to it - changed source to colshape data, etc., and i encountered a problem on my way to finish this. \vehicles.lua:15: attempt to perform arithmetic on local 'damage' (a table value) This is code, added also colshape data (parent) to identify vehicle later: triggerLatentServerEvent("sendDataToServer", resourceRoot, parent, damageToSync) So basically it sends a table, not value of damage for certain car, how can i fix it? This is server-side event which is triggered. function sendDataToServer(index, damage) vehiclesCacheData.armorPoints[index] = vehiclesCacheData.armorPoints[index] - damage -- shows error here triggerLatentClientEvent("receiveVehicleData", resourceRoot, index, damage) end addEvent("sendDataToServer", true) addEventHandler("sendDataToServer", resourceRoot, sendDataToServer) Link to comment
Moderators IIYAMA Posted March 8, 2019 Moderators Share Posted March 8, 2019 40 minutes ago, majqq said: Hey, @IIYAMA i am glad about to say that your code works perfectly. I did some changes to it - changed source to colshape data, etc., and i encountered a problem on my way to finish this. \vehicles.lua:15: attempt to perform arithmetic on local 'damage' (a table value) This is code, added also colshape data (parent) to identify vehicle later: triggerLatentServerEvent("sendDataToServer", resourceRoot, parent, damageToSync) So basically it sends a table, not value of damage for certain car, how can i fix it? This is server-side event which is triggered. function sendDataToServer(index, damage) vehiclesCacheData.armorPoints[index] = vehiclesCacheData.armorPoints[index] - damage -- shows error here triggerLatentClientEvent("receiveVehicleData", resourceRoot, index, damage) end addEvent("sendDataToServer", true) addEventHandler("sendDataToServer", resourceRoot, sendDataToServer) Shouldn't you send the update of the table, instead of the table itself? Hmmm I am currently a bit slow to keep up with your development. Can you take a step back so that I can follow it? Link to comment
Scripting Moderators ds1-e Posted March 8, 2019 Author Scripting Moderators Share Posted March 8, 2019 (edited) 1 hour ago, IIYAMA said: Shouldn't you send the update of the table, instead of the table itself? Hmmm I am currently a bit slow to keep up with your development. Can you take a step back so that I can follow it? Maybe i didn't understand everything correctly. I made this in some other way. - Once you create a vehicle, it inserts vehicle in table with data, and send it to players. (vehicle interface) - delay: 60 seconds for player - When you repair a vehicle, it update data for certain vehicle in table, and send it to players. (vehicle interface) - delay: 60 seconds for player * This is only for the players connected to server. Some players can join later, they would need to have same data as players which have been before latejoiners. So: - Once a player login, a triggerLatentClientEvent from server it's sended directly to him, to copy whole data from server-side table, which should be up-to-date all the time, and it replaces (most-likely empty at this moment) client-side table with vehicles data. About data in tables - i delete cache for certain vehicles from both tables, onVehicleExplode on server-side and onClientElementDestroy (after about 30 seconds) on client-side. And about question. Shouldn't it work? Vehicle got damage > client send triggerLatentServerEvent with damage value > server checks it, updates a server-side table, and send updated data to clients with triggerLatentClientEvent. (Tested it alone, data was correct for every vehicle, after reconnect too.) Edited March 8, 2019 by majqq Link to comment
Moderators IIYAMA Posted March 8, 2019 Moderators Share Posted March 8, 2019 (edited) 43 minutes ago, majqq said: Maybe i didn't understand everything correctly. I made this in some other way. - Once you create a vehicle, it inserts vehicle in table with data, and send it to players. (vehicle interface) - delay: 60 seconds for player - When you repair a vehicle, it update data for certain vehicle in table, and send it to players. (vehicle interface) - delay: 60 seconds for player * This is only for the players connected to server. Some players can join later, they would need to have same data as players which have been before latejoiners. So: - Once a player login, a triggerLatentClientEvent from server it's sended directly to him, to copy whole data from server-side table, which should be up-to-date all the time, and it replaces (most-likely empty at this moment) client-side table with vehicles data. About data in tables - i delete cache for certain vehicles from both tables, onVehicleExplode on server-side and onClientElementDestroy (after about 30 seconds) on client-side. And about question. Shouldn't it work? Vehicle got damage > client send triggerLatentServerEvent with damage value > server checks it, updates a server-side table, and send updated data to clients with triggerLatentClientEvent. (Tested it alone, data was correct for every vehicle, after reconnect too.) Oke, it is growing rapidly I can see. Well then, how to BLOCK incorrect new data before you letting it flows in to your collection of all data: if damage and type(damage) == "number" then local vehicleArmorPoints = vehiclesCacheData.armorPoints[index] if vehicleArmorPoints and type(vehicleArmorPoints) == "number" then vehiclesCacheData.armorPoints[index] = vehicleArmorPoints - damage else outputDebugString("`vehicleArmorPoints` should contain a number, but it contains: " .. inspect(vehicleArmorPoints), 2) end else outputDebugString("`damage` should contain a number, but it contains: " .. inspect(damage), 2) end If it enters your collection, then you are more or less ** *** ** **** *** ***! because everything that relies on it will break. Might not be the case in your example, but `better safe than sorry`. Edited March 8, 2019 by IIYAMA 1 Link to comment
Scripting Moderators ds1-e Posted March 8, 2019 Author Scripting Moderators Share Posted March 8, 2019 3 minutes ago, IIYAMA said: Oke, it is growing rapidly I can see. Well then, how to BLOCK incorrect new data before you letting it flow in to your collection of all data: if damage and type(damage) == "number" then local vehicleArmorPoints = vehiclesCacheData.armorPoints[index] if vehicleArmorPoints and type(vehicleArmorPoints) == "number" then vehiclesCacheData.armorPoints[index] = vehicleArmorPoints - damage else outputDebugString("`vehicleArmorPoints` should contain a number, but it contains: " .. inspect(vehicleArmorPoints), 2) end else outputDebugString("`damage` should contain a number, but it contains: " .. inspect(damage), 2) end If it enters your collection, then you are more or less ** *** ** **** *** ***! because everything that relies on it will break. Might not be the case in your example, but `better safe than sorry`. Nah it's not rapid , looks like it but it isn't. I have created basics for this system about 1~ month ago. And hardest (for me) things i am doing now (after a lot of other stuff creating. You helped me a lot of with certain things, big thanks to you ), at nearly end of this which I am doing. So this way should work, I am right? Quote Vehicle got damage > client send triggerLatentServerEvent with damage value > server checks it, updates a server-side table, and send updated data to clients with triggerLatentClientEvent Still i don't know how can i get awaiting damage from this table. -- table structure -- local damageToSync = { [vehicle] = { [attacker] = loss, [attacker] = loss } [vehicle] = { [attacker] = loss, [attacker] = loss } } ]] 1 Link to comment
Moderators IIYAMA Posted March 8, 2019 Moderators Share Posted March 8, 2019 (edited) for vehicle, damageData in pairs(damageToSync) do local vehicleDamage = 0 for attacker, damage in pairs(damageData) do vehicleDamage = vehicleDamage + damage end setElementHealth(vehicle, math.max(getElementHealth(vehicle) - vehicleDamage, 0)) end You can process it for example like that. You might also need to use isElement in this example, as client data can be out of date. Just so you know: it is not the fastest table structure for reading the data, but it is by far the fastest table structure for writing data. <-- please ignore this bull:~. Edited March 8, 2019 by IIYAMA 1 Link to comment
Scripting Moderators ds1-e Posted March 11, 2019 Author Scripting Moderators Share Posted March 11, 2019 On 08/03/2019 at 20:28, IIYAMA said: for vehicle, damageData in pairs(damageToSync) do local vehicleDamage = 0 for attacker, damage in pairs(damageData) do vehicleDamage = vehicleDamage + damage end setElementHealth(vehicle, math.max(getElementHealth(vehicle) - vehicleDamage, 0)) end You can process it for example like that. You might also need to use isElement in this example, as client data can be out of date. Just so you know: it is not the fastest table structure for reading the data, but it is by far the fastest table structure for writing data. <-- please ignore this bull:~. Okey, looks like i have finished this system for vehicles Thanks for help, i will test it soon with players and i will let you know how it works. One more question, so i wouldn't need to create another topic for it. What exactly does declaring function as local I know what it does if you declare variable as local, but it's the same for function, like will be faster? Link to comment
Moderators IIYAMA Posted March 11, 2019 Moderators Share Posted March 11, 2019 45 minutes ago, majqq said: Okey, looks like i have finished this system for vehicles Thanks for help, i will test it soon with players and i will let you know how it works. One more question, so i wouldn't need to create another topic for it. What exactly does declaring function as local I know what it does if you declare variable as local, but it's the same for function, like will be faster? Function names are 1 = 1 variables. So a local function is nothing more than a function saved in a local variable. And as you know local variables are faster because they have a limited scope. Instead of searching through all global variables, those variables are more or less being a part of the scope. It is like searching for polar bears on the: A the whole world B the North Pole C graveyard Where will you find that animal first? Different ways of writing them + differences in access: local function functionName () iprint(functionName) -- "function functionName" end iprint(functionName) -- "function functionName" functionName() local functionName = function () iprint(functionName) -- nil NOOOOOOO! end iprint(functionName) -- "function functionName" functionName() local functionName function functionName () iprint(functionName) -- "function functionName" end iprint(functionName) -- "function functionName" functionName() 1 1 Link to comment
Scripting Moderators ds1-e Posted March 11, 2019 Author Scripting Moderators Share Posted March 11, 2019 7 hours ago, IIYAMA said: Function names are 1 = 1 variables. So a local function is nothing more than a function saved in a local variable. And as you know local variables are faster because they have a limited scope. Instead of searching through all global variables, those variables are more or less being a part of the scope. It is like searching for polar bears on the: A the whole world B the North Pole C graveyard Where will you find that animal first? Different ways of writing them + differences in access: local function functionName () iprint(functionName) -- "function functionName" end iprint(functionName) -- "function functionName" functionName() local functionName = function () iprint(functionName) -- nil NOOOOOOO! end iprint(functionName) -- "function functionName" functionName() local functionName function functionName () iprint(functionName) -- "function functionName" end iprint(functionName) -- "function functionName" functionName() So if i don't need use function(s) globally i can make all of them local, and it will be better a bit? Link to comment
Moderators IIYAMA Posted March 11, 2019 Moderators Share Posted March 11, 2019 1 minute ago, majqq said: So if i don't need use function(s) globally i can make all of them local, and it will be better a bit? It will be indeed a bit better. But there are three very important downsides: A limit of the amount of local variables per function. Quote Limit on number: There is a limit to the number of locals per function (MAXLOCALS, typically 200). http://lua-users.org/wiki/LocalsVsGlobals 100% locals? It basically means that you can't use multiple files. Which will de-increase your own scripting performance. An local variable can only be called below it's declaration.So this will not work: local function test2 () test() -- input:2: attempt to call a nil value (global 'test') end local function test () end test2() But this will: local test2, test function test2 () test() end function test () end test2() 1 Link to comment
Scripting Moderators ds1-e Posted March 19, 2019 Author Scripting Moderators Share Posted March 19, 2019 On 11/03/2019 at 20:45, IIYAMA said: It will be indeed a bit better. But there are three very important downsides: A limit of the amount of local variables per function. 100% locals? It basically means that you can't use multiple files. Which will de-increase your own scripting performance. An local variable can only be called below it's declaration.So this will not work: local function test2 () test() -- input:2: attempt to call a nil value (global 'test') end local function test () end test2() But this will: local test2, test function test2 () test() end function test () end test2() Hey once again. I want merge some script files, about 16~ lua files. Into 2-4 files (1 shared, others client/server side), to make rework easier. It's just about data system and GUI inventory at all (data for vehicles work well ). I probably misunderstood this: A limit of the amount of local variables per function. It's limit for local variables inside function(s)? Or in whole lua file. Link to comment
Moderators IIYAMA Posted March 20, 2019 Moderators Share Posted March 20, 2019 8 hours ago, majqq said: Hey once again. I want merge some script files, about 16~ lua files. Into 2-4 files (1 shared, others client/server side), to make rework easier. It's just about data system and GUI inventory at all (data for vehicles work well ). I probably misunderstood this: A limit of the amount of local variables per function. It's limit for local variables inside function(s)? Or in whole lua file. A file counts also as a function. Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now