Golf Project – Map Generation Pt. 2 (Modifiers & Tools)
Ok, part 2. Here’s what we can do so far:
- Generate a path that follows multiple points along a spline
- Fill out that path with a mesh based on each point’s preferred distance radius
- Add a mesh collider
All that looks like this:
And that’s it. Not golf courses yet, but a good start; we’ve at least got a flat plane of ground that can be easily manipulated. To achieve interesting terrain, we’ll need a few extra modifiers. First off, height modifiers; ways to add hills, bumps, or pits. These are achieved by using point modifiers with a basic radius, and extra interpolation curves / offset rules to have control over how strong the height influence is. Examples:
Same course as above, with no modifiers.
The course, with some small bumps on the right, and then a subtle hill on the left.
The course, but from an even angle, with debug draw for the height modifiers turned on. The two larger ones are very small offsets that work over a large radius.
In addition to small height differences, we’re also going to need terrain differences, and hell; terrain physics at all! The solution I ended up going with for encoding terrain information into the fairway was to use vertex colors. Since the fairway mesh has to be extremely granular in order to represent subtle hills and bunkers with accuracy, we know for sure that there will be enough vertices for vertex colors to be precise enough to use (this wouldn’t be the case if we had well optimized mesh topology, for example).
Here’s a visual example of what that ended up looking like for us.
A different course, showcasing a few different terrain types.
The previous course, but with a debug draw for vertex colors turned on. Bunkers are green, rough is red, and the putting green is alpha (not visible)
The previous picture with debug draw for the terrain modifier points turned on. Some of them are wobbly-looking, thanks to some polar coordinate tech on the radius.
Both of these two modifier types are point radius modifiers; they only modify any vertices contained within their radius, and modify them based on their distance to the point’s origin. Only having spheres is a little limiting, but the distance calculation is very fast.
Next up is map randomization. The way I ended up implementing this was pretty straightforward; a series of components that can be placed on modifiers & fairway path objects, with parameters for randomizing size, position, and whatever else. Then, before the generation step, we go through all these components and shuffle their objects around according to their parameters (and a global random seed). Example:
The same course as above. Note the flag denoting the hole’s position.
The course being repeatedly regenerated. With each generation, the positions of the two bunkers and hole shift slightly from their origin.
At this point, it’s possible to make more engaging course designs. However, all if this is for nothing if the process of making a course is obtuse and irritating, which, in the beginning, it certainly was. To alleviate this issue, I added a custom editor window for mapmaking. I was also the primary user of said tool, so I found myself frequently adding new parts to this window every time I added a new feature. Here’s some small demos:
A small demo of the previous course being modified, but with the editor window onscreen. I’m able to quickly push, turn and shrink the course, and then add a new height modifier with one click, then moving and resizing it within the inspector.
Another demo: creating a brand new course, adding new path points to it, moving, rotating, and resizing them.
I have a lot of ideas on how to improve the tools further, but for the level of map polish we were initially targeting, I think this is adequate. Barring some extra polish features (adding trees / other objects, generating some surrounding terrain, and multi-fairway island support), this is where I stopped on this particular feature. Let’s bring up the goals from the first post and see how / if they’re being met.
#1: Quick, simple & flexible mapmaking tools for making golf courses.
#2: Map data that can be procedurally modified and randomized.
#3: Map mesh collider physics that are precise enough for golf.
#4: Fast map transitions.
#2 and #3 are definitely handled at this point. The basic editor theory holds up, and the map collider mesh is definitely dense enough (and could easily be made denser if need be). #4 is a question that can’t really be answered definitively at this point, and there’s assuredly a great deal of optimization I could do for mesh generation. Currently, maps generate pretty quick, so that’s a good sign.
Out of all of these, #1 is, in my opinion, the one that still needs the most work, and it’s not specifically just improving the tools; it’s making the courses appear more natural, automatically. Right now, without excessive touch-ups on terrain using modifiers, all the courses look too smooth. It’s fine for this stage, but figuring out how to add enough noise to the process to make things appear “natural” is my #1 priority for this system going forward.
Some other final notes…
- I didn’t go into detail here, but if you look at the left-side gif, below, you’ll see that the courses have little sandbars or cliffs underneath. I spent a little time figuring out how to generate them alongside the course (I call them “terrain skirts”), and it was a small thing that added a great deal visually; certainly something I want to expand upon a great deal in the future.
- You may recall in the very beginning of the first post, that I mentioned being able to use vector shapes to define the course, but ended up only using points and splines. I thought early on that supporting full vector shapes to define things like bunkers and hills would be more trouble than it was worth, but now, I think it’d be pretty useful to figure something out for specifically terrain, at least. Seems difficult, though.
- Finally, at some point when I was discussing this system with an engineer friend of mine, he asked if I was intending to include a level editor in the shipped version of the final game. My reflexive answer was, and still is, hell no that’s too much work (and also how am I gonna stop people from making a legion of dick-shaped courses). I do think it’d be neat to support some amount of custom mapping, though; I could see a future where the course prefabs become their own custom JSON-like serialized structure, and then add a “Custom Maps” folder within the game’s file structure where you could add your own. I think I’d also have to provide a standalone version of *some* of the editor tools in a Unity project, to make it less painful for modders, but at least that way I don’t have to re-engineer half of Unity’s inspector.
That’s it for my posts of the map generation system! Here’s some of the courses in the game so far:
Some of the playable courses in the prototype.
The finished version of the main example course from earlier.