Greetings. Welcome to the sixteenth Greglog devlog Greg RPG devlog! You might be pleasantly surprised by the length of this one. Or maybe unpleasantly, if you happen to hate reading. But there's some pictures too, so it is fun and appropriate for everyone.
Monday. I think... I think it went well. I finally tested the kiosk stuff in context of the actual game with perk functionality added and it feels Pretty Good to play. That gave me a huge confidence boost.
Also, just for fun really, I added a cheat console for debugging purposes.
Tuesday got like, nothing done haha lol XD!!!! All the work I did was on the, uh, mining minigame actually. I'm worried about its performance, and I think I improved it somewhat. I also changed how bbcode tags work in dialogue, they now encompass the line not every single letter :) This all took like 20 minutes maybe.
Also, did you notice how I gave a much more detailed account on tuesday than monday? For some reason. I can assure you I did three times as much work on monday than tuesday.
Wednesday? I did not note anything down during wednesday. But I did reveal the new character, the Mail Man to the Neocities Discord. And he was quite well received! I think!
I mean, he was already. Like, revealed... His face already exists on the outline page. But I guess people now saw him in action, kind of. Yeah.
Mostly worked on cosmetic things. Newspapers have a cool glowing trail now. They also now get properly aimed towards where you click, not in the approximate direction... Can't believe it took me that long to realise look_at() exists. Well, I knew it existed... But I didn't think to use it there for some reason. The last implemented perk with no functionality now has functionality. And some dialogue jank with the kiosk has been fixed too: you will no longer ever open the kiosk to a fully typed out dialogue.
Thursday. This day has been weird? Little actual work on the game... I edited some artwork and wrote more into the story document... Yes, the story document, that should hold everything that can and will happen in Greg. It is very barren at the moment. Or, not that barren anymore, I guess... I wrote about the final boss battle, its intro and aftermath. Mhmh.
I did a bit of testing with low fps... Battles and overworld work fine, but dialogue is way slower on a lower fps, because it uses yield(get_tree(), "physics_frame") to keep the while loop running, and that is affected by fps. And I doubt I'd be able to fix it at all to be honest.
Also, I ran out of bandwidth for the month... Yes, I live with limited bandwidth... Shouldn't have downloaded those No Man's Sky updates... It matters little anyway, since the month is almost over.
Friday. Say, have you encountered... a car... during the last two weeks? Yes? You have? Great! That means you have experience with meeting cars. Which means that the next Greg RPG feature will be super immersive and impressive for you!
Cars! They look kind of bad... That's because I suck at drawing cars.
Cars use the in-built PathFollow2D node, which, as the name suggests moves along a set path.
They seem pretty performant, even with this many cars I still get 60fps. The editor is a different story, though, but I can live with that...
As in real life, getting hit by a car is a bad idea in Greg RPG.
The music for this battle is one of my favourites to be honest... It sounds stupid and rather ridiculous at points. But that's good? I think it fits very well.
I also changed some more technical stuff about enemies. They now use exported variables mostly to store their data.
The old solution used the enemies.gd resource file and looked like this:
I don't know if the new one is, like, much better than the previous solution... But it is slightly easier for the enemy to access stuff. Because it's in its own code now, instead of in some dictionary... The enemies.gd file still stores the path to the enemy's scene and their name.
And a little bug fixed, not even noteworthy... Enemies could not use a spell if they had exactly the amount of magic that the spell costs to use, because I used "if spell's cost is less than magic" instead of "if spell's cost is less than or equal to magic" in the code... No longer will they get stuck there.
So, friday was a pretty good day... Yes...
I added some more save functionality on saturday morning: cars now have their positions on the road saved. And, if you manage to defeat a car in battle, it will not reappear in the world. So, yeah.
I added camera shake to the battle screen, when actors get hurt. I also added a slider to set screen shaking intensity in the options menu, next to the checkbox that toggles the trippy battle background shaders, added yesterday.
I entered, like, a coding rabbit hole. So, I wanted to add in support for new enemies to join the battle DURING the battle. The first thing I did was edit the battle starting function and decouple spawning enemies from it - the LOAD_BATTLE() function now only calls the add_enemy() function, instead of containing it completely. Then I had to remake the assigning-enemy-names-Greek-letters system, since it was reliant on the battle loading function. If you don't know what the Greek letters system is, it basically gives duplicate enemies in a battle greek letters at the end of their name, to differentiate them. It also has support for when the enemy count exceeds the length of the Greek alphabet (25 or something?), in which case it repeats the letter... like, the enemy next from enemy ω is enemy αα. This should NEVER EVER even come into action during actual gameplay! But I added that system nonetheless. And I readded it now as well. Took a long time. Anyway, as I was testing the rewritten Greek letter system, I noticed some flaws with the battle acting cooldown system, so I replaced the in-code yield() calls with a separate timer that emits the act_finished signal straight from the BattleActor class. The act_finished signal basically tells the battle to resume the time progress, it waits for all actors to act before resuming. Previously, the signal was only emitted from the inheritors of BattleActor (Greg and all enemies). Also it turned out that Greg's act_finished signals were being told to be emitted from the battle code, so now Greg too emits act_finished from when the acts in BattleActor are finished. The main issue that this fixes is when a spell is used on a lot of enemies, the spell caster should not emit act_finished until all the targets of the spell are affected. Which was not the case before. So that's good. But I still haven't added support for adding enemies during the battle!
I also think I fixed a bug where the enemies could keep acting even if Greg's cooldown is 0. I mean, it only seemed to appear when there were a LOT of enemies (I was testing it with 111 Multipanthers - never ever going to happen in-game), but I like knowing that it's fixed.
I don't know where else to put this, but I'd like you to know that the battle system is being held together with glue from an old gluestick. As is most of Greg RPG, actually... As is most of my life, if I think about it...
Also, here's what roughly 111 Multipanthers looks like:
The screen shake when they attack each other (confusion status effect!) is making me dizzy...
Pfft... That's not right. I have to add an exception to not display that message when it's Greg... He is always confused. That's the in-game explanation to why the confusion effect doesn't do anything to him (it's actually because I'm too lazy to code in exceptions to make Greg not take in user input).
(Sunday Lyth popping in to say that I fixed this by making only enemies send the "not confused anymore" message, instead of saying "anything but Greg should send this message". Nice!)
Also look at these Multipanthers gliding to the bottom of the screen after dying in sync. Cool.
This truly has been a "111 Panther Experience". (In the actual game the level will be capped at 99...)
I took some more time off my rapidly shrinking life and started adding support for dialogue inside battles. At the moment they use the global dialogue boxes, but I was thinking of maybe adding in little speech bubbles? The enemies now have variables to store these lines. There are turn lines which aim to speak a new line every turn. There are health lines that are spoken if the enemy's health reaches a low enough point. If there are multiple enemies of the same type in the battle, and they have lines, then only one of them can speak a line. The others can speak another line if they're lucky. The code for speaking these lines is an absolute mess. It's really bad. But it works!
Also: talking graphics for the bike ghost.
I think it looks pretty cute when angry :3
I added death lines also, that enemies can say when they're defeated. That was a good idea. Bike Ghost's line is pretty funny... I think. I have a juvenile sense of humour, so
I'm really sensing the aura of internetless boredom wafting towards me as I reread the text I've written today. But this has been really productive also... Not even my phone can distract me now. I dread going back to normalcy slightly... But alright. Good night.
Well, it's sunday now. I made a little theme that plays when you win a battle. I'm worried it might be a bit too long and boring (around over 10 seconds) but further testing is in order I suppose.
Currently waiting for a battle with 9999 Bike Ghosts to load at all. I think I've been staring at the boot screen for over a minute or two now.
HOLY crap IT LOADED!!! I went away from the screen for a while so I don't know how long it took.
The UI is super messed up looking... And look at those enemy names just exiting the screen lol! The fps is at a stable 2 at the moment. Also, the correct battle background didn't load.
The turn updater seems to struggle at such a low fps... It's definitely not decreasing fast enough...
A bike ghost is trying to say its turn line! But the fps is too low so it's going terribly slow.
Thank good that skipping dialogue exists! Anyway, it was Bike Ghost iota saying that. The one with one iota, not with a bunch of iotas... So they kind of act in order.
It's so slow... We're only at Bike Ghost psi right now... still at singular letters.
Alright, this was "fun". Time to do something productive now.
This is hours after I promised to do something productive, but I think I added support for extra enemies to enter the battle through spells (the thing that I started yesterday). Multipanther now has a spell that summons an extra cat to fight during its battle - oh yeah, I added cat enemies.
Their gimmick is that they're really fast but also have a high chance of not doing anything during their turn.
They can appear in packs up to, like, four, currently, and they're really tough. In the above image, I started fighting them as a level 58 Greg and barely survived. I had to resort to healing items after my magic ran out.
Also, they're called "hatebeasts" in the screenshots, but I don't know if I like that name too much... I mean, it has to be something different than just "cat". Just how Multipanther isn't called "tower of cats", which is what it actually is. I don't know... If you have name suggestions for the evil cat enemy, uh, suggest.
Back to the adding enemies system: I decoupled the initial enemy spawning function from the LOAD_BATTLE() function entirely, it now can be called more than once per battle. And I discovered that the storage solution for enemy types and counts inside battles.gd works well enough, so I copied the syntax into the spells.gd file and made GLOBAL.interpret_effects() interpret that syntax. The new enemy is technically spawned by whoever the "spawn new enemy"-type spell is used on.
This is the new most beautiful part of the Greg RPG codebase. This code checks if a spell has an enemy addition part, then checks if the part specifies a max count for enemies in battle, then checks the count of enemies currently in battle and if it is less than the max count, says "go ahead, use that spell". If a spell doesn't have an enemy addition part, it's also free game... And if at the deepest level the check fails it suggests to the enemy to do a regular attack instead. The enemy spawning code in Battle.gd also checks those same criteria roughly, just with less out-of-hand indentation. I promise most of Greg's codebase looks more normal than this. Most of it. If you happen to be surprised that the game runs at all after seeing this: Hey! Welcome to the club.
While you weren't looking, I went back to the cone-shaped function and made it even worse. It now also checks for if the spell has the "use_cases" dictionary parameter, which specifies stuff like, at what health percentage should the AI start using that spell and so on...
Okay, I cleaned it up a bit. I moved the stuff-checking into its own function that can return either true, if all checks pass, or false, if any of them fail. Here:
It's still cone-shaped enough for me.
I also added a new type of message into the battle log that shows when someone's stats temporarily increase or decrease.
Related to the stat increases and decreases, I've found an annoying bug. The message "x is no longer confused" is being put into the battle log even if x is still very much confused. I found this weird Godot glitch while working on fixing it...
Why is that text green? It's supposed to be white. A mystery for the ages.
Alright, I fixed the issue with people saying that they're no longer confused even if they still are. The fix is ugly and cringe, but so is how the entire status effect system is made. It's sad. I'm sad. How did this happen? What cheers me up though is this:
So. Technically, the car's "runs you over" attack is a spell. And spells cost magic! And the cost for that spell is around 700 magic I think, which is the entirety of the car's magic reserves (the cost's that high to avoid it being used if somehow given to the player). And I was playing around, putting all the currently available enemies into a battle together and then giving them all the confusion status effect, to make them attack each other randomly. That's my idea of entertainment. This is also how I discovered the bug mentioned previously. Anyway, I decided that the car should be able to use the "runs you over" attack more than once, because it's amusing. And instead of just increasing its magic reserves, I gave it another spell that fully replenishes its magic reserves, this time the "revs engines" spell, right. So the car can use that spell on anyone if it has the confused status effect... So I think it's pretty funny when the car revs Greg's engines and how Greg is "all gassed up and ready to go"... The implications of this are terrifying, so I'd rather laugh at it instead, thank you.
Speaking of spells, I gave Bike Ghost a cool-looking new attack, the, uh, "Beatdown of Justice!!".
It can only use this attack when its health is below a quarter of its max health, so it's like a last resort.
At this point it's around 23:00, so I should start wrapping things up for uploading once my internet comes back online. I have a lot of pictures to upload and then link to inside this document... (I would, if I had internet access, have sent all these to my friend on Discord instead, but I don't have internet) I think the lesson here... well. There could be either of two lessons here:
Possible lesson one: I must restrict my internet access even further to make adequate progress! These three days without internet were wonderful for the progress of my game, and that might just be because I wasted all my monthly data on downloading 8GB No Man's Sky updates! Not even my phone could distract me now. However, consider:
Possible lesson two: notice how I worked mostly on the battle system of all things, instead of the biking minigame, which would probably require the biggest amount of work right now. I was, to be honest, quite tired of working on the biking minigame... And the battle system's flaws kind of just got in my way as I was making new enemies for fun (the car, the cats). So I still kind of worked on something other than the priority...
What can we figure out from this? Probably elements of both lessons are applicable... I'll have to see whether going back online will decrease my productivity too much, and then maybe restrict my internet connection myself even harder.
Another thing I wanted to mention... I kind of want to. Make a playable demo version available in this august, call it the "august demo"... It should include the first section of the overworld (technically, the Greghouse and Town1 scenes) and the overworld should have connections to the mining and biking minigames. That all would literally be everything added to the game, by the way. I'd really like to get player feedback on the current state, and hopefully we can catch some of the nastier bugs lurking around. Because I am certain that they are lurking around, I just can't think of any way to play to find them. It's a paranoid mindset but, like the old folk's saying goes: "better to fear than to regret". Yeah. I think I might even link the demo inside a devlog, instead of only burdening the Neocities Discord.
Fun trivia since I'm bored: this devlog as I am writing it is a whopping 21kb of data. It is only second place in size though, the glorious devlog number five is over 2Mb, thanks to the genius of Base64 encoded images. So smart! So clever! So fun to work with. Devlog sixteen is a much bigger milestone than devlog ten was, as you can see... I can live with that. 16 is, like, two power of something. And those kinds of numbers are very cool.
It's getting closer and closer to midnight... Closer and closer to the new month... Closer and closer to reestablishing contact with civilisation! I am anxious over this.
But... that's everything I managed to pour out of my mind, I think... It's scary what free time can do with a person (me). See you in the next one ε>