2011/04/06

Monologue

The latest check-in has example dialog support. Well, really at this point it’s Monologue (the hero doesn’t talk back yet). I also have support for completing dialog options (same function for completing quests) and awarding xp, gold, and loot.

I implemented campaign states as strings instead of as ints. It’s much more readable and easier to maintain the data. See an example of the syntax here.

I still have to make campaign get/set in Map Events and on Enemy deaths. That will open up many simple quest types.

2011/04/04

CampaignManager.cpp

I started the very basic framework for the Campaign (story) Manager class for Flare. Right now all it does is read/write a bool status[1024] from the save file (as plaintext hex, cause that sounded good at the time).

On the plus side, this will be very easy to implement. Various classes will get/set these booleans. NPCs, map events, and the quest log will react to these simple statuses.

On the down side, this is as complex as I would get before strongly considering a full scripting engine. So extravagant cutscenes, branching dialog, etc. probably won’t be part of the first game.

Item Storage

Bonbadil completed some fine refactoring of the Inventory and Vendor menus. Here’s a quick explanation of the new classes.

ItemStorage is all about data; an array of ItemStacks along with generic functions to add/remove/return items.

MenuItemStorage is a derived class of ItemStorage that adds GUI functions (rendering icons, determining on-screen slot locations).

And here’s how they’re currently used:

  • MenuVendor has a MenuItemStorage for the 80 vendor slots
  • MenuInventory has two copies of MenuItemStorage (equipment and carried blocks)
  • NPC has an ItemStorage for vendor stocks; multiple vendors share the one MenuVendor. NPC ItemStorage data is passed to the MenuVendor MenuItemStorage on MenuVendor::setInventory()

Having common code pulled into these new classes should help these menus work consistently. It also makes some features easy to add later e.g. workspaces for crafting or player stashes.

2011/03/29

Art used in 7-Day Roguelike

I’m proud to see one of my tilesets used in a 7-Day Roguelike Challenge game! The developers, Ido Yehieli and Corey Martin, really poured some life into this minimalist tileset! Congrats to those guys — making a game in a short amount of time is quite a feat.

Play the game: Detribus

Ido is also raising funds for a more in-depth roguelike. Check out Cardinal Quest on 8-bit funding (only 3 days left)!

2011/03/28


Portraits

I’m starting to test portrait integration into NPC talkers. Here’s an in-game mockup.

screenshot of an NPC portrait dialog

Campaign Dialog

I’ve been pondering how to handle dialog that depends on the current state of the story. The NPC files will have [dialog] blocks that contain story-dependent conversations.

Here’s an example of plain back and forth dialog that only occurs once (sets a new campaign status upon completion).

[dialog]
requires_status=1
him=Welcome to … say, you wouldn’t happen to be Matthias’s kid?
you=I didn’t know my father was known in this part of the Kingdom. My name’s %n.
him=The kingdom’s smaller than you think. I’m Reginald. I worked with your old man on the Skybridge project, back before your time. How is he these days?
you=Surviving, like the rest of us.
him=Glad to hear it. Say, unless you’re just passing through, pay a visit to Jameson over at the Frothy Tankard Inn. He served at Skybridge with us too. The two of them were best of friends. Hells, Jameson might even put you up for the night free of charge.
set_status=2

If you talk to the guy again, he’ll say something different. The engine will display the lattermost dialog option where the requirements are all met.

[dialog]
requires_status=2
him=Frothy Tankard Inn is right on town square. This road will take you straight to it. I’m sure Jameson will have plenty of stories to share about your father.

Now here’s an example of how quests might work with dialogs.

[dialog]
requires_status=10
her=There is a storage room under the cathedral ruins. There should at least be a few sacks of grains, if the plague rats haven’t gotten to them first. It would buy us a couple more weeks here… but don’t go risking your neck on our account.
set_status=11

[dialog]
requires_status=11
her=There must be a safe path to the cathedral storage rooms…

Campaign status checks could also be added to map events.

[event]
# if on the “sack of grain” quest, drop it here
requires_status=11
requires_not=12
msg=You find a sack of wheat grain. Maybe luck has turned around for those refugees.
loot=item,2000
set_status=12

And quest turn-in:

[dialog]
requires_status=12
requires_item=2000
her=You’ve found food! I don’t know what to say, or how we could possibly repay you.
remove_item=2000
reward_xp=100
set_status=13

So, the possible fields in a dialog node:

  • requires_status
  • requires_item
  • requires_not
  • him
  • her
  • you
  • remove_item
  • reward_item
  • reward_xp
  • reward_gold
  • set_status

Campaign statuses will be checked or set in various ways to create stories and quests.

  • Map Events might only occur on a specific status, or set a status
  • Enemies might only spawn on a specific status, or set a status when defeated
  • The Log menu will display reminder text based on current statuses

Examples of the kind of simple connections possible with this system:

  • Boss treasure chest only openable if the boss is dead
  • Story bosses that stay dead
  • Conditional map teleports to make map phasing (e.g. village burns down, next time you enter that area it actually loads a different map)
  • Doors that require specific keys to open
  • Chest drops a quest item if you’re on the quest, otherwise it drops random loot

The status booleans will be written to the save file. The first implementation will have 1024 status fields. I’ll store them as plain text hexadecimal like this:

campaign=f1fea3b000000000000000000000000000000000000000000000000000000000

2011/03/22

Stat Renaming

This is what happens when I get too much extra time — I start changing things randomly!

I have renamed the following stats (across the game source code and data files).

  • Magical is now Mental
  • Health is now HP
  • Mana is now MP

I’ve done this to make the engine genre-neutral. An additional reason for this is to make populating the Powers menu easier, thematically — I can slot Mental Offense or Mental Defense powers that aren’t necessarily Magical in nature. Later when I add translation support, it will be possible to change the “Mental” label back to “Magical” (if desired).

Also, I did this update with bulk find/replace. I’m sure I broke stuff in the process. If you see something wrong lemme know.

Power Tree Rearrangement

From the change log for r298:

Trying a rearranged Powers tree.
- Lore removed, in its place is Channel
- Return removed, in its place Block
- Blood Strike moved to where Block was
- Immobilize added where Blood Strike was
- Haste and Cleave swapped
- Piering Shot and Multi Shot swapped

Additionally with this revision:
- New art for Channel
- New icons for the rearranged tree, and new base Powers menu
- Refactored "requires_ammo" into "requires_offense_weapon"
- Added requires_physical_weapon, requires_mental_weapon

2011/03/21

Playtesting levels 1-4

Tonight I playtested each “pure” build from levels 1-4. It’s a vulnerable area, especially in a non-class-based system where a player might make unusual attribute choices. Later levels aren’t so bad, especially once a character starts mixing in secondary attributes.

Pure Physical (straight to longsword proficiency)

The higher health pool definitely helps this build. I didn’t really need potions until I got to the cave. I was a bit reckless around some spitters so I used up a few potions, but overall I felt like I could run around and destroy stuff. Pulling using line-of-sight and bleed kiting was effective and fun.

Pure Magical (straight to staff proficiency)

I had to conserve mana at first (picked off the slow zombies with a rod bash) but it felt fun and precarious. Once I could afford it I bought a handful of mana potions that kept the action going. Keeping shields up at level 4 was important for survival.

Pure Offense (straight to longbow proficiency)

This character has a very easy time at early levels. When he starts facing ranged creatures (skeletal mages and antlion spitters) he can easily be two-shot, so cautious and smart play take over. Feels like it’s lacking a mana-cost power at levels 2 and 3; a high-powered arrow shot could help.

Pure Defense (straight to steel armor proficiency)

By far the worst build in terms of fun. I died a lot until I could afford a buckler; after that I was able to stay alive by blocking and counterpunching. Survival becomes easy with a buckler and block, but it takes forever to kill anything. Block/counterattack does have a fun feel to it, but it definitely makes more sense with Physical sprinkled in. I’m not worried about the deficiencies here; nearly all players build around their main weapon first and add defense later.

2011/03/20

Balance – Part 2

I’m testing several balance changes.

  • Starting HP and MP is now 12
  • Each level of Physical now grants +8 HP and +4 HP regen
  • Each level of Magical now grants +8 MP and +4 MP regen
  • Shock now costs mana again
  • HP Regen, MP Regen, and Crit are doubled on gear bonuses

The result I’m looking for: I want basic Physical characters to feel sturdier
and Physical Defense characters to feel like damage-soaking tanks.

Low-level mages and archers will have lower health. Mages have an easy Heal and
early Shield but have to manage mana. Archers have no easy healing but no
resource management (e.g. ammo).

I packaged up a Windows build of these changes. Also, I started up a forum thread to talk about balance issues.

Update: Potions

In r295 I have a new low-level potion (25 points, 25 gold). The high level potion has been changed (75 points, 75 gold).