This was so helpful for me. I'm hoping to adapt your tutorial to pull off something similar comparing modern satellite imagery with historical maps. No topo, so my steps should be simpler, but I'm a novice with Blender and you've really helped. Thanks!
Even Top Notch Artists will be replaced by AI. You have no idea what you are talking about. If you do, only very superficial. At the end you are only an employee. You dont have any contact or experience to the High End Echelons we worked on. In 20 years, 40% of workforce working today will be out of jobs. First we will get worldwide financial crash, then AI takes over. Admin will remember my words in not distance future.
Very talented 3d artist Jakob Gavelli talked a bit about the way he’s prototyping mechanics and building procedural levels for indie game Phylactery.
Hi! First I want to thank you for the opportunity to do this interview, I’ve been reading articles on 80.lv for a long time and I really enjoy the work you do!
My name is Jakob Gavelli, I’m a 3d artist working with Crows Crows Crows on a bunch of really fun and interesting projects. Since Crows Crows Crows is a small company I get to wear a lot of hats so my day-to-day work encompasses everything from 3d modeling and sculpting to some rigging and shader programming.
I’m also a Co-Founder of Right Nice Games who released a 3d platformer called Skylar & Plux earlier this year. On Skylar & Plux I was one of two artists, I was responsible for all of the environments and technical art such as VFX and shaders. While my co-worker was responsible for character art among a bunch of other things.
On my spare time I’m working on this little pet project of mine currently titled Phylactery, which is a very arcadey and fast paced dungeon crawler.
The main idea of the game is to have a short and action-packed dungeon crawler that focuses on replayability and choice as to how you play the game. I really enjoy playing Diablo or Path of Exile and trying to come up with new interesting ways to play the game and combining different skills and attributes. I want to capture that feeling but in a smaller more arcadey format.
My personal goal with Phylactery is to see if I can make a game by myself, spending only a couple of hours a week on it. This means I have to cut A LOT of corners during development. So it felt natural to take a procedural approach to the levels, since I simply don’t have the man hours to create unique levels the regular way. The camera is also very zoomed out which gives a cool aesthetic and a sense of scale, but it also means I can get away with a bit rougher animation and character art without it looking too bad. I also basically only sculpt and decimate models before import, without UVing them, and use world-space textures in the engine instead. I think it’s important to keep the scope small, but it’s just as important to work smart and make the little time you have make as large an impact as possible.
I think the camera having a narrow FOV and being very zoomed out is the major contributor to the vertical and flat look. There’s also a lot of post-processing effects going on such as Depth of Field that also adds to the verticality and sense of scale.
One of my absolute favorite series is the Dark Souls-series and I was inspired by the sense of scale and verticality of their environments. In more traditional ARPGs like Diablo your character is tied to a navigation mesh so you can’t “fall down” or leave the play-area as it were, this means a ledge isn’t scary to walk along because you know that it’s no threat. In Dark Souls on the other hand, and in Phylactery, if you fall off a ledge you die! So I wanted to experiment with that. The verticality of the levels increases the tension of fighting on narrow bridges and ledges which I really like.
I’m a big believer in letting the gameplay dictate the art and direction of the whole game, it makes everything feel more grounded and intuitive for the player and I hope the game will be better because of it.
Procedural generation is something I’ve always wanted to try out. It sounds very compelling to me to be able to test the game myself, the same way an experienced player would, without knowing the level layouts or where enemies spawn etc. I want to be able to play the game and have fun!
The levels are basically a big grid where each grid space is a potential room. At level generation the blueprint generates a path and fills in the grid spaces with their corresponding rooms. The blueprint grabs the rooms from different Pools I’ve created with Turns – Straights – T-Crossings etc to create the levels. Then each room goes through it’s own generation with zones to spawn enemies, debris and other random elements.
At the beginning I was struggling with the size of the grid and what is a reasonable size for the rooms. If they’re too big it takes more time to create them and it’s easier to spot the repetition. If they’re too small then you can see very clearly where the edges of the grid-spaces are and it ruins the illusion of an organic level, it also makes it harder to create cool unique moments. This took a couple of weeks of iteration to get right and I think I’m at a good size of the rooms, time will tell if it will work in the long run.
As for creating the rooms I have a library of assets I’ve created using Maya and Zbrush. I use Zbrush for most of the work and Decimation Master helps me make the sculpts into low-polys which I can get into the engine quickly. Most of the assets aren’t UVed as I have a master material that applies textures in world-space, this is another way of saving precious time. Which means my process for creating most assets is simply sculpt > decimate > import > drag-n-drop a material onto it > done. Another important goal for me was to get to spend more time doing the things I enjoy, mostly sculpting, and spend less time doing the tedious UVing and Retopo steps of traditional workflows. This way I do none of the boring stuff and only the fun stuff, which also gives the game a pretty organic and nice aestethic.
Here’s a timelapse of one of the big skulls sculpts in the game:
I assemble the assets in the engine in a construction-template-level sort of thing. Each room assembled like this can be a couple of hundred meshes, which is bad. It would take a long time for the engine to spawn all of these separate meshes during runtime and since the game is fully dynamically lit it would be very performance heavy to light all of the separate objects the draw calls would go through the roof! Luckily Unreal 4 has a Merge Actors-Tool, so that’s what I use, I select all the assets that make up the room and merge them into one single mesh.
Here are two pictures of two different generated layouts. The first layout having 4 rooms and the second having 5 rooms. The game is still very much in development and not even in Alpha yet, so you will see a lot of repeating rooms in the current iteration:
Lighting is such an important aspect of all art, in Phylactery 99% of the color comes from the lighting, most of the environments materials are just different grey values. Lighting is an extremely important tool for guiding the player, especially when my game is so dark, and it serves as a reward when something bright and beaming such as the skull entrance comes into view. In Phylactery I also have torches that light up when the player gets close. It feels good for the player but also serves as a breadcrumb so that the player knows where they’ve been and explored if they get lost.
The player is a walking light source, where the radius is dictated by the players health, this does a lot already for how the game looks and feels. The other major light sources are two directional lights, one that points straight down to create strong silhouettes for the player to easier see the playable area. The other directional light points along the x-axis to show edges of the geometry and add color to the level,
Here are two pictures with the light turned on and off.
VFX is a easy and cheap way to add movement to an otherwise static scene. I have a couple of layers of dust, sparks and glows that gives the environment more depth and these emitters are just attached to the player and follow the player around.
It’s very important that when you pick up a new modifier for your spell, if it’s the ability to ricochet, explode or change the element from Ice to Fire, that there’s not only a change to the gameplay but to the visuals as well. The spells blueprint has a huge section dedicated to changing the visuals. Such as adding particles as well as changing particle parameters such as color and size. I have some examples of this here:
Magic Missile without modifications :
Modified to Explode :
Modified with several things :
Optimization is difficult when at the end of the game players can shoot 12+ fireballs that pierce through enemies, ricochet and explode. And on top of that you can play with up to 3 friends so all of that can happen times 4! It hasn’t been an issue yet, but it’s something I’m keeping an eye on for sure.
For gameplay reasons I want to keep the levels pretty small, but I doubt the size of the level would have a large impact on performance since enemies and other more performance heavy objects get spawned at a certain proximity to the player. That said I want as many people to enjoy the game as possible no matter their hardware.
The most important part is to optimize repeating elements both in the environment and programming wise. Sometimes there are 50+ enemies on the screen at once and making that smooth is a challenge for a inexperienced programmer like myself, and I’m still trying to figure that out.
I have a better grasp around optimizing art thought. Because of the camera position and art-style I get away with very low-poly models and without unique UVs I have very few textures as well. Because the levels are procedural and don’t have any lightmaps the file size of the project is very small. The entire game weighs in at 144 mb at the moment! To give you some hard STATS the largest amount of polygons on the screen at one time at the moment is 200 000 tris, which is nothing really. And the amount of draw calls peaks at 500 which is also relatively low. Hopefully this gives me a lot of room to improve the visuals without affecting performance.