Newbie tries making a fantasy city generator

Ah i should have refreshed the page that I had left open for 20 minutes before posting :stuck_out_tongue:

Gonna have a play around you’ve intrigued me. No experience with spline roads. But I’ve messed around the random seeds for my puzzle game which I could do for buildings. I.e construction script goes through a series of random ints for each attachment point and then sets a static mesh component based on what the int gets from an array.

Can’t wait work must finish faster.

@Zedrophobe: Good show! I’d love to see what you put together. :smiley:

So, a bit more progress. Tried getting into the road making, but that got way more complicated than I have any chance of cracking anytime soon, so I stuck with the building generator and made a completely new one that’s quite a bit smarter. All meshes are still absolute placeholders, but it’s sorta kinda starting to look like dilapidated medieval buildings. I’ve exposed the number of floors and most of the general scaling and material changes as parameters, so with any luck I’m gonna be able to hook that up into some sort of “quarter”-system (like, rich quarters, poor quarters, docks, that kinda thing).

Right now my biggest problem is how to hook something like this into something that generates a coherent village inside one blueprint. Each building in the pic is an instance of the same blueprint, but I suspect just having another blueprint spawn copies of the building-blueprint isn’t the best way to go about it. And the one time I tried, it also absolutely tanked performance once I spawned more than a hundred buildings.

I also started looking a bit into procedural world generation and holy hell am I out of my depth. Ah well. One step at a time.

Looking good mate!

Yeah, procedural worlds needs a bit of serious math to make anything custom efficient enough to run.

You could try staggering the spawn to make performance smoother. Make it so that the code only spawns small segments of the thing with every frame so your game doesnt freeze up.

Unless you mean youre running into FPS problems after youve done spawned everything. In which case its likely a problem with polygon counts (you want to cull polys you dont see like on the in between of building floors), level of detail and/or drawdistance. Optimization is hard work!

Personally I would run a blueprint function / blutility to generate the buildings. That way rather than doing it with a construction script you can just press the button and it will do it. Then you could also trigger a different function to re-seed a single building or all buildings etc if you wanted.

You will also probably want to change it all over to instanced static mesh instead of individual static meshes or you will start to hit some performance issues with a large town.

How are you doing your randomization for the number of floors on each house too? Since you are looking at doing different “regions” within a town I think you could have a cool “budget” system for the houses, each component would be a certain cost and each house has an allocated budget they can use to build the house. Could come up with some cool results, using cheaper smaller parts in the poor part of town and bigger better parts in the rich part.

@Bluntie: I suggest you should do some research into Binary Space Partitioning (BSP Trees). Its a rather neat and simple way to breakup a space into modular parts, this would be a good place for you to start looking at how to build a city and may give you ideas for the future when it comes to building roads as well.

There are a few ways to tackle this problem, but BSP Trees in my opinion would be easy for you to pickup and implement in Blueprints.

Good luck, also, the buildings are really coming along now.

@6ixpool: Basically, the performance hit is just when I move 100+ blueprints that all rebuild themselves every frame, so it’s not really a big surprise. :smiley: I just need to figure out how the pros would do it, and do that instead. And yeah, I totally need a culling system. And LOD’s. And…well…lots of things. xD Also thanks!

@AMZoltanJr: Building the buildings in a seperate funtion sounds smart, I’ll look into that. So far I’ve built everything just in the construction script. As for instanced meshes, I was under the impression that using those for something like this would be bad since they wouldn’t be able to handle LOD’s and stuff like that properly then? But I might be absolutely wrong - just seem to remember reading it somewhere. But I’d love to use instanced meshes instead. My initial take on the city generator (the one in the first post) used instanced meshes, and that handled like 5000+ buildings with basically no performance hit. Those were all just single meshes though, no randomization, so that might also have something to do with it. :stuck_out_tongue:

Right now I’m spawning the floors using a ForLoop with a set minumum and maximum of floors to spawn, with each loop picking a mesh from an array, apply various transforms to it, and spawn windows and doors as seperate meshes. I spawn everything using Socket locations I put manually on each static mesh. The sockets seem lovely as a system, but I definitely missing some info - I can’t figure out how to auto-generate arrays based on them, so I have to type them all by hand, which seems a bit newbish…not to mention that several windows might spawn on the same socket, which is just messy.

The “budgets” for the buildings is a really cool idea, I’ll definitely implement something along those lines in time.

@DevilsD: BSP trees sound lovely! Never heard of them before, but they sound like exactly what I need. Shall read up. :smiley:

Thanks alot for the feedback, folks! It’s a big help. :smiley:

So, I’ve been toying a bit with putting the house maker into a Function inside the Blueprint, which works fine. Functions seem rad. But now I’ve hit something of a wall. This is what I’m looking at right now:

How on Earth do I DO anything to that Function? I can’t seem find any way at all to hook it into a transform or anything since it has no output like you’d see on a Add Static Mesh component. I feel like I’m missing something completely fundamental that’ll make me facepalm quite hard once I figure it out.

Add elements to the input and output pins for your function. :slight_smile:

While tempting, its generally bad practice calling variables from inside functions since you cant be sure when the values for those variables were last updated. Be extra mindful of your code structure when using functions. Its easy to fall into circular dependencies and other nasty bugs when using them (i know i always make these kinds of mistakes xD)

As for your spawn logic involving markers, ill probably set it up like so;

Wall of text ahoy!

1a. Geneate “road splines” (or just scatter them about until you figureout how to generate the road splines)

1b. Generate “house markers” at logical intervals along the splines (based on standard house dimensions, if its near/overlaps another object, etc)

1c. [Optional] based on the certain factors (e.g. position of the marker on the spline, if the “house marker” is inside a “poor/rich/dock” district, climate, etc) designate logic on which meshes/materials/how many floors the house on said marker would spawn (this is where those input pins come in handy).

2a. Store all the house markers inside an array (either with the get all actors of class node or an overlap volume to populate your array)

2b. Run a foreachloop referencing the array fro #2a. ([Optional] you can also use a forloopwithbreak to stagger the spawn of each house across several tick events. I.e.break after x iterations of the loop, store x in a variable, use x as the array index for when you call the function again next frame. Remeber to terminate the loop! Infiniteloops are bad for your health.)

2c. Call your brand spankin new “spawn house” function as the body of the loop in #2b. with inputs (such as number of floors, meshes to use, etc) being returned from the “house marker” currently ondeck in the foreachloop. You can have this be randomly/procedurally generated as part of the construction script of each “house marker”. The construction script is also where you set the initial values for each instance of the house markers (either random/procedural or based on #1c)

(Each number could be a function/macro/blueprint)

Good luck!

I would be going along a similar route to 6ixpool, break out your different functionality into different segments, personally I break mine out into totally different blueprints with my little tests in this area.

So I have a building generator that creates each individual building as it’s own blueprint actor that you can then manipulate in the level editor as you like, move scale etc if it doesn’t quite sit right.

A building spawner that spawns the building and runs it’s generator. This could be based on the road spline locations like 6ixpool mentioned.

An instancer that goes through every 1 of the spawned buildings and destroys all the static meshes and replaces them all with a single blueprint that is an instanced static mesh. You only want to do this when you are ready to stop fiddling with the buildings because they then can’t be manipulated as easily.

@zoltanjr
Ohh, that last bit is new to me (the part wbere you combine everything into a single mesh). Seems like a really nifty tool to really save on performance. What nodes/functions should i be looking into to make me one of those? :slight_smile:

Possibly not the best way to do it but it does the trick.

This is my “Instancer” blueprint. I call it from a blutility in my “Building Generator” blueprint.

I should probably explain what it’s doing just to make it clearer.

My “Building Generator” blueprint, using a blutility, goes through all of my “Road” blueprint’s to find all the possible locations it can build. On each of those points it will spawn a “Building” actor. From there I can move and manipulate and do whatever I want with the building itself.

Once I am happy with that I go back to my “Building Generator” blutilities and run my “Instancer” which then steps into here. It will go through every “Building” actor that’s in the level, find all of the different static meshes that are in it and create a new “instanced static mesh” for each new static mesh that it finds. It will then get the transform of that mesh, add an instance to that instanced static mesh and set it’s transform to be what the static mesh was and then destroy the static mesh.

So you will end up with an “instanced static mesh” for however many unique meshes you have, after the mesh has been found then everything will be added as an instance to that 1.

Based on Blunties meshes he should have 18 instanced static meshes and all of the parts will be instances in there.

So it gets rid of the actor that contains the mesh in question and replaces it with an instance of the mesh with the exact same transform? Thats pretty great actually, seems like a breeze to implement too (now that i have your algorithm to get me along the right track!).

It replaces each “static mesh component” with an “instanced static mesh instance”, as confusing as the instanced static mesh stuff is. Once it has found every static mesh in the actor it will then destroy that actor and move onto the next 1.

I did a test with it and spawned 10 000 houses, each with 4 meshes and with all of them in view I had an fps of 1-5fps, click the button and after about 10-20 seconds of converting it jumps back up to 60fps.

Since once you have them as instances you can’t actually do anything with them I would only actually do this when you want to publish, but you can do it for everything pretty much.

Like I would run this for my road as well so that street signs etc all became instanced instead. It’s pretty much how the foliage painter does stuff really.

You can just run the instancer at begin play as well to get the optimization at runtime, but with that many buildings I end up struggling to move around in the editor. I think I might change it around to be based on regions. So that I can instance out a region and save it and move onto the next 1.

Actually I just figured out another method I might try with using savegame to save out the arrays that the instances have and then write a reverse function to change them back to static meshes so that they can be modified and re-saved. I will do some tweaks and make some updates

How do you run functions in editor before you hit play? Do you just swap around execution pins in the constructor or something?

I do it through custom events.

Create a custom event, then tick “call in editor” then this will add a blutility that you can fire off through a drop down box in the details panel when you select the actor

Man! You guys went to town while I was away! I’m afraid Zoltan’s incredible-looking blueprint is a bit beyond me just yet (still struggling to figure out Instanced Meshes properly, though I found a few tutorials that helped me some), but it sounds like the way to go for sure. I think what I’d like optimally would be to get the blueprint to randomly make a building from static meshes (as it does now), convert all of that into a single mesh somehow, then repeat that a set number of times to generate a nice number of random buildings, then generate a full city from instances of those.

[Edit] Also, @6ixpool: Sorry for not acknowledging you, for some reason I forgot to mention your list. That sounds like something I might be able to figure out, so I’ll give it my best shot. :slight_smile: