Mansion Upgrade Project

Important News! I’ve created a test pack for this project.

Download CDDAMansionTestPack.zip 33KB

It’s a little different from my ultimate goal. This will only produce 4 variations of the mansion to ensure z-levels are stacked properly. Please try it out and then criticize it without mercy give me helpful feedback here.

[hr]
Original Post:

Proposal: Take the bulk of mansion generation out of hard code and into json files while also upgrading the layout.

Purpose: To see how I like coding for CDDA with a relatively small project.

Who am I?: Amature programmer with zero Github experience. You may have seen my sprite-work in some of the tilesets.

True Purpose: What I’d really like to fix is the missions. The buggy missions keep ruining my games. :frowning: That would be a lot to take on for my first dive into the source though. We’ll see how this goes.

Progress: I’ve found the appropriate code and read through it. It’s quite interesting how they inserted the furniture layouts into rooms of varying size, but the downside is furniture blocking doors. I don’t think I can imitate that with json files, and I don’t intend to. However, I will try to keep the loot drops of the original, and that will require a large amount of tedium.

Actual Progress: I’ve drawn up some blueprints for the ground floor of a mansion. The pieces are modular, so with a bunch of them for the rng to choose from each mansion should feel somewhat unique.

[spoiler=Corner Images]

[/spoiler]

[spoiler=T-Intersection Images]

[/spoiler]

[spoiler=Middle Images]

[/spoiler]

I threw these together quickly, and I have to rework some of the ideas here, like which pieces hold the adjoining walls. For example, the pool doesn’t work with my ball room. Criticisms, advice, and ideas are all welcome.

neat.

I approve. and you make them look classy. How modular/interchangeable are you imagining this to be?

I think it really looks great!

How do you plan on stacking z-levels? Will south-west corner be an “A” template so that the basement and potential second floor have the same perimeter wall and same stair locations? Or are you thinking about bundling all three into a singe unit, so if you find kitchen “C” on the first floor you can predict library “C” on the second? I like the irregular shape of the outside wall but I know it can be a pain to try and match the floor on the other levels.

P.S. Sorry that the missions suck. I added a bunch but changes to the code keep breaking them and I only usually have a month or two each year to contribute.

It almost makes me cry of how beautiful it looks. Yes, please!

My plan is to create a variety of corners, t-intersections, entrances, centers, and rear t-intersections. Entrances, centers, and rears will rotate according to the mansion’s orientation on the over-map. The corners/t-intersections can be placed at any corner/side with the appropriate rotation and t-intersections can be used as rear t-intersections too. Furthermore, I’d like to limit the number of room types. I’ve seen mansions with 4 pools, 6 kitchens, and 12 dining rooms but not one bedroom. I don’t want that to happen anymore.

As for z-levels, I’m afraid they’ll have to be tied to the main floor for the design to make real world sense, or at least the sections with stair wells do. The other pieces can be modular, but here is any area where my knowledge is lacking. If an above ground floor does not fully cover the ground floor, will you see into the ground floor or will you see the roof? I would think that the roof would be automatically inserted if it was indoors below, but is outdoors above. I guess I need to find a z-level construction guide.

I’ve also been wondering if it’s wise to build mansions that require z-levels to be enabled. This isn’t a mod dependent on other mods, this is a hard code update. Once I’m done anyone should be able to mod mansions, so there could be a non-z-level mansion mod, but I don’t like that. The end user should not be responsible for picking compatible world generation options. I need a fool proof solution.

[edit]@acidia: Don’t take my gripe about mission bugs personally. They’ve always been a mess/incomplete as far as I know. This last time I got back to the refugee center with some hard found loot and half the occupants were just gone. Unfortunately, I’d driven past several days ago in game and saved since then, so there was no getting them back. I think this problem is deeper than the mission code itself.[/edit]

Update: I’ve read through all the relevant documentation now. I’ve been refining my blueprints, making new layouts, and converting them into json. I’ve even tested out sections of the mansion in game spawned as regular houses. The plan to match up certain z-levels is at odds with the plan to keep the pieces modular, so this is going to be a more complicated project than first imagined.

[spoiler=Talking at length about z-levels and map generation]You can match z-levels if the generated world map gives unique IDs to a location and it’s z-levels. For example the the “more locations” mod will cause map locations with IDs like 2storyA_first with 2storyA_basement below and 2storyA_second above. When you first approach the location in game it builds correctly because the jsons with those IDs all have the exact same footprints and stairwells. This won’t work for mansions unless all footprints, stairwells, and open spaces are identical. Way too predictable for my taste. I want you to run up stairs and get trapped in a dead end. Not going to happen if you know there will be another stair well in the next wing. In short, I still need a way to hook z-levels together when multiple blueprints have the same ID. What we really need is a universal convention for this sort of thing. I may have to write one myself.

[glow=green,2,300]Ohohohoho![/glow] While writing this I just had a great idea! If the json blueprints could alter the over map IDs, then a randomly chosen blueprint could specify it’s z-level neighbors. Then it would be a matter of making duplicate blueprints, one set with generic IDs and one with specific IDs.[/spoiler][hr]On the bright side, json blueprints are far more versatile than I thought they would be. The more I dig into what’s behind the scenes, the more awed I am at the incredible amount of work that has gone into Dark Days Ahead.

You don’t need to match the drops too closely. The only parts that shouldn’t get stronger are medieval weaponry/armor and books, since mansions are already great sources of each.
Food, clothing, crafting stuff, “junk” - those are mostly flavor and

If you have a good idea on how would you like the overmap-to-mapgen interface to look like, it may actually be easy to implement.

It may even be possible to have some limited puzzle piece support already, but I’m not sure how much of it is there, since the only way to really understand how lacking the implementation is is to actually try to add something with it.

Would it be enough if overmap_specials could force rotations? Say, assume the rotation 0 is the tile in upper-left, the one in upper-right is rotation 1, lower-right is 2, lower-left is 3 (or reversed order). That way there would need to be only 4 tile types: entrance, center, T-junction and corner.
The overmap_specials.json would then construct a building out of those 4 types + rotation arguments.

Most of the errors weren’t really caused by changes, but inadequate testing. It’s hard to properly test missions due to their implementation being inadequate (pointers, IDs, hardcoded enums - those are being fixed, but still) and due to how extensive many of them are (many of them invoke mapgen on already generated maps).
For example, there was a mission-related crash caused not by mission code, but by vehicle code. The missions add vehicles with no regard for proper placement. This worked most of the time, but sometimes it just didn’t and instead crashed the game. The bug is now fixed, but it’s a good example of what can be easily blamed on innocents.

Most of the bugs in missions are only found months after merging, when enough people actually finish them.

Dumb question: how do you look at the room/tile layouts so neatly like you have here! I’ve been looking to attempt to edit map tiles as well, but don’t know how to make it come up like you have it & edit it! Thanks so much!

[quote=“Coolthulhu, post:7, topic:12888”]You don’t need to match the drops too closely. The only parts that shouldn’t get stronger are medieval weaponry/armor and books, since mansions are already great sources of each.
Food, clothing, crafting stuff, “junk” - those are mostly flavor[/quote]
Already planning to nerf books by controlling the drop points. With the current system you can get multiple, huge libraries at random. I’m being judicial with my bookcase placement and I’m hoping I’ll be able to limit the number of library containing maps in any given mansion. As for the other stuff, I really just want to make sure I don’t change things in a drastically bad way. Mansions should be worth a visit but not be an unguarded piggy bank.

[quote=“Coolthulhu, post:7, topic:12888”]It may even be possible to have some limited puzzle piece support already, but I’m not sure how much of it is there, since the only way to really understand how lacking the implementation is is to actually try to add something with it.

Would it be enough if overmap_specials could force rotations? Say, assume the rotation 0 is the tile in upper-left, the one in upper-right is rotation 1, lower-right is 2, lower-left is 3 (or reversed order). That way there would need to be only 4 tile types: entrance, center, T-junction and corner.
The overmap_specials.json would then construct a building out of those 4 types + rotation arguments.[/quote]
That’s pretty much what I was thinking, just 4 types of mansion pieces. Initially I wanted a 5th type for special center-back pieces though I’ve changed my initial layouts, so those pieces could go at any t-intersection except the entrance of course. I hadn’t considered putting the rotation control into the overmap_specials, but that would work just fine. In fact it’s probably better that way since it makes rotation control accessible to all modders for all purposes. Incidentally, I’m drawing my maps so that front-left corners would be rotation 0, and center-back t-intersections are rotation 0. My centers aren’t rotatable but that could be handy for other structures. Labs in particular will need all piece types in all orientations if they ever get this treatment.

Something like this:

[ { "comment": "Mansion", "type": "mapgen", "om_terrain": [ "mansion" ], "method": "json", "weight": ... "object": ... "new_overmaps" : [ { "point":[0,0,-1], "overmap": "mansion_corner1_b1"}, { "point":[0,0,0], "overmap": "mansion_corner1_f1"}, { "point":[0,0,1], "overmap": "mansion_corner1_f2"} ] } { "comment": "Mansion", "type": "mapgen", "om_terrain": [ "mansion_corner1_f1" ], "method": "json", "weight": ... "object": ... ] } ]Each z-level would have the same code, so that whether you approach by land, subway, or air the correct layers will be generated for the randomly chosen corner piece. Possibly you could combine the two declarations into one by including both IDs in the “om_terrain” array, but then you’d needlessly re-write the new overmap values with each floor’s generation.

That’s not a dumb question at all. I’m using 3 programs which are all free.
[ul][li]Gimp is a free photo editor. You can use whatever picture editor you like. I find the terrain and furniture I want to use and place them in a small tileset. I put in multiples of furniture that may land on different terrains. For something that is drawn with multiple tiles use just one tile, e.g. walls, the pool table.
[/li]
[li]Tiled is a pay-what-you-want map editor. Create a new orthagonal map 24x24 tiles in size. The tiles themselves depend on which tileset you use. I’m using a 32x32 pixel tileset. Import the mini-tileset you made. Draw your map on a single layer. Now to turn this into map data you can use, open map properties and make sure it’s set to “XML” and “Right Down”. Export to a CSV file, then export it to a lua file. Note: Exporting to CSV before exporting to lua makes the map data appear in 24 rows instead of one big row.
[/li]
[li]Notepad++ is a great free text editor, especially if you do a lot of simple coding. Open your lua file and you’ll find a section of comma separated numbers. This is the map data, but we can’t use it in this form. So, open up the find and replace tool and turn all those 2 digit numbers into single digit characters. Turn the commas followed by spaces into nothing. Take the 2 tab spaces at the beginning of each line and convert them into 12 single spaces and a double quote. Finally, with the extended mode enabled, use \r to add ", to the end of each line. When you’ve got it looking like a proper json map, put it in your json file. Now, you have to define what all your symbols mean. Remember how I suggested making separate tiles for the same furniture standing on different terrain? You should now have different symbols for the different circumstances so you can declare terrain and furniture correctly

[/li]
[li]Productivity: The last step was highly tedious and time consuming, but if you’re making a bunch of maps from the same mini-tileset then the find-and-replace-all step can be performed on all of them at once and the terrain/furniture key you create for one will work for all. If you create each map as a new layer in the same Tiled project, then all the data will export to a single lua file in neat little chunks with the same labels you gave your layers.[/li][/ul]

It’s not an awesome method, but it’s the best I’ve been able to come up with. It’s possible to make a custom exporter for Tiled which would be the ultimate solution, but it looked like the time it would take me to do that would overshadow the time it would take me to use this method.

[edit]Corrected some misinformation here. I was mistaken on how to get Tiled to output the map data with rows.[/edit]

1 Like

I want to tell you that that is a really neat tutorial you made there, egomassive!

Update: I’ve designed 46 out of 54 blueprints. That might sound like a lot, but a single 2-story mansion with basement will include 27 of them. Later I might make more blueprints and destroyed versions, but 54 is enough for good variety. I’m itching to jump into the programming portion of this project.

@StopSignal: Glad you like it. I hope it’s helpful and not problematic. I’m new at this, so my methods may be lacking.

[quote=“egomassive, post:12, topic:12888”]Update: I’ve designed 46 out of 54 blueprints. That might sound like a lot, but a single 2-story mansion with basement will include 27 of them. Later I might make more blueprints and destroyed versions, but 54 is enough for good variety. I’m itching to jump into the programming portion of this project.

@StopSignal: Glad you like it. I hope it’s helpful and not problematic. I’m new at this, so my methods may be lacking.[/quote]
dude , we’re all with you on this , you’re doing god’s work
if you ever need a tester or something , hit me up

I realized I could control rotation with the tools that are already there, but I need info on how jsons work. If I define an object and then define it again with other traits will the two definitions be merged? Here’s what I’m thinking of doing.

First: Overmap_specials lays out the mansion plots with directions, like “mansion-ne” for the North-East corner.

Second: The blue prints for a corner piece would contain a generic definition for all directions.

[ { "comment": "Mansion", "type": "mapgen", "om_terrain": [ "mansion-ne", "mansion-nw", "mansion-se", "mansion-sw" ], "method": "json", "weight": *snip* "object": *snip* } ]

Third: I give rotation individually.

[ { "comment": "Mansion", "type": "mapgen", "om_terrain": [ "mansion-nw" ], "rotation": 0 } { "comment": "Mansion", "type": "mapgen", "om_terrain": [ "mansion-ne" ], "rotation": 1 } { "comment": "Mansion", "type": "mapgen", "om_terrain": [ "mansion-se" ], "rotation": 2 } { "comment": "Mansion", "type": "mapgen", "om_terrain": [ "mansion-sw" ], "rotation": 3 } ]

If this wouldn’t work I could create complete duplicates, but since I was already thinking of making duplicates for z-level association I’ll end up with 8 duplicates for each corner design for each z-level. My 54 blueprints just became 4032. That’s a lot and not a mod-maker friendly solution.

@Gnorse: I appreciate your support.

[edit]Switched East and West in my example, because I had them flipped.[/edit]

This is looking awesome man. I’ve only played two characters in this game so far but I’m loving it, and the mansions I’ve found are so… samey and bland. This looks like it has killer potential. I eagerly await its release.

I have been poring over the source, the documentation, the github, the forum… I cannot figure out why maps do or don’t rotate. Overmap specials marked [glow=red,2,300]“rotate” : false[/glow] still rotate! But mine only rotate if I mark them true, but while the whole mansion rotates the individual sections do not. If I add [glow=red,2,300]“rotate” : true[/glow] to any of my overmap terrains they fail the validation check while other structures have it and pass. I’m so frusterated. This is the specific error I get if anyone cares to shed some light on it:
Debug : Invalid terrain “mansion_c” in overmap special “Mansion_Road”.
Function : void overmap_special::check() const
File : src/overmap.cpp
Line : 986

Sidenote: I discovered that the 2 floor motel is rooved with shrubs. I think I’ll get into the gethub side of things by submitting a fix for it.

This is going to be a bit new but what you need to do to get a multi-tile building to rotate as a single unit is to add “_north” to the end of all of the entries in overmap_specials.json, but no where else. This tells the game that the existing orientation of the map is north… I haven’t tried it but something like the below may work… but I’ve never used anything but _north to designate orientation.

{ "type" : "overmap_special", "id" : "mansion_new", "overmaps" : [ { "point":[0,0,0], "overmap": "mansion_new_corner_north"}, { "point":[1,0,0], "overmap": "mansion_new_side_north"}, { "point":[2,0,0], "overmap": "mansion_new_corner_east"}, { "point":[0,1,0], "overmap": "mansion_new_side_west"}, { "point":[1,1,0], "overmap": "mansion_new_center_north"}, { "point":[2,1,0], "overmap": "mansion_new_side_east"}, { "point":[0,2,0], "overmap": "mansion_new_corner_south"}, { "point":[1,2,0], "overmap": "mansion_new_entrance_north", "connect":"road"}, { "point":[2,2,0], "overmap": "mansion_new__corner_west"} ], "locations" : [ "wilderness" ], "city_distance" : [3, 5], "city_sizes" : [1, 12], "occurrences" : [75, 100], "rotate" : true }

Wow, I was so close! I saw this in the source code and went searching for examples with _east and then _south and came up empty. sigh Thank you so much acidia!

[edit]Update: Rotation is working great now (as long as the mansion doesn’t rotate as a whole.) Each corner and t-section can rotate to the correct orientation. That was an extremely fast turnaround from concept to implementation. Now, I need to tie the z-levels together and finish adding in all the item and monsters.[/edit]

Man, that’s really good to hear. Keep it up! Can’t wait to test it out!

I’ve added items to all 54 maps. It took 1341 lines of json just to declare my item groups, and my mansion blueprint file is now at 4387 lines. wipes brow with back of hand

To Do List:
[ul][li]add monsters[/li]
[li]figure out some items that aren’t working correctly[/li]
[li]z-level linking and rotation issues dealt with[/li]
[li]test, balance, repeat.[/li][/ul]

I’ll push it to my github branch after I’ve knocked out a few of these points. I’ll be wanting feedback on balance, and you’ll probably be wanting to check it out.