Runtime error
Hello Aubergine,
I hope you can help me with a issue, that I can not fix, this is also my first project with lua and mods in general.
At the moment I am making some prefab/quickbuild rooms with added items from other mods. I have copy the script from the walls from another mod and modify it so its working with floors also. But when I want to place a prefab with a plant, then the game runs very slow, the console gives me a runtime error. The object is placed and does work with a huge lag.
I do not understand where its coming from. I hope you van help me :)
Maybe important: If I dont add the plant the game will run without sprite file, do I add the plant I need the sprite file, the sprite file I use is in game and on the top of the mod loader, the prefab mod is on the bottom of the list so it does not corrupt everything.
materials.txt prefabs.txt BrickPlaceholder.lua.txt ConcretePlaceholder.lua.txt DarkWoodFloorPlaceHolder.lua.txt FoliagePlantDPlaceHolder.lua.txt WoodenFloorPlaceHolder.lua.txt base-language.txt
Steam workshop: http://steamcommunity.com/sharedfiles/filedetails/?id=890438049
https://brandjuh.stackstorage.com/s/RsqAagXE47Owph5 = complete pack with all mod files in the current state. Screenshot below gives the info from the URL.

Many thanks!
with if cell.Ind==true then I get
Parsing LUA script 'C:\Users\Roel\AppData\Local/Introversion/Prison Architect/mods/BrandjuhsPrefab/data/scripts/DarkWoodFloorPlaceHolder.lua' DataRegistry Warning : Failed to match enum value 'object_FoliagePlantD' Waited for prerender group to finish for 0.000003 seconds
as error with no plant.
And with cell.Id==true I get the plant but with "lua table destructor called when we've already been popped off the top of the stack prison architect"
I don't know what mod you borrowed but your lua scripts of plant, etc, have serous flaws: too many (maybe infinite) loops of Update() calls.
Update() is called every tick (the smallest interval of time) of the game. Hundreds, thousands or tens of thousands (depending on the PC) of calls occurs in a second.
So you must:
- Make sure something will happen only once with a Boolean switch-like variable, or
- Let somthing happens in a reasonable interval of time (such as a "minute" in the game) according to Game.TimeIndex.
I guess your placeholders are supposed to loop for checking. So the latter suggestion is for you.
Moreover, "cell.Id" should be an integer when -1 means empty. I don't understand why checking it against true.
You can probably learn from my mod: All-in-One Deluxe
First of all, thanks for answer!
I have borrowed a script from a quick builder/prefab. The plant file is coming with the Murg combipack 11 I think the original is coming from the gardening mod.
The strange thing is that only the plant gives problems and the walls and floors doesn't. The only difference is that instead of cell.Mat = "DarkWood"; there is cell.Mat = "object_FoliagePlantD";
Also I do not understand what is the difference between cell.id and cell.Ind
The basic of the script is not that complex I thought, I define a placeholder, then I put the placeholderobject in the materials list and the script deletes the placeholder and create the object.
I am going to take a look at your mod.
There is no "FoliagePlantD" in your materials.txt.
And as "object_FoliagePlantD" implies, it is supposed to be an object, instead of material.
Objects are completely different from materials. They must be spawned and given position such as {x=0.5, y=20.5}.
One tile (cell) can have only one material while there can be many objects standing on the same tile.
And don't add "object_" before the name of an object kind. "object_" prefix is only used in language/base-language.txt.
I am getting a little but more confused now, haha.
In Materials.txt I have
BEGIN Object
Name FoliagePlantDPlaceHolder
Width 1
Height 1
ConstructionTime 0.001
Toughness 10.000
Price -50
RenderPreOffset -2
RenderDepth 1
Group StaticObject
MadeOf Wood
Properties StaticObject
Properties CanPlaceOnRoad
Properties Teleportable
Properties Scripted
BEGIN Sprite x 30 y 16 w 2 h 2 RotateType 4 END
END
Then I have defined his position in the Prefabs.txt
BEGIN Prefab
Name BRAND-NiceOffice1-6x6
w 6
h 6
RoomType Office
BEGIN Object Type DarkWoodFloorPlaceHolder x 1 y 1 orX 0 orY 1 END
BEGIN Object Type DarkWoodFloorPlaceHolder x 1 y 2 orX 0 orY 1 END
BEGIN Object Type DarkWoodFloorPlaceHolder x 1 y 3 orX 0 orY 1 END
BEGIN Object Type DarkWoodFloorPlaceHolder x 1 y 4 orX 0 orY 1 END
BEGIN Object Type DarkWoodFloorPlaceHolder x 2 y 1 orX 0 orY 1 END
BEGIN Object Type DarkWoodFloorPlaceHolder x 2 y 2 orX 0 orY 1 END
BEGIN Object Type DarkWoodFloorPlaceHolder x 2 y 3 orX 0 orY 1 END
BEGIN Object Type DarkWoodFloorPlaceHolder x 2 y 4 orX 0 orY 1 END
BEGIN Object Type DarkWoodFloorPlaceHolder x 3 y 1 orX 0 orY 1 END
BEGIN Object Type DarkWoodFloorPlaceHolder x 3 y 2 orX 0 orY 1 END
BEGIN Object Type DarkWoodFloorPlaceHolder x 3 y 3 orX 0 orY 1 END
BEGIN Object Type DarkWoodFloorPlaceHolder x 3 y 4 orX 0 orY 1 END
BEGIN Object Type DarkWoodFloorPlaceHolder x 4 y 1 orX 0 orY 1 END
BEGIN Object Type DarkWoodFloorPlaceHolder x 4 y 2 orX 0 orY 1 END
BEGIN Object Type DarkWoodFloorPlaceHolder x 4 y 3 orX 0 orY 1 END
BEGIN Object Type DarkWoodFloorPlaceHolder x 4 y 4 orX 0 orY 1 END
BEGIN Object Type Chair x 2 y 1 orX 0 orY 1 END
BEGIN Object Type FilingCabinet x 4 y 1 orX 0 orY 1 END
BEGIN Object Type OfficeDesk x 2 y 2 orX 0 orY 1 END
BEGIN Object Type Chair x 2 y 3 orX 0 orY -1 END
BEGIN Object Type Chair x 3 y 3 orX 0 orY -1 END
BEGIN Object Type StaffDoor x 3 y 5 orX 0 orY 1 END
BEGIN Object Type Light x 2 y 2 orX 0 orY 1 END
BEGIN Object Type FoliagePlantDPlaceHolder x 1 y 4 orX 0 orY 1 END
END
Then I want place the quick build and this script
function Update()
local x = math.floor(this.Pos.x);
local y = math.floor(this.Pos.y);
local cell = World.GetCell(x,y);
if cell.Ind==true then
cell.Mat = "object_FoliagePlantD";
this.Delete();
end
end
is replacing the placeholder for the object.
The objects are also placed in base-language.txt
object_BrickPlaceholder Brandjuh - Dont place this! Brick Wall
buildtoolbar_popup_obj_BrickPlaceholder Used for Brandjuh's prefabs, do not place this.
object_ConcretePlaceholder Brandjuh - Dont place this! Concrete Wall
buildtoolbar_popup_obj_ConcretePlaceholder Used for Brandjuh's prefabs, do not place this.
object_WoodenFloorPlaceHolder Brandjuh - Dont place this! Wooden Floor
buildtoolbar_popup_obj_WoodenFloorPlaceHolder Used for Brandjuh's prefabs, do not place this.
object_FoliagePlantDPlaceHolder Brandjuh - Dont place this! Plant D
buildtoolbar_popup_obj_FoliagePlantDPlaceHolder Used for Brandjuh's prefabs, do not place this. (Script error + lag)
The object is placed but gives a lag.
When a "BRAND-NiceOffice1-6x6" is placed in the map, the game spawn objects according to your Prefabs.txt.
A FoliagePlantDPlaceHolder is spawned by this action, since FoliagePlantDPlaceHolder is a valid object type/kind defined in your materials.txt.
Then, all these objects keeps calling their respective Update() in your lua scripts named after them.
In your "FoliagePlantDPlaceHolder.lua", the script tries to replace itself with "object_FoliagePlantD", but there is no such thing in your materials.txt.
The objects are also placed in base-language.txt
Word "placed" is irrelevant here. base-language.txt is a table for the game to find what TEXT to display. It has no other function. It cannot define an object type/kind.
How can you expect your placeholder be replaced with NOTHING?
Of course the script will never success and therefore the loops will never end; they keeps consuming your CPU.
You really need to learn from more scripts, like mine, about objects, scripts and spawning.
But why is the darkwood floor working since that is also from a mod content. So far you say its because thats not a object but a material, that's right?
How can you expect your placeholder be replaced with NOTHING? That's why I get confused.... If I place it with the cell.id = true instead of the cell.ind then the object is placed.
You really need to learn from more scripts, like mine, about objects, scripts and spawning.
I do my best. :) Do you have a good example script that eg. place objects? I never tried this kind of stuff before, so its all new for me and need to understand how its working.
Yes. Materials are much simpiler than objects. They are just used as a property "Mat" of cells. They don't exist alone, nor do they move.
Objects must be spawned and then set its Pos proprety. That's what really happens when you "place" an object.
I have many scripts in my mod. Use your code editor and search helper function "SpawnAt" among them.
Well I have add it too the materials and its working. Only walls and floors are possible to place with a script? I think I get some light point here.
Ehh. Please reread my explanations more carefully.
Scripts can place objects, of course!
Just in a different way from materials (walls and floors), though.
- "Placing" a floor is actually changing a cell/tile's
Matproperty. - "Placing" an object is spawning it and setting tis
Pos(x, y). Objects have NO bond with certain cells. And objects can be moved (like Food Trays, Baskets, Trash Bags, etc) by changing theirPosproperties.
I think I got the difference and how the materials are working.
I hope I can ask my 2 other questions as well.
-
In m quick build layouts for prison blocks I want only zone the prisoncells, how can I dezone the corridors? Maybe by placing objects/materials and the script dezone those cells/tiles?
-
Some rooms have the same floortiles is there a way to say X to Y = wood instead of place a object every tile?
-
I have no idea about what you mean by "zone" and "dezone". If you mean something like the Staff-Only, Max-Sec, etc zonings in Deploy toolbar menu, well, the answer is: no, it is impossible.
-
You have to deal with tiles one by one. Use "for" loops. See my "Foreman.lua" especially as a good example.
I am curious about a question to you, too.
If you want to place an object A by Prefab, and then automatically replace A with B, why don't you just place B by Prefab directly?
-
With zone I mean "Cell", "Kitchen", "classroom" etc. I want made a cell block where you do not need to remove zones to only have a cell assigned as cell and not the corridor.
-
I an going take a look later today.
I am curious about a question to you, too.
If you want to place an object A by Prefab, and then automatically replace A with B, why don't you just place B by Prefab directly?
At that point I didn't know that only walls needed a script to place in a prefab, Otherwise they are not placed, at that point I thought that everything not based in the gamed needed a prefab because the objects didn't work. However I did not realize that the material had a "Blocked by static object" so it was not possible to place it.
- You mean when you use Prefab, it overrides existing rooms according to the
RoomTypebut you don't want that to happen? That's what Prefab does.
Perhaps you just need to delete the line of RoomType "Office" in your Prefabs.txt?
If this makes no difference, I guess you have to consider other ways.
I never like Prefabs.
Why not let players do their building and installing in normal ways?
That takes some clicks and time, but without limitations and let alone the usually false presumptions by dev team (and you, modder) about what players need these rooms to be like.
BTW, after you have fully understood Foreman.lua, if you still want to learn more about placing materials and objects, you may study my "Clone Rooms" series scripts.
I do not want override room type, I am making a prefab layout for my own but others can use them too. the people that are going to use them are looking for them. I do want define more rooms in 1 prefab layout. ATM I am making cell blocks, at this time the whole block is a a cell, so I need to manually 'dezone' the corridors, so I need to remove the 'not cell'.