Rule #1 about planning and estimates, your plans change and your estimates sucks. And you know what? That's normal. The computation prowess of the collective world has increased by magnitudes in the last century and yet, somehow, algorithmic trading is a very hard problem, and you'd think that somehow, writing down what you'll have for dinner the day after tomorrow will cause the monstrous forces of chaos and entropy to halt their rampant surge to incoherence and they'll say "Oh no, he wrote things down. I'll have to reschedule".
That is all to say, I did not write a screen-space shader, or make 160 spells, or do a lot of animations, or have many points of interest for world-building, nah, instead I spent most of it re-working things to use still-flat, but present in 3D enemy textures, adding a spell book, writing a save system that's awkward and kind of broken, and some nice-ish UI elements which tied the game together into the final release and where it stands today.
But hey, I made the jam deadline and you can play it!1
One of the most important things to do when planning work is to honestly ask "Is this really worth doing?" and the horrid, awful truth of the matter is that you can't possibly know unless you actually perform that work.
I believe strongly it was worth spending the time modifying the game to use 3D textures that are actually in the world instead of 2D ones that would just be in screen space. This opens up a lot of possibilities like using spatial shaders to punch holes in, warp, and do many other manipulations to the enemies while still having them do things like cast shadows. There was a little teeth-pulling with adapting the system from 2D, but thankfully my making the Animation Player "dumb" and just passing pointers to the enemy representations in the world helped a lot since I only had to modify those functions and not care about the underlying data structure. This will also make it much easier to un-parent the damn things from the battle scene, which is a child of the camera, which is a child of the world, which is what the enemy representations should be a child of so they don't inherit the camera transform, but I'm getting ahead of myself…
Adding the save game system, from the game jam perspective, was not a valuable use of my time. I was stuck in the whole data mentality of that I had built the system to be serialized and I've done this before once so it shouldn't be a large lift. This ignored the fact that I was making a jam game that had, at the time, one room, that grew to four by the end of the jam. I could've used those four hours, which I spent messing about with serialization issues, in order to add animations, sfx, more models, more spells, maybe status icons, tooltips… all of which would have improved my jam submission much more.
And you know something? I'm not even mad. In fact, I'm glad I screwed up because this was a future landmine I'd step into anyway so while my jam submission might not be 5% better for it, I still believe the time was well spent in the greater context of my long-term plans.
As for the spell book, it looks pretty and I like it. Can't wait to replace all those default engine panels with textures, spend hours texture painting book leather, and add dove tails π to everything.
It took me 10-odd games to get comfortable with it, but I now see the wisdom in Godot's Control node system and have come to understand it's zen and how it works with themes:
Many users, including myself, start to work with control nodes and get frustrated because we can't get elements to fill the space we want, align to the right place, and we see the dreaded scroll bar appear. So, basically a normal day in the life of a web designer. To bring sanity to this situation, let's remind ourselves of the two problems UI layout frameworks solve: Content should be displayed consistently, despite screen resolution or context AND content must be well-framed so the user can quickly find what they need.
We can fit most of what I've done here into those two buckets, having different containers with alignment controls, minimum sizes, and 'expand' flags tells Godot how my UI should be handled in any context, while margins, drop shadow, different fonts, separators, and color help to separate elements and create context the user can pick up on. Since I've reasoned about this, some unknowns like why you have to specify sizes for fonts/minimum sizes have become more clear, because Godot has to consistently figure out how to place your stuff and they're many edge cases for this.
Programming wise, the biggest show-stopper is the accursed mouse_filter
property any UI element has2. See, when a use clicks on a UI element, it might be on top of another UI element like if you've opened a sub-menu. So, naturally you'd like the top-most menu to not let that input propagate to the things below it and this is where mouse_filter.STOP
comes into play and is the default behavior for panels and text elements in Godot. Where you have to be careful is when the UI element is purely for display purposes and you might keep it instantiated, but not visible in the scene. Then if you have, for example, an interact prompt centered in a scene that has a standard Control
node at it's root, which by default is mouse_filter.STOP
then you'll probably have some rage-clicking later when you realize you can't click on anything else in your scene! For such a case, setting mouse_filter.IGNORE
on the offending element solves the problem.
Some other tricks for the curious:
Default_Cursor_Shape
to POINTING_HAND
for buttons. You don't notice it in most games, but it's important to let players know they can click things!X
buttonesc
I delayed for quite a bit on the illustrations for the monsters. I don't really regret this, since I was knee-deep in other work, but I do believe I could've produced better baddies had I been more consistently putting time into them. Which is something to note for the future.3
Since about Bayou Fishing4 I've used this style of creating a sketch, putting vector graphics on top of it, and using compositing touches in order to give the result some more life. It's handy because with vectors I can make small adjustments and still have a "clean" line that I don't have to fret over much, although without having organic strokes I believe it still triggers the 'oh no, cooperate propaganda or cereal ad' response. Might be somewhere I can add an extra step to jump over like giving these guys outlines or something.
The concept of 'The Weeper' was that it was someone who mutated into a sort of living-candle and is suffering immensely from it, weeping, but he has not tear ducts so he cries wax instead. To make the flames I created a sphere gradient which I ramped from yellow to orange, stretched it, and used a liquefy transform to give it a point, then I just airbrushed out the bottom part of the flame and gave it a touch of blue. He probably suffers from my choice of color scheme and lack of exaggerating his agony, which makes him look a bit like a cartoon, but he's getting there.
For 'The Shade', he's a buff-casting support kind of enemy, so I wanted him to look lithe and mysterious. The symbols on his hood where meant to almost make it look like a face with the hood hole being his mouth. In the initial sketch, I had the front hand only have needle fingers, but this looked too much like Freddy Krueger so I tried something a little different5. For his left hand I initially just had the fingers as holes but thought it would be neat if they were colorful like 'these are where the magic comes from', but now it just makes me think of the Infinity gauntlet. The Jade necklace was me trying some stuff with materials and the texture layer is just a cloth texture multiplied then messed around with using a liquefy transform. Out of all three, I dislike this incarnation of the idea the most because it 'feels' like it's trying too many things at once and I should either just go absolutely ham on that or pick one idea to focus on.
'The Spiked' was, hands-down, the winner in my opinion. When I painted on the eyes, looked at them, and felt a chill run down my spine I knew I hand something on target. I really want to explore more texture painting for things like this. The idea for him was that something erupted from his insides and, not only punctured outward, but skewed other parts of his body as well, like his right arm. Reflecting on it, all three of these designs have messed up left arms, which I'm gonna attribute to an old Scout leader I knew who had his left hand amputated, it plays well into a core theme I have in mind for the game which goes along the lines of 'people that are missing something'.
I believe these guys are a pretty promising starting point, although in the future I need to do sketches/experiments every day instead of maybe once a week. 'Having ideas' for things every once in a while isn't hard, but if you hold someone at gun point and ask them 'give me ten horrifying concepts for demon-possessed people' you'd probably hear a bang not long after. Same goes for actual technique, I've gotta give myself some more exposure to ways of doing things so I can make something unique.
Honestly, I made four of the five spells the night the jam was due as well as two of the enemy effects.
The idea for spells was meant to be balanced around the weeper having a lot of health and outlasting you, so you'd have to:
This, of course, didn't work because I refactored the encounter system last minute to use enemy definitions instead of re-using the same enemy object over and over for encounters, which caused a bug of empty encounters popping up. This in turn, caused me to do some balancing that made the weeper weaker and borked any sort of strategy beyond spamming Flare.
There's a couple things I could do to fix this version of the game:
Either way, much experimentation to be had.
Movement in the game was handled in a short of classic, dungeon-crawler fashion where the player adheres to a strict grid and moves in discrete increments in cardinal directions, rotates in right angles, and can strafe from left to right. for things to feel more responsive, I also buffer inputs so that if the player presses move during a move, the system will register it and perform that move after the one their currently making which is a small thing, but also essential for things not to feel stiff…
Yeah, things still felt stiff. This isn't a blog to talk about feedback exhaustively, since the jam grading period is still on and I'm still gathering data, but the one piece I will mention is just about everyone talked about the movement feeling bad which I didn't even thing about! Here's a few things I've noted:
The old Megaten games were brought up as an example where the movement was constrained but felt 'snappy', which maybe means I don't really need to interpolate between locations and could just 'snap' around like 2D games do. There's also the option of just making things faster, but I don't think that necessarily makes movement feel less 'stiff' or less 'restrictive'.
So I've got some experiments to try here:
Once Lent is over and I can play more video games for research7 I'll look into what they do as well. to see how other games have solved this problem. Whatever I chose, it'll likely affect the types of environments I can make if I want to do stuff like having a 'flying spell' or 'teleportation' in the over world.
A decent model, I feel, for level design is to think of things in terms of 'setting' and 'points of interest'(POI). The 'setting' is things like a path, walls that confine the players movement, the skybox, ect. These elements frame the world and either enable the player or restrict their options in some way. POI is anything the player can directly mess with, like an item they can pick up, a physics object they can toss, switches they can throw, areas that react to certain spells/abilities, and locked doors. From a programming and design perspective a 'setting' object should be something that can be easily placed, modified, brushed into the environment without any scripting since why would an artist need to worry about collisions? POI should, likewise, have minimal scripting so you can create as many of them as you need without breaking level design flow UNLESS they're part of your game's core mechanics, but they should be parameterized whenever possible.
If you've ever made a Doom map8 you'd call a POI a 'trigger' for some action. In my case this is mainly the object spawning a dialog and doing things depending on the context, if a door is locked, don't do anything unless the player has a key, if it's a key item, the player picks it up after reading some dialog.
Some of this is self-evident, like 'no duh you can model a switch element the same as a locked door you numbskull', but what if I want the switch to operate on the logic of some puzzle? What if I want the locked door to go to a different location depending on the key used? What if I want an item pickup to trigger an enemy encounter, dialog box, itemGet
event, and so much more? And if it doesn't need any of those parameterizations, then I can just put it in a general class of thing, like a collision box generator for level meshes and leave it alone. Point is, complexity can be built upon simple rules, you can save yourself work if you can categorize things, and it's fun to reason about this.
Right now the POI system in Monastic Inversion is fairly simple and ad-hoc logic handled by if
's in the player movement script, since they're only two objects. I plan on expanding upon it greatly with the hopes that I can pull off something similar to Darkwood where items, locations, characters are consistent, but where they are in the world may be different, encouraging replays. Might also be fun to provide a level editor, challenge levels, or randomly generated gauntlets that have the over world as part of the competition. For those kind of tasks, I need a good interaction model.
Another thing I think Gamers appreciate without thinking too much about it is dialog boxes and I have a system for this:
The only other thing I really have to add is that bbcode and text shadows are great tools for making dialog feel more 'alive'. I think most people have caught on because we all played Runescape when we were young, but I'm still surprised by the amount of games that don't even have different colored fonts or any fancy formatting/animations. It can become a gimmick if over-used I suppose, but games like Pyre with it's hyper-linked lore text makes me think this space is still worth exploring.
The greatest part about this whole mess is the dialog_finished
signal. Any component that calls up a dialog box can wait on it's completion which makes it very handy in the overworld, battles, and ad-hoc opening and ending animations. I think eventually I'll come to regret using await
so much, but it really has been a useful tool.
I do still need to add a system that'll allow me to write in something that can be read in by the game so I can proof-read things. In the past, I've used .csv
files, but I hate writing in .csv
rows in cellular editors. Plenty of 'dialog tree' solutions exist as well, but ultimately I think those would be more useful if I was aiming for an immersive sim or full on open world RPG. I'll probably write things in Org mode where they can be categorized and tagged, then write a script to put that into .csv
which a translator can add translations to, then load into the game.9
For a competition with over 5k sign-ups and almost 1,000 submissions, I think Acerola, the youtuber putting on this jam, has done a pretty good job10. I hadn't really considered jams to ever really be 'team' experience because I've done everything solo up till now and probably will continue to do so for awhile and having a jam where EVERYONE's gotta go in it alone feels, balanced I suppose? Like, if I get crushed by another submission, it's not because they had a full on squad of a game dev studio behind them to just sweep the competition, but because I was soundly beaten by somebody better. It's kind of comforting.
Having two weeks to work on things has also done me a solid by forcing me to really work daily and make a deadline for something reasonably complex. I've already working daily since last valentines day, this jam has just made me work harder for the opportunity of early feedback.
The theme kind of sucks, but I don't think there's ever been a good jam theme anyway.
Doubtful.
Monastic Inversion, as it stands, is more like a tech demo. Solid foundation and a glimpse at what could be with a beginning, middle, and end, just not a 'complete' game experience. I'll do a full roundup at the end of the jam to talk about my favorite submissions, which all felt more like actual games in the sense that there was a challenge to be met, a skill curve, and cooler game play mechanics.
'Winning' a game jam has never really been my goal. It's not a Olympic sport or chess tournament where you've got a sort of meritocracy on who's best, it's more like a festival of ideas and prototypes, a modern day, Internet held World's Fair of good works by artists who get things done.
Usually I forsake any sort of Discord/IRC chat kind of thing during Lent, but I made an exception here because I believed that there was real merit in taking part of the shared experience of devving for two weeks with people. It was a good decision, posting daily progress and discussing various roadblocks, frustrations, or delights of development was motivating. What I took to doing daily was creating some of the images you see in this very blog explaining, at length, various solutions I'd come up, changes I made to the system, or just general barking about my way of doing things. It helped a few people, myself most of all since in having to think on how I'd explain something, it forced me to consider whether I was making good decisions or not.
However, soon the tent pole of the game jam will be kicked out, at which point I'll probably purge most of my presence on that server, mute everything except the article channel and maybe the shader programming one, and check on it very rarely. See, I'm the kind of person who LOVES to talk, analyze, model, explain, write about, and over share whatever they've been doing(if this blog is any evidence of that). In the workplace, this serves me very well because nobody has to ask me what I'm up to and a lot of landmines are side-stepped this way. On personal projects, it's kind of an addiction, almost a vice.
Curving my craving to constantly vocalize and share my thoughts has been an uphill battle. One that I've been fighting every since work-from-home became a thing, probably from even before that time. Discord is a huge temptation for me on that front, since it makes it easy for me to expel whatever I'm thinking to a select, possibly interested group of people. Then we start talking about other minutia and before I know it, it's three A.M.
The other issue, that I'm loathe to talk about because it feels nasty, is that I believe the community is gonna turn for the worst. Like I said, the tent pole of the jam has been kicked and I've consistently found that every Discord channel I've been apart of the real 'doers' aren't the ones that are always in the chat room posting memes, it's the ones who're like Sasquatch, popping up every once in a blue moon to post stuff and then disappear. The people left over, constantly posting, will mainly be people who probably didn't even submit a game or stopped developing games immediately after the jam was over.
The problem with always socializing with those people and being tempted to, is that a lot of the discussion will come down to "ahh, yea, I haven't devved in forever" or "nah, I gave up on my jam game like two days in" and this is poison to me. I'm way more empathetic then I believe myself to be and when I read these people's stuff, I die a little inside and try to encourage them or give them advice. But I don't have the time and what happens is that I absorb their pessimism like a sponge and become like them. This has happened to me several times in my professional career and has only been fixed by A. getting on a new team or B. separating myself entirely and acting as a solo unit.
Again, I don't mean to be vindictive or blame anybody here, I've just got a mission and if I'm gonna do it, I can't let over-socialization get in the way. I have to remain focused.
At his point, I've decided to hit pause on "Boat Game"11 for now. I still believe it's a great idea with potential, but I'm way more excited about Monastic Inversion right now and there's so much I want to develop on.
It kind of makes me anxious, because I have to wonder 'was this always going to happen?' taking a two-week pause to work consistently on another project that gets feedback versus the other two-week project that didn't kind of feels like I've screwed the first one doesn't it? On the other hand, if I was so willing to take a two-week break to work on something else, how 'sticky' was the first idea really?
That whole discussion is kind of pointless I think since, I haven't published a commercial game yet and fretting about which idea of the two is better is meaningless in that light. From the motivation perspective, I really want to use the tools I've made for Monastic Inversion and improve upon them.
Then, the only real hurdles are the added complexity of Monastic Inversion over Boat Game, which I reason are:
Problem #1 I feel is very surmountable with public-domain textures from ambientCG and a little work on level creation flow12. Problem #2 is a larger risk. I could work on many enemies, spells, effects, for months and just find the whole concept wholly unfun by August 14th which is the deadline I've set for putting up a Steam page. If this becomes the case, I'll cap off the project as best I can, set the price to $5 or less, and then let it cook wishlist's for six months while I go work on the next project instead. I'm running a marathon here, no need to worry about one bad leg of the race. I'm hopeful though! This is just 'worst-case scenario' kind of stuff.
With all that In mind, I think my best course of action is to prepare a fall demo. A vertical slice of the game that'll feature:
The goal here is to create something 'pitchable' that I'll be able to show at Steam's fall "next fest" festival, then begin the content grind in earnest as I work toward the February 14th, 2025 release.
It has been a long winter, about a month since I started to work on games daily, and I have roughly 330 days to ship a Steam game or I'm out $5k. I won't say I've been 'uber-productive', my metrics won't let me, I have kept the thread going however, and, when I am working it feels like I'm in a metro car, constantly carried forward by some unknowable force. Sometimes I see distractions and temptations and we'll chat for a bit, but I don't lose the thread anymore when I decide to work, I don't orate as much to an empty room or get distracted by researching the steam tunnels.
I'm looking forward to see where I'll be next month.
1 https://soulreviews.itch.io/monastic-inversion
2 https://docs.godotengine.org/en/stable/classes/class_control.html#enum-control-mousefilter
3 If you read the past blog and are wondering where that one design went with the bug on that guy's head, I accidentally saved over it at some point when doing some scaling experiments. I've been keeping binaries out of source control for SOME REASON, but I can't say that was a smart move for smaller files.
4 https://soulreviews.itch.io/bayou-fishing
5 Was also thinking about Candy Man at the time.
6 Think Eternal Darkness: Sanity' Requiem where each spell was aligned to an Outer god and had an RPS like interaction system. I'm not totally set on what alignments should be or if they should even be in the game however.
7 I don't play video games during Lent for pleasure. I don't know where the line is on that, but I know playing other jam submissions is my Godly responsibility and that playing Legends of Grimrock or classic Megaten games might be a temptation too far to break that rule.
8 If the answer to this is no and you suck at level design, please go make a doom map. It's easy, fun, and educational.
9 Although I wonder if a translator would be able to respect BBcode coloring in all cases? Or if I should just check for keywords when loading things into the game and insert the proper tags. Would allow me to have that particular bit of player ergonomics without having to hand-roll it every time.
10 https://www.youtube.com/@Acerola_t
11 https://soulreviews.net/blog/Boat-Game-Dev-Log and https://soulreviews.net/blog/Boat-Game-Dev-Log-2
12 I'm not gonna gush about it as much in this blog, but there are over 2,000 textures available here: https://ambientcg.com/ which are public domain, include normal maps, and if you sub to his patreon, you get access to his drive with all of them as Blender materials with asset library support. Best $6 I've ever spent.