Return nil if key does not exist in object
-
- Smart Inserter
- Posts: 2550
- Joined: Tue Apr 25, 2017 2:01 pm
- Contact:
Return nil if key does not exist in object
I have a function in control.lua that can take as inputs either LuaTilePrototype or LuaEntityPrototype, but what I'm finding is that I can't tell which I've been passed within the function because .type does not exist in LuaTilePrototype and, rather than returning nil, it errors the game.
Can objects be modified such that if the key does not exist that they return nil instead of generating an error? I feel like that'd be the better approach in case there are other scenarios where this could occur that I don't know of, but I suppose in lacking that, can .type be added to LuaTilePrototype?
Can objects be modified such that if the key does not exist that they return nil instead of generating an error? I feel like that'd be the better approach in case there are other scenarios where this could occur that I don't know of, but I suppose in lacking that, can .type be added to LuaTilePrototype?
My Mods: Classic Factorio Basic Oil Processing | Sulfur Production from Oils | Wood to Oil Processing | Infinite Resources - Normal Yield | Tree Saplings (Redux) | Alien Biomes Tweaked | Restrictions on Artificial Tiles
Re: Return nil if key does not exist in object
How about querying object_name instead of type?FuryoftheStars wrote: ↑Wed Jun 15, 2022 3:46 amI have a function in control.lua that can take as inputs either LuaTilePrototype or LuaEntityPrototype, but what I'm finding is that I can't tell which I've been passed within the function because .type does not exist in LuaTilePrototype and, rather than returning nil, it errors the game.
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!
-
- Smart Inserter
- Posts: 2550
- Joined: Tue Apr 25, 2017 2:01 pm
- Contact:
Re: Return nil if key does not exist in object
Thanks, that could work for my purposes, though I feel it'd still be better if it simply didn't error out (if that's possible, depending on how they have their objects and error handling set up internally).Pi-C wrote: ↑Wed Jun 15, 2022 6:30 amHow about querying object_name instead of type?FuryoftheStars wrote: ↑Wed Jun 15, 2022 3:46 amI have a function in control.lua that can take as inputs either LuaTilePrototype or LuaEntityPrototype, but what I'm finding is that I can't tell which I've been passed within the function because .type does not exist in LuaTilePrototype and, rather than returning nil, it errors the game.
My Mods: Classic Factorio Basic Oil Processing | Sulfur Production from Oils | Wood to Oil Processing | Infinite Resources - Normal Yield | Tree Saplings (Redux) | Alien Biomes Tweaked | Restrictions on Artificial Tiles
Re: Return nil if key does not exist in object
In the vast majority of the usages asking for an invalid key/method is an error and silently suppressing that error by returning nil isn't doing mod developers a favor.
Ideally the game could verify that the API calls are even vaguely possible before they get executed but due to Lua being Lua that isn't possible.
Ideally the game could verify that the API calls are even vaguely possible before they get executed but due to Lua being Lua that isn't possible.
If you want to get ahold of me I'm almost always on Discord.
-
- Smart Inserter
- Posts: 2550
- Joined: Tue Apr 25, 2017 2:01 pm
- Contact:
Re: Return nil if key does not exist in object
Could .type be added to LuaTilePrototype, then (and any other prototype that may be missing it)? Just being able to reference .type on any passed Prototype is easier than having to query .object_name, if it's LuaTilePrototype, then assign "tile" to some variable, if it's not, then query .type and assign that to the variable, then always reference that variable whenever I need the type. Especially in a function where I have multiple prototypes that get passed in (meant to be worked on together, not in a loop), because then I'm having to have several of these variables (or one table of the values), one for each prototype.Rseding91 wrote: ↑Wed Jun 15, 2022 3:59 pmIn the vast majority of the usages asking for an invalid key/method is an error and silently suppressing that error by returning nil isn't doing mod developers a favor.
Ideally the game could verify that the API calls are even vaguely possible before they get executed but due to Lua being Lua that isn't possible.
My Mods: Classic Factorio Basic Oil Processing | Sulfur Production from Oils | Wood to Oil Processing | Infinite Resources - Normal Yield | Tree Saplings (Redux) | Alien Biomes Tweaked | Restrictions on Artificial Tiles
Re: Return nil if key does not exist in object
You're describing object_name and it already exists as mentioned: https://lua-api.factorio.com/latest/Lua ... bject_name for each thing in the API.
If you want to get ahold of me I'm almost always on Discord.
-
- Smart Inserter
- Posts: 2550
- Joined: Tue Apr 25, 2017 2:01 pm
- Contact:
Re: Return nil if key does not exist in object
Yes, but this returns the actual object name, like "LuaTilePrototype", etc, right? So in the case of LuaEntityPrototype, I'd still need to query the .type property to know exactly which entity type has been passed, correct? So in a function where it's meant to be passed either LuaTilePrototype or LuaEntityPrototype, I have to first check .object_name and see what it is before I can then query .type.Rseding91 wrote: ↑Wed Jun 15, 2022 5:24 pmYou're describing object_name and it already exists as mentioned: https://lua-api.factorio.com/latest/Lua ... bject_name for each thing in the API.
My Mods: Classic Factorio Basic Oil Processing | Sulfur Production from Oils | Wood to Oil Processing | Infinite Resources - Normal Yield | Tree Saplings (Redux) | Alien Biomes Tweaked | Restrictions on Artificial Tiles
Re: Return nil if key does not exist in object
Yes. But I question; why do you not simply have 2 functions: one that is meant to accept a LuaEntityPrototype and one that is meant to accept a LuaTilePrototype.FuryoftheStars wrote: ↑Wed Jun 15, 2022 5:36 pmYes, but this returns the actual object name, like "LuaTilePrototype", etc, right? So in the case of LuaEntityPrototype, I'd still need to query the .type property to know exactly which entity type has been passed, correct? So in a function where it's meant to be passed either LuaTilePrototype or LuaEntityPrototype, I have to first check .object_name and see what it is before I can then query .type.
So far, the only time i've seen a legitimate use-case for a 'generic accept anything' function was a debugger someone was writing. As a mod; you should always know what you're passing around to know what you can call on it. If you've lost that information then it seems like something has gone weird in your code.
If you want to get ahold of me I'm almost always on Discord.
Re: Return nil if key does not exist in object
Why do you want such a function in the first place when tile and entity prototypes, as you have noted, don't have in common what you care about?
-
- Smart Inserter
- Posts: 2550
- Joined: Tue Apr 25, 2017 2:01 pm
- Contact:
Re: Return nil if key does not exist in object
Because I'm passing 2 prototypes at the same time, checking the collision masks of them prior to placement. Maybe they're both entities, maybe they're both tiles, maybe they're one of each. Both have the .collision_mask and .collision_mask_with_flags properties, however, the collision behavior is different if one has the "colliding-with-tiles-only" flag, so I need to know if either are a tile and, so far, I don't see a (good) way of checking these built in. I mean, LuaTile has a .collides_with and LuaSurface has entity_prototype_collides, but both of these require at least one of the two prototypes I'm trying to compare to already be placed into the world, which means that if by doing so I'm having to remove other entities/tiles first, I then need to also track what I just removed so I can place it back in case what I was trying to do doesn't work (because what I'm doing is dynamic and can be influenced by the terrain and what the player may or may not have already done before even loading my mod, or what other mods are in use that may be altering things).
If you want, I suppose this request would make this particular use case moot. I just didn't want to assume that my use case is the only possible use case. (Edit: And the idea of asking for a dedicated function for that didn't occur to me until an hour later. )
Edit2: Forgot to throw in here, the entity offshore-pump has a secondary collision mask as well, so I need to be able to tell when one of those is passed in, hence why .type on everything would just be easier vs .object_name.
Last edited by FuryoftheStars on Wed Jun 15, 2022 8:38 pm, edited 1 time in total.
My Mods: Classic Factorio Basic Oil Processing | Sulfur Production from Oils | Wood to Oil Processing | Infinite Resources - Normal Yield | Tree Saplings (Redux) | Alien Biomes Tweaked | Restrictions on Artificial Tiles
Re: Return nil if key does not exist in object
It may also make sense if you have no direct control about what arguments are passed on to your function: think of remote calls from other mods that pass on unexpected values. Also, as already mentioned by Rseding91, it's quite useful for debugging. For example, while working on a mod I like to see exactly what function gets called with what arguments, and it really doesn't help if for every object I try to look at I get just __self = "userdata". Using object_name, I know what properties I'm allowed to query and can log something more reasonable, like this:
Code: Select all
====================================================================================================
Entered event script for on_gui_checked_state_changed
Event data: tick = 291182, player_index = 1, element = LuaGuiElement checkbox "GCKI_select_area_vehicle_list_toggle_lock_776"
(@__GCKI__/scripts/gui.lua: 423)
====================================================================================================
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!
Re: Return nil if key does not exist in object
You can easily do this yourself, run the prototypes you care about and build a plain lua table keying off the name. `type` in the entity prototypes is an attribute value the created entity will have, it's not anything to do with the prototype itself.
and now `(mystuff[arg.name] or empty).type` will be nil if you didn't set it.
Code: Select all
mystuff={} empty={}
for k,v in pairs(game.get_filtered_entity_prototypes{}) do mystuff[k]={whatever} end
for k,v in pairs(game.get_filtered_tile_prototypes{}) do mystuff[k]={whatever} end
-
- Smart Inserter
- Posts: 2550
- Joined: Tue Apr 25, 2017 2:01 pm
- Contact:
Re: Return nil if key does not exist in object
I know what .type is. It's what will tell me if the entity is a tree, or a turret, or any of the other things. The fact that LuaTilePrototype is missing this so that I can't just query .type on any given passed prototype is the issue, though.quyxkh wrote: ↑Wed Jun 15, 2022 7:49 pmYou can easily do this yourself, run the prototypes you care about and build a plain lua table keying off the name. `type` in the entity prototypes is an attribute value the created entity will have, it's not anything to do with the prototype itself.
and now `(mystuff[arg.name] or empty).type` will be nil if you didn't set it.Code: Select all
mystuff={} empty={} for k,v in pairs(game.get_filtered_entity_prototypes{}) do mystuff[k]={whatever} end for k,v in pairs(game.get_filtered_tile_prototypes{}) do mystuff[k]={whatever} end
And frankly, I'm getting tired of being told "you can do this yourself by just manually building a table blah blah blah" as if that's the solution (vs getting the request pushed through). There already exists a table of everything in the game right in the LuaGame object. Why should I add extra processing overhead and save file bloat for something that already exists but just needs 1 property added to it that shouldn't hurt the vanilla game in any way? I mean, what if "everything (I) care about" in the game is everything? And I may not be the only one that needs something like this, so why suggest this as a "solution" for each modder? After 50-100 mods all doing the same thing, that's going to add a decent amount of extra time and save file bloat.
My Mods: Classic Factorio Basic Oil Processing | Sulfur Production from Oils | Wood to Oil Processing | Infinite Resources - Normal Yield | Tree Saplings (Redux) | Alien Biomes Tweaked | Restrictions on Artificial Tiles
Re: Return nil if key does not exist in object
Why, you ask? Because you can't always have everything handed to you. Because the world isn't perfect. Why should the devs solve your problems? Why should they add bloat to their code? You have to work with what you can get. So stop complaining about the injustice of the world and do something productive.FuryoftheStars wrote: ↑Wed Jun 15, 2022 8:36 pmAnd frankly, I'm getting tired of being told "you can do this yourself by just manually building a table blah blah blah" as if that's the solution (vs getting the request pushed through). There already exists a table of everything in the game right in the LuaGame object. Why should I add extra processing overhead and save file bloat for something that already exists but just needs 1 property added to it that shouldn't hurt the vanilla game in any way? I mean, what if "everything (I) care about" in the game is everything? And I may not be the only one that needs something like this, so why suggest this as a "solution" for each modder? After 50-100 mods all doing the same thing, that's going to add a decent amount of extra time and save file bloat.
-
- Smart Inserter
- Posts: 2550
- Joined: Tue Apr 25, 2017 2:01 pm
- Contact:
Re: Return nil if key does not exist in object
It's not a matter of having "everything handed to (me)". I know how to solve this myself and already have. It's a matter of reducing code complexity where it's not needed (because the game already has ready access to all of this information while processing everything from the data stage) and not needing to "reinvent the wheel" in a language that runs slower than the native game's. And it's 1 string property on the object vs a whole table (as in the suggestion I was replying to) per mod that needs it. The "bloat" isn't comparable.curiosity wrote: ↑Wed Jun 15, 2022 10:54 pmWhy, you ask? Because you can't always have everything handed to you. Because the world isn't perfect. Why should the devs solve your problems? Why should they add bloat to their code?FuryoftheStars wrote: ↑Wed Jun 15, 2022 8:36 pmAnd frankly, I'm getting tired of being told "you can do this yourself by just manually building a table blah blah blah" as if that's the solution (vs getting the request pushed through). There already exists a table of everything in the game right in the LuaGame object. Why should I add extra processing overhead and save file bloat for something that already exists but just needs 1 property added to it that shouldn't hurt the vanilla game in any way? I mean, what if "everything (I) care about" in the game is everything? And I may not be the only one that needs something like this, so why suggest this as a "solution" for each modder? After 50-100 mods all doing the same thing, that's going to add a decent amount of extra time and save file bloat.
My Mods: Classic Factorio Basic Oil Processing | Sulfur Production from Oils | Wood to Oil Processing | Infinite Resources - Normal Yield | Tree Saplings (Redux) | Alien Biomes Tweaked | Restrictions on Artificial Tiles
Re: Return nil if key does not exist in object
Returning nil for an invalid parameter is bad because of the reasons given by the devs-- type-property errors are invaluable in debugging the vast majority of mods.
Besides, nil is a valid return value for some properties, so while returning nil for invalid properties might work for Fury's polymorphic case, it wouldn't help in a generic application that wants to know that the property exists and is nil. There really isn't any reason to complain about making a nested IF statement to retrieve a fixed list of parameters from a fixed number of types.
What would actually improve things is moving the "valid property" list into the API as a separate accessible table. There is value in having this update without each debug mod author having to change their copy of the table. But of course, anyone should be able to automate the generation of the master table if the machine-readable API documentation works as advertised.
Besides, nil is a valid return value for some properties, so while returning nil for invalid properties might work for Fury's polymorphic case, it wouldn't help in a generic application that wants to know that the property exists and is nil. There really isn't any reason to complain about making a nested IF statement to retrieve a fixed list of parameters from a fixed number of types.
What would actually improve things is moving the "valid property" list into the API as a separate accessible table. There is value in having this update without each debug mod author having to change their copy of the table. But of course, anyone should be able to automate the generation of the master table if the machine-readable API documentation works as advertised.
My mods: Multiple Unit Train Control, Smart Artillery Wagons
Maintainer of Vehicle Wagon 2, Cargo Ships, Honk
Maintainer of Vehicle Wagon 2, Cargo Ships, Honk
-
- Smart Inserter
- Posts: 2550
- Joined: Tue Apr 25, 2017 2:01 pm
- Contact:
Re: Return nil if key does not exist in object
robot256 wrote: ↑Thu Jun 16, 2022 1:27 amReturning nil for an invalid parameter is bad because of the reasons given by the devs-- type-property errors are invaluable in debugging the vast majority of mods.
Besides, nil is a valid return value for some properties, so while returning nil for invalid properties might work for Fury's polymorphic case, it wouldn't help in a generic application that wants to know that the property exists and is nil. There really isn't any reason to complain about making a nested IF statement to retrieve a fixed list of parameters from a fixed number of types.
And just for clarity sake, I'm not saying add .type with a nil value in this case.FuryoftheStars wrote: ↑Wed Jun 15, 2022 4:35 pmCould .type be added to LuaTilePrototype, then (and any other prototype that may be missing it)? [...]Rseding91 wrote: ↑Wed Jun 15, 2022 3:59 pmIn the vast majority of the usages asking for an invalid key/method is an error and silently suppressing that error by returning nil isn't doing mod developers a favor.
Ideally the game could verify that the API calls are even vaguely possible before they get executed but due to Lua being Lua that isn't possible.
Edit: Should probably throw this in there, too:
End edit.FuryoftheStars wrote: ↑Wed Jun 15, 2022 7:20 pmIf you want, I suppose this request would make this particular use case moot. I just didn't want to assume that my use case is the only possible use case.
For my use here (the reason for the request), I'm not sure if it'd be much more useful than just checking .object_name, but if you think it may have value with other things, then I'd be all for that.robot256 wrote: ↑Thu Jun 16, 2022 1:27 amWhat would actually improve things is moving the "valid property" list into the API as a separate accessible table. There is value in having this update without each debug mod author having to change their copy of the table. But of course, anyone should be able to automate the generation of the master table if the machine-readable API documentation works as advertised.
My Mods: Classic Factorio Basic Oil Processing | Sulfur Production from Oils | Wood to Oil Processing | Infinite Resources - Normal Yield | Tree Saplings (Redux) | Alien Biomes Tweaked | Restrictions on Artificial Tiles
Re: Return nil if key does not exist in object
That is the solution. It's like five lines of code you run in control.lua, once when the game starts up. Takes much less than 10ms (two, on my getting-ancient rig) to run those tables. Milliseconds. Once per play session while you're getting settled. That's the horrifying effort and cost you're so volubly and endlessly demanding somebody else relieve you and your legion of suffering users of.FuryoftheStars wrote: ↑Wed Jun 15, 2022 8:36 pm[snip]"you can do this yourself by just manually building a table blah blah blah" as if that's the solution (vs getting the request pushed through).
No, there doesn't. There are ten tables, of ten different kinds of things in the game. Two of them are similar enough for your purposes you wanted to treat them as identical. They're not.There already exists a table of everything in the game right in the LuaGame object.
Because (a) that "save file bloat" is as imaginary as your imagined horde of other modders wanting to treat tiles and entities as identical, sometimes, maybe, and (b) because that's how you build the mod you want to build.Why should I add extra processing overhead and save file bloat for something that already exists but just needs 1 property added to it that shouldn't hurt the vanilla game in any way?
Re: Return nil if key does not exist in object
A small addon to the conversation: if a given method/property is valid for something like an entity/player can runtime depend on the state of the entity so saying 'this method/property is valid for this object' is not a simple docs-parsing task.
Example: reading data about a crafting queue from a player; if the player is not a controller type that has one then it is invalid to read/write the crafting queue. This is only known at runtime.
Example: reading data about a crafting queue from a player; if the player is not a controller type that has one then it is invalid to read/write the crafting queue. This is only known at runtime.
If you want to get ahold of me I'm almost always on Discord.
-
- Smart Inserter
- Posts: 2550
- Joined: Tue Apr 25, 2017 2:01 pm
- Contact:
Re: Return nil if key does not exist in object
I’m not demanding jack. I’m defending my (revised) request against people saying my request is not needed because I can hack together my own solution. Seriously, how many things have the devs added to this game over the years that weren’t needed because the modder could do it themselves, but by the devs adding it things were made simpler? It’s
Look, you want to always have to build your own solutions for things? Feel free to not use many of the APIs and properties available to us that made modding easier for this game.
It doesn’t matter to me if it’s only a 5 ms savings. It’s still a savings that most likely doesn’t even have a measurable impact on the base game, let alone any impact felt would only be at the end of the data stage while they’re compiling them into their final objects. And I’m sorry, but I do not think in the mindset “it’ll only be me that needs this.”
If the devs ultimately decide they don’t want to do it, fine, but the arguments I’m seeing so far on why they shouldn’t don’t hold any water.
Edit: Updated “2 lines” of code to “1 line” and altered the rest to reflect that. /Edit
—————————————
Yeah, I think I get this. I’m revising my ask to being: can you include the .type property on LuaTilePrototype (and any other prototype, really, where type could be valid on) with a valid return value?
I realize that means for (example) all LuaTilePrototype objects the value would just then be “tile”, but I do believe it would be easier just being able to query .type on all prototypes in generic functions. This avoids having to do any of the following:
a) Have additional logic to first query .object_name and sort out what object it is, then if it’s a LuaEntityPrototype query .type anyway, but also ultimately having to store this result in a separate variable for future reference for the life of the function.
b) Run extra code on every game load to (re)populate a table of name/type pairs, which will require doing the first part of (a), that then you reference with the object’s .name property to get the paired type.
c) Spilt some of your code out into separate specialized functions, essentially duplicating some of the code, but will still require doing the first part of (a) so you can sort them out to the correct functions.
Again, I just want to make it clear: I’m no longer asking for the return of nil if the property does not exist (or run-time compilation that checks for if the property is valid on the given object). I’m merely asking for .type to be included and populated on all prototype objects instead of just LuaEntityPrototype.
Edit2: Also, want to point out, while I still believe it’d be a “nice have”, if the other suggestion thread I linked to in an earlier post were to be implemented, then my use case for this would be removed.
My Mods: Classic Factorio Basic Oil Processing | Sulfur Production from Oils | Wood to Oil Processing | Infinite Resources - Normal Yield | Tree Saplings (Redux) | Alien Biomes Tweaked | Restrictions on Artificial Tiles