Project Janus - Procedural Level Generator/Third-person Shooter Prototype

Hello all,

Figured I’d share what I’ve been working on the last month in my spare time. Currently the title’s just a working title, and the final form might not even be a third person shooter, but it’s where my prototype currently is leaning towards.

The main concept being that the level’s are generated via a custom blueprint script I made that out of a specified grid size. From the initial seed, it will then figure out where to place roads, where the player should start(currently on the tile that has a road going to the edge of the map), what objective type this level will contain (Eliminate enemies, disarm bombs, stop the bank robber, protect the civilians from UFOs, etc. as possible “objectives”), and then use that selected objective to determine the required type/amount of buildings, enemy spawns, and any special objects. The game will then ensure those min requirements are created while also adding to its randomizing when beginning to fill the tiles after the roads are generated with various pieces such as buildings, forests, parks, etc.

The way the building/forest/park/etc is generated is by pulling from a list of actorsubclasses, so it might decide on the left sidewalk of the road to select template layout 3 for the straight road, which is a zone composed of 5 random building locations. Within that zone’s function, it determines it only wants to spawn 3 out of 5 buildings. Then for those 3 it will pull from a global list of buildings that fit in the space, currently its random but later it will be random, remove until the list is exhausted like pulling numbers out of a hat then reset. Once it determined a building, if that building has variations of it, the game will choose one.

I was inspired a bit after reading about X-Com 2’s development process on their procedural levels, so while there are tiny chunks of content "hand-crafted,"the game will decide how to stitch them all together. While also adding in special “features” besides buildings, such as an invisible grid actor that can be parented to any of the tiles and cause a scattering of tree instances to be created, grass to be generated, a box volume actor that can be added to the buildings in order to destroy any grass/trees that might of been generated inside its volume, etc.

Currently my testing idea is that of a sort of mix between a tactical police game like Swat 3 and a traditional third person shooter; where you play the role of a deputy sheriff and have to arrest or neutralize the generated crime of a particular level. So level 1-5 might be to stop and arrest the convenience store/gas station/etc robber, which later escalates to an increasingly lethal list of objectives such as warrant serving, gang-activity, bank robbers, crazed gunman, find and defuse the bombs, vip escort etc. With possibily some strange occurrences like zombies on the in-games Halloween or a bit of story to serve as a pause in-between missions; inspired a bit after watching Twin Peaks.

It’s currently more of a wrapper than the determined game theme though, for all I know the final prototype form might be red vs blue in a medieval village.

Anywho here’s the very first test after 2 days since starting the project, where I was focused on seeing if a simple procedural generator based on a collection of randomized elements with a bit of handcrafting for the smallest pieces could work and not take forever.
https://youtube.com/watch?v=D4HrPkGosqM

And here’s the latest test today: after modeling and implementing some models, grass actor, AI that only notices its enemy if within the angle of a conal sight, if not will react to noises, determines enemy by going through list of current enemies and calculates highest score of closest to, if saw recently/can see, did damage to me; a new basic character model’s form along with eye blinking, head turning to target, re-targeting animations, hit reaction, ragdoll, blood effect, bullet decal, grass that won’t appear darker on the back planes but still receives dynamic shadows due to normals being set to up and non tangent spaced, etc. Camera/player also auto switches between orient to movement, and face camera’s reticle if recently pressed shoot or right-clicked for shoulder-aim.

All the character stuff took a bit of time to get working to a decent form, but now it’s time to focus again on the map generator and the creation of simple mission objectives/building interiors/etc. One idea is the mission objective creator can layer in new objectives, or even “invisible objectives” while the game is being played, so if the player kills say 3 out of 5, enemy reinforcements are triggered to spawn and run in from the maps edge with heavier weapons, criminal is fleeing, bombs are detected etc.
https://youtube.com/watch?v=Q7xgLIW2fYI

Hi Deathstick,

I like what your doing here. Proc Gen is awesome. Art style looks fun. Game mechanics look tight. Keep up the great work!

Hey @Deathstick - got a bit of a request.

Would it be possible to get a screen cap of your Blueprints used to generate this or share them via https://blueprintue.com/?
Just curious as I am wanting to learn more about Procgen in UE4.

Hey all, thanks for the kind words! It helps with the motivation :smiley:

      @franktech currently the navigation mesh is set to be fully dynamic and so far I have no problems. Take's about half a second or less after pressing generate for the 2x2 option which is still a pretty large space, the 4x4 option is enormous and takes a few seconds longer but you can't tell since it's all done in the background, and I'll probably set it up so that when a new level is destroyed/created, there will be some sort of nice camera transition that'll give the navmesh a couple of seconds to generate before enabling the AI. Such as the camera going into an overview, then transitioning down to the player in the very first test, following a police car moving into the gameplay area, or a simple fade-to-black for example. We're still talking a few seconds max though, so the transition will be more of a game polish thing with navmesh finishing generation during the time as more of a little bonus.

I will say I did have issues with the navmesh on a different more expensive generator I did awhile ago for a different game prototype, where the game generated 200x200 individually destroyable instances with a large tile size sort of like rimworld/minecraft; but that was mostly solved for that particular example just by finding the sweet spot in the navigation generator’s project settings of how big the sizes/tightness/chunk size the navmesh would generate. Generally the larger the area, the larger you’ll want the navigation mesh’s chunk/misc settings to be. Though I doubt I’ll run into that issue with this particular game since it deals with relatively small-medium map sizes, there are other tricks you can do for larger games such as navmesh generation around Invokers, moving the navmesh volume periodically to the players position(haven’t actually tried that but it might work), or having the AI fallback to simple vector/position updates or node pathing if outside of the navmesh for an open-world game (think fallout/elderscrolls, where its a mixture of navmesh and nodes/hints, and how the AI “walks” across the whole map via their AI Schedule. I’m pretty sure they don’t actually physically walk when out of the players loaded cell area, the game probably just does simple vector math projected to a grid of the world size, and then loads the AI/spawns it at a point in the cell if the projection is detected to be within a loaded cell by the player. No idea if that’s how it does it though, just a guess.) I think at one point for that specific project I was considering using breadth-first search to find a path using nearby points instead of using the navmesh, but scaling down the size of the map for that project and increasing the navigation mesh cell/chunk sizes seemed to be good enough.

Making a new level literally just calls a function that destroys all child classes of “GenericCell”, which basically all structures are some child of in a tree, or an actor is a child component of a GenericCell child so everything is destroyed; as well as destroying all actors of class humanoid which the player and enemies are based from. Since the level generation and even player assignment all stem from functions called from an initial map generation event in the game mode, calling that event once causes everything to be rebuilt again from a new seed. Oh, and map layout/buildings/etc all use randomize from stream whenever any randomizing or shuffling occurs, the exceptions being grass instances (because why bother) and enemy AI. I’ll probably split certain functions to not be from the seed though, such as specific enemy placement so if the player dies and the map reloads from the same seed, the enemies initial positions can be a little different. I like the whole seed stream thing though, as it’ll give me the option to have a mode where players can share seeds if they wanted, test out changes to the procedural design, or specifically force the game to use a specific seed in an order of difficulty or a tutorial/intro series of levels.

I also plan on the actual progression of the game using specific parameters in the initial generation as the levels progress. So just as an example, missions 1-5 would maybe use a “low” enemy setting of 1-4 possible enemies with pistols and smgs as their weapons, levels 5-10 3-8 enemies, 11+ 10-20 etc. Or make it so the level settings tend to favor a percentage/pick an option out of a hat until it’s empty before refilling. So say out of a list of 7 options there’s 3 robbery, 1 bank heist, 2 investigate murder missions, 1 diffuse bombs, it’ll randomly select from that list and remove element until the list is empty; preventing things such as the player having a horrible random percentage chance where they roll 20 robbery levels and never even got to play a bank heist mission.

      @HeadClot My procedural generation is split into a bunch of smaller functions across multiple classes, so it would be a bit hard to share as a simple screenshot. I will tell you Epic's video tutorial on procedural generation is what first got me started doing this sort of stuff awhile back which you can find here: https://www.youtube.com/watch?v=mI7eYXMJ5eI&t=660s

I also tend to rely on a specific math function which can turn an array’s element index into physical x, y coordinates, as well as do the opposite to take an x, y value and convert it back into an index. It’s a very useful math function as its insanely faster to specifically identify an index from the start, rather than finding a specific coordinate via a foreachloop with break function. You can find where I found the math I used at this link: math - Treating a 1D data structure as 2D grid - Software Engineering Stack Exchange

I’ll also mention since my cells are based on very large road pieces, it’s easy for me to fill a large space without having too many active actors/collisions/whatevahs. (I think mine currently is about 200 actors for a filled 4x4 scene?) But if you have very small tile sizes like minecraft, or anything that needs large numbers getting into the thousands, you’ll want to use instance static meshes. And if you need those instance static meshes to be dynamically built/destroyed during runtime with no lag spike, you’ll need to split those instances into chunks of 100 elements or whatever instead of having 20 thousand entries in one instance (as instances technically have to recreate everything each time an instance index of it is created or destroyed, recreating 100 in a frame is much faster than 20,000) Which is why you’ll see things like quadtrees/tile chunks/whatever in games like minecraft or spore. I mention collision, because collision can also become expensive if you have ridiculously large amounts of objects with collision turned on. I wouldn’t worry about that one though unless it becomes an issue, then you’d have to look into simplifying your collision or disabling collision on objects far away.

aeb57ef5610d98bb1e542d46697b836d89d0ae4c.jpeg
You can sort of see in this screenshot how the game relies on a grid, and depending on that grid will assign a specific road. In this case it made everything a road, so it filled up with X-Intersection pieces, as each roads adjacent/nearest neighbors in the grid were also marked as roads. And then the road spawns a grass and silewalk built to fit on one corner of that XRoad, and since the origin of that actor is offseted to match the center of the intersection while placed in the corner, all the road does is spawn the same class 4 times, each time rotating it by 90 degrees so all corners are filled. The straight road piece does the same, except it spawns 2 sidewalk classes built to line with the straight road, and rotates the second 180 degrees. Then the children classes of these sidewalk/zone classes will be filled with buildings or trees/whatever.

Later I might expand it so the game will include dead end roads and 90 degree corners so it’s not all just X and Straight but that’s another “addon.” Zone height varation so roads slope up or down might be nice too, but I’m probably going to just keep that in the nice-to-have pile instead of required-features pile. If I do add any Z-axis to the height it might be just on empty forest tiles, or if I decide to make a border/background LOD for the game so the view distance isn’t just cut off. I probably in that instance would make a new zone creation method based around spline meshes, where an intersection would be a flat/level cell, where as the spline end points would match up to it and raycast downwards to align with the bordering terrain height.

Additional bonus is Operation Sour lemon is just a randomized name pulled from a CSV file, inspired from X-Com’s loading screen mission names. Final polish type stuff if it was a police game in the end would be to randomize names and assign them to the suspects at the opening briefing. For some reason giving names to NPCs just seems cool to me even though its such a simple function, such as in RimWorld or your soldiers in X-Com. Perhaps the game saves the names and appearances of an arrested suspect in an array when a mission is completed, so 5 missions later you have a chance of seeing him again or have him spawned in at an inbetween mission police station? Food for thought on how I might add some flavor further to a procedural shooter :smiley: I guess that would fall into making a “story generator” that pairs with the mission generator as well. E.G. game generates the Purple Tiger Gang who favor mac-10s, pistols wear purple, and only appear during drug related-missions while the Fancy Professionals carry mostly shotguns and assault rifles, suit and tie, and tend to spawn on bank heists. Complete enough missions and the gang is locked up forever/new one is created. Also would have to be tied into a sort of Law-And-Order template that tracks time and seasons, so 5 months later, game is in the winter at night, and Jimmy who you arrested 10 missions ago made bail and instead of becoming part of society, decided to rob the nearest gas station for the thrill of it all. Darn it Jimmy!

And with that, I have typed too much and should get back to focusing on basic building interiors :smiley:

Np!

Spent a bit of time today messing around with some very early tests on seasons/weather, which I’d like to be in the finalized game. It’s really too early to actually be working on it but meh I was having fun with the distraction :slight_smile:

Concept would probably require me setting up a material parameter collection for rain/wetness, dirt blend, snow lerp, and a season lerp to adjust colors of say the grass during the fall. Rain/wetness being used to lerp or blend in a lower roughness value or multiply a wet texture on top, as well as slightly darken the current color/texture a tad to give off a more wet look (roughness being more obvious when a texture is darker). Snow is super-duper early/will get redone, but right now is a world space/tangent disabled world tiling material so any meshes I intersect with the ground plane will have no seams from the tangent normals. I’ll probably have to revise that though to see if I can get some tangent information in there for fresnel/sparkling snow effects.

The whole weather/season along with time-of-day presets would be tied into the concept of time passing in-between missions to help give off a sense of a career or story progression (e.g. Jimmy got arrested 3 winters ago). I could make the time-of-day actually change during the map’s runtime, but unless there’s some specific gameplay mechanic that requires an active cycle I think I’ll aim towards setting up specific preset lighting conditions to get the most interesting looking results such as day, dawn, dusk, night, as I’m not a fan of certain real-life conditions like a straight down sun or no real light shadow source before the moon rises. But meh, I’ll figure out whether I go preset or full dynamic at a later date. I definitely have to get some sort of law and order or 24 counter at the beginning of a new map though, basically a necessity :wink:

Oh, and started working on a couple props to help with setting up the scaling of the interiors. Here’s a CRT Monitor/desk that’s still early. I think I’m aiming for late 1980s/early 1990s to 2000 for furniture since Twin Peaks is one of my current inspirations and the earlier bits of CRT Monitors/tube televisions/VCRs/large telephones/etc go better with the current chunky stylization the game seems to be leaning towards. It’s also a time period which fits into modern weapons/technology, but not being too modern as to retain a slightly nostalgic world stuck between self-contained communities and today’s more globalized environment. Gotta add in dem’ suburban houses complete with newspapers by the picket fence!

Think Twin Peaks, Better Call Saul/Breaking Bad, Early Law And Order, Friends, Seinfeld set dressing.

Anywho, time to quit being lazy with distractions and focus on finishing the basic building tileset before I screw around any further :smiley:

Worked on making some modular pieces for the buildings, though after working on it and testing in game I’m debating whether to just make each building their own model in Maya, and add props to the structure in Unreal to get around having to deal with seams being kind of a pain to hide with distance field AO, as well as cutting down on the draw calls; just leaving holes for breakable windows/interactive doors. Small modular walls similar to the ones in oblivion seem to add up on the draw calls rather quickly, though if it becomes an issue I guess I could always write a function that converts all staticmeshes of the same mesh into an instance at level generation. I definitely want to rewrite how my grass instances are created at some point/automatically split it into smaller instance chunks and either generate a few per frame until empty/done or generate dynamically around the player, instead of the current generate all the instance locations at the start as that adds a couple of seconds to the initial level.

Added in a smoke puff and tiny mesh rubble particle effect in addition to the bullet decals to make shooting look a bit more visually interesting. While working on figuring out how I’m going to set up translucent windows for the buildings that you can enter, I realized that they currently don’t seem to support decals which is kind of a bummer, as well as being rather costly. I think for the windows I’ll stick with one of the cheaper translucent shader options, and just put alot of work into the color and opacity map to make it visually pleasing while not being so expensive. I noticed decals don’t work and the glass is mostly diffuse while staring at the windows in Battlefield 1 which also uses a differed renderer, so I’m guessing that’s the best compromise/just make a mesh particle effect of glass shards+glass hit sound+set g lass window mesh to be a destroyed model after taking damage.

Doors are also implemented after having converted them from one of my older mini projects (comes complete as a child off of my interactive class, which includes functions for health/damage/destroyed/used custom events, so it’s easy to make windows/doors/whatever requires either taking damage or a simple interactive function just by casting to the same parent class) It’ll be interesting in tackling getting the dynamic lighting for the interiors to look nice while also being optimized, currently I’m using the lights as a child actor blueprint so I can adjust any settings for all the buildings by altering one preset. I wonder if a post process volume might be called for in transitioning from exteriors to interiors.

Also messed around in FL Studio today to compose a new possible soundtrack for the game. Genre might change depending on what fits the best/might end up going with stock music in the end as quality takes forever, but it’s always a nice break to mess around making music for awhile.

Soundtrack examples

new WIP track: Stream Artemis Song 2 v1a by Anthony Russello 1 | Listen online for free on SoundCloud

one of my tracks from a few months ago that might work: Stream Artemis Western v2 by Anthony Russello 1 | Listen online for free on SoundCloud

another slower paced one:

and lastly a bit more of a over-the-top combat one, that needs alot of work/might not even use. The bright side about music is its fun to open up old unfinished songs and hear them with fresh ears to see if there was anything worth keeping:

Read an article about how music fading between states is usually handled, I’m thinking later on when I actually require music in the game (don’t really need it atm for gameplay) that I’ll look into “vertical remixing.” Here’s the link if anyone’s curious, was a nice easy read with samples provided: http://www.designingmusicnow.com/2016/06/13/advantages-disadvantages-common-interactive-music-techniques-used-video-games/

Well, I probably should of made my project thread title more generic haha.

Anywho I’ve moved on from the procedural shooter prototype due to a variety of reasons, ultimately due to it coming to light that the game’s systems were getting a bit overtly time-consuming and complex versus what the end product actually would be. E.g. spending weeks on features that are barely noticeable to the player while also having to create a lot of art assets. I think there’s still potential in the prototype, but it’s not the safest bet to work on when I’m on a limited time budget.

The latest prototype is now a comparatively more simple game inspired by Stardew Valley, Harvest Moon, etc. with the most complex systems being the plant growth stages/farm tile grid, contextual based actions, and player item inventory / stores. I enjoy how these types of games revolve around a relatively small self-contained town while adding on to the amount of detail and functions a self-contained setting can have in comparison to an open-world, while also allowing the player the ability to plant/construct/harvest on their own property. The current task is to make sure the farming-> item management -> store management are implemented upon a solid foundation, and then expand off from there in making the neighboring village, NPCs with a day/week/month schedule and dialogue, and additional features like fishing/festivals/boating/combat/etc.

Anywho I’ve got most of the foundation laid off on the initial farm plot generation, ability to till grass to dirt, plant seeds in dirt, water, and have them grow over time while being optimized on its own cycle so technically 10,000 plants can grow in semi-realtime without there being any drops in framerates. All trees/grass/plants/rocks/etcs are instanced meshes. Tree log items are technically actors with physics turned on, although I did implement a special limiter that starts to remove the oldest items dropped on the ground when reaching a numeric threshold, to say prevent the player from lagging the game by leaving thousands of individual items with physics on the ground. I could technically probably change it so after physics are settled its converted to an instance mesh, and back when the player is near, but meh that’s a bit over-complicating things when a hard-cap limit of 200-500 logs works just fine, since Items left on the ground in most games end up disappearing anyways. Item management between player’s inventory and how the buy/sell at the store would work was a bit tricky, but came much easier after I decided to handle them as generic item structure arrays with fixed sizes. Store UI/player inventory is also pogrammed to automatically expand depending on what I add to the stores inventory list, or how many stacks of items the players inventory can hold. (Currently just 3 for testing purposes to make sure the rules work)

Here’s the vid:

Did anything come to fruition with the Stardew Valley game? Both game prototypes look amazing!