LUA Mapgen Problems

I’ve been experimenting with the LUA mapgen method to make an interesting procedural house with many potential variants and so far I’ve been met only by the same error from the game when attempting to generate the map;

DEBUG: map::saven grid (0,0,0) uninitialized! FUNCTION: void map::saven(int, int, int) FILE: src/map.cpp LINE: 6524
From what I can gather that can only come about if a totally blank map of t_null had been generated which means the LUA code isn't actually being executed at all which is frustrating. Could anyone with more in-depth knowledge shine a light on this and either tell me what I'm doing wrong? I'm using experimental build 6003 from the 3rd of December 2016 if that sheds any light on the matter. Offending code below in spoiler/quote. [spoiler]
[ { "type": "mapgen", "method": "lua", "om_terrain": [ "house" ], "weight": 250000, "//": "ideally it should look a little like this" "//": "...........ss...........", "//": ".---vvv----;v----vvv---.", "//": ".| | r| |.", "//": ".| | t | |.", "//": ".| | | |.", "//": ".| + c + |.", "//": ".| @@ | S r| |.", "//": ".| n@@n | c -| |.", "//": ".| | | |.", "//": ".|---------+----------|.", "//": ".|BBB ctD| | |.", "//": ".| | | |.", "//": ".| + + |.", "//": ".| ccscc| | |.", "//": ".|-------| |-------|.", "//": ".| + + |.", "//": ".| |-+--| |.", "//": ".| | | |.", "//": ".---vvv--| | |.", "//": ".........| | |.", "//": ".........| | |.", "//": ".........| | |.", "//": ".........--;------vv---.", "//": "........................",
"//": "LUA stuff",
"//": "position of desk in the study/office/game room, the bookcases/counters are opposite the desk",
"script": [
"-- lua procgen house, hopefully this looks a little more like it was designed and lived in by people",
"-- and not generated by a computer",
"-- some initial functions",
"function window_or_curtain()",
"  if game.one_in(8) then",
"    return \"t_curtains\"",
"  end",
"  return \"t_window_domestic\"",
"end",
"function door_locked_or_not()",
"  if game.one_in(5) then",
"    return \"t_door_c\"",
"  end",
"  return \"t_door_locked\"",
"end",
"-- fill the place with grass and add the front sidewalk",
"square_ter(\"t_grass\",0,0,23,23)",
"map:line_ter(\"t_sidewalk\",11,0,12,0)",
"-- to begin let's get the initial wallplan down",
"map:square_ter(\"t_wall\",1,1,22,22)",
"map:square_ter(\"t_floor\",2,2,21,21)",
"map:line_ter(\"t_wall\",9,2,9,21)",
"map:line_ter(\"t_wall\",14,2,14,21)",
"map:line_ter(\"t_wall\",2,9,21,9)",
"map:line_ter(\"t_wall\",2,14,9,14)",
"map:line_ter(\"t_wall\",15,14,21,14)",
"map:line_ter(\"t_wall\",10,16,13,16)",
"map:line_ter(\"t_wall\",1,18,8,18)",
"-- and the yard/patio area",
"map:square_ter(\"t_sidewalk\",1,19,8,22)",
"-- now for some windows",
"map:line_ter(window_or_curtain(),4,1,6,1)",
"map:ter_set(12,1,window_or_curtain())",
"map:ter_set(12,22,window_or_curtain())",
"map:line_ter(window_or_curtain(),4,1,6,1)",
"map:line_ter(window_or_curtain(),17,1,19,1)",
"map:line_ter(window_or_curtain(),4,18,6,18)",
"map:line_ter(window_or_curtain(),17,22,19,22)",
"map:line_ter(window_or_curtain(),1,11,1,12)",
"map:line_ter(window_or_curtain(),22,11,22,12)",
"-- and doors, external then internal",
"map:ter_set(11,1,door_locked_or_not())",
"map:ter_set(11,22,door_locked_or_not())",
"-- center hallway doors",
"map:ter_set(11,9,\"t_door_c\")",
"map:ter_set(11,16,\"t_door_c\")",
"-- left hallway doors",
"map:ter_set(9,5,\"t_door_c\")",
"map:ter_set(9,12,\"t_door_c\")",
"-- right hallway doors",
"map:ter_set(14,5,\"t_door_c\")",
"map:ter_set(14,12,\"t_door_c\")",
"",
"-- study/office/game room ",
"desk = game.rng(4)",
"if desk == \"1\" then",
"  map:line_furn(\"f_desk\",15,10,17,10)",
"  map:furn_set(16,11,\"f_chair\")",
"  if game.one_in(2) then",
"    map:ter_set(16,10,\"t_console\")",
"  end",
"  if game.one_in(3) then",
"    map:furn_set(18,10,\"f_indoor_plant\")",
"  end",
"  map:line_furn(\"f_bookcase\",15,13,17,13)",
"  map:line_furn(\"f_counter\",19,13,21,13)",
"elseif desk == \"2\" then",
"  map:line_furn(\"f_desk\",19,10,21,10)",
"  map:furn_set(20,11,\"f_chair\")",
"  if game.one_in(2) then",
"    map:ter_set(20,10,\"t_console\")",
"  end",
"  if game.one_in(3) then",
"    map:furn_set(18,10,\"f_indoor_plant\")",
"  end",
"  map:line_furn(\"f_bookcase\",19,13,21,13)",
"  map:line_furn(\"f_counter\",15,13,17,13)",
"elseif desk == \"3\" then",
"  map:line_furn(\"f_desk\",15,13,17,13)",
"  map:furn_set(16,12,\"f_chair\")",
"  if game.one_in(2) then",
"    map:ter_set(16,13,\"t_console\")",
"  end",
"  if game.one_in(3) then",
"    map:furn_set(18,13,\"f_indoor_plant\")",
"  end",
"  map:line_furn(\"f_bookcase\",15,10,17,10)",
"  map:line_furn(\"f_counter\",19,10,21,10)",
"else",
"  map:line_furn(\"f_desk\",19,13,21,13)",
"  map:furn_set(20,12,\"f_chair\")",
"  if game.one_in(2) then",
"    map:ter_set(20,13,\"t_console\")",
"  end",
"  if game.one_in(3) then",
"    map:furn_set(18,13,\"f_indoor_plant\")",
"  end",
"  map:line_furn(\"f_bookcase\",19,10,21,10)",
"  map:line_furn(\"f_counter\",15,10,17,10)",
"end"
]

}
]

[/spoiler]

A map is uninitialized if upper-left (coord 0,0) tile is null, not necessarily the entire map.
Try creating a minimal example that works and progressing from there. Or at least forcing different error message - I’m not sure if the Lua interface reports the errors properly.

Just a warning, LUA support is under the axe, we haven’t had any significant use out of it, and we’ve sunk a LOT of effort into it, it’s probably going to be gone by June or so.

After some further experimentation I simply can’t get a result out of the LUA mapgen method or the lua json method entry even using a single line of map:fill_background or map:draw_fill_backround or other variations without the same result of the game complaining about 0,0 0,1 1,0 and 1,1 being uninitialized then failing to generate submaps b before promptly crashing.
I’m aware it’s days are numbered that’s kind of what prompted me to play around with it before it’s gone and I’m not expecting anyone to put any further effort into it if there is some underlying backend problem preventing this. If anyone’s experimented with using LUA to spice up mapgen I’d appreciate it if you shared your experience with it.

You need to use map:draw_square_ter function, not square_ter, also you need to provide ter_str_id, not a string as first parameter of this function.

Code will be like this:

map:draw_square_ter(ter_str_id("t_grass"),0,0,23,23)

Same for line_ter and line_furn functions, which should be draw_line_ter and draw_line_furn.


Functions ter_set/furn_set takes tripoint and ter_str_id/furn_str_id as arguments, so it will be like this:

map:ter_set(tirpoint(16,10,0),ter_str_id("t_console"))
map:furn_set(tripoint(18,13,0),furn_str_id("f_indoor_plant"))

Function game.rng takes two int parameters.


It is possible to move script to external file:

        "script": [
          "dofile('./data/json/mapgen_lua/dojo.lua')"
        ]

When lua mapgen script is in external file it will also be easier to test it using LUA debug console and following command:

dofile('./data/json/mapgen_lua/dojo.lua')

Here is an example: https://www.dropbox.com/s/pm8rpd1bhkhu9f5/cdda_lua_mapgen_example.zip?dl=0

dojo building was replaced with your house using lua mapgen


Here is another example: https://www.dropbox.com/s/3gn2p4sgmt5gdmz/cdda_mapgen_mil_surplus.zip?dl=0

mil_surplus buidling using lua mapgen (don’t mind excess amount of loot - i didn’t add check for loot spawn chance yet )

1 Like

This is exactly what I had hoped to see and if you don’t mind I’m going to use these examples (formatting and all) to really flesh this little project out, it’s a shame I didn’t notice your reply earlier.

I believe lua-generated buildings won’t be automatically rotated and that will severely hinders lua mapgen usefulness.

Looking through the source code of catalua.cpp, I’ve found that terrain type and current turn are already being exposed to global variables tertype and turn, so one can use them like this:

print (“degrading:”…_G.tertype…" in turn:"…tostring(_G.turn))
game.add_msg (“degrading:”…_G.tertype…" in turn:"…tostring(_G.turn))

It will be also possible to get a rotation of the building (and rotate it accordingly) as tertype variable contains not only id of the overmap terrain, but also direction suffix (_north, _south, _east or _west).

Hmm I’ve found that both the examples you’ve provided and all my further attempts at experimenting with them just result in the same error as in the OP, any ideas?

The examples I provided should both work out-of-the box.

You have probably did something wrong in the code. First of all, make sure you have filled all of the with map with some terrain, like this:

--Init map (fill whole square with dirt)
map:draw_square_ter(ter_str_id("t_grass"),0,0,23,23)

Also please tell which CDDA version you are using - is it latest experimental, 0.C or something else?

I’m using experimental version 6003 and I hadn’t considered that version would be a problem, I’ll leaf through the github to see if there’s been a change which has broken it. I’ll also add that the log file that that would be written to is blank if that says anything.

Can you drop somewhere lua mapgen file that causes errors?

Even with 0.C none of the examples you’ve provided work even out the box, causing the same uninitialised grid error and placing a copy of the overmap I’ve moved from in place of whatever the LUA would generate which is frustrating.

Older versions of DDA had somewhat different LUA-functions. Either use latest experimental DDA version or change function calls.

For example, you should use

map:square_ter(id,basex+x1,basey+y1,basex+x2,basey+y2)

instead of:

map:draw_square_ter(ter_str_id(id),basex+x1,basey+y1,basex+x2,basey+y2)

Also ids of terrain and furniture are changed between version, so it is likely you will also need to change ids of some terrains. For example t_wall in latest experimental was separated to two instance t_wall_h and t_wall_v previously.


version 0.C

    map = {
        attributes = {
        },
        functions = {
            ter = {
                args = {"int", "int"},
                rval = "int"
            },
            ter_set = {
                args = {"int", "int", "string"},
                rval = nil
            },
            ter_iset = {
                cpp_name = "ter_set",
                args = {"int", "int", "int"},
                rval = nil
            },

            furn = {
                args = {"int", "int"},
                rval = "int"
            },
            furn_set = {
                args = {"int", "int", "string"},
                rval = nil
            },
            line_ter = {
                cpp_name = "draw_line_ter",
                args = {"string", "int", "int", "int", "int"},
                rval = nil
            },
            line_furn = {
                cpp_name = "draw_line_furn",
                args = {"string", "int", "int", "int", "int"},
                rval = nil
            },
            fill_background = {
                cpp_name = "draw_fill_background",
                args = {"string"},
                rval = nil
            },
            square_ter = {
                cpp_name = "draw_square_ter",
                args = {"string", "int", "int", "int", "int"},
                rval = nil
            },
            square_furn = {
                cpp_name = "draw_square_furn",
                args = {"string", "int", "int", "int", "int"},
                rval = nil
            },
            rough_circle = {
                cpp_name = "draw_rough_circle",
                args = {"string", "int", "int", "int"},
                rval = nil
            },
            place_items = {
                args = {"string", "int", "int", "int", "int",  "int", "bool", "int"},
                rval = nil
            }
        }

latest experimental

    map = {
        attributes = {
        },
        functions = {
            { name = "accessible_furniture", rval = "bool", args = { "tripoint", "tripoint", "int" } },
            { name = "accessible_items", rval = "bool", args = { "tripoint", "tripoint", "int" } },
            { name = "add_camp", rval = nil, args = { "tripoint", "string" } },
            { name = "add_corpse", rval = nil, args = { "tripoint" } },
            { name = "add_field", rval = "bool", args = { "tripoint", "field_id", "int", "int" } },
            { name = "add_item", rval = "item&", args = { "tripoint", "item" } },
            { name = "add_item_or_charges", rval = "item&", args = { "tripoint", "item" } },
            { name = "add_item_or_charges", rval = "item&", args = { "tripoint", "item", "bool" } },
            { name = "add_spawn", rval = nil, args = { "mtype_id", "int", "int", "int" } },
            { name = "add_spawn", rval = nil, args = { "mtype_id", "int", "int", "int", "bool" } },
            { name = "add_spawn", rval = nil, args = { "mtype_id", "int", "int", "int", "bool", "int" } },
            { name = "add_spawn", rval = nil, args = { "mtype_id", "int", "int", "int", "bool", "int", "int" } },
            { name = "add_spawn", rval = nil, args = { "mtype_id", "int", "int", "int", "bool", "int", "int", "string" } },
            { name = "add_trap", rval = nil, args = { "tripoint", "trap_id" } },
            { name = "adjust_field_age", rval = "int", args = { "tripoint", "field_id", "int" } },
            { name = "adjust_field_strength", rval = "int", args = { "tripoint", "field_id", "int" } },
            { name = "adjust_radiation", rval = nil, args = { "tripoint", "int" } },
            { name = "allow_camp", rval = "bool", args = { "tripoint", "int" } },
            { name = "ambient_light_at", rval = "float", args = { "tripoint" } },
            { name = "bash_rating", rval = "int", args = { "int", "tripoint" } },
            { name = "bash_rating", rval = "int", args = { "int", "tripoint", "bool" } },
            { name = "bash_resistance", rval = "int", args = { "tripoint" } },
            { name = "bash_resistance", rval = "int", args = { "tripoint", "bool" } },
            { name = "bash_strength", rval = "int", args = { "tripoint" } },
            { name = "bash_strength", rval = "int", args = { "tripoint", "bool" } },
            { name = "board_vehicle", rval = nil, args = { "tripoint", "player" } },
            { name = "can_move_furniture", rval = "bool", args = { "tripoint" } },
            { name = "can_move_furniture", rval = "bool", args = { "tripoint", "player" } },
            { name = "can_put_items", rval = "bool", args = { "tripoint" } },
            { name = "clear_path", rval = "bool", args = { "tripoint", "tripoint", "int", "int", "int" } },
            { name = "clear_spawns", rval = nil, args = { } },
            { name = "clear_traps", rval = nil, args = { } },
            { name = "climb_difficulty", rval = "int", args = { "tripoint" } },
            { name = "close_door", rval = "bool", args = { "tripoint", "bool", "bool" } },
            { name = "collapse_at", rval = nil, args = { "tripoint", "bool" } },
            { name = "collapse_check", rval = "int", args = { "tripoint" } },
            { name = "combined_movecost", rval = "int", args = { "tripoint", "tripoint" } },
            { name = "coord_to_angle", rval = "int", args = { "int", "int", "int", "int" } },
            { name = "could_see_items", rval = "bool", args = { "tripoint", "Creature" } },
            { name = "creature_in_field", rval = nil, args = { "Creature" } },
            { name = "creature_on_trap", rval = nil, args = { "Creature" } },
            { name = "creature_on_trap", rval = nil, args = { "Creature", "bool" } },
            { name = "crush", rval = nil, args = { "tripoint" } },
            { name = "decay_fields_and_scent", rval = nil, args = { "int" } },
            { name = "delete_graffiti", rval = nil, args = { "tripoint" } },
            { name = "delete_signage", rval = nil, args = { "tripoint" } },
            { name = "destroy", rval = nil, args = { "tripoint" } },
            { name = "destroy", rval = nil, args = { "tripoint", "bool" } },
            { name = "destroy_furn", rval = nil, args = { "tripoint" } },
            { name = "destroy_furn", rval = nil, args = { "tripoint", "bool" } },
            { name = "disarm_trap", rval = nil, args = { "tripoint" } },
            { name = "disp_name", rval = "string", args = { "tripoint" } },
            { name = "displace_vehicle", rval = nil, args = { "tripoint", "tripoint" } },
            { name = "displace_water", rval = "bool", args = { "tripoint" } },
            { name = "draw_circle_furn", rval = nil, args = { "furn_id", "int", "int", "int" } },
            { name = "draw_circle_furn", rval = nil, args = { "furn_str_id", "int", "int", "int" } },
            { name = "draw_circle_ter", rval = nil, args = { "ter_str_id", "int", "int", "int" } },
            { name = "draw_circle_ter", rval = nil, args = { "ter_id", "float", "float", "float" } },
            { name = "draw_circle_ter", rval = nil, args = { "ter_id", "int", "int", "int" } },
            { name = "draw_fill_background", rval = nil, args = { "ter_id" } },
            { name = "draw_fill_background", rval = nil, args = { "ter_str_id" } },
            { name = "draw_line_furn", rval = nil, args = { "furn_id", "int", "int", "int", "int" } },
            { name = "draw_line_furn", rval = nil, args = { "furn_str_id", "int", "int", "int", "int" } },
            { name = "draw_line_ter", rval = nil, args = { "ter_id", "int", "int", "int", "int" } },
            { name = "draw_line_ter", rval = nil, args = { "ter_str_id", "int", "int", "int", "int" } },
            { name = "draw_rough_circle_ter", rval = nil, args = { "ter_id", "int", "int", "int" } },
            { name = "draw_rough_circle_ter", rval = nil, args = { "ter_str_id", "int", "int", "int" } },
            { name = "draw_rough_circle_furn", rval = nil, args = { "furn_id", "int", "int", "int" } },
            { name = "draw_rough_circle_furn", rval = nil, args = { "furn_str_id", "int", "int", "int" } },
            { name = "draw_square_furn", rval = nil, args = { "furn_id", "int", "int", "int", "int" } },
            { name = "draw_square_furn", rval = nil, args = { "furn_str_id", "int", "int", "int", "int" } },
            { name = "draw_square_ter", rval = nil, args = { "ter_id", "int", "int", "int", "int" } },
            { name = "draw_square_ter", rval = nil, args = { "ter_str_id", "int", "int", "int", "int" } },
            { name = "features", rval = "string", args = { "tripoint" } },
            { name = "field_at", rval = "field&", args = { "tripoint" } },
            { name = "flammable_items_at", rval = "bool", args = { "tripoint" } },
            { name = "free_volume", rval = "volume", args = { "tripoint" } },
            { name = "furn", rval = "furn_id", args = { "tripoint" } },
            { name = "furn_set", rval = nil, args = { "tripoint", "furn_id" } },
            { name = "furn_set", rval = nil, args = { "tripoint", "furn_str_id" } },
            { name = "furnname", rval = "string", args = { "tripoint" } },
            { name = "get_abs_sub", rval = "tripoint", args = { } },
            { name = "get_field", rval = "field_entry&", args = { "tripoint", "field_id" } },
            { name = "get_field_age", rval = "int", args = { "tripoint", "field_id" } },
            { name = "get_field_strength", rval = "int", args = { "tripoint", "field_id" } },
            { name = "get_radiation", rval = "int", args = { "tripoint" } },
            { name = "get_signage", rval = "string", args = { "tripoint" } },
            { name = "get_ter_transforms_into", rval = "ter_id", args = { "tripoint" } },
            { name = "getabs", rval = "tripoint", args = { "tripoint" } },
            { name = "getlocal", rval = "tripoint", args = { "tripoint" } },
            { name = "getmapsize", rval = "int", args = { } },
            { name = "graffiti_at", rval = "string", args = { "tripoint" } },
            { name = "has_adjacent_furniture", rval = "bool", args = { "tripoint" } },
            { name = "has_flag", rval = "bool", args = { "string", "tripoint" } },
            { name = "has_flag_furn", rval = "bool", args = { "string", "tripoint" } },
            { name = "has_flag_ter", rval = "bool", args = { "string", "tripoint" } },
            { name = "has_flag_ter_or_furn", rval = "bool", args = { "string", "tripoint" } },
            { name = "has_floor", rval = "bool", args = { "tripoint" } },
            { name = "has_floor_or_support", rval = "bool", args = { "tripoint" } },
            { name = "has_furn", rval = "bool", args = { "tripoint" } },
            { name = "has_graffiti_at", rval = "bool", args = { "tripoint" } },
            { name = "has_items", rval = "bool", args = { "tripoint" } },
            { name = "has_nearby_fire", rval = "bool", args = { "tripoint" } },
            { name = "has_nearby_fire", rval = "bool", args = { "tripoint", "int" } },
            { name = "has_zlevels", rval = "bool", args = { } },
            { name = "hit_with_acid", rval = "bool", args = { "tripoint" } },
            { name = "hit_with_fire", rval = "bool", args = { "tripoint" } },
            { name = "i_at", rval = "map_stack", args = { "tripoint" } },
            { name = "i_clear", rval = nil, args = { "tripoint" } },
            { name = "i_rem", rval = "int", args = { "tripoint", "int" } },
            { name = "i_rem", rval = "item_stack_iterator", args = { "tripoint", "item_stack_iterator" } },
            { name = "i_rem", rval = nil, args = { "tripoint", "item" } },
            { name = "impassable", rval = "bool", args = { "tripoint" } },
            { name = "impassable_ter_furn", rval = "bool", args = { "tripoint" } },
            { name = "inbounds", rval = "bool", args = { "int", "int", "int" } },
            { name = "inbounds", rval = "bool", args = { "tripoint" } },
            { name = "is_bashable", rval = "bool", args = { "tripoint" } },
            { name = "is_bashable", rval = "bool", args = { "tripoint", "bool" } },
            { name = "is_bashable_furn", rval = "bool", args = { "tripoint" } },
            { name = "is_bashable_ter", rval = "bool", args = { "tripoint" } },
            { name = "is_bashable_ter", rval = "bool", args = { "tripoint", "bool" } },
            { name = "is_bashable_ter_furn", rval = "bool", args = { "tripoint" } },
            { name = "is_bashable_ter_furn", rval = "bool", args = { "tripoint", "bool" } },
            { name = "is_divable", rval = "bool", args = { "tripoint" } },
            { name = "is_outside", rval = "bool", args = { "tripoint" } },
            { name = "item_from", rval = "item&", args = { "tripoint", "int" } },
            { name = "light_transparency", rval = "float", args = { "tripoint" } },
            { name = "load", rval = nil, args = { "int", "int", "int", "bool" } },
            { name = "make_rubble", rval = nil, args = { "tripoint" } },
            { name = "make_rubble", rval = nil, args = { "tripoint", "furn_id", "bool" } },
            { name = "make_rubble", rval = nil, args = { "tripoint", "furn_id", "bool", "ter_id" } },
            { name = "make_rubble", rval = nil, args = { "tripoint", "furn_id", "bool", "ter_id", "bool" } },
            { name = "max_volume", rval = "volume", args = { "tripoint" } },
            { name = "mop_spills", rval = nil, args = { "tripoint" } },
            { name = "move_cost", rval = "int", args = { "tripoint" } },
            { name = "move_cost_ter_furn", rval = "int", args = { "tripoint" } },
            { name = "name", rval = "string", args = { "tripoint" } },
            { name = "on_vehicle_moved", rval = nil, args = { "int" } },
            { name = "open_door", rval = "bool", args = { "tripoint", "bool" } },
            { name = "open_door", rval = "bool", args = { "tripoint", "bool", "bool" } },
            { name = "passable", rval = "bool", args = { "tripoint" } },
            { name = "passable_ter_furn", rval = "bool", args = { "tripoint" } },
            { name = "pl_sees", rval = "bool", args = { "tripoint", "int" } },
            { name = "place_gas_pump", rval = nil, args = { "int", "int", "int" } },
            { name = "place_gas_pump", rval = nil, args = { "int", "int", "int", "string" } },
            { name = "place_npc", rval = "int", args = { "int", "int", "npc_template_id" } },
            { name = "place_spawns", rval = nil, args = { "mongroup_id", "int", "int", "int", "int", "int", "float" } },
            { name = "place_toilet", rval = nil, args = { "int", "int" } },
            { name = "place_toilet", rval = nil, args = { "int", "int", "int" } },
            { name = "place_vending", rval = nil, args = { "int", "int", "string" } },
            { name = "put_items_from_loc", rval = nil, args = { "string", "tripoint" } },
            { name = "put_items_from_loc", rval = nil, args = { "string", "tripoint", "int" } },
            { name = "random_outdoor_tile", rval = "point", args = { } },
            { name = "remove_field", rval = nil, args = { "tripoint", "field_id" } },
            { name = "remove_trap", rval = nil, args = { "tripoint" } },
            { name = "save", rval = nil, args = { } },
            { name = "sees", rval = "bool", args = { "tripoint", "tripoint", "int" } },
            { name = "sees_some_items", rval = "bool", args = { "tripoint", "Creature" } },
            { name = "set_field_age", rval = "int", args = { "tripoint", "field_id", "int" } },
            { name = "set_field_age", rval = "int", args = { "tripoint", "field_id", "int", "bool" } },
            { name = "set_field_strength", rval = "int", args = { "tripoint", "field_id", "int" } },
            { name = "set_field_strength", rval = "int", args = { "tripoint", "field_id", "int", "bool" } },
            { name = "set_graffiti", rval = nil, args = { "tripoint", "string" } },
            { name = "set_radiation", rval = nil, args = { "tripoint", "int" } },
            { name = "set_signage", rval = nil, args = { "tripoint", "string" } },
            { name = "set_temperature", rval = nil, args = { "tripoint", "int" } },
            { name = "smash_items", rval = nil, args = { "tripoint", "int" } },
            { name = "spawn_an_item", rval = "item&", args = { "tripoint", "item", "int", "int" } },
            { name = "spawn_artifact", rval = nil, args = { "tripoint" } },
            { name = "spawn_item", rval = nil, args = { "tripoint", "string" } },
            { name = "spawn_item", rval = nil, args = { "tripoint", "string", "int" } },
            { name = "spawn_item", rval = nil, args = { "tripoint", "string", "int", "int" } },
            { name = "spawn_item", rval = nil, args = { "tripoint", "string", "int", "int", "int" } },
            { name = "spawn_item", rval = nil, args = { "tripoint", "string", "int", "int", "int", "int" } },
            { name = "spawn_monsters", rval = nil, args = { "bool" } },
            { name = "stored_volume", rval = "volume", args = { "tripoint" } },
            { name = "supports_above", rval = "bool", args = { "tripoint" } },
            { name = "ter", rval = "ter_id", args = { "tripoint" } },
            { name = "ter_set", rval = nil, args = { "tripoint", "ter_id" } },
            { name = "ter_set", rval = nil, args = { "tripoint", "ter_str_id" } },
            { name = "tername", rval = "string", args = { "tripoint" } },
            { name = "tr_at", rval = "trap&", args = { "tripoint" } },
            { name = "trans", rval = "bool", args = { "tripoint" } },
            { name = "translate", rval = nil, args = { "ter_id", "ter_id" } },
            { name = "trap_set", rval = nil, args = { "tripoint", "trap_id" } },
            { name = "translate_radius", rval = nil, args = { "ter_id", "ter_id", "float", "tripoint" } },
            { name = "trigger_rc_items", rval = nil, args = { "string" } },
            { name = "unboard_vehicle", rval = nil, args = { "tripoint" } },
            { name = "valid_move", rval = "bool", args = { "tripoint", "tripoint" } },
            { name = "valid_move", rval = "bool", args = { "tripoint", "tripoint", "bool" } },
            { name = "valid_move", rval = "bool", args = { "tripoint", "tripoint", "bool", "bool" } },
            { name = "veh_part_coordinates", rval = "point", args = { "tripoint" } },
            { name = "water_from", rval = "item", args = { "tripoint" } },
        }
    },

Ok in the latest experimental it seems to be working fine and dandy in the game’s data folder though the game reports that there’s a syntax error in prochouse1.lua after ‘",’ on line 50(???). I had tried to make the house just generate on north-facing instances to avoid rotation weirdness but it’s refusing to run now.
Here’s the json and lua file:
prochouse1.json :

[
  {
    "id": "prochouse_1",
    "type": "overmap_terrain",
    "name": "house_north",
	"om_terrain": [ "house_north" ],
    "see_cost": 5,
    "mondensity": 2,
    "extras": "build",
    "mapgen": [
      {
        "method": "lua",
        "weight": 100000,
        "script": [
          "dofile('./data/json/mapgen_lua/prochouse1.lua')\n"
        ]
      }
    ],
    "flags": [ "SIDEWALK" ]
  }
]

prochouse1.lua :

-- Major credit to Zhilkin for providing LUA solutions
-- lua procgen house, hopefully this looks a little more like it was designed and lived in by people
-- and not generated by a computer
--
--
--	"...........ss...........",
--  ".----------+v----------.",
--  ".|       |    |       |.",
--  ".|       |    |       |.",
--  ".|       +    +       |.",
--  ".|       |    |       |.",
--  ".|       |    |       |.",
--  ".|---------  ---------|.",
--  ".|       |    |       |.",
--  ".|       |    |       |.",
--  ".|       +    +       |.",
--  ".|       |    |       |.",
--  ".|       |    |       |.",
--  ".|-------|    |-------|.",
--  ".|       |    |       |.",
--  ".|       +    +       |.",
--  ".----------+-----------.",
--  ".ssssssss|    |sssssss*.",
--  ".ssssssss|    |ssssssss.",
--  ".ssssssss--+v--s*s*s*s*.",
--  ".ssssssssssssssssssssss.",
--  ".ssssssssssssssssssssss.",
--  ".ssssssssssssssssssssss.",
--  "........................"
		
-- *** *** *** *** *** *** *** *** *** *** *** *** *** *** --

Log = require("./lua/Log")
MapGen = require("./lua/MapGen")

-- *** *** *** *** *** *** *** *** *** *** *** *** *** *** --

local OvermapName = "house"

-- *** *** *** *** *** *** *** *** *** *** *** *** *** *** --

local function Draw ()


	Log.Message ("Mapgen:"..OvermapName.."\n")

    MapGen.Init()
	
	-- some initial functions
	function window_or_curtain ()
	  if game.one_in(6) then
	    return "t_curtains"
	  end
	  return "t_window_domestic"
	end
	function door_locked_or_not ()
	  if game.one_in(5) then
	    return "t_door_c_peep"
	  end
	  return "t_door_locked_peep"
	end
	function door_closed_or_not ()
	  if game.one_in(3) then
	    return "t_door_o"
	  end
	  return "t_door_c"
	end
	local walltype = "t_wall"
	if game.one_in(2) then
		walltype = "t_brick_wall"
	end
	local lowalls = game.rng(1,2)
	local lowindow = game.rng(1,2)
	local looffice = game.rng(1,2)
	local lomdoor = game.rng(1,3)
	-- fill the place with grass and add the front sidewalk
	map:fill_background("t_grass")
	MapGen.LineTerrain ("t_sidewalk",11,0,12,0)
	-- to begin let's get the initial wallplan down
	if lowalls == 1 then
		MapGen.SquareTerrain(walltype,1,1,22,16)
		MapGen.SquareTerrain("t_floor",2,2,21,15)
	
		MapGen.LineTerrain (walltype,1,16,21,16)
	else
		MapGen.SquareTerrain(walltype,1,1,22,19)
		MapGen.SquareTerrain("t_floor",2,2,21,18)
	end
	Log.Message ("Wall Layout: "..lowalls.."\n")
	MapGen.LineTerrain (walltype,9,2,9,17)
	MapGen.LineTerrain (walltype,14,2,14,17)
	MapGen.LineTerrain (walltype,2,7,10,7)
	MapGen.LineTerrain (walltype,13,7,21,7)
	
	MapGen.LineTerrain (walltype,2,13,8,13)
	MapGen.LineTerrain (walltype,15,13,21,13)
	MapGen.LineTerrain (walltype,1,16,21,16)
	MapGen.LineTerrain (walltype,1,18,8,18)
	-- and the yard/patio area
	if lowalls == 1 then
		MapGen.SquareTerrain("t_sidewalk",1,17,8,19)
		MapGen.SquareTerrain("t_sidewalk",15,17,22,19)
	end
	MapGen.SquareTerrain("t_sidewalk",1,20,22,22)
	-- now for some windows
	
	MapGen.PointTerrain(window_or_curtain(),12,1)
	MapGen.PointTerrain(window_or_curtain(),12,19)
	if lowindow == 1 then
		MapGen.LineTerrain (window_or_curtain(),4,1,7,1)
		MapGen.LineTerrain (window_or_curtain(),16,1,18,1)
		MapGen.LineTerrain (window_or_curtain(),1,3,1,5)
		MapGen.LineTerrain (window_or_curtain(),22,3,22,5)
		if lowalls == 1 then
			MapGen.LineTerrain (window_or_curtain(),4,16,7,16)
			MapGen.LineTerrain (window_or_curtain(),16,16,18,16)
		else
			MapGen.LineTerrain (window_or_curtain(),4,19,7,19)
			MapGen.LineTerrain (window_or_curtain(),16,19,18,19)
			MapGen.LineTerrain (window_or_curtain(),1,15,1,17)
			MapGen.LineTerrain (window_or_curtain(),22,15,22,17)
		end
	else
		MapGen.PointTerrain(window_or_curtain(),4,1)
		MapGen.PointTerrain(window_or_curtain(),7,1)
		MapGen.PointTerrain(window_or_curtain(),16,1)
		MapGen.PointTerrain(window_or_curtain(),18,1)
		if lowalls == 1 then
			MapGen.PointTerrain(window_or_curtain(),4,16)
			MapGen.PointTerrain(window_or_curtain(),7,16)
			MapGen.PointTerrain(window_or_curtain(),16,16)
			MapGen.PointTerrain(window_or_curtain(),18,16)
		else
			MapGen.PointTerrain(window_or_curtain(),4,19)
			MapGen.PointTerrain(window_or_curtain(),7,19)
			MapGen.PointTerrain(window_or_curtain(),16,19)
			MapGen.PointTerrain(window_or_curtain(),18,19)
		end
	end
	Log.Message ("Window Layout: "..lowindow.."\n")
	
	-- and doors, external...
	MapGen.PointTerrain(door_locked_or_not(),11,1)
	MapGen.PointTerrain(door_locked_or_not(),11,19)
	-- ...and internal
	MapGen.PointTerrain(door_closed_or_not(),9,4)
	MapGen.PointTerrain(door_closed_or_not(),14,4)
	MapGen.PointTerrain(door_closed_or_not(),9,10)
	MapGen.PointTerrain(door_closed_or_not(),14,10)
	MapGen.PointTerrain(door_closed_or_not(),9,15)
	MapGen.PointTerrain(door_closed_or_not(),14,15)
	MapGen.PointTerrain(door_closed_or_not(),14,15)
	-- middle dividing door(s) (or space)
	if game.one_in(3) then
		if one_in(2) then
			MapGen.LineTerrain (door_closed_or_not(),11,7,12,7)
		else
			if game.one_in(2) then
				MapGen.PointTerrain(door_closed_or_not(),11,7)
				MapGen.PointTerrain(walltype,12,7)
			else
				MapGen.PointTerrain(door_closed_or_not(),12,7)
				MapGen.PointTerrain(walltype,11,7)
			end
		end
	end
	-- study/office/game room 
	local desklength = game.rng(1,2) -- actually a length of 2-3
	local deskstart = 0
	local deskend = 0
	local deskoffset = game.rng(1,3)
	local desk = game.rng(1,3)
	local chairoffset = game.rng(0,desklength)
	local bcase = game.rng(15,18)
	local bcaselength = game.rng(2,3)
	-- desk/bookcase/counter placement switch
  	if desk == "1" then
	  -- desk against far right wall
	  deskstart = 7 + deskoffset
	  deskend = deskstart + desklength
      MapGen.LineFurniture("f_desk",22,deskstart,22,deskend)
	  MapGen.PointFurniture("f_chair",21,deskstart+chairoffset)
	  if game.one_in(2) then
	    MapGen.PointTerrain("t_console",22,deskstart+chairoffset)
	  end
	  if game.one_in(3) then
	    MapGen.PointFurniture("f_indoor_plant",15,10)
	  end
	  MapGen.LineFurniture("f_counter",15,13,20,13)
	  MapGen.LineFurniture("f_bookcase",bcase,13,bcase+bcaselength,13)
	elseif desk == "2" then
	  -- desk against top wall
	  deskoffset = game.rng(1,4)
	  deskstart = 15 + deskoffset
	  deskend = deskstart + desklength
	  MapGen.LineFurniture("f_desk",deskstart,8,deskend,8)
	  MapGen.PointFurniture("f_chair",deskstart+chairoffset,9)
	  if game.one_in(2) then
	    MapGen.PointTerrain("t_console",deskstart+chairoffset,8)
	  end
	  if game.one_in(3) then
	    MapGen.PointFurniture("f_indoor_plant",18,12)
	  end
	  MapGen.LineFurniture("f_bookcase",19,13,21,13)
	  MapGen.LineFurniture("f_counter",15,13,17,13)
	else
	  -- desk against bottom wall
	  deskoffset = game.rng(1,4)
	  deskstart = 15 + deskoffset
	  deskend = deskstart + desklength
	  MapGen.LineFurniture("f_desk",deskstart,12,deskend,12)
	  MapGen.PointFurniture("f_chair",deskstart+chairoffset,11)
	  if game.one_in(2) then
	    MapGen.PointTerrain("t_console",deskstart+chairoffset,12)
	  end
	  if game.one_in(3) then
	    MapGen.PointFurniture("f_indoor_plant",18,8)
	  end
	  MapGen.LineFurniture("f_bookcase",19,10,21,10)
	  MapGen.LineFurniture("f_counter",15,10,17,10)
	end
	
end

-- *** *** *** *** *** *** *** *** *** *** *** *** *** *** --

Log.Start ()

Draw ()

Log.End ()

-- *** *** *** *** *** *** *** *** *** *** *** *** *** *** --

There is no such string on line 50 in the file you provided. Probably you provided wrong or incomplete code. Try to make lua file as simple as possible (remove all comments and empty lines) - that way you will know certain line number which fails.

Better yet provide archive with all of the files you’ve changed. There are should be ate least Log.lua and MapGen.lua from the lua folder.

A few minor syntax errors later (turns out the copy of the prochouse.lua I posted wasn’t the one being run and didn’t have the pair of spurious ’ ", ’ strings) and it spawns fine using the lua console, I haven’t seen it spawn in the wild yet but that might be down to the game being funny with me trying to force it to be a house_north. It’s rough but it should shape up nicely and I’ll look for a solution to the rotation later.
Ultimately I’m hoping to make some kind of trade post/bunker with a merchant npc that totally flushes and updates their stock every 1-3 days and the only straightforward solution to that I’ve thought of is to simply delete the NPC and respawn them after checking how long it’s been.

[quote=“Catasteroid, post:17, topic:13515”]A few minor syntax errors later (turns out the copy of the prochouse.lua I posted wasn’t the one being run and didn’t have the pair of spurious ’ ", ’ strings) and it spawns fine using the lua console, I haven’t seen it spawn in the wild yet but that might be down to the game being funny with me trying to force it to be a house_north. It’s rough but it should shape up nicely and I’ll look for a solution to the rotation later.
Ultimately I’m hoping to make some kind of trade post/bunker with a merchant npc that totally flushes and updates their stock every 1-3 days and the only straightforward solution to that I’ve thought of is to simply delete the NPC and respawn them after checking how long it’s been.

There is little of npc-related function in lua. I believe exposing more npc-related functions to lua is required to make this happen.

I am getting a “there are too many mandatory overmap specials” error. (https://imgur.com/a4QQbM4)

Also the game keeps crashing/freezing when I get to this one area. I’m thinking that because I added urban development mod AND the building pack, and in the patch notes I saw buildings 11-20 added… is that maybe what is causing this?

I hope this is the correct thread to post this. I am using tiles and 32bit, instead of 64bit and tiles like usual, since x64 isn’t updating for me.

[quote=“NuG, post:19, topic:13515”]I am getting a “there are too many mandatory overmap specials” error. (https://imgur.com/a4QQbM4)

Also the game keeps crashing/freezing when I get to this one area. I’m thinking that because I added urban development mod AND the building pack, and in the patch notes I saw buildings 11-20 added… is that maybe what is causing this?

I hope this is the correct thread to post this. I am using tiles and 32bit, instead of 64bit and tiles like usual, since x64 isn’t updating for me.[/quote]
That issue doesn’t belong in here. The error you mentioned doesn’t related to LUA mapgen code.