Player Interaction with the "ground"

I am looking to develop a project that will use a large mesh representing the “ground” and I want the player to be able to interact with it in a way I have never seen before. I have been doing some testing and have come up short and though I would ask around in here to see if anyone else had any ideas.

Maybe I have never seen this because it isn’t feasible to do from a performance standpoint, I don’t know.

So we have all seen footprints on the ground. They appear behind the player and fade shortly after he is gone. This is not what I am looking for.

I am looking for something much more complex. I want footprints to stay in the world, and the more people walk this same path, I want to store a value, and constantly update that value each time it is walked over again. The more that spot is walked over, the higher the value gets.

Eventually as time passes - if there is enough player traffic I want a path to form. this path’s intensity is based on the values stored in the map created by the players walking in that area.

The end result is a naked world free of paths, then as the game progresses, players find the best ways from point A to B and always run that way (regardless of the roads and paths build by devs - ask yourself how many times you followed predefined roads in something like WoW") Normally the players cut corners and go their own way.

First I would start by lerping in a new material re represent dirt instead of grass, but to take it further, I would also edit the mesh to form a depression that would continue to deepen until it reached a max depth set for paths.

What do you guys think?

As with a lot of things, it’s certainly possible. The question you should really be asking yourself is, how many CPU/GPU resources are you willing to allocate just for this feature? If it’s a key part of your game, go for it. If it isn’t, then you may want to think about how much it will affect your performance.

In a big MMO type world, it would require quite a lot, on a per player basis.

Basically you’d have to sample your mesh/heightmap based on a recurring poll to your player character’s footsteps. You’d then have some sort of data structure attached to your surface which stores the values and feeds the shader the parameters to blend between dirt and grass, then on your mesh level you’d do the deformation using that data.

My honest opinion? Unless your game is all about building paths and roads in such a manner, this isn’t worth it. There are probably better ways of “faking” the effect you’re after (though I can’t think of any but you should spend some time thinking of ideas if it is important to you).

hehe :slight_smile: without tipping my hand, it is the focus of the entire game, I had to use a mock example of someone walking on the “ground” to get my point across.

As I suspected, this will probably be a performance hog - I have this fleshed out currently for testing. I am just not getting the results I expected, the amount of data points I need in the ground mesh is going to be very high in order for the player to actually make contact with them at a decent rate and not miss them all the time creating a very “choppy” effect.

I just didn’t know if there was maybe a more efficient way of storing data :slight_smile:

Maybe this would help ?

Impact Deformable

1 Like

IMO, this isn’t something the client should be doing. The server should be tracking this data and figuring things out, then telling the client what to display.

As for showing the footprints, I wouldn’t. I’d use the same old disappearing footprint trick. The server can still keep the info, though. Otherwise, you’ll get griefers that make it their life’s work to cover every inch of your server with footprints and ruin the trails created by legit players.

To help combat griefers, you might also keep in mind that a path isn’t created quickly, no matter how much traffic there is. The plants are damaged until they won’t regrow, but they don’t disappear immediately. The killing process could be quick, or could take a lot of time.

If you really needed the footprints, it’d still be a server-side thing anyhow, though.

Nice! I will look into this!

It’s all a very complex system that takes the collisions into account. I will need to look at the players inertia and force values on the colliders to figure out how “much” to effect the terrain. So I suppose data collection from the client, do all the work on the server and update the client with the resulting effect. And yes this will be a slow build up over time. Conversely if X time has passed with no “traffic”, the mesh will begin to “heal” itself as if no one had been there previously. So for someone to grief - they would REALLY need to dedicate vast amounts of time to “upkeep” the path they have created haha :slight_smile: Would be interesting to see.

A couple of other variables :slight_smile: Ground moisture would lend itself to more “give” when players would pass over the ground creating the paths faster. Feet are also not the only mode of deformation to the mesh. Things could be dragged over the ground or rolled if there were carts and things like that, as well as horses and/or livestock. All having different mass and force as well as a difference between walking and running.

Also throughout time heavily travelled paths evolved into roads to allow for faster travel. That is the idea I am going for here. To give a player the options to take heavily travelled paths and “build” roads on them eventually.

In the end footprints are not really necessary but the path creation itself is paramount (and the way in which it is created)

There might be a better way but that sort of thing heavily depends on the problem you are trying to solve. For the example you gave you have alternatives. Instead of having a pre-made set of data points for the ground that have info about themselves (like how much they have been stepped on), you could simply use ray casts from the player’s feet to the ground and then at that point create a node on the ground object with that information. As a result your ground would not contain any nodes unless someone has stepped on them in the past, and the effect should be less choppy.

However like I said, how performant this is as a solution varies by your actual use case.

I imagine the psuedocode of such a feature might look something like this:

  • Create a grid of numbers of an arbitrary resolution, depending on the size of the map and the desired granularity of the dynamic roads. In C# this might look like “float RoadMap = new float[100,100];” I personally prefer floats for things like this, but you may want to try for “byte” if memory consumption becomes a problem. Alternatively, you could draw it as a texture, but I don’t have much experience with things like that.

  • Whenever a path-making agent (i.e. the player, wildlife, AI villagers, other players if it’s cringe an MMO) moves, check if they’ve moved into another RoadMap tile.

  • If so, increment the RoadMap tile by a small amount (RoadMap[x, y] += Agent.RoadWeight), specific to the agent. (an ogre would create more wear on a road than a deer, and you should always give more weight to the player so they feel like they have an impact on the world)

  • If the RoadMap value has changed significantly since its last graphical update, draw a decal in the world that represents the path.

Perhaps RoadMap isn’t the right name because it overloads the out-of-game concept of a “roadmap”, referring to a plan of future development…

But anyways, implemented like this, it’s not horribly performance intensive, but it’ll take a fair bit of memory, and it’ll do some computations at frequent intervals; it might also put strain on the GPU, depending on you implement the decals (I personally recommend using the terrain decal feature that’s already built into Unity - although I believe it’s meant for static decals and not necessarily dynamic ones)

What about using heightmaps ?

I do like Rico’s idea of raycast’s to create a point and then if that point is ever hit agian it will exist to begin with and then get updated. My fear is at the resolution i am after I will be creating many thousands of points with data structures waiting to be filled. The downside is that most of them never will be touched by a player. That was my original problem. It felt very messy to just create a huge empty dataset. I’m already using a raycast to get distance from objects to the ground. I can simply attach some extra code to that and create a point that will hold data.

I could also provide a range to find a point before creating a new one. if there are points within a reasonable range - simply update their values pseudo = this.value +=1 ( probably more of a float than an int but you get it )

This way I limit how may new nodes go down and just update existing ones if they are close enough. I like it, I could possibly run something that would also scan for close nodes and take an average of their values and rewrite the data of the main node and delete the others to keep it clean and fast.

Thanks!

My thought would be to actually feed the data from the nodes into a dynamic heightmap?? (need to research this), but it will take some work to get it to smooth the way i want it to.

For example if I feed a greyscale value of 150 150 150 into a pixel I would need to soften the surrounding values or I would get some ugly spikes. I’m not as knowledgeable with heightmaps as i should be though :frowning: might have to do some learning there. I’ve made some, but never really worked with them any further than bringing them in and texturing them.

It was just an idea… I never used heightmaps…

DallonF’s solution is more or less what springs to mind for me, too. This needn’t be hugely complex.

Also, Black and White does something similar to this.

I’m not sure if you want the recorded data to stay permanent or have them middled out over the time (You probably get the gist what i mean there.)

But in the over-time idea i would try looking in example;
If any data stored in arrays containing these steps once in so much time can get reprocessed to, in example a heightmap.

A theoretical example setup could maybe be;
From start, an empty heightmap (black/ value 0)
Data is logged and ’ flushed’ to this heightmap every 24h

reference data;
in 24 h about 2 million steps are registered.
we want to average the data over 8 days
data is converted from data matrix to 2 by 2 heightmaps (total resolution of 81928192 data points thanks to 40964096 textures)

For every pixel on the heightmap, the relative area in the data matrix should be compared against to the total amount of registered steps or somekind of average and multiplie.
An example could be;
Daily about 2 million steps are registered, for a specific area a total of 20.000 steps is registered.
Stats would be averaged on 8 days (after 8 days without activity, all traces would be gone).
HeightMapResult = (StepsRegistered/ReferenceSteps)*Weight
I’d guess a weight of 1 or more would be preferable…
HeightMap = saturate(HeightMap-(1/AveragedCycles)+HeightMapResult);

I have no idea how doable the implementation would be, found it interesting to try and think about it and share what i came up with :slight_smile:

Same here, I had a very simple idea in mind but as my team and I began discussing it - it got deeper and deeper. Hence the need for a much more accurate system than I had originally planned.

The difference between doing what has been done before vs. coming up with an entirely new (never seen before) way of handling this in game is the choice I have to make now.

The more I thought about it though - the more interested I was in it haha, same as Annihilator.

Could be very cool! or flop! who knows! This weekend I plan on making significant progress, wish me luck and thanks for your feedback guys!