so I'll fix those up over the weekend and hopefully have basically an entire game on Monday.
Damn son you make this stuff seem so easy, this game seems to be coming along way faster than the last one.
Stumbling over all those stones on Capumon really paid off. It also helps that this game is a lot less technically complex and is also much more in line with what Godot is meant for - so, for much of this, I can rely on built-in features rather than having to build them myself.
Okay, Sewer Kings:So previously I made a class object (naming convention still escapes me, so this is likely the wrong terminology) - which is effectively a node that can do some operations for us given certain information. I took the same idea and made a more regular class: an NPC.
This is a Godot Reference - which isn't a Node. The difference? Heck buddy, if you figure it out please tell me because I have no fucking clue. You'll notice, I also didn't declare this as a class. I'm not sure if I'll be using the same structure for enemies - so I left it as its own thing for now.
What it does is quite simple - it takes a random description, name, and dialogue text from whatever arrays we feed it from the outside. I sat down and made a bit of content for each category.
About 12 first and last names:
Ten or so dialogues (really, it's a monologue, since the protagonist remains silent)
And then several descriptors, which I decided to break up into three parts:
When you start a new game, the game will go through the list, grabbing a first name and a last name at random, then removing both from the rotation, so that we don't get any repeats.
You'll notice it's reliant on the size of the first names list. I'll add a conditional here later so it will operate correctly if the last name list happens to be shorter than the long name list. You'll also notice that this will make 12 unique names only - which isn't many, but is a lot with such a small cast so far.
Since I decided to cut up the descriptions into three parts - I also decided that it's fine if some of these repeat (unlike dialogue and names, which shouldn't repeat). I move all these description parts into the Reference itself, then grab three at random and attach a pronoun to them. So now it'll read something like:
Here we have delphonso.
He is tall and thick around the middle.
He smells of cheap wine...on a good day.
He has a tendency to obsess over one topic for weeks or months at a time before moving to the next one.
This also means we only need to pass two lists to the NPC Reference, now. One full of names and one full of dialogue. These need to remain outside the Reference, because the Reference is going to be checked for every NPC we make - so it would be quite difficult to modify the lists if they're not outside of it.
Okay, let's make NPCs!
First we see how many NPCs are on the homeworld map,
Then, for each of those, we make a new NPC by sending the dialogue and namelist to the Reference.
What we get is a new object that has a name, description, and dialogue.
We add that to a dictionary of NPCs.
We then erase that dialogue and name from the list and start again.
The dictionary of NPCs is indexed by coordinates, so it looks like this:
(24,13) : name="delphonso", description="He looks like shit", dialog="Oh no, I pooped my pants"
(25,13) : name="Urist", description="A short, sturdy creature fond of drink and industry", dialog="So the kestrel and the kobold..."
Except description is actually an array of 3 description sentences. More like, description[0] = "He looks like shit.", description[1] = "He smells like shit.", description[2] = "He is shit."
You may have noticed I called for the global a lot here. Like - A LOT. Don't worry, I realized that as I was getting started, finished it to test it, then moved it over to the global. It now rests comfortably there, with most other functions in the game.
This is also only adding NPCs to the game based on the number I've placed in the home-town (something I expected to change, but haven't and it's growing on me how it is). I added this function for adding new NPCs should we ever want to. For now, it just does nothing.
Finally, I grabbed the right-most position in the dungeon and added a different symbol to it. I gave that position a collision that sends you back to the hometown.
Before releasing it on itch, I also modified some of the colors and have hit a more generic rogue-green with dark background for the textlog. I'll keep messing with it.
Oh, I also cleaned up the Look and Talk function so they now use the same function, but flip a boolean whether you're looking or talking to someone.
Okay,
Sewer Combat!For the sewer combat I decided to abandon the grid-based movement and just have critters/warriors move on a pixel-by-pixel basis. I simply put two buttons down that say "Add Ally" and "Add Enemy". This is just a prototype, remember. The whole thing consists of a tilemap to build the walls and floors, two positions for spawning enemies/allies, and that's all.
First thing's first - get the enemies to target the good guys.
The enemies grab their parent(the arena, effectively), then grab the list of allies that the arena keeps track of. They target ally_list[0], which will always be the ally that has been around the longest. Here you see a lot of dudes rushing down a dude who isn't moving.
Now, we add the same logic in reverse to the allies. Now that's what I call a real battle! Just a bunch of happy dudes shoving each other around.
Oh god, they got knives!
Now both teams spawn with weapons which they rotate around themselves (I can add a swing motion later, but there's something silly about all these guys wind-milling at each other). If a weapon hits someone on the opposite team, that member is deleted. I also added a win/lose screen that prompted the player to start again. This is what my wife found so appealing - trying to keep the violence going as long as possible. This is a cry for help from me, delphonso.
I also changed it so the pawns now target a random member of the opposite team, which changes occasionally, and means they tend to move toward the middle of the pack every time. I'll tweak this as well, as it sometimes looks pretty buggy - although it's effective for now.
I added some HP to units, then variable damage. I can pretty simply add a defensive value (damage reduction) as well.
It's enjoyable to watch, but would also be over real quickly in regular play. I'm not expecting the player to have more than just something like this on the field:
@ k
k ë
@
g
As of now, I'm thinking of how to make this more engaging for the player. I've got two ideas currently, both of which should easily slot into what I have now.
Option 1:
Rally Points:
The player remains engaged as they have some control over the positioning of their team and can tell them to move to certain areas of the map - this works best if the map has more obstacles, which would mean more pathfinding intelligence on my part.
Option 2:
Rematch!:
Instead of finer control, the player has zero control and is just betting on RNG. When you start a combat, you'll have 3 retries. You'll also be shown the reward, should you win: Let's say "3 kobolds added to your team". You can rematch any time before combat finishes, and if you do, the reward is reduced. This should make even fights way more exciting - as you hover over the rematch button praying that Cheeslfeebus can kill that last kestrel.
Not sure which one to go with, but I think both are decently good ideas. Implementing both might be possible, but depends how much work I want to put in - how much work it takes to add this to the game.