Hey! As promised, today's devlog will be about code and addons.
What are addons? These are pieces of code that perform the function for which they were created. Simply put, these are modules that help in development, such as inventory, camera movement, effects, loading, etc. And you may think "if there are already addons that implement parts of the game's functionality, then what are you developing at all?!". But unfortunately, not everything is so simple with addons.
Godot is an engine that is frequently updated and each new version of the engine adds new features. And so it happened that when something is added to the code, it usually has a high chance of breaking something old. And addons are the first thing that breaks. I once tried to use addons that are freely available, but after a couple of updates, the addons stopped working on the new version of the engine and the authors did not even try to update addon.
This is an open source issue and you can't know for 100% whether the addon will work. Therefore, after studying addons and how they work, I decided to create my own addons that have the functionality I need.
Today I will describe the functionality of the basic addon that is in each of my games, CZD (Chimera Zak Development):
As you can see, there are many folders here, but each of them has no more than 2-3 scripts. These scripts are the backend of any game. Audio, scene tree, events, inputs, UI, and saving with loading are available in any game, and in order not to rewrite all the systems for new games, I decided to create this addon.
But using this addon requires a full understanding of how it works. For example, audio:
I have a special audio manager that controls all audio in the game, as well as new resources for audio streams. So I don't use the audio stream directly (as in the standard), but create a special resource that has the ability to immediately specify on which audio bus the audio will be played (SFX, BGM), have special conditions for playback (as in the screenshot above, random Pitch) and other things.
For some games, this is not necessary at all, and perhaps this audio manager will be superfluous. But the advantages of already organized use of audio in this way reduces the burden on me as a developer, I don't think about these things anymore, since the addon already has everything I need to work with audio (of course, I can still add a lot of things, but this is enough for now). And since this audio control was completely done by me, I don't worry about it breaking and not being able to use it anymore, since I have a complete understanding of what and how it works.
Of course, audio is only part of this addon. Next on the list is the base scene tree:
This is something that everyone uses in their own way. I like that the scene never changes in the game, in fact, there is always a World, which is a container for everything the player sees. This gives me an understanding of the construction of the scene and that it will always be of the same type. This is a basic thing for any of my projects and the addon already has simple scripts to function this type of basic scene structure
Next folders is a bit experimental and new, but already have really cool uses :
EventBus is probably one of the most successful scripts I have created (although the architecture is not new). This script manages custom signals during gameplay and does not require binding like Godot's signals. It's a bit hard to explain for those who don't understand code, but here's an example.
Demonett, when moving from one floor to another, must tell the game about it:
For this in Godot, the door ( with which the player interacts) needs to give a signal that there is a change of floor:
This is basic data (int = which floor), and GameManager (another script that simply manages data) must receive a signal from the door. To do this, i need to create a FloorChanging signal in the door script, then when the door is created in the game, bind this signal to the GameManager script to the desired method:
This will connect the signals so that the GameManager understands that the floor is changing in the game. But if the change of floor is not through the door? For example, there is a plan to add magic to the game and there will be a new object like a magic circle. This will require repeating the binding of the floor change signal to the new script.
What does EventBus do? It ignores all the ways to create a signal and attach it via Godot, and has two new methods: subscribe and publish :
And this is all so that the Game Manager understands that the floor has been changed. It subscribes to the string (event name) and only checks it. If the new object also tells EventBus that it changes the floor, then the GameManager will understand this and will work without problems (of course, if the floor data is specified correctly, since it expects exactly int value, if there is no data, then the floor will not be changed).
This helps a lot, as none of the participants in the interaction depends on each other. Of course there is another problem here as the data is not bound, you can send a signal with the wrong data type, but this is easy to fix as it is easy to find who exactly sent the signal.
Next, there are two folders in the addon: GameState and Inputs. GameState is an experimental thing and an algorithm that I found. It was created to divide the game into stages by type (Menu, Gameplay, Cutscene, Titles, etc.). And this should fix the problem of the game not being able to mix different states with each other, But so far I have not been able to achieve modularity in it, so it is difficult to use in different games (States need to be hardcoded and this is a problem).
The inputs speak for themselves. This is the management of any inputs (touchscreen, gamepad, keyboard, mouse). These scripts help control exactly how the game receives inputs. There is also an experimental InputStack script here:
This thing is very cool in its idea. Each object in the game that requires input from the player has its own priority. When the game starts, this priority is written to the stack, and when the player presses something, the stack is checked from the highest priority to the lowest. This removes any possible bugs with clicking what can't be clicked, but creates an additional load on the system. So for now I'm still working on it.
Next, I have things that do not really need much explanation:
These are basic things for loading and saving the game, small extension scripts that simplify writing repetitive code (for example, basic killing of all children of a node, with type checking). And also the UI Manager, which works similarly to InputStack, but with the difference that each newly created UI element overrides (disables, if necessary) the previous UI element, and when closed, returns the functionality of the previous UI element.
That's all about this addon (I won't touch on the console as well as a more detailed description of loads and saves, as this is a topic for another devlog). As you can see, even the basic stuff for any game needs work, especially when you're not working on just one project. And this addon greatly simplifies the development of new projects, although it took a long time to create (and I still haven't finished everything I want).
On this I can say with confidence that I have described to you the basis of my projects. Now the next devlog will be a deeper dive into the project that is currently being developed (Demonettes Playtime). So stay tuned for the next devlog!