Worldgen Rewrite

Alright, I figured out why I’m not getting native subways, ant-hills, or sewers, and in order to fix it I’m going to add a bitfield to oter_t with flags for is_asphalt, is_sewer, is_building, etc. Should I also go through and change all the existing bools on oter_t to use said bitfield, or would you rather I left them be?

Also, I see no reference to std::bitfield. Did you mean std::bitfset?

std::bitset is what you would want, yeah (which implements a bitfield).

Important note, but document what the bitfield contains thoroughly; you might even want to make getter functions (like “get_is_sewer()”) instead of accessing the bitfield directly to ensure that clarity of what each spot is is maintained.

That’s what I was planning, yes.

So it’s alright if I go and shove the booleans for Rotates, Is_river, allows_road, etc into the bitset as well? Also I’m planning on renaming Is_road, because it has barely anything to do with roads.

Yeah, it would work well.
Do create an enum for it, though. Look at how it is used in mtype.h and mtypedef.cpp. There’s an enum declared for the flags and the bitfield is only accessed through a getter: has_flag( flag_enum_type_here )
That way it is all cleanly expressed as, for example, m.has_flag(MF_SEES) rather than m.type->flagfield[4]

I’s actually been making individually named functions for each bit, I.E. is_asphalt(), set_asphalt(), is_ants(), set_ants, etc. It might be easier to just use an enum, though.

In other news, I’m trying to come up with a way to implement an “Architect” system, for when you have multi-tile structures you want to be intelligently laid out, like labs, mansions, malls, skyscrapers, that bloody necropolis, etc. That way, instead of having 100 mall tiles, you can just have like one or two, and instead have the architect figure out what to put on each tile.

Also, does anyone know why it sometimes accesses an oter_t from an oter_id by using “oter_id.t()” and sometimes by using “otermap[oterid]”? what’s the rationale behind that?

For the necropolis, I’d suggest leaving them alone for now, and considering converting them to dynamic generation as a seperate set of changes. The same applies for the mall and prison. It would be all too easy to get bogged down in making that just right and delaying the rest of the system.
We will want to keep a system around that allows people to statically define structures anyway, some people can’t or don’t want to deal with dynamic generation, and just want to supply static layouts.

Yeah, I’m thinking I’m going to make sure there’s an option for that in my Architect system, and port the generation of those into it. and that won’t come until much later, I’m about 90% done with part A, altering the tile code to support the multiple tile types. after that comes changing the mapgen to actually care about the multiple tile types, and then moving the map extras into tiles, and making some of them invisible.

After that, though, should I procede with D though G: Editing the worldgen code to make the placements of tiles make more sense, adding additional functionality for varying regions, adding many more tile types and the worldgen code to handle them, and adding an additional region type, Heavy Forest? or should I skip all that and work on the Architect system?

I should probably also point out that it might be easier to just go and implement the new Architect system than to go through and make the malls, prisons, and necropoli play nice with my new system on account of how many tiles they have. Like seriously, two thirds of the overmap_terrain file is for those two.

I don’t follow, we WILL support specifying building layouts statically, that’s not negotiable, so if you’re overhauling everything you are going to have to implement support for buildings like that anyway. If you think you can improve on them by making them dynamic, great, but the ability to do large-scale static layout like that is a must.

otermap[oterid] is used when oterid is a string. When you have oter_id, use oter_id.t() instead.

My point is that it’d be easier to reprogram things so we have that without having a billion different overmap tiles. Instead, you’d just have a big blob of the same kind of mall tile, and then it’d load the information for the function that manages the layout from the JSON files. Th Architect would then go through and generate all of these tiles at once, using the information it loaded from the JSON to figure out where to add the individual details. I’ll have to add a new JSON detail, and translate the existing functions into it, but that shouldn’t be too much of a problem, and I was planning on doing it anyway.

Oh ok, so you just have one gigantic blob of layout that does the whole thing, and a second entry just for the shape of it on the overmap? if so yes that’s a massive improvement.

Yup. Looking at things, the current code is so unwieldy, that doig the whole architect rewrite right now, before I progress any further is probably worthwhile. I mean, have you seen map::draw_map in mapgen.cpp? Over 8000 lines for one function! Oh, the humanity!

So the way things’ll work now, is that you’ll have a class called Architect. The architect has a list of pointer, or references, to the tiles it works with. It also has a description of what it’s supposed to put on them, I.E. a list of possible rooms and hallways, and instructions on how to put those together. This will include capabilities to just specify static layouts, I.E. what I’ll do for the mall, necropolis, etc. For things that aren’t completely static, though, like mansions & labs, it’ll go through and decide how many of each room it’ll put in the whole building, figure out where the hallways should go, and match the two up. Then it goes and actually generates the terrain for the individual tiles, following it’s schematic.

[quote=“Angle, post:72, topic:8934”]Yup. Looking at things, the current code is so unwieldy, that doig the whole architect rewrite right now, before I progress any further is probably worthwhile. I mean, have you seen map::draw_map in mapgen.cpp? Over 8000 lines for one function! Oh, the humanity!

So the way things’ll work now, is that you’ll have a class called Architect. The architect has a list of pointer, or references, to the tiles it works with. It also has a description of what it’s supposed to put on them, I.E. a list of possible rooms and hallways, and instructions on how to put those together. This will include capabilities to just specify static layouts, I.E. what I’ll do for the mall, necropolis, etc. For things that aren’t completely static, though, like mansions & labs, it’ll go through and decide how many of each room it’ll put in the whole building, figure out where the hallways should go, and match the two up. Then it goes and actually generates the terrain for the individual tiles, following it’s schematic.[/quote]
So it will support both static and random generation?, sounds cool.
The only thing I’m concerned is whether or not you are going to have to change the jsons to work with the new system, if so… that’s a lot of work.

I’ve already had to edit the overmap_terrain JSONs a bunch. I’m actually hoping that implementing this system will help me avoid having to edit the remaining two thirds of it too. Ad yes, I’ll probably have to add a another JSON file or two, but that’s manageable.

Angle, that’s some amazing work you’re doing!

A hint from someone who pushed a few PRs: once you have the basic Architect framework working, PR it and do the next stages as separate PRs. This way, they get reviewed (and merged) faster!

Hmm, possibly. I want to make sure I have everything working at least as well as it was once I started. But yeah, I’ll PR before I start adding new content.

The only thing that concerns me about this is that last step, at exactly what point in game execution is a tile populated? It sounds like if you get in range of a mall your game is going to stop for several seconds to sort the whole thing out, which if it isn’t obvious is a thing we don’t want.
One very good thing about how the current system works is the separation of overmap and submap generation, we don’t want to lose that. You should however be able to make decisions about things at the higher level and bundle up some state for the lower level code to process further.

Please rethink this, it sounds like you have a gigantic amount of changes already, and are about to embark on an even bigger set of changes, that is a bad idea. Please keep this in mind, if your PR becomes too big, it CAN get to the point where it will never be merged, simply because of its size.

I was planning to have it generate the tiles for large things at world creation. It’ll slow things down a bit, But I think that’s acceptable. As for merging, the game is currently not in as good a state as it was when I started. I haven’t gone over the mall, necropolis, etc. yet, so they have roads and building dropped on top of them on a regular basis. Perhaps I could merge the changes that have happened to cataclysm since, into my repo?

Generating tiles of large things at world generation (actually overmapgen, there is no world gen) is not ok, that is an unbounded and unmanageable amount of computation to do up front, and worse overmapgen happens at unpredictable intervals as the player moves around. Doing all the work for large structures in one shot is simply not a workable solution, there is no point where it’s reasonable to do up to several hundred tiles of mapgen all in one go. Your solution must break map generation into tiered pieces.

I’ve been insisting all along you need to break changes up into manageable pieces, if you don’t do that this isn’t going anywhere. Yes, you need to either merge the upstream repository into yours or rebase your changes on top of upstream on a regular basis, if you don’t it WILL become unmergeable. That doesn’t have a thing with making your changes manageable though, your changes need to be small enough to review and test in a reasonable amount of time. For context, 1000 lines of changes (not counting straightforward renames) is a very large PR.

Hmm. Alright, I’ll work on both of those things.