How it's made? - Technical Side Pt.1(?) (Patreon)
Content
I thought it could be pretty fun to share how the game is built, from the engine used, to the classes, scripts and topology. So it's time for me to ramble and give bad advice and explanations to you about software engineering!
This post is mostly written in a way that assumes you have no idea how coding works. If you're a software engineer, feel free to critique my choices and offer advice. Otherwise I hope this post maybe inspires you to do some game development of your own! (also don't take my explanations too seriously if you're actually trying to learn, please)
Picking the game engine. [Insert joke about waiting]
The game is made with the Godot Engine, specifically the 3.5 release. Godot is an open-source 2D and 3D game engine that's been overshadowed by Unity and Unreal for a long time, but recently it has been rising in popularity and use. It's relatively young compared to the others, first released in 2014 and from what I've heard, it took a long time for it to get to a usable state, much less become actually viable.
Although I used Unity a bit prior to this, Unity is generally considered very bloated and it shows. While Godot might not necessarily be on par with the big names like Unity and Unreal, especially for 3D games (although that seems to be changing with the recently released Godot 4), it's generally considered a great pick for 2D games. It's also shockingly lightweight, with Godot 4 being a single file of ~100MB. That's it. That's all you need to get started.
I'm a bit of a shill for open-source projects, so the open-source nature of Godot made it a pretty good candidate for what I could use. For those who don't know, open-source means that the source code for the engine is free and publicly available to everyone. In fact, you can go and look at the actual code for the engine right now! This setup allows for a lot of collaborative effort from the community and it's thanks to a bunch of people (enthusiasts and volunteers) working on Godot that it is what it is today.
Programming languages!
(A snippet of code for gaining weight during battles.)
Godot uses its own, custom scripting language called "GDScript." It's a dynamically typed language with very similar syntax to Python (it's still it's own thing and not related to Python itself in any way though!). Dynamically typed means that things don't have to be of a specific type (Is it a number? Text? A picture? Music?) and it's only checked when it matters (to put it in very simplified terms).
Godot also allows you to use C# and thanks to GDNative (GDExtensions in Godot 4) you should theoretically be able to use any language. I used C# when I first picked up Godot, admittedly because of a bit of prejudice towards GDScript. I basically figured C# could have more practical use in other places too instead of the engine-specific GDScript (which isn't untrue) and I was also a bit put off by the dynamic typing. (GDScript actually does have optional explicit typing, it's in the snippet above! But it still feels a bit awkward compared to actual statically typed languages.)
Because Cards of Gluttony is centered around kink and adult content, it was pretty clear it was mostly going to be a side project, so when I started working on the game, I saw it as an opportunity to stop being so rigid and serious in the way I do things. I stopped worrying about doing things perfectly and getting hung up on finding the "best" way to do things. I just hopped onto GDScript and started trying things out (Fun fact!: the first character model I used was a simple 3D model I made that had a weight slider). That free attitude is also quite noticeable in all of the art in the game, it's all messy and sketchy (although that is my general art-style, a lot of it is still very rushed by those standards).
This turned out to be a great way for me to explore and learn without putting too much pressure on myself. GDScript and dynamically typed languages (specifically Python) are quite intuitive and fast to prototype with, so it's very useful when exploring ideas and just quickly implementing and changing a bunch of them. Although I still prefer the more organized C# and other statically typed languages, GDScript was very much made to work perfectly in tandem with the engine and it's very evident.
The... topology? Architecture? Whatever the right word is.
So the way Godot structures it's scenes and game objects is in the form of a Tree. Trees are a basic data structure that comprises of a bunch of nodes, these nodes are connected to one another. Tree is a pretty accurate word for the way they work, as you start with a "root" node that represents the start. When you add more nodes to the tree, you add them as "children" to an existing node. You can branch these in many ways to form something that looks like this:
So what are these "node" things, exactly? In context of Godot, the answer is... well, almost anything. Godot has nodes for many things, ranging from Sprites, Text Labels, Audio Players and so on. These nodes do the things that they're supposed to and allow you to access their properties and functions via scripts that you attach to them. Here's what Cards of Gluttony's tree looks like:
(Please don't use this as reference for good design.)
You can see the root I mentioned earlier, and then the children. Most of the nodes you see here are always running in the game at all times. Global handles the overall state of the game, PlayerData houses all of your stats, PlotTracker stores info about your progress and story flags like losing/winning, and so on. The bottom-most node is the screen you're currently on, here it's TitleScreen.
For example when a battle starts, I swap out TitleScreen for CardGame, which is a node I created that houses all of the scripts and nodes to run battles (that is: the UI, character models, state of the battle, functions and game logic). They're not all just crammed into one node and a script of course. An important part of software engineering is to separate things and compartmentalize them into pieces that each have a single scope/responsibility they're meant to do. (See how that fits into the tree structure with a bunch of nodes?)
That's it for today!
This post was basically just a Godot appreciation post, but that's because it's great and if you have any interest in making games, you should definitely check it out!
I know there wasn't a lot of Cards of Gluttony specific info in here, but I hope it was at least somewhat interesting to you, I suppose I just wanted to ramble about the technical side of things for a bit. If you'd like to hear more about some actual aspects of the game like the card battles, the cards themselves, the way PlayerData is stored, maybe how the character customization works, or anything else, let me know!