Development logs

Welcome to the engine's development logs. If you want, also check the itch io page to see the release notes (under the Development log area): Cave Engine on itch io

Cave Engine 0.9.7 (alpha) Release Notes!

Say hello to the Cave Engine version 0.9.7 (alpha)! It took a while, but it's finally here.

I'm very happy about how it turned out and that's thanks to you and the amazing on growth community being built around it. Talking about community, I do have some exciting news: We finally have The World's first Cave Game! Yes, this is the first game ever made and exported with Cave Engine (version 0.9.6 - alpha). It was made in about 72 hours by @renatoaruffo for a Game Jam (#UnidayJam2021). The game is inspired by Little Nightmares and Hansel and Gretel. The player is lost in a forest, on a heavy rainy night, full of delicious treat, trying to find her brother. You can download and play the game here if you want to: Sweet Shelter on itch io.

Of course, this one was made using the previous version (0.9.6), but Renato actually teamed up with two more people (Bruno and Murilo) and they made a second game, using a closed version of 0.9.7 (that I've released earlier to my Patrons) and I'll probably do a video on it soon.

Ralph is also doing some amazing work using the engine:

Thank you everyone using the engine and involved somehow, the community is amazing!

I'm excited and I really hope y'all like it as I do. So let's jump to the release notes!

New Renderer!

Let's start with the big features! The entire renderer was rewritten from scratch. Why? Because now it is much more PBR accurate, easy to use and adjust and the best part: more lightweight! But that's not everything... besides all that, there is a bunch of new exciting features on it:

  • ALPHA BLENDING is here!

If you've used the engine before, you know that there was zero alpha blend support (only alpha clip). Now you can prepare your .png files, because it is working like a charm! Even with particles... so say hello to your smoke.

  • Added Mist!

The good and old mist. I use to say with some friends that mist is that magical button you press to instantly make the game looks better and now you have it in Cave. Awesome!

  • Added an Aperture variable to the camera

Soon we'll have HDR, but for now, you can manually adjust the camera aperture to support higher color ranges in your scene.

  • Old Renderer removed!

Well, I'm pretty sure that with the new one, no one will gonna mist that, but it's worth mentioning. The last thing I want it to have a bunch of different and non compatible renderers in the engine at the same time (as some other GEs are doing) so I decided to remove the old one. But don't worry: it means that I'll have more time to work in the new renderer and make it even more exciting and feature complete!

New Editor's Console

I know, I know... the Editor already had a Console before. But now it is 100% of what it was intended to be:

  • Python prints and errors are displayed in the Editor's Console
  • System console is now hidden by default That means no awkward black console window floating around when you're using the engine. Everything you need will be displayed in the editor's console. But if you're really that kind of person who likes random windows floating around your monitors, you can still enable back the console in the top menu. Just keep in mind that it will probably remain empty.

Animations

Animations are way cooler now. Let's start by the fact that I've fixed THIS (it took me a while, but it's working!). And...

  • Now it's possible to blend two different animations when changing the current one.
  • Animations now have independent frames and always starts from the beginning (cheerz!)
  • Improved the Animation Importer: Previously it was not considering more than 4 bone weights. Well, it still doesn't, but now it sorts the weights in order to get the higher influences and also renormalizes it to avoid glitches.

Audio

YES! Audio finally received some love. Now there is 3D sound support and you can access the audio instance being executed and do a lot of fun stuff with it:

class AddSoundTest(cave.Component):
    def start(self, scene):    
        # kw arguments = volume=1, fadeIn=0, loop=0
        self.sound = cave.playSound("testSound", fadeIn=2.0)
        self.timer = cave.Timer()

    def update(self):
        self.sound.volume = math.sin(self.timer.get()) * 0.5 + 0.5

        events = cave.getEvents()
        if events.pressed("W"):
            self.sound.pause()
        elif events.pressed("S"):
            self.sound.resume()

    def end(self, scene):
        pass

Including 3D audio. But if you're not into code, you can use the native new Audio Component as well!

Entity Templates: Working like a charm!

Entity Templates are something very special and important in the game engine. Let's say that you are making a platform game with multiple levels and a lot of enemies spread across the maps. How would you make the same player have an instance on every level? Or even more: How to use the same enemy, without a bunch of duplicates (that makes you project hard to maintain) all across the map?

That's why we have entity templates:

You can create a new template by right clicking in the asset browser and then assign a selected object (in the 3D view) to it. It will store the entity structure and make it available to you to use anywhere you want to. So it will be just a matter of adding an empty where you want to spawn the template and select it in the entity's Settings menu.

Previously it was not working as intended but now it is! Expect (a lot) more on it later.

Editor Tools

Previously I've said that I was planning to improve the Tooling support. And I did it! I've added default Editor Tools and you can make your own if you want to! Let me explain: Now it's possible to paste python scripts inside the Editor/Tools/ folder to automatically register them into the editor. So every time you open the engine, the custom made tools will be there, ready to use.

Well, which tools? Various, including the community tools! But someone had to be the first one to write a tool for it, right? Right. So I decided to start this: The world's first official Cave tool is a built in Python API! And why that's good? I'm glad you asked. The tool uses the cave module itself to retrieve the data, so it will be always up to date to your current version. So if you want to check if there is a bleeding edge but yet not documented feature in the api, this is your place! This tool if far from complete yet, but the good news is that it's source open and everyone can go to "Editor/Tools/" and edit it. Enjoy!

Python API

If you want to create some advanced logic for you game, you can use Python scripts for it (visual scripting is coming). So it's very important to provide a smooth and easy experience for you to make everything you want. That's why version 0.9.7 is full of new exciting python features!

Let's start with some usability improvements: You often want to access other custom made components inside your code. Previously, there was no garantee that all the python components in your entity where initialized when running the start method, so that could lead to self.entity.get("YourComponent") returning None. Now all the components are initialized first and then the start method is called.

So if you have Foo and Bar attached to your entity, you can always access each other:

class Foo(cave.Component):
    def start(self, scene):
        cmp = self.entity.get("Bar")
        print("Bar = ", cmp)

    def end(self, scene):
        pass

class Bar(cave.Component):
    def start(self, scene):
        cmp = self.entity.get("Foo")
        print("Foo = ", cmp)

    def end(self, scene):
        pass

But that could be not enough. Sometimes you actually want to wait until certain component initialize properly before accessing it. That's why we now have the optional method firstUpdate(). As the name suggest, it will be called once after all start(s) method run and before the regular update().

class Bar(cave.Component):
    def start(self, scene):
        print("Start method...")

    def firstUpdate(self):
        print("FirstUpdate method...")

    def update(self):
        # Called every frame!
        print("Update method...")

    def end(self, scene):
        print("End method...")

To be honest, I can talk FOREVER about the python api improvements. Now you can grab the Mesh Component, get, set or modify its current mesh, material, animation and more! You can select the mesh, copy it to make it unique to a specific object and change as you want to.

cmp = self.entity.get("Mesh") # MeshComponent

mesh = cmp.getMesh()
mesh = mesh.getCopy()
cmp.setMesh(mesh)

# Do whatever you want with the mesh here!
for vertex in mesh.vertices:
    mesh.position += cave.Vector(0, random.random(), 0)

for index in mesh.indices: 
    # For every 3 indices, we have a triangle
    print(index)

mesh.reload()

For instance, the code bellow will duplicate the material from the MeshComponent (to make it unique to that specific object) and make it pulse a random glow value, in realtime. Watch the Showcase Video:

import cave
import random
import math

class Emissive(cave.Component):
    def start(self, scene):
        self.timer = cave.Timer(random.random()*6)

        cmp = self.entity.get("Mesh")        
        self.mat = cmp.getMaterial()
        self.mat = self.mat.getCopy()
        cmp.setMaterial(self.mat)

    def update(self):
        c = (math.sin(self.timer.get()) + 1) / 2
        self.mat.emission.set(c, c, c)

    def end(self, scene):
        pass

And there is much more!

  • Transform: lerp, untransform, unrotate
  • Now it's possible to get python made components from pythoncmp = self.entity.get("YourOwnComponent").
  • Exposed a transform.[get/set]WorldPosition() method to the Python API
  • Exposed the CharacterComponent fields to the Python API
  • Added a RigidBodyComponent.applyImpulse(...) method
  • Added a MeshComponent.getAnimationLoops() method
  • Added the MeshComponent.getAnimationProgress() method
  • Exposed the DecalComponent to python

Mouselook Component

This one deserves his own section: Now there is a new default component called "Mouselook". It allows you to use the mouse movement to apply some specific rotation to an object. You can use it to, well, do a mouselook, but for a lot more, such as that badass "item preview" from Skyrim, that rotates with the mouse.

Documentation

The engine's documentation is still not 100% up to date (at least not by the time I'm writting this release notes), but I did a lot of improvements on it. By the way, check the previous "Tooling" category to see why you should not be worried about the Python API documentation anymore! Anyways, here is some changed I've made:

  • Renamed "engine" to "cave"
  • New homepage + theme
  • Added Tooling examples
  • Added a Showcase tab

New Entity UI + tag UI

Now the entity tab (properties) are more organized, divided into sub tabs: Components, Settings and Tags. Tag UI was redesigned as well.

New "Quit Editor" popup menu

The "quit editor" window was redesigned to use the engine's UI instead of the OS message dialogues and now displays a "Cancel" button.

Git control

When people started working with Cave for real, they sent me some messages regarding the "git friendless". In other words, it was necessary to make the engine work with git so multiple people could work in the same project at the same time. So I've made some changed to allow this:

  • Option to expose the scripts externally, in a Scripts/ folder
  • Exposed the Asset names in the Project Files (previously it was just the unique ID, aka a weird and huge number) I'm planning to do more things related to that, but it was a great start!

Usability (UI/UX):

Want to see a lot of miscellaneous improvements regarding the engine usability? Here you go!

  • UI Text Renderer rewritten from scratch

The previous UI Text was very sketchy and was not working at all in a lot of cases. Now it was completely rewritted and it's working like a charm.

  • Highlight active asset in the Asset Browser
  • Added a debug grid to the viewport
  • Changed the color of the selected text (it was not visible before)
  • Reduced the color of the tab arrow (text editor)
  • Mesh Entity are now added with a rigid body component by default
  • Do not change the window focus while simulating the game!

Addressing the report: "The Shift + Space makes the screen in Full mode. The problem is that when I run+jump with the character controller it keeps scaling up/down"

  • Removed the Delete and Duplicate icon from the Scene Graph items:

The user could easily accidentally click on them. I've added a dropdown menu instead. Those options are still available using the keyboard shortcuts.

  • Added bulk actions for the Animation Asset
  • Increased the Sun bias range in the editor

Project Manager improvements

Project manager is the first window you see when you open the engine. Keep in mind that there is a bunch of other things I'm planning to make on it. Soon!

  • Show a message when there is no projects
  • Improve the "new project" layout

Export Game:

I did a bunch of things related to the game exporting:

  • Fix: The engine was not copying the the folders inside the "Lib/" directory, causing the game to not run as a standalone (exported version).
  • Renamed the executable to the project name (previously it was always "Game.exe")
  • Removed the Python STDOUT from the runtime + hide terminal
  • Don't allow the user to export the game without a default scene selected! I've also improved the Settings UI by adding tabs to organize the content on it.

Fixes:

Something very important happened recently: We started to have actual Games being made using Cave Engine. And because of that, I had to make sure that the engine was stable enough and "bug free". So that's why we have so many bug fixes. Good news: it's working very well now!

  • Fix: Crash when trying to display a nullptr image (ui)
  • Fix: Light Gizmo was not world space (when parented)
  • Fix: Camera with 0 scale was resulting in NaN values
  • Fix: Overlapping text when hovering some dropdowns
  • Fix: Editor Icons + use a custom file extension
  • Fix: Camera view not working most of the times:

The camera view was a bit sketchy, most of the times, it would simply not work at all and keep using the free camera of the viewport. Specially in the runtime. Now it works just fine.

  • Fix: Deleting an Entity Tag was crashing the engine
  • Fix: Tools getting invalid when you stop the game
  • Fix: glDrawElements access violation (crash)
  • Fix: Problem when displaying multiple ColorSampler UIs in the editor
  • Fix a typo in the PropRange UI element
  • Fix: ColorSampler loading issue
  • Fix: Crash when adding physics to a Folder:

Personal Developer note: Yes, someone had to try to add rigid body physics to.. wel... A FOLDER! You guys are amazing finding all sorts of corner cases and I LOVE IT! Cheerz. lol

  • Fix: View Gizmo was being activated when moving a tab around (over it):

Two actions at the same time when You're moving tab + You forgot to not move cursor over 3D View Cube at the same time... Thank you Ralph for the report.

  • Fix: Character sliding
  • Fix: It was not possible to set a character's position
  • Fix: Some python components where not showing in the UI
  • Fix: It was not possible to edit two PyComponents at the same time
  • Fix: Making it possible to always have multiple components of the same type in an entity
  • Fix: Dropdown filter was not working
  • Fix: Crash when you run a python script with no start method
  • Fix: I've Hidden the Jump Height because it is not used by bullet at all:

There was a character physics option called "Jump Height". But after a close inspection in the bullet's source code, I relized that the jump Height was not used at all... lol (that's not my fault). Bullet code - for the Nerds

  • Fix: PythonComponent was not being properly copied when duplicated
  • Fix: Animation issues:

This one is huge... remember This Video I made sometime ago? Well... it turns out that it was my fault as well (thanks to quaternions not being normalized). But now it's fixed! No more weird rotation behaviours.

  • Fix: Activating the RigidBody when you set something
  • Fix: Removed the shader error exception throw
  • Fix: Some EntityTemplate crashes
  • Fix: Crash when iterating the childrens
  • Fix: Entity mem leaks and mem violations
  • Fix: Shadows disappearing when the camera is far away from the world's center
  • Fix: It was not possible to add components in realtime (python)
  • Fix: Ensure that the Python Components are all constructed when calling the start
  • Fix: Crash when modifying the entity component list (during iteration)
  • Fix: Unicode characters was not working in the game UI:

For the brazilian people out there (and maybe the russians and others): Say hello to special characters in your games! Words like "AÇÃO!" and "PAÇOCA" will be displayed properly in the game UI.

Internal stuff:

I've omitted all the fixes and improvements that are internal (only noticeable inside the engine's codebase), but it's worth mentioning that... well, I've removed A BUNCH of unnecessary core, redundant stuff and fixed a lot of things. Huge refactors behind this big set of updates. I really liked the way it turned out.