"Procgen Dungeon" by Harkness [https://68bf7jgt.play.borogove.io/] Section - Coordinate System and Map Dimensions map_width is initially 6. map_height is initially 6. map_depth is initially 6. A coordinate is a kind of value. 100x100y100z specifies a coordinate with parts x_pos and y_pos (without leading zeros) and z_pos (without leading zeros). The map_stack is initially {1x1y1z}. Section - Declaring Rooms and Stairs A mapTile is a kind of room. A mapTile has a number called the level_z. A mapTile has a coordinate called the tile_coord. The tile_coord of a mapTile is usually 0x0y0z. A mapTileA is a kind of mapTile. There are 100 mapTileAs. A mapTileB is a kind of mapTile. There are 100 mapTileBs. A mapTileC is a kind of mapTile. There are 16 mapTileCs. The printed name of a mapTile is usually "Dungeon Corridor". The description of a mapTile is usually "[tunnel desc]." To say tunnel desc: let dir_list be a list of directions; repeat with D running through directions: if the room D from the location is not nothing: if D is not up and D is not down: add D to dir_list; unless the number of entries in dir_list is 0: say "[if the number of entries in dir_list is greater than 1]Tunnels stretch[else]A tunnel stretches[end if] through the cold stone to [dir_list with definite articles]"; else: say "Featureless stone surrounds you" A mapStair is a kind of fixed in place thing. Understand "stair/stairs/stairway/staircase/step/steps" as a mapStair. An upStair is a kind of mapStair. There are 100 upStairs. A downStair is a kind of mapStair. There are 100 downStairs. The printed name of a mapStair is usually "staircase". The initial appearance of an upStair is "A staircase leads up through the labyrinth." The initial appearance of a downStair is "A staircase descends into darkness." Section - Definitions Definition: A mapTile is unassigned if the tile_coord of it is 0x0y0z. Definition: A mapTile is assigned if it is not unassigned. Definition: A mapStair is unassigned if it is nowhere. The verb to be located at means the tile_coord property. The verb to be z-located at means the level_z property. Section - Random Room Layout Generation To decide which coordinate is the space (D - a direction) from (C - a coordinate): if D is: -- east: increase C by 1x0y0z; -- west: decrease C by 1x0y0z; -- south: increase C by 0x1y0z; -- north: decrease C by 0x1y0z; -- down: increase C by 0x0y1z; -- up: decrease C by 0x0y1z; decide on C. To decide which list of directions is the viable directions from (C - a coordinate): let dir_list be {north, south, east, west, up, down}; if the x_pos part of C is 1: remove west from dir_list; if the x_pos part of C is map_width: remove east from dir_list; if the y_pos part of C is 1: remove north from dir_list; if the y_pos part of C is map_height: remove south from dir_list; if the z_pos part of C is 1: remove up from dir_list; if the z_pos part of C is map_depth: remove down from dir_list; let temp_list be dir_list; repeat with D running through temp_list: let R be a random mapTile that is located at the space D from C; unless R is nothing: remove D from dir_list; decide on dir_list. To place a room at (C - a coordinate): let R be a random unassigned mapTile; unless R is nothing: now tile_coord of R is C; now level_z of R is the z_pos part of C; else: say "Bug: out of unassigned rooms." To place a stair going (D - a direction) from (curr_room - a mapTile) to (new_room - a mapTile): let u_stair be a random unassigned upStair; let d_stair be a random unassigned downStair; if u_stair is nothing or d_stair is nothing: say "Bug: out of unassigned stairs."; else: if D is: -- up: now u_stair is in curr_room; now d_stair is in new_room; -- down: now d_stair is in curr_room; now u_stair is in new_room. To initialize the burrowing wyrm: let C be entry 1 in map_stack; place a room at C; say "Initializing wyrm..."; drive forth the wyrm from C. To drive forth the wyrm from (C - a coordinate): let dir_list be the viable directions from C; unless the number of entries in dir_list is 0: let N be a random number from 1 to the number of entries in dir_list; let D be entry N in dir_list; let new_coord be the space D from C; add new_coord to map_stack; place a room at new_coord; let curr_room be a random mapTile that is located at C; let new_room be a random mapTile that is located at new_coord; change D exit of curr_room to new_room; change opposite of D exit of new_room to curr_room; if D is up or D is down: place a stair going D from curr_room to new_room; drive forth the wyrm from new_coord; else: let N be the number of entries in map_stack; remove entry N from map_stack; if the number of entries in map_stack is greater than 0: decrement N; let new_coord be entry N in map_stack; drive forth the wyrm from new_coord; else: say "Map complete." When play begins: initialize the burrowing wyrm; let R be a random assigned mapTile; move the player to R, without printing a room description. Section - The Ascii Mapper To construct a tilemap for level (curr_level - a number): let L be the list of mapTiles that are z-located at curr_level; sort L in tile_coord order; say "[fixed letter spacing]"; repeat with y running from 1 to map_height: repeat with x running from 0 to (map_width - 1): let N be y + (x * map_height); let R be entry N in L; say "[map symbol of R] "; say "[line break]"; say "[variable letter spacing]". To decide which text is the map symbol of (R - a mapTile): if R is the location of the player, decide on "@"; if R is unvisited, decide on "·"; let dir_list be a list of directions; let vert_list be a list of directions; repeat with D running through directions: if the room D from R is not nothing: if D is not up and D is not down: add D to dir_list; else: add D to vert_list; if dir_list is: -- {north}: decide on "║"; -- {south}: decide on "║"; -- {east}: decide on "═"; -- {west}: decide on "═"; -- {south, east}: decide on "╔"; -- {south, west}: decide on "╗"; -- {north, east}: decide on "╚"; -- {north, west}: decide on "╝"; -- {east, west}: decide on "═"; -- {north, south}: decide on "║"; -- {north, south, east}: decide on "╠"; -- {north, south, west}: decide on "╣"; -- {south, east, west}: decide on "╦"; -- {north, east, west}: decide on "╩"; -- {north, south, east, west}: decide on "╬"; if vert_list is: -- {up}: decide on "⇑"; -- {down}: decide on "⇓"; -- {up, down}: decide on "⇕"; decide on "+". Section - The Dungeon Map The dungeon map is a thing. The player carries the dungeon map. Instead of examining the dungeon map: let z be the z_pos part of the tile_coord of the location; construct a tilemap for level z. Mapping a level is an action applying to one number. Understand "map [number]" and "level [number]" as mapping a level. Check mapping a level (this is the can't map out of bounds rule): let N be the number understood; if N is less than 1: say "You possess no map of the surface."; stop the action; if N is greater than map_depth: say "The ones who built this place never delved so deep."; stop the action. Carry out mapping a level: let N be the number understood; construct a tilemap for level N.