October 2023 Update: Shopkeeping, Battles, Fights, and AI!


It's been a very productive month for me! I haven't felt so inspired to work on Bravewater in a long time. It's honestly been fantastic.

I'll talk about what I worked on in a second, but there's a giant elephant in the room I have to address...

Unity

Unity announced some absolutely wild changes to their terms of service during the middle of my last month of development. It was, and frankly still is, a massive disappointment to see them do that. They've since walked most of it back, but they can't un-let the cat out of the bag.

At this point, I've been working on this game since 2016, and re-written the entire game once. I can't do it again. So I'm pretty much stuck with Unity. They're allowing users to stay on older versions and not be subject to any of their new terms of service, so that's what I plan to do. Hopefully that works out.

If I ever make another game though, it will definitely not be on Unity.

Anyways, on to the updates!

The Shopkeeper

I've added the shopkeeper system to my game! Here's what the buy screen looks like:

The first shopkeeper in the game will be the main character's dad, hence why you're seeing him. (another shout out to @KoltRiv for the amazing artwork!)

As well as buying things, you can sell things as well! Here's the UI for that:


I think it's looking pretty spiffy! There's some polish that I'd like to do to the overall look and feel of the UI down the road, but it's more than functional for the time being.

I made the shopkeeper system work with my favorite configuration file syntax - JSON! Each shopkeeper has a config file that looks like this:

{
     "shopkeeperIdentifier": "oscar",
     "shopkeeperName": "Your Dad",
     "buyWelcomeText": [
         "Now don't go crazy, I know how much money is in your allowance!",
         "I keep a limited stock, so leave some for the rest of the town!"
      ],
     "sellWelcomeText": [
         "What am I giving up some of daddy's money for today?",
         "I hope I can afford to buy all the junk you're selling me..."
     ],
     "afterPurchaseText": [
         "Thanks! I'll just add that money to your next allowance!",
         "Thanks for giving me my own money back!"
     ],
     "afterSellText": [
         "I have no idea what I'm going to do with this, but thanks!",
         "I'm going to go broke if you make me buy any more of your stuff!"
     ],
     "sellCharacterText": [
         "What's {CHARACTER} trying to pawn off on me?",
         "I bet {CHARACTER}'s got some good stuff to sell me!"
     ],
     "sellItemText": [
         "I'll give you ${AMOUNT} for it. You know... depreciation is a valuable lesson, son.",
         "I think ${AMOUNT} is fair, right?",
         "I mean it's one {ITEM}, {PLAYER}. How much could it be worth? ${AMOUNT}?"
     ],
     "canNotSellItemText": [
         "Uh... son... I can't do anything with that. You keep it.",
         "What the hell would I do with this? You keep it!"
     ],
     "notEnoughMoneyText": [
         "I don't think you have enough in your allowance to cover this...",
         "You're way too broke to afford this. Get a job!"
     ],
     "inventoryFullText": [
         "You can't hold any more things in your pockets if you tried!",
         "I question how you are even holding this much stuff as it is!"
     ],
     "items": [
         "health_potion",
         "mana_potion",
         "key"
     ],
     "weapons": [
         "wooden_stick"
     ]
}

This lets me put all the fun little quips the shopkeeper says, as well as the details of what they are selling and how the shopkeeper appears, all in one location.

I had a lot of fun building this. JSON is becoming my new favorite syntax for developing things.

Which brings us to the battle system!

Battles and Fights

In my last blog post, I mentioned that I had previously started working on a battle system about a year ago. Well... I threw it all out and started over!

Here's a demo of everything:

There's a lot to cover, so let's go through it!

Attacking

The "Attack" button lights up when you're in range to attack another character. Once you press the button, the option to choose who you're going to attack appears, like so:

This menu gives you the option to choose exactly who in the attack range you're going to fight. You press "Attack" once you've chosen your target, and you're off to your fight!

Magic

Certain characters have the ability to cast magic spells. The player starts by choosing a spell...


Then choosing a level of the spell - this also shows the range for each level of the spell.

Finally, when the player hits "Cast (spell and level)", they are presented with a menu to choose the center of the attack.


Press "Cast Spell", and you're off to blow away some enemies! Or heal your teammates, if you've cast a healing spell.

Items

Items in battle are controlled through the normal inventory system. The only catch is that you'll only see the selected character in the inventory screen, and can only give items to characters that are directly next to you. Here's what that looks like:


Signposts and Chests

When you're in battle and near a signpost or chest, you'll see a new "Interact With" option pop up in the options bar:

From there, you can choose a chest or signpost to interact with:

I hide the "Interact With" button until you're near a chest or signpost, as it's rare that you'll be near one in battle.

Fight!

When you're finally attacking a character, a cool transition brings you into the fight! Here you'll (eventually) see both characters that are fighting, and the background will reflect where the characters are fighting. 

For now, the character art is using their portraits as a placeholder, and it looks like this:

Pretty nifty!

AI

When I coded AI in the previous iterations of the battle system, it was a giant "if/else if/else if/else if/else if..." tree. That works, but it was incredibly hard to change the logic if I needed to tweak it.

Enter my good old friend, JSON!

I've made a decision tree out of JSON to represent those if/else conditions, then use reflection to turn them into code that can be executed. Here's a snippet of the JSON:

Basically, each node has a true/false path. Based on the logic in each node, it will call the code for either the true path or the false path. To prevent having giant files, I've split them up into separate files with separate identifiers. That's where you see things like "ai_logic_strategy.HealIndividualStrategy" - that's going to a different file to find its logic tree.

I call one node as the starting point and then keep following the tree till I hit a "null". At that point the logic is done!

Here's what the code behind one of these nodes looks like:


The system is not perfect by any means, but it's much better than a bunch of hardcoded if/else if statements.

I actually liked the system so much that I used it for the fight logic as well. Here's a snippet of what that looks like:

The end result is what you see in the video.

Both the fight logic and the AI logic need some tweaking, but that's as simple as modifying the JSON and some code behind the scenes to make it all work. So it's on my to-do list.

What's Next?

At this point, the RPG and battle systems are complete enough that I have a full game prototype working! There are a lot of small bugs to fix/tweaks I want to make, but the hardest part - coding all the major systems in the game, is basically done.

Next comes actual game dev work! I'll be starting by building the tutorial level, including all the artwork needed to get it done. This is going to be a fair amount of work, so I wouldn't expect to have any more of these massive dev logs any time soon.

I'm excited for things to start looking like a real game soon! And I look forward to sharing more as things progress along.

Before I sign off, I just want to say thank you so much for following along in my journey! Your support means a lot to me, and helps me stay motivated to make this little hobby project into a full game.

See you all later,

-J

Leave a comment

Log in with itch.io to leave a comment.