I can't imagine a dungeon crawler without boss fights, and so despite the huge scope creep this adds to my otherwise simple production, I had to try prototype one. Throughout this process one thing that really suprised me was how much of a solid level editor Blender wound up being.
Being a solo indie dev crazy enough to write everything from scratch, writing a complete editor myself would wind up being a massive timesink. However most 3d packages contain much of the functionality required of a basic level editor. The overview of the desired pipeline is that I need to be able to achieve the following:
For simplicities sake I’ve chosen to define the bahaviour of prop types in my game code, while the data required for them is handled by the build pipeline. Blender on the other hand gets to manage the content creation and the prop placement.
I'm not doing anything super fancy to define my prop types. Props are simply a collection of entities built in the prop factory. For example, if a model is told that it is a chest prop, the prop factory will gather all the information a chest requires loading the model, animations, and other relivent assets. The prop factory then uses this information to build the various entities a chest requires, such as the model, a name label, open button icon, and all the loot entities.
Additionally, it will build a state machine that handles the transitions of all the animations from spawning the chest to opening it. Something like that winds up looking like the graph below.
Props also come with a dictionary of any interesting elements of that particular type of prop. For example, a chest might have the "open" transition added to the list so it can be changed to be locked until something in the level is completed. The creation process may be pretty hard coded, but at least this dictionary means I can mutate the behaviour of props placed in the level.
The build pipeline is also pretty simple (see my "Getting Started" and "A Matter Of Substance" blog posts for more details on my build pipeline). I’ve added some prop utilities that know what each type of prop expects, and makes sure the data is built for it. To add a chest to the build pipeline I simply add a line in Lua to my build script:
props.AddChest(PropList, "BasicChest")
This will add the chest model, textures, materials, shaders, skeleton, and animations to the build pipeline. In addition to this, some game data is saved out telling the engine that the prop exists, and what was actually built for it.
This is all pretty standard asset creation. I use Blender to model the prop, as well as rig and animate them. Furthermore, Substance Painter or Designer is used to texture it (I won't cover this here as I've talked about this in my "How to (not procedurally) Build a Tiling Cobblestone Texture" and "A Matter Of Substance" blog posts).
To turn the prop into something that can be placed in a level, I group it and name the asset the name of the prop. The prop is then added to the build pipeline, as well as exported to FBX.
Ctrl-G to group, then the name can be seen in the side tab, brought up with T
Grouping in Blender isn’t really the same as it is in many other apps. Usually grouping objects will wind up placing a parent transform underneath them. In Blender a group is simple a list of things that belong together. I’d never really understood how this was useful until I started researching how linking (instancing objects from another file) works in Blender.
One of the weird quirks with linking objects in Blender is that you can’t move them around when linked into a file. I’ve always kind of just thought that Blender was bad at this. However, when I looked closer, if you group objects in one file, you can link the group in another. It imports it as a reference to the external group copied to a locators location. This is perfect as a prop placement tool. It means that my props will always stay up to date when I edit them.
To link a prop, browse to link in the file menu. Find the blend file, and then browse to the group folder inside the blend file. Select the group you want to link. You can now duplicate it with Shift-D as well as move it around!
So now I can build a scene in Blender referencing all my props I’ve created. This scene gets exported as an FBX file. All of the names of groups models wind up getting “|dupli|” injected into their names on export. I use this to my advantage to prevent the prop geometry from ever getting built into the level model, and keep locators as a list of props. Now my level factory can parse this list, and create props wherever instances of them occur. Additionally the FBX file format also keeps any metadata you leave on a locator. You can use this to your advantage to tag special properties on any instance of a prop.
I like this approach as it meant literally no scripting work in Blender. I can basically just work with how Blender likes to treat instancing from other files, and know that no special set up is required whenever I download Blender on a new machine.
Everything that moves or changes in the boss fight is actually a prop, even the boss himself! The types I’ve defined are:
While the types are very hard coded, the realisation of them is not. Even Boss1 could become a radically different fight if I created a new boss model with different animations. Additionally, the ability to easily find meaningful bits of props means that they are very flexible when used in context. The boss will not spawn until the bridge collapses. Also, the boss fight is able to require the boss to be dead for the chest to spawn, and the doors to open. Also, all of these elements are easily placed in Blender, and it doesn’t require me to do anything other than export the level when I’m done! It’s not an amazing set up if you want to sell an engine. But if you are a small tight knit team, it’s definitely enough to get by without sinking huge amounts of time into a custom editor.