Lab mapgen jsonization - problem of adjacency

The primary reason for https://github.com/CleverRaven/Cataclysm-DDA/pull/21900 was that I wanted to make json labs possible.
That PR isn’t enough, as it does not account for lab piece connections: two lab pieces need to have doors between them, while lab adjacent to rock should not have doors to nowhere.

I see two ways of connecting lab pieces:

[ul][li]Crude: change lab tile type from “lab”/“ice_lab”, to one that explicitly mentions connections, then enumerate all possibilities. For example, “lab_NSE” means “lab tile that connects to north, south, and east”[/li]
[li]Conditional mapgen nesting: add a nested mapgen piece on a condition[/li][/ul]

The first option is easy, but tedious, menial, can’t be easily verified without going through all options.

The latter option, while very flexible, could be a bit complex to use: you’d have to define the condition somehow, then apply it to something. That something would most likely be a nested mapgen entry.
This means that I’d probably need to write a “mapgen condition structure”, which would look roughly like one of those (not sure which is the best):

Option 1:
"place_nested": [
  { "entries": [ [ "lab_door_horiz", 100 ] ], "x": 12, "y": 0, "conditions": [ { "condition_type": "neighbor_type", "dir": "north", "allowed_ids": [ "lab", "lab_ice" ] } ] }
  { "entries": [ [ "lab_door_horiz", 100 ] ], "x": 12, "y": 23, "conditions": [ { "condition_type": "neighbor_type", "dir": "south", "allowed_ids": [ "lab", "lab_ice" ] } ] }
  ...
]

Option 2:
"place_nested": [
  { "entries": [ [ "lab_door_horiz", 100 ] ], "x": 12, "y": 0, "neighbors": [ [ "lab", "lab_ice" ], "any", "any", "any" ] },
  { "entries": [ [ "lab_door_horiz", 100 ] ], "x": 12, "y": 23, "neighbors": [ "any", [ "lab", "lab_ice" ], "any", "any" ] },
  ...
]

Option 3:
"conditionals": [
  {
    "conditions": [ { "condition_type": "neighbor_type", "dir": "north", "allowed_ids": [ "lab", "lab_ice" ] } ]
    "place_nested": [
      { "entries": [ [ "lab_door_horiz", 100 ] ], "x": 12, "y": 0 }
    ]
  },
  {
    "conditions": [ { "condition_type": "neighbor_type", "dir": "south", "allowed_ids": [ "lab", "lab_ice" ] } ]
    "place_nested": [
      { "entries": [ [ "lab_door_horiz", 100 ] ], "x": 12, "y": 23 }
    ]
  },
  ...
]

Option 4:
"conditionals": [
  {
    "conditions": [ { "condition_type": "neighbor_type", "dir": "north", "allowed_ids": [ "lab", "lab_ice" ] } ]
    "place_terrain": [
      { "ter": "t_metal_door", "x": 12, "y": 0 },
      { "ter": "t_metal_door", "x": 13, "y": 0 }
    ]
  },
  {
    "conditions": [ { "condition_type": "neighbor_type", "dir": "south", "allowed_ids": [ "lab", "lab_ice" ] } ]
    "place_terrain": [
      { "ter": "t_metal_door", "x": 12, "y": 23 },
      { "ter": "t_metal_door", "x": 13, "y": 23 }
    ]
  },
  ...
]

Option 3/4 (those are basically one thing, just expressed differently) is interesting because it would allow defining entire conditional mapgen entries without nesting. That is, you could use this syntax to overwrite a palette based on conditions.
Option 2 is the least flexible, only useful for nesting based on neighbors. But it is also the simplest and least likely to lead to problems when some modder implements a complex mapgen entity on hacks and errors in implementation.
Option 1 is a compromise: only useful for nesting, but probably much easier to implement than 3/4.

Any other options? Is this good enough to be useful for anything other than lab mapgen?

Option 2 looks great, but with a few adjustments:

"place_nested": [
  {
    "chunks": { "lab_door_horiz": 100 },
    "origin": { "x": 12, "y": 0 },
    "neighbors": {
      "north": [ "lab", "lab_ice" ]
    },
  ...
]

“entries” is confusingly generic.
The coordinates need a label.
Specify adjacency with keywords instead of implicitly with array position.
Generally, prefer objects to arrays.

Would be usefull for the conections of any type of procedual dungeon. Say better triffid grooves and ancient temples.

With some creativity you could use methods 3/4 it to make big, complex labyrinths (but the json file would probably be gigantic).

[quote=“Kevin Granade, post:2, topic:14353”] "place_nested": [ { "chunks": { "lab_door_horiz": 100 }, "origin": { "x": 12, "y": 0 }, "neighbors": { "north": [ "lab", "lab_ice" ] }, ... ] [/quote]

x and y being in the outermost context of the entry is a part of mapgen system. It can’t be easily wrapped in a structure without reworking a lot.
The rest is doable.

That’s doable even with 1 and 2, just with some more deference and wrapping.
What isn’t doable with 1 and 2 is the ability to change the binding of a symbol on palette, for example to have a house made entirely from concrete use the same definition as one made from wood.

I simply used the doors when making my own, and they do often go to nowhere, but it does work

having a list that can be added to would be neat.

Can we just check for nearby terrains and place door only if nearby terrain is passable?

Also can we define junction directions for overmap tile, so we could place random tiles from the list (automatically rotating if necessary)?

[
  "overmap_blueprint": {
    "overmap_blueprint_rows": {
      " S ",
      "CXC",
      "TTC",
      "TSC",
      "S S",
      "CSC" 
    },
    "overmap_blueprint_tiles": {
      " ": [ "empty_rock" ],
      "C": [ "lab_room1_corner", "lab_room2_corner", "lab_room3_corner" ],
      "X": [ "lab_room_main_center" ],
      "T": [ "lab_room1_t" ],
      "S": [ "lab_room1_s" ]
    }
  }
]

T for random overmap with t-junction
X for random overmap with center tile/4-way-junction
C for random overmap with corner tile
S for random overmap with single direction connection

" ║ "
"╔╬╗"
"╠╩╝"
"╠═╗"
"║ ║"
"╚═╝"

You can already use multiple mapgens for the same OM tile, so C could map to lab_corner, and lab_corner could have 3 separate mapgens associated with it.

True, but they aren’t getting rotated automatically.

Automatic rotation is a separate problem. For now I’m assuming unrotated (or rotation-agnostic).
Option 3/4 could allow to request specific rotation during mapgen, though.