Cashgen - (kinda) Infinite Procedural World Generator

New update pushed!

*Now uses instanced terrain material
*Simplified LOD (now only 0/1/2)
*Dithered LOD transitions and zone spawning :smiley:

Demo showing LOD dithering…

Ugh, I’m officially giving up on world origin rebasing for now…does not want to behave. Going to go back to biome work.

looks really good dude keep up the good work

Minor update, added Fractal Gain to the noise plugin

i saw a few questions about mutliplayer and such, and, im wondering if it would be possible to set this up on a dedicated with replication and just have the dedicated generate the landscape … i know, it is always simple when you try and imagine how it might work lol …

I would assume thats possible … assume … never a safe thing. But, moving on, would that be possible to allow a dedicated server flag generate and then replicate to clients who do not have the “isServer” flag?

I do this with something I wrote myself that’s similar to the Dungeon Architect plugin, and the only part that didn’t ‘just work’ is that UCharacterMovementComponent needs whatever UPrimitiveComponent it is standing on to be NetAddressable (I’m a bit vague on the details of why, but otherwise you’ll get a ton of log spam stating that the thing the player is standing on is null, since the Server and Client can’t agree on the NetGUIID of the component being stood on) so if you add that to the RuntimeMeshComponent in use with CashGen it might work fine without much modification. I’ll see if I can confirm that this weekend.

@mid_gen: I’m going to add a new generator that isn’t noise based, but just takes a distance function and an array of splines. I plan on using it as a selector so I can specify connected playable areas where I can place things like buildings, while surrounding them with pretty scenery from the noise functions. Sound reasonable? It will be a bit slow compared to the noise functions.

To make multiplayer work, I would have a WorldManager per client, and add functionality so that when two world managers intersect (as the players get close to one another), overlapping zones are only built once by whichever client navigated to that chunk of space first.

I’ve not dabbled in UE multiplayer yet though, I suspect the instanced foliage stuff would be a bit of a nightmare. I will look into it down the line.

Sure, as you can see there’s not a huge amount of code. I want to implement a Voxel version of the ZoneManager actor at some point, so I will probably do a big refactor and create an abstract ‘ZoneManager’ class, convert the existing code to a HeightMapZoneManager : public ZoneManager, and add a VoxelZoneManager.

The interface between WorldManager and ZoneManager is fairly light, although there are a few nasty direct accesses of public members between the two that I’d need to abstract away.

Ok after a bit of thinking and talking with Woppin, I’m going to make a branch and refactor the plugin a fair bit. Things to do:

  • Do away with the ZoneManager Actor
  • Replace the zone manager with a UObject that is purely responsible for generating heightmaps/zone mesh data
    This class will have a generic base so different mesh generation algorithms can be swapped in and out
  • WorldManager will contain :
  • Array of ZoneManager UObjects
  • RuntimeMeshComponents
  • Pool of of LOD data structures and corresponding RMC pointers
  • Foliage spawning component

This should make multiplayer implementation a lot easier for starters.

It’ll save a shedload of memory as instead of maintaining complete mesh data structures for every LOD + zone, I’ll just have a pool big enough to use for current in-process generation jobs. This should give a 99.5%+ memory saving on the demo scene.

Foliage spawning will now be done at the world level, spawning in a radius around the pawn, this’ll save a ton of draw calls and duplicate ISMC components.

Also going to switch to a single re-used worker thread for mesh data generation instead of spinning up a new one all the time.

Shouldn’t be too big a job (hopefully). There’s only about 1000 lines of real code in the plugin.

Hey mid_gen, that refactor sounds like a good direction. Also, that LOD dithering… bad@$$. Keep up the good work!

is this is one of those Blueprint things that you can type in a Random Seed value and it auto generates all the landscape for you? Or you can add in rocks and other stuff and have it a random seed to scatter it ect…

If this is all done in just only blueprints, I could certainly use this in my game for doing the alien worlds. Save me the time having to
create the landscape. What about choosing Layers also for the Texturing of the landscapes?

This is a C++ Plugin that has blueprint bindings so that artist can use it as well :slight_smile:

Arghh drat, everytime I go near C++ it threatens to rebuild the whole engine, Epic says any changes to the engine we make, it won’t work for other engine versions and that the engine code must be kept the same for it to work for other engine versions so this is more like
the same rule they use for root bones, for the Skeleton, there must be only one root bone for all skeletons, and all skeletons must have the same bone hireachy. Because of this I have to write my game out in blueprints and can’t touch C++ because I don’t know anything about it,… I already have most of the game already written but its in windows script form, not in blueprints and its not a small game… (Easiest.). Unreal 4 is not really suited for huge large outdoor areas or will cause engine slowdown unless you can level stream it in somehow, but this plugin looks interesting, although you can do a fade in to hide all the drawing of the landscape…

Heh I just saw this - I think the origin is offset by the distance from the target pawn to the corner of the world. I can see it in my spline testing really clearly because the spline is at 0,0 but the corresponding modifications to the terrain are way over in the corner several km away, but I haven’t tracked down where the bug is yet.

Edit: My attachment got eaten…

https://imgur.com/a/6DfRH

This is a spline mask generator that’s somewhat working that might be nice for inserting playable areas with less rough terrain, roads, or other things that should be manually specified rather than procedurally generated. In this example it’s being used to blend between a constant terrain and a rougher, fractal noise terrain. It’s not perfect particularly in areas that are very convex, because it’s using nearest distance rather than some sort of projection from spline space to make things smoother.

How would you get a 3d noise value in code? Are there static method calls or do I need to have an object of it? What text should I use in the Build.cs to be able to reference the proper include files?

I’m having trouble instantiating an object of UFastNoise. I’ve added UnrealFastNoisePlugin to the build.cs and I include #include “FastNoise/FastNoise.h” Any ideas why I can’t create a reference?

I’m getting this error when I try the above.

unresolved external symbol "private: static class UClass * __cdecl UFastNoise::GetPrivateStaticClass

There are some blueprint helper functions for creating noise generators. ‘Create Fractal Noise Generator’ ‘Create Cellular Noise Generator’ etc. You’ll need to make sure you hold a reference to the noise generator in the WorldManager-derived blueprint otherwise the noise generator will get GC’ed. Should be included in the sample project.

Away this weekend and still scribbling down a few different ideas for the big refactoring job, so not likely to have any updates for a couple of weeks…

I’m not able to create a reference to UFastNoise object in c++. I added UnrealFastNoisePlugin to build.cs and I’ve included FastNoise/FastNoise.h but when I compile my project I get

error LNK2019: unresolved external symbol "private: static class UClass * __cdecl UFastNoise::GetPrivateStaticClass

Has anyone had any success using the plugin through code? I cannot figure out what object to create. I was trying to create a UFastNoise object at first, then I tried including the UFNBlueprintFunctionLibrary.h and using one of the static methods to return a UUFNNoiseGenerator object. I keep getting Unresolved External symbol.