Thursday, May 31, 2007
Frayed Knights Dev Diary: Stupid Is As Stupid Fights
The heart of any RPG is the combat system.Right now, Frayed Knights is feeling kinda heartless. And who taught that skeleton to hold an axe like that, anyway? Yeesh!
This week I spent some time working on combat. Putting together menus, re-thinking the interface, and then re-thinking it again once I prototyped it and saw where it was going.
Analysis Paralysis
One challenge I've faced is sort of a low-grade "analysis paralysis" with respect to individual systems. I found myself sitting down at the computer and not really being too sure how to approach the problem. Where do I begin? Do I use Torque's built-in UI stuff for the interface, or try to take greater advantage of the TGB-added sprites for menus? If I can't nicely pick out which enemy I'm attacking by clicking on them (overlapping collision areas makes it tricky), how do I handle it?
The trick I should have learned by now (but it still slowed me a bit) is - after preliminary analysis and consideration is done - to just pick one way and do it. Modularize it as best as you can so it CAN be changed later without too much impact if you decide you took the wrong path. But like the quote says (many attribute it to General George S. Patton, but I heard he borrowed it from a civil war general):
"A good plan, violently executed today, is far and away better than a perfect plan next week."
Stupid Torque Tricks
Torque has UI controls called "GUI Bitmap Buttons" that are supposed to be pure bitmaps. You are supposed to have one for each state of the button (normal, disabled, hovered-over, and pressed). Now, in the event no such bitmap exists, the fallback behavior of the button is simply to display text.
I needed text you could click on in menus, and so the fallback behavior seemed to be about perfect for me. There was a problem, however. For some reason, GuiBitmapButtonCtrl doesn't respect its given profile, and keeps reverting back to GuiDefaultProfile.
That screws up my pretty little font and stuff, which irritates me. Now, a good and responsible programmer, with the source code to the engine, would hunt down this bug, kill it, and check in the changes back into HEAD and contribute to the community and stuff. Me? I just cheesed out and whipped up a work-around. When the menu first comes up, I call setProfile() to force it to my nicer display font & stuff. Now, this still doesn't solve the problem, as there is another bug I've run into a few times where the string doesn't respect case... I guess the engine is trying to re-use strings and isn't paying attention to differences in case. So instead of "Attack" (capital A) I get "attack". The same problem cropped up in last week's post where the NPC was labeled "ELF LADY" (all caps) - which isn't the string I passed in (only the E and the L are supposed to be capitalized). There is probably something boneheaded that I'm doing here, so if anybody knows how to fix this issue, please let me know.
Behind the Curtain
Though a lot of what I've been doing has been creating only semi-functional interfaces and stubs, I did spend some time this week getting the framework of combat handled. Combat works in a phased system, rather than pure turn-based. Every action takes a certain amount of time to complete. An "average" action takes 10 phases. Now, rather than having you delay that many phases to complete the action, I play with time a little bit and reverse the order of things: The action and its effects take place immediately, and the delay occurs afterwards as you recover or recoil from the action.
So, for example, if you rest (take a breather) to recover endurance, you will immediately gain back the endurance, but you will have to then wait 10 phases to take your next action. The time it takes for the 'recoil' may be dependent upon your character... one character may take 10 phases to swing a sword, but another may be able to do it in 8. So after 80 phases, the faster character will have had 10 attacks, and the slower character will have only had 8.
Combat just proceeds in this way, phase-by-phase. I have the basic pipeline in and more-or-less functional, but there's really nothing HAPPENING at this point. Combat ends after 40 phases (or when you hit the "C" button, which is also how you initiate combat right now). No attacks or damage take place (yet). But I have some of the core logic in tracking everyone involved in the fight and handling combat order in place.
Which means I think it will work, but I still have no idea whether or not it will be fun.
Monster Spawning
While I GUESS I could have had combat occur completely abstractly for testing purposes, without any monster visuals, I am a sucker for the shiny. I wanted to see monsters appear when I forced combat (for testing purposes) by pressing the "C" key. So I used the DrewFX Skeleton Pack along with the Tridinaut Medieval Weapons Pack, and created a little funtion to spawn an attacking monster for the combat code to use. As you can see from the screenshots, the two different packs aren't 100% compatible out-of-the-box. The skeleton can hold the weapons by its thumb - which could show great talent, but I'm not too thrilled with the idea. So I'm going to have to go in and fix them myself.Unfortunately, very few content developers seem to support Blender formats in their content packs. Which confuses me. I mean, Blender is FREE guys... how much effort would it take? Well, okay, I know the answer to that one. Blender's import utilities are not exactly stellar, and do I expect any of these premium modeling packages to support export to a top open-source competitor? So I'm going to have to go through the painful process of importing them into Blender myself, and then fixing their mountpoints / origins and hope they export without losing crucial data.
Later.
The other thing this process brought up was just how I'm going to be handling creature spawning and the "abstract" method of handling positioning. How and where do the players encounter the monsters? I am trying to avoid dealing with complex pathfinding and collision issues with this game - we're talking quick-and-dirty here. What this is coming down to is a secondary set of data structures defining abstract pathing.
Constructor Madness
I also played around a little more with Torque Constructor (version 1.01) this weekend. Since it has been nearly 2 months since I last played with it, I had to re-learn everything. I had it crash on me once, and lock up on me once more. Still not quite ready for prime time. However, I note that version 1.02 is now up, so hopefully that'll be fixed up.
My assessment hasn't changed a whole lot from the last time I messed around with it. But this time I was actually trying to create something vaguely useful for the game. There's still a bit of a learning curve to figure out, but I am very, very fond of the ability to slice up brushes so easily. Maybe because that's how I'm used to working with Blender.
What's Up This Week
There's still some more functionality I want to get in place with combat.
Aside from that, this week will be spent working on the Traps & Locks minigame dialogs. Yes, after all my ranting about making more rogue-friendly RPGs, I figured I'd BETTER have an interesting rogue-oriented elements in the game.
If I have time, I'm going to throw in the save / load menus (non-functional). At that point, I'll have a crappy prototype of full game functionality.
(Vaguely) related thinking aloud... well, not aloud, I mean... bah, you get the idea...
* Making a Rogue-Friendly RPG part I: Rogues Get No Respect
* Frayed Knights Dev Diary: Getting Around In the World
* Frayed Knights Dev Diary: Background and High Concept
* Frayed Knights Website
Yo! Conference Happening In the Forum
Labels: Frayed Knights, Game Design, Roleplaying Games
