In my last post I used my hypothetical language, Foxie, to set up a simple, although woefully incomplete RPG battle system. I got caught up in the details and missed the most important part: the battles! So let’s give the player some weapons, define what a “level” is and how difficult it is to level up, and define options for each turn of battle (we’re going for a d20-style system by default).
Again, this is mostly a stream-of-consciousness, as I’m building on Foxie on the fly, making it up as I go.
Let’s make a weapon:
Masumune of Weapon attack: 99 accuracy: 99%
Simple. Like defining a monster, we just “inherit” or extend Weapon and add a few properties. Now, what about leveling up? Seems like something that should go in the main player config:
Chrono of Player # These 2 fields are already defined on the Player object # xp: 0 # level: 1 # stats: # strength: 10 # endurance: 10 # dexterity: 10 # wisdom: 10 # intelligence: 10 # charisma: 10 levelUp: (lvl) -> each self.stats, (stat) -> increase stat, 10% weapons: [ Masamune ]
Here we finally see the Player object. We have a reference to the Player’s experience points, level, and stats, the latter being the most interesting. In our
levelUp function, we simply iterate over each state and increase it by 10%. You can imagine doing all sorts of fun stat manipulation here, like increasing stats based on the Player’s chosen class.
I think we have everything we need for a battle! We have a player, they have a weapon, and in the last post, I defined an area on the map that had random encounters. Given a base engine, where your character can walk around and interact with NPCs and tiles with the press of a button, we have almost everything we need. What about the battle UI?
By default, we’ll present a battle UI in the style of Final Fantasy or Chrono Trigger. You can customize this UI with a domain-specific language like we used in my first post to define conversations. Let’s take a look:
function of BattleDisplay -> screen battlefield height 70% align top player align left each enemies, (enemy, existingEnemies) -> enemy align right if length existingEnemies > 0 align top, bottom last existingEnemies else align top menu height 30% align bottom menu-items attack ("Attack") defend ("Defend") items ("Items") run ("Escape")
This sample is worth a post of its own, but let’s get the highlights. First, I made an anonymous function that extends
BattleDisplay – that’s what gives it access to all those UI-modifying functions. This particular DSL is like a template and styling in one, much like an Android layout. I shamelessly stole their alignment semantics, as in
align top, bottom last existingEnemies, which will align the top of the current enemy’s box with the bottom of the last enemy that was rendered.
There’s more to be covered, but given the engine I’m envisioning, with a Rails-like system that will take files in certain places and turn them into behavior and logic in the game, we have a full battle system in place.
Next time, I’ll cover quest scripting in detail. I’d also like to cover time-sensitive environments, party scripting, more on conversations, special items, inventory and player menu UIs, and more.
What would you add to or change in this language so far? What do you want to see more details on?