How to approach forests in a strategy game

Hello,

I am wondering how to tackle forests in a strategy game. I want trees to grow and die over time, with the option of being cut down by workers. Will this work with the foliage tool [1] or do I need to create my own system? I played around building a blueprint for a tree that will grow over time, spread offspring and eventually die, but the game becomes quite laggy with around 1,000 trees ingame, so I am wondering if I should use the foliage system even when trees are supposed to grow and die dynamically, or if there maybe is a another better way to achieve what I am aiming for?

Thanks in advance

[1] Procedural Foliage Tool Quick Start | Unreal Engine Documentation

If the events happen “on tick” that’s why the lag happens.

You need to create a forest manager that keeps the tick going and adjusts the instance pool accordingly.

Mind you that even with a proper instance loop the sheer amount of things to keep track off can cause a delay.
If you try and update 1000 instances at once for instance.

You should build the manager so that the growth steps have a maximum amount per tick and get pushed to a second call of they exceed it.

1 Like

Thanks, that makes sense! I did have a tick implemented for each tree. So when building a manager, can I safely ignore the Foliage Tools for landscape for my use case, or should I still try to use them for the forest for performance or other reasons?

I am worried for this you will eventually need to go C++.

Anyway, first of all, you probably don’t want to update the growth each tick, but let’s say at least each second. Then, you can always update only part of the trees each second, not all of them. For example just 25% of the trees just on the borders of the forest (borders of fully grown tree tiles) each second.

So let’s say you have 10 000 tree forest. Only areas on the edges of the forest are supposed to grow further, so you somehow mark those for update, that reduces it to maybe 1000. You then partition those 1000 to 4 update groups, so every second, 250 of them updates. So every 4 seconds, you will update the entire growth cycle.

From the graphical performance standpoint, I’d suggest just having some C++ based system which keeps track of the forest growth and visually, that system would be represented by Hierarchical Instanced Static Mesh Component in the game. So the trees in the simulation would be tied to the HISM instance indices (HISM keeps track of its instances using simple integer index values, which you can then use to efficiently edit and transform individual instances), and animation-wise, you could always just get an array of the trees to update visually, and modify transforms or other properties of the specific HISM instances.

This should give you performant solution both when it comes to game code and graphics code.

That being said, this is quite an advanced thing to pull off. It should be also possible to pull this off just with BP alone, but it will probably require truly expert level BP skillset to pull it off with good performance :slight_smile:

1 Like

Thanks, I want to focus on Blueprint exclusively for now, even though I am a programmer. The engine is so large that I would like to understand the systems better before getting into coding.

The HISM approach indeed sounds advanced, but I understand this is only for visual performance, so I would skip it for now, just for the sake of simplicity. I am still confused whether or not I should / could build the forest with the foliage system or if that would be counter-productive. Anyway I am sitting on a manager class now, that will do the updates on all trees, and only every second or so, instead of ticking each tree individually.

HISM is just a component you can add to blueprint, and use that to actually spawn the tree instances. So then you could just update the HISM instances with whatever the tree manager is doing. I’d expect HISM instances to be much more performant than individual actors.

It’s really not as complicated as it sounds. Simply add Hierarchical Instanced Static Mesh component to your tree manager class, and you will see it has functions like Add Instance, Remove Instance, Update Instance Transform, and so on :slight_smile:

1 Like

Okay after reading up a bit and looking around, this all makes a bit more sense to me now. Thanks for pointing me to the right direction. I also found this video tutorial that explains how to replace instanced meshes with actors for interaction, which was a bit of a concern for me: https://www.reddit.com/r/unrealengine/comments/kmg2pu/how_to_have_30k_interactable_actor_foliage_with/

Just for clarification, if I use HISM I will need one HISM instance per tree model that I plan to use, correct? So using different kinds of tree models will make the setup even a bit more complicated.

Also, is there a good way to place the instances in the editor? I found the “instances” node for the HISM, but so far I am only able to put the coordinates manually for each tree, which is kind of tedious.

Yes, you will need one HISM component per mesh. It’s not that hard to manage though. Especially if you just name the HISM components after the tree types. As for placement, yes, that one is more difficult. Basically it’s just a raw component, so it expect you to take care of placement. Whether you do it procedurally, or make yourself some simple painting tool is up to you, but both are advanced tasks. There’s no placement tool for HISM premade in the UE4. Since you talked about large amounts of trees for RTS game, I expected you want to be placing them procedurally anyway, since placing high counts of them by hand would be tedious anyway.

1 Like

Yes.
Its not hard to setup. And potentially you could use alembic geometry cache too.

You can check DynoFoliage: UE4 Interactive Foliage
For a fully working replacement system that transforms instances of foliage into actors at runtime.

For placement, just use a large brush with the proper settings on each instance. You don’t have to place them individually. And you can cover nearly a 1km area per click if you manually change the size of the brush.

Now as far as growt in an rts goes.
For spruces and single log trees its easy.
Set the instance to be almost completely underground, move it up over time.
There’s your growth.

For other species with split branches the alembic cache can help - but you do need to test performance as they may not get instanced.
Another alternative is to shift vertex via material - you do that in sequence, grow up to a swap, swap mesh, grow some more.

For mediterranean pines, oaks, and anything who’s canopy grow in size over time combining the 2 systems would help sell the effect.

I would say that if every tick you update 10 instances you’ll have a great end result at a crawl in a completed forest.
The manager needs to do the math though. Keep track of the growth from the “starting” state to current for each instance. An array of v3 is probably your best friend…

Note:
Your own hism implementation will suck performance wise compared to the foliage.
The systems partition for rendering differently and foliage is actually more optimized.

1 Like

If I understand you correctly, you suggest to use the foliage tools instead of my own HISM component / implementation, is that correct? At least I don’t know how else I would use the brush tool as you suggest.

Out of curiosity I worked with the procedural foliage component today and it seems to offer a lot of the functionality I want (age, growth and spread parameters). But I couldn’t find a way to access (add or remove) instances through blueprint and I also could not find any actual API documentation, except for the little walkthrough I included in my first post (is there really no documentation on the class?).

Is there a way to access, add and remove the foliage instances that were created with the procedural foliage tool? If yes this should allow me to build everything I want, without worrying about several HISM layers for different models. Ideally I could just “step” the procedual foliage simulation to grow my forest, no?

Thanks in advance

There is.
I haven’t gotten around to updating my plugin for it- mostly because those tools are all “beta” and I think they are about to go Bye Bye having been in beta for years.

Theoretically, using my plugin you can change the system to use the correct HISM for the procedural stuff and call it a day.
There are a couple nodes that would need fixing and what not, but its mostly similar/the same.

As far as the procedural tools - they can be great but come with their own set of challenges when dealing in world comp.

And, most importantly you usually end up using both tools in a game. Because the proc. Is great, but when you need a tree where you want a tree the only way is to place it by hand. Either as a mesh or as a foliage item.
I prefer to use the foliage tool to keep everything where it has to be… call it paranoia. A mesh would do just the same 90% of the time.

As far as the rest. Yes.
Definitely do not try to implement your own HISM system. Use what’s there to reap the optimization benefits and fuatrum culling that’s built into the existing things.
Procedural and foliage tool both.

1 Like

There is.

With Blueprint? How? I couldn’t find any way to access it and didn’t find any documentation or coverage on the topic.

mostly because those tools are all “beta” and I think they are about to go Bye Bye having been in beta for years

Yeah I noticed that, kind of odd. I guess in Unreal 5 things will be changed a bit and either they are in or out.

Theoretically, using my plugin you can change the system to use the correct HISM for the procedural stuff and call it a day.

Since I am still learning the engine I would like to understand how to use the engine systems correctly. If ever there is a playable prototype coming out, I will be willing to invest into quality, but right now it’s more trying to use the engine in the right way.

Definitely do not try to implement your own HISM system. Use what’s there to reap the optimization benefits and fuatrum culling that’s built into the existing things.
Procedural and foliage tool both.

Yeah makes sense and should also prove to be the easier solution, once I find out how to access the foliage instances myself. I will dig a bit more but any link is appreciated.

I think there’s some confusion. Not sure if you guys are talking about making own HISM type component from scratch, or utilizing existing HISM component and making custom placement system. The former is of course crazy and not suggested, but the latter is what I was suggesting.

I am not sure why @MostHost_LA is saying that HISM component doesn’t have culling. It has both frustum and distance based culling already implemented, with the distance based culling being even controllable. In fact both Foliage Paint and Procedural Foliage tools in UE4 use HISM under the hood, because there are several cvars that control HISM behavior which are actually named “foliage” :slight_smile:

So the only reason I can think of why @MostHost_LA talks about that is that you both think about something different. He thinks about writing something like HISM component from scratch, where as @NEVQ151 talks about using existing HISM component.

HISM is an an actor scene component which allows to render static meshes and instances. Unlike ISM (Instanced Static Mesh Component), HISM allows to do that with LOD levels, while ISM doesn’t. Other than that, they are nearly the same.

Foliage Paint tool and Procedural Foliage tool both use HISM under the hood.

1 Like

Yes correct I was assuming you suggested using the existing HISM component in a manager class, not writing my own HISM component. In the end I want to use the engine tools as efficient as possible for my use case. So the current question is, should I use the existing foliage system or implement my own system using the existing HISM component.

I would prefer to use the foliage system because it offers some simplifications over doing it myself, if only I know how to access the foliage instances from Blueprint to replace them with actors when needed or grow them over time. It also seems to be the “recommended” way. If the engine is already offering a foliage system, I should probably use it.

EDIT: I found this, which seems to bring in the missing pieces for me:

This gets me one step closer to building my forest :slight_smile:

First of all:


My ideas:
NOTE: I haven’t tried any of this, I’m just brainstorming, so it may or may not work. My main focus was on avoiding having to update the trees.

Meshes:
Instead of using actors for each tree, just use a single actor for all (or groups of) trees. Use mesh components for the meshes, and an array of structs for the data (or you can extend the mesh instance class in blueprints and add the variables in that). You can place them on a mesh or terrain by just using a line trace.

Updating:
You can avoid having to update or manage trees entirely if you store the creation time rather than the progress. Whenever it’s accessed (e.g. when it’s being chopped down), compare the tree’s creation time to the current game time, and this will give you the tree’s age (i.e. progress).

Rendering (this is a little iffy, so idk if this will work):
I’ve never worked with instancing, so this only deals with cosmetic stuff.

The problem now is that since trees are no longer updated per frame, we can only do material-side things (like change colors or world offset), but not gameplay-side things (like change meshes or materials), or else we’ll have to update them. So rendering is gonna have to be done solely through materials.

If you only have one tree mesh, and you don’t need anything fancy, then just animating colors and world offset should be enough. But if you want to have more than one mesh for different stages, you can try this: combine all the meshes into one single mesh (i.e. all meshes are overlapping each other in one file). Have a mask texture that tells which mesh should be visible at which stage of the tree’s lifetime (e.g. 0 = stage 0, 1 = stage 1, etc.). When the tree is created, set the creation time as a scalar parameter on the material instance. In the material, compute the age of the tree and use that to determine the stage, then compare the stage with the mask: if the mask is equal to the stage, it’s visible, else, it’s masked. This will allow you to “switch meshes” using only the material.

You can alternatively make a tree growing effect by making the tree appear from bottom to top over time (like an invisibility or dissolve effect), then animating the leaves using a world offset.

Chopping:
When a character chops down a tree, calculate its age and use that to determine how much resources to get from it.

Dying:
You can group trees with similar die times together, and only kill off trees in one group at a time. After the last tree from the group is killed off, kill off the next group.

Ticking:
My goal was to avoid ticking the trees altogether, but if you use the component tick interval idea, you can update trees gameplay-side every so often.

1 Like

Thanks, some good input concerning some parts that I haven’t thought through, yet, like how to position new meshes or handling tree lifetime events.

I am currently sitting on implementing my tree manager from scratch by using the foliage tools of the engine and the concepts we discussed here. I feel I am onto something and I will share some progress later.

Nope.

Try and duplicate a foliage system into a custom HSIM.

Export all the mesh/locations and import into the HSIM

Then bench performance, and enable the debug view(s).

You’ll see that the 2 systems are handled (at least as of .25) completely different internally. With foliage splitting up the batches much more intelligently then the standard HSIM component does - leading to a much better performance even with a unified field system.

I literally jumped to using the foliage system to place rows of corinthian columns because of the performance differential compared to a standard actor with an HISM component.

As far as the rest goes.

It’s not that complicated but there is no documentation on any of it, and the tutorial you pulled up from YouTube is a decent starting place for replacing at runtime. It’s just not efficient and you need to bring about a big number of changes to preserve performance.

The base concept is all the same.
Access the hism loop It’s objects, set their location. Or remove them - place a new object at its location.

Do you have any tests or reproduction steps to back it up?

The only thing I am aware is that grass tool works differently. That one asynchronously spawns instances near the camera, so it can cover much larger areas as it doesn’t need to decide all the instance locations ahead of the game start. But foliage pained by the brush (foliage paint tool) or foliage placed by procedural foliage volume from my tests behaved more or less same as HISM.

I would love to know more if that is not the case, but I can’t really reproduce that with such unspecific information :confused:

I am very interested in this problematic. As I found both foliage paint tool and procedural foliage volume to be insufficient in terms of workflow efficiency, so I’ve created a plugin to provide alternative:

And during the creation of that plugin, I was doing some performance comparisons, but aside from the grass tool, which works very differently and is constrained to be used with landscapes only, I haven’t found any significant performance wins on the side of built in tools.

I was literally benching between a custom actor with the component and the same meshes @ same locations VS the foliage tool with the painted instance (where the mesh and locations were extracted from).

The real difference was how foliage subdivided/partitioned the internal instances into different groups for drawcall culling.
(Think of it as HLOD since it’s essentially the same idea).

The custom hism wasn’t doing this.

PS: the plugin looks great, but are the draw calls being reduced by some sort of grouping system?
If they aren’t, then that’s one possible avenue of optimization…

A really simple solution to spawning and killing trees is, instead of actually spawning or destroying a tree, simply “reset” it. Essentially, under the hood, trees always exist (they never spawn and never de-spawn). “Growing” animates the tree growing, “chopping” animates the tree being chopped down, and “dying” animates the tree falling. When the tree is chopped down or dies, instead of destroying it, you simply reset its state back to “growing”. This will put it back in the ground and make it grow again. Of course, you don’t want a tree to grow right after it’s destroyed, so you would temporally disable it, or make the spawn have a delay in it. For performance, you could set the mesh’s visibility to false so it doesn’t render when under the ground (although, occlusion culling may do this for you).

The benefit of this is that the positions of the trees never actually change, so you don’t have to worry about positioning new trees (however, this is a downside if you want new trees to have new positions). This will also allow you to spawn the meshes any way you want (foliage tool, blueprint, etc.) since the trees are only spawned once when the level is loaded.


If you store a set of boxes across the level, you can manually cull groups of trees based on which box the character is overlapping. You still have to take into account the camera view, but this is a start (possibly use WasActor/ComponentRecentlyRendered on “landmarks”?)