David fixed the issue with the floating branches when you merge the tree. Mostly it had to do with getting quaternions right to handle the correct rotation.
We had another problem though, with the bands on the tree:
These are only supposed to appear at the base of the tree to indicate how many fruit cubes grow from it. I think Chris wrote the script so that it should only go on the trunk part, which should be separate from the rest of the tree.
Anyway, right now it is getting applied to the entire tree.
Lines are pretty important in Manifold Garden. They connect switches to doors or other objects, and a light travels through them to know when it has been switched on.
Originally, lines were made with separate individual prefabs.
Each segment had to be scaled and placed manually, and every corner needed a separate piece. Not only that, I also had to manually toggle the corner to invert the material if the bend was going the other way. The default corner material is for bending right, so if it was left bend, the material needed to get flipped.
The segments also needed to be placed in the right order, as that was how the line manager figured out in which sequences the lines should turn on. It was a bit of a mess from the code standpoint as well, with each line having to check the previous line to get the timing of when it should turn on.
Anyway, here’s how it was built:
As you can see, very tedious.
Decided to finally write a tool for this. Here’s the line mesh generator in action:
How this works is I bring up the tool, and I can select what kind of line (cube, button activator, or independent). The difference is that it will attach the finished line mesh to the appropriate object with the appropriate script.
Then, I just hit ‘P’ to place down the marker. There is also undo, which is great, as occasionally you can place the marker just a little off. David wrote the undo feature, but I believe it’s just using a stack and putting things on and taking them off accordingly.
A preview of the mesh is generated as the markers are placed down, and when you’re ready, just hit “Form Mesh” and the final mesh is formed. All as one piece, instead of multiple different segments, so much easier to manage.
The trickiest part was getting the correct offsets and UI for it. The actual mesh generating stuff is actually almost exactly the same as the mesh generation for water, which Chris Wade had written several weeks back.
The new water system actually generates a new mesh every frame, and simply updates the points of the mesh based on what happens. Because the water also handles bends in various directions (left, right, up, and down), the code for setting the vertices of the mesh was just what I needed for the line mesh generator.
The key for the tool was setting up markers as line is placed. They are restricted to be along the axis of the previous marker, so that you can’t make diagonal lines (which I don’t want anyway). Also, a marker doesn’t know which way it is bending until the next marker is placed, so there is some back communication.
After a tree is made by the tree generator, all the parts are actually separate individual components, parented to the object it spawned from.
As you can see here by the object hierarchy on the right:
This is necessary, because often I still need to do a bit of editing to the tree – removing overlapping branches, rotating trunk pieces, etc.
Once that is done, all the trunk and branch pieces need to get merged together, as well as the leaves, and then everything needs to have the appropriate materials and scripts applied.
There are also some additional considerations, such as adding the “tree base cube” – this is the cube at the base of the tree that the tree grew from, the soil patch, and also any cubes that are growing from the tree.
Instead of manually dragging the scripts and prefabs and placing them in the hierarchy, it’s just much easier to automate this with a tool.
Here’s what the tree finalizer window looks like:
A bunch of the processing is optional. In the case in the above image, everything is selected, and we’re generated 2 cubes to grow from the tree.
When you click to finalize the tree, a warning message comes up. This is important as the trunk and leaves are merged into separate individual meshes and there is no undo.
Here’s what it looks like when the tree has been finalized.
Note the hierarchy of objects on the right. There’s the “branch” object, the “leaf” object, leafShadow is an object specifically for the shadow of the leaf due to some weirdness with shaders. Note that there are two CubeSpawnPoints. They are both placed at the base of the tree so they’re overlapping. You have to manually move them to the position you want, but this is something that I wouldn’t want to be automated anyway, as the placement needs to be carefully designed.
Trees are a pretty important part of the core gameplay system of Manifold Garden. After all, trees are the source of the cubes, which are used to solve puzzles, bend water, and grow more trees.
Here are some of the tree designs:
All of the trees above were made by hand. You can see that the same tree repeats many times. I was originally planning to make 100 trees by hand. I made about 4, before I realized that process was not fun and also super tedious.
Here is how I used to build trees:
Like the old ways of building stairs and windows, it involved using ProBuilder and building each separate component, manually sizing and placing every segment.
Some people have asked “why not just create a set of 10 trees or so and randomize their placement?”.
The reason is because the volume of the tree matters a lot in a level. If there are only a set number of trees, I would actually have to design the level based around their volume, and the specific needs of trees vary widely from location to location.
A much more typical process for me is I’ll design a level, and then go: “this area needs a tree, but it needs to be 20x40x20 in volume, because of the setup of the level”. If I just have a fixed set of trees to choose from, it’s highly unlikely I’ll find a tree that’s exactly of that size.
Also, using a fixed set of trees can get pretty obvious to the player.
Anyway, the trees do follow a very specific ruleset in their look, so there’s really no reason that the process can’t be automated.
David and I decided to make a tree generator for this.
As you can see, it takes a lot of input. You can choose the probability for growing upwards, the probability of a trunk or branch splitting into two, the range for each segment (vertical or horizontal), etc.
The red outline box is the tree boundary, and the green outline box is the trunk boundary. The idea is that the trunk would never grow outside of the green box, and the tree would never grow outside of the red box. They’re kind of soft boundaries (especially the red box as the leaves can go past the boundary). However, it’s pretty easy to tweak, which is part of the tool design.
You hit “Generate Tree” to create a tree, and then if you actually want to make it a tree in the game, you hit “Actually Create Tree”. This allows me to go through a bunch of variations to pick out the one I need, which is really great.
Once the tree is generated, it’s actually all in separate parts, with each branch parented to the one it grew out from, so it’s quite easy to edit (or should I say… prune?) the tree and tweak it till I get exactly what I want.
It also saves the seed value, so you can always go back to the base design.
Here’s the tool in action:
The key with the tree generation algorithm is that each segment uses world coordinates to determine the direction. So the y positive is always up. This was thanks to David.
I’ve done some procedural generation with fractals before, and always used local coordinate systems, with each object passing on its rotation and position with relation to its parent to the next object. In this case, none of the objects had a sense of the objective up, only in relation to its previous object. This would actually have been pretty complicated, involving passing on rotation with matrices and all that.
Using the world coordinate system worked out quite well in this case and made the algorithm a lot easier to manage and piece together. It works in this case because the trees do have a sense of “up” when growing.
Anyway, what I love about the tool is that in the time it used to take me to make one tree, I can go through hundreds of design in the same time.
Once the tree is built, there still needs to be some processing done to make it work in the game. Of course, I made a tool for this as well . That will be in the next update.
The last few weeks have been crazy busy. I really need to get better at posting in the devlog more frequently.
I’m taking this weekend to write an update on everything: tools, game design, related projects, etc. It’s going to be quite extensive, so I will break it up into parts.
Let’s get started.
David Laskey came on board to the project earlier this year, initially with the goal of working on optimization and PlayStation 4 port. Pretty soon after, David started working on a bunch of custom tools to help streamline the design process.
I didn’t quite realize it at the time, but the project was basically going from pre-production to production. As in, the prototyping stage was more or less over, and it was time to refine the development process and trim inefficiencies.
I also started learning to write Unity3D editor extensions as a result of working with David, and it really has been such a huge help to production. There were so many processes that used to be super tedious and time consuming to do, which now have been refined.
The thing with tedious processes is also not just the time it takes up (although that is definitely a big factor). It also makes you mentally dread working on it, because it’s just not fun. I’d be really in the zone making a level, iterating on areas, moving stuff around, and then all of a sudden, I have to make a window, which would just be tedium for an hour, and it would really kill the mood for me.
Also, it meant I was reluctant to iterate. If a window was good enough, but not great, I would just leave it at good enough, because the time it would take to get up to great just didn’t feel worth it.
The window making process is just one example. There were a lot of similar task that were incredibly tedious for me to perform, and the last several months, we’ve put a lot of time into trimming these inefficiencies.
I’m going to start talking about all these tools in detail in these next few updates.
We’ll start with the window generator.
Here’s a quick video showing a timelapse comparing the old and the new ways of making windows in Unity for Manifold Garden:
The old way:
Here’s how I built windows the old way (everything is done with ProBuilder here, just FYI):
1. Make a “backboard” that is the dimension of the window I want. This gives me a reference for the size
2. Start putting in frame pieces. Almost every straight segment is a separate piece.
3. Horizontal and vertical pieces are colored differently so I can tell them apart.
4. Place the window pieces. These are also colored differently than the frame pieces.
5. Color the outside faces of the window to be the glass material
6. Merge the frame pieces and the glass pieces (but first need to save the version with the separate pieces in case I want to come back and make changes).
For a complicated design, this can easily take an hour or more. In the gif, I was just randomly putting pieces in place without actually thinking of the design, and that still took 10 minutes.
Also, if I wanted to make changes to a design, it was a lot like having to rebuild the entire window again. Even a small change involved moving a bunch of pieces out of the way and readjusting their sizes. It was not fun.
The new way:
One of the first tools that David worked on when he joined was the window generator. I showed him the old process and we both agreed that it needed to go.
It felt like the most natural way of designing the windows, since they were basically 2D designs, was to design in photoshop, and then extrude that into a 2D shape.
For the process now, I basically have a grid in photoshop, each pixel is 0.25 units, make the design there, and then open up the window generator tool from Unity, which automatically makes a 3D version of the window and has it automatically prefabbed and aligned to the grid.
For the image, grey means frame, white means glass, and black means cutout.
Using photoshop means that I can take advantage of all the photoshop features (layers, invert, etc) when doing the actual design.
An entire window, even complicated one, instead of taking hours, can now take just minutes.
It’s easily my favorite tool in the engine.
If you’re interested in how the window tool works, David actually came on the stream a few weeks ago to talk about the tech behind it. It was storming in Chicago that day, so there were some internet issues, and the stream got cut up into 2 parts.
Finally got the tree generator algorithm down! The tool is still not fully complete. We still need to add in features like mesh merging, applying final material, auto-make prefab, auto-name, etc. But those are all pretty minor stuff that should be very simple to add.
The important part is the algorithm, and that is now done.
Here are some images showing the tool and trees generated:
A major part of what made the algorithm relatively easy to work with was we stuck with world coordinates for the directions (David’s idea!), instead of using local rotations and matrices to pass down information from parent to child (totally what I would have done). So vector3.up was up for every trunk and branch, which is quite important, because the rules guiding horizontal and vertical growth are quite different (different probabilities, lengths, restrictions, etc).
I made a video explaining more of the process, why we chose to write this tool, and show some of the different variables that can be tweaked