Posted July 19, 2026 by JHyde
I haven't made a devlog in months, but work has continued at a steady pace. There are too many additions since the last devlog to talk about them all. So I will just talk about the optimizations I have made to the game.
The thing that has had the most impact on frame rates has been using raylib's DrawMeshInstanced function. Where you can batch render all the mesh at once on the GPU, instead of doing an individual draw call for each model. This saves thousands of draw calls. So I now batch render floors, walls, trees, and grass. I can't batch render the terrain mesh because it has to be the same shape mesh for all instances. This gives me 350 FPS in dungeons, and like 250 FPS for island maps. Batch rendering the walls made the biggest improvement because the wall mesh is more complicated than the floors.
For vegetation on the island, I replaced the old 3D bush model, with 2 quads that are crossed at 90 degrees. So it looks more 3D. How old 3D games used to do grass. Since they are just quads and I'm batch rendering them I can do like 5000 grass cards without getting any slowdowns. I have 4 different types of grass cards that I randomly draw from. I also vary the size and rotation of each grass card. In the end it looks a lot better than before, and runs a lot faster.
Another optimization idea came from making a loading progress bar. While the level is loading I display a progress bar that gets updated when each of the dungeon generation functions finish. It also displays what the current generation function is in text. So "Generating Floor Tiles" and such will be displayed over the progress bar. This let me see how long each function took to load. This led me to discover it was the dungeon lights and specifically shadows that was slowing down the load times.
Shadows in the dungeon are made by doing thousands of 3D raycasts from light source to nearby walls. This is expensive and was taking up about 80 percent of the load times. Doing the lighting this way gives the best results however and I'm keeping it as the default mode. I added another kind of lighting mode that uses DDA algorithm on the dungeon tile map to find the occlusion data. Using this method load times for dungeons are nearly instant. Even for big 64x64 maps which used to take 15 seconds to load with raycast lighting, takes less than a second using DDA lighting. The DDA lighting makes tiles underneath walls unlit. So you get dark corners around all the rooms, but this prevents light bleeding through walls, which is a problem with the normal lighting. I heard Wolfenstein 3D used the same kind of DDA algorithm for lighting. I made the DDA lighting an option in the menu. If you check a box it will use the DDA lighting for instant level loads. Perfect for low end laptops.
Another optimization I did, was to do one less render texture draw pass. I was doing two post process shader passes, where I render to a render texture, apply a shader, then repeat and apply a different shader. Instead I combined the two post process shaders into one so I only need one pass. I didn't notice much of a speed up, but I heard it might be noticeable on slower machines.
That's about all I can think of when it comes to optimizations. While I'm here I can talk about some other additions to the game. Like the day/night cycle. The sky box is just a giant cube where we only render the inside of it. We apply a shader to it that either colors the skybox blue and adds moving clouds and a sun over head, or it colors the sky box dark and draws stars and a moon and a planet for night. I added a third state to the shader where it transitions between day and night. It looks pretty cool, you start to see stars and the moon behind the blue sky as it slowly gets darker. I add a pinkish color to it as well so it looks like dusk. I made the water color, and the distant fog color match the color of the sky. This works really well for night time because the distant fog becomes blended toward black so things in the distant are to dark to see. It gives it a lot of atmosphere. I may need a night time version of the ambient jungle sound track.
Another big thing I added was the command console. Hitting ~ will bring down the console quake style and you can type in certain commands. You can type help to get a list of them. Give all weapons, health potions etc. You can type the command "stats" and it will bring up a debug window that displays live information about the game. Like how much of the geometry is being rendered, how many active bullets is tracked along with particle count and more. Both the console and debug window have an old amber colored terminal look to them. I used a mono space terminal style font, and added subtle grid lines. I really like how it ended up looking.
Another game changing addition was sword combos. Before you would swing the sword down from right to left for every swing. Now it swings down from right to left, then left to right, then a stab motion, then it repeats. The stab attack does twice the damage as the first two swings. It's a reward for finishing the combo, but leaves you open to attack. Moving the sword model around in 3D space to animate the sword swings took a lot of trail and error. If I ever want to add arms that are holding the weapons I'm going to need some kind of rig. Instead on manually applying rotations and translations in code. I also changed the melee hit box to match which type of swing your doing. There is a hitbox volume. Which is an array of 5 hitboxes. The hit boxes are laid out in an arc around the front of the player. When the swing starts we activate the right most hitbox then activate the next hitbox in line over time so it makes an arcing motion of detection. For the stab the hitboxes are laid out in straight line forward, so you need to be more precise with the stab. I also added a 2D slash effect the helps sell the swings.
I also added a double shot attack to the blunderbuss. After reloading the gun, if you right click it plays the reload animation again and then the gun starts to glow red. The next time you fire it will shoot twice the amount of pellets, with a higher spread. This lets you one shot a skeleton. At first I thought it was too over powered, but I think it just makes the game way more fun. Charging up your weapon before engaging feels good to do. One idea was to have these weapon upgrades unlock over time. This double shot ability could be unlocked by spending gold at a shop. The magic staff could be bought with gold, and certain one time use upgrades I added like quad damage and mega health. I even started making a shop level, but I'm not sure how I want it to work yet.
I could go on and on about the automated dungeon prop generator. That randomly places a prop like crates, and chairs, and spider webs in the free corners of the dungeon. I could talk about the randomized mini boss enemies that get generated 10 percent of the time, or the new cut scene camera rig that can follow waypoints while dynamically tracking different targets, but I will leave it there.
I hope to release v0.7 soon that will contain all these additions and more.