Too Many Local Variables

Place to get help with not working mods / modding interface.
Post Reply
Shrooblord
Long Handed Inserter
Long Handed Inserter
Posts: 54
Joined: Thu May 12, 2016 12:57 pm
Contact:

Too Many Local Variables

Post by Shrooblord »

Hey modders,

I'm creating a mod but I'm running into a problem regarding local variables used in the control.lua. I have entities in the world that store values concerning themselves as local variables, but if there's too many of these entities in the world, on world load, the game will return an error, telling you the maximum limit of local variables is 200, and this save file has exceeded this.

The only way to restore the file is to uninstall the mod, load the save file, have it kill all entities and items pertaining to that mod automatically, save that game, exit and reinstall the mod and reload the level.


I'm asking you help on solving this case - how can I either reduce the number of local variables I need (work-around); limit the amount of entities placed of this type (worse work-around - factorio is all about going big; putting a hard limit on certain entities seems silly); increase the local variable limit (possibly this means overriding/hacking into base game defaults - something not all users would be happy with); come up with a way to not need local variables?

In my case, I'm setting up the local variables so they can later be altered through research; i.e. have their values altered depending on the amount of research done in a particular, custom tech tree.

Thanks,
Shrooblord

User avatar
DaveMcW
Smart Inserter
Smart Inserter
Posts: 3700
Joined: Tue May 13, 2014 11:06 am
Contact:

Re: Too Many Local Variables

Post by DaveMcW »

Store all the variables in one table?

Shrooblord
Long Handed Inserter
Long Handed Inserter
Posts: 54
Joined: Thu May 12, 2016 12:57 pm
Contact:

Re: Too Many Local Variables

Post by Shrooblord »

How do you do that? Do you define a global table and store all variables there?

Basically, don't use local variables? (That goes against everything my programmer brain tells me to do. :P )

User avatar
DaveMcW
Smart Inserter
Smart Inserter
Posts: 3700
Joined: Tue May 13, 2014 11:06 am
Contact:

Re: Too Many Local Variables

Post by DaveMcW »

instead of:
local a = 1
local b = 2
local c = 3

do:
local var = {}
var.a = 1
var.b = 2
var.c = 3

User avatar
bobingabout
Smart Inserter
Smart Inserter
Posts: 7352
Joined: Fri May 09, 2014 1:01 pm
Contact:

Re: Too Many Local Variables

Post by bobingabout »

Talking about entities in existence, I assume this is in the control.lua file?

If this is the case, why are you storing information about entities in local variables in the first place? is this a one off calculation, and all these local variables are dismissed on the very next tick? If the answer is no, you're probably doing it wrong.

Only the global table is saved to the save game, as such any information stored in a local is not saved, and due to the way the game works, is not guaranteed to exist on the next tick, because that next tick might be a save/load away.


As a general rule, only use local for storing "to be used on the same tick" information, everything else should be a variable, or sub-table in the global table.
Creator of Bob's mods. Expanding your gameplay since version 0.9.8.
I also have a Patreon.

Shrooblord
Long Handed Inserter
Long Handed Inserter
Posts: 54
Joined: Thu May 12, 2016 12:57 pm
Contact:

Re: Too Many Local Variables

Post by Shrooblord »

bobingabout wrote:Talking about entities in existence, I assume this is in the control.lua file?
Yes.
As a general rule, only use local for storing "to be used on the same tick" information, everything else should be a variable, or sub-table in the global table.
Okay, I'm sort of doing both. I did run into this problem before, and in moving other local variables to the global table, then placing more than 200 entities of the offending type, saving and reloading, did not encounter the error. I guess I should just continue that trend for variables that need their value stored across ticks. Thanks.
However, I'm not currently using any such variables as locals anymore.
I'm doing some operations on a per-tick basis that require a local variable. For example, I'm spawning in entities where there were other entities before, each of which has a variable entry in the global table. So their spawn code is:

Code: Select all

if (spawn condition) then
   local newEntity = game.get_surface(1).create_entity({ name='myEntity2', amount=1, position=k});
   global.shr.growing[newEntity.position] = math.floor(game.tick / 60);
end
Where the position k is a key value in a for k, v in pairs loop that can be read as thisEntity.position as the key x in global.shr.growing[x] - it can be interpreted as a unique identifier for a single entity: only one entity with position newEntity.position and that specific creation time can exist in one place at any given moment, therefore this variable points to specific entities.

Beforehand, the previous entity thisEntity was destroyed (see below for the findAndDestroyEntity function) and the new entity is put in its place. After the spawning code, the old entity's data in the global table is wiped:

Code: Select all

global.shr.growing[k] = nil;
Thus clearing the memory used by the old entity thisEntity now that it has been destroyed.

Do I need to manually clean up the local variable newEntity right before the end statement in this if block by redefining it as nil? I'd assume the local variable is thrown away automatically once the if statement has ended. Is this assumption wrong?


For the rest I just have two local variables remaining: a local string that details the name of the type of an entity that was recently destroyed to make way for a new one that's replacing it. This string is only used in an if pyramid straight afterwards and its value is not needed for any further ticks. Do I need to manually clean this local up too?
The other is a variable named checkAlive, whose value is removed from memory as soon as we're done with it :
checkAlive
The function call findAndDestroyEntity with the second argument passed as false is what finds entities using find_entities_filtered in a tiny area and then destroys them (I should say, 'it', as realistically only one entity can exist in the area I'm searching in) unless the second argument is passed as false :
findAndDestroyEntity

Am I using any of these variables wrong?
[W]hy are you storing information about entities in local variables in the first place? is this a one off calculation, and all these local variables are dismissed on the very next tick? If the answer is no, you're probably doing it wrong.
So, the variables I use are either the unique identifiers stored in a table that is defined at the very top of the code and is called from everywhere using global.shr.growing[] (I'm assuming this is the global table you mean); or they are locals used solely in the place they're needed (therefore used as locals rather than global variables to save on program performance).


EDIT:
In an attempt to solve the problem myself, I removed all local variables from the script and instead turned them all into global variables stored in the main table (I know, bad coding practice, but I'm experimenting). However, the error still persists. There are too many local variables... except there are no local variables???

Shrooblord
Long Handed Inserter
Long Handed Inserter
Posts: 54
Joined: Thu May 12, 2016 12:57 pm
Contact:

Re: Too Many Local Variables

Post by Shrooblord »

Would any of you be so kind to take a look at my mod in progress? I could really do with some help.
TreeSaplings_0.1.3.zip
Sapling Mod, Shrooblord Edition
(202.49 KiB) Downloaded 126 times
It's a continuation of the Sapling Mod. I hope its original author doesn't mind me using his work to create a derivate inspired by its potential, but seeing great opportunity for progress.

Post Reply

Return to “Modding help”