An RPG is driven by data. There are stats of monsters, weapons, spells. There are maps and dialog trees and quest checkpoints. All that data has to be stored somewhere. One approach is to come up with proprietary formats, creating ASCII text files that custom reader / writer methods.
But the defacto standard of data storage these days is JSON. The great thing about JSON is you can use some nice .NET libraries to read/write it. JSON.NET: http://james.newtonking.com/json
However, it can be a little cumbersome to pop it open in a text editor and edit the raw fields. Ideally, the level designer could store all the game data in Excel CSV files, and translate to JSON with a single click.
I built CSVtoJSON to do just that. https://github.com/tdonlan/CSVtoJSON
It's a .NET Command Line utility that takes in a CSV file and will output a JSON file, via command line arguments. CSV is read via csvHelper: http://joshclose.github.io/CsvHelper/
CSVtoJSON.exe 'input.csv' 'output.json'
The first row (column names) of the CSV will be used for the JSON keys.
One of the nice features is that you can put raw JSON in a column. The converter will read in the JSON, translate to a .NET object, then serialize it back out as valid JSON (instead of wrapping it in a string).
Overall its a nice tool that will come in handy later on in the game development process, when there's lots of tweaking to the enemies, items and abilities that make up the game.
Wednesday, December 31, 2014
Composition and Inheritance
One of the architectural decisions to make when building a complex system is how you want to represent the relationship between objects. There are two patterns that are pretty common in gamedev. Composition and Inheritance.
There's been a lot written on both, and I'm not an academic, so I'm sure a lot of my arguments will be simplified or use the wrong terminology.
First, what do the terms mean? For our RPG, let’s say we have a Character class. How do we break that down into enemy vs player?
Inheritance:
We'd have two subclasses:
Each class would implement the logic specific to a player or enemy. The logic and relationships would resolve at compile time.
Composition:
The character class would have a CharacterType attribute, with different types.
The logic of both player and enemy would be included in the character class, and the control would be decided by a switch statement. The logic and relationships would resolve at runtime, once the attribute is set.
For the RPG game, I'm mostly using composition. The benefits are that there aren't as many classes, and I don't have to worry about casting my parent classes into subclasses.
ex:
The drawbacks are that if the data isn't initialized correctly, the wrong logic may execute, and bugs could potentially be more difficult to track down. But from the standpoint of developing the code, using composition can be a lot quicker.
If I want to create a new ability, I simply add a few types, make a new line in my switch statement, and implement the behavior. The alternative would be creating new classes that inherent from parent objects, and then figuring out when/where to instantiate those new classes.
The only instance where I'm using the OO inheritance is in the Item system. Here's the relationship:
In this case, inheritance made sense. Ranged weapons need a lot more attributes then a healing potion. Simply using composition would have left me with lots of empty properties.
The logic I've used when deciding to use Inheritance vs Composition:
If you have lots of items in a set that are pretty similar and could share the same number of methods/attributes - use composition. If you have nested relationships, where the subset items require lots of additional fields or methods, use inheritance.
There's been a lot written on both, and I'm not an academic, so I'm sure a lot of my arguments will be simplified or use the wrong terminology.
First, what do the terms mean? For our RPG, let’s say we have a Character class. How do we break that down into enemy vs player?
Inheritance:
We'd have two subclasses:
public class Enemy : Character
public class Player : Character
Each class would implement the logic specific to a player or enemy. The logic and relationships would resolve at compile time.
Composition:
The character class would have a CharacterType attribute, with different types.
public enum CharacterType { Player, Enemy, NPC }
The logic of both player and enemy would be included in the character class, and the control would be decided by a switch statement. The logic and relationships would resolve at runtime, once the attribute is set.
For the RPG game, I'm mostly using composition. The benefits are that there aren't as many classes, and I don't have to worry about casting my parent classes into subclasses.
ex:
Enemy e = (Enemy)character;
The drawbacks are that if the data isn't initialized correctly, the wrong logic may execute, and bugs could potentially be more difficult to track down. But from the standpoint of developing the code, using composition can be a lot quicker.
If I want to create a new ability, I simply add a few types, make a new line in my switch statement, and implement the behavior. The alternative would be creating new classes that inherent from parent objects, and then figuring out when/where to instantiate those new classes.
The only instance where I'm using the OO inheritance is in the Item system. Here's the relationship:
Item UsableItem : Item Weapon : Item RangedWeapon : Weapon Ammo : Item Armor : Item
In this case, inheritance made sense. Ranged weapons need a lot more attributes then a healing potion. Simply using composition would have left me with lots of empty properties.
The logic I've used when deciding to use Inheritance vs Composition:
If you have lots of items in a set that are pretty similar and could share the same number of methods/attributes - use composition. If you have nested relationships, where the subset items require lots of additional fields or methods, use inheritance.
Ability System
One of the core parts of any RPG is casting spells. Implementing a spell system can get pretty hairy, and I wanted a system that was robust enough to handle both traditional offensive spells (fireball, magic missile), buffs (sheild), damage over time (poison), debuffs (curse) and healing. Additionally, items would be able to "cast" spells, either through one time use (healing potion) or a proc (flaming sword that catches enemies on fire).
The Ability class is what I came up with.
An ability is anything spell-like a character can use. The key parts:
These types are used in the logic that executes each ability to return a list of character affected by the ability.
The Tile Pattern is used to return a group of tiles surrounding the target point. From there, you can determine the characters affected by each ability. Targets of type Self, AllFriends, etc ignore the TilePattern attribute.
The effects also contain a statType attribute:
So far the ability system is flexible enough that new abilities can be described in data and will give the game a ton of breadth and range.
You can even come up with new and interesting abilities by combining multiple active effects in interesting ways.
A "charge" ability for a warrior class is implemented like this:
The Ability class is what I came up with.
An ability is anything spell-like a character can use. The key parts:
public AbilityTargetType targetType { get; set; }The target type defines what type of character, tile or group are affected by the ability. A self healing spell would only have target Self. But something like fireball would have LOS (line of sight) target.
These types are used in the logic that executes each ability to return a list of character affected by the ability.
public enum AbilityTargetType { Self, SingleFriend, SingleFoe, AllFriends, AllFoes, PointEmpty, PointTarget, LOSEmpty, LOSTarget, }
public TilePatternType tilePatternType { get; set; }For AoE (Area of Effect) abilities, the Tile Pattern type is key. Something like fireball explodes in a large circle around the radius.
The Tile Pattern is used to return a group of tiles surrounding the target point. From there, you can determine the characters affected by each ability. Targets of type Self, AllFriends, etc ignore the TilePattern attribute.
public enum TilePatternType { Single, FourAdj, EightAdj, NineSquare, ThreeLineVert, ThreeLineHor, }
public List<ActiveEffect> activeEffects { get; set; } public List<PassiveEffect> passiveEffects { get; set; }Abilities also contain a list of active and passive effects. Both Active and Passive effects are pretty similar. The main difference is that an active effect is "applied" to a character each turn, while a Passive Effect simply changes stats. So an active effect would be used for damage, healing, or damage over time. Buffs that give HP or extra stats would be passive effects.
The effects also contain a statType attribute:
public StatType statType { get; set; } public enum StatType { ActionPoints, Armor, Damage, Heal, HitPoints, //temp buff to hitpoints Attack, Teleport, //move character to target Knockback, // move targets away from character Explode, //move characters away from target Stuck, //character cannot move Dispell, //remove active effects Stun, //player can't do anything }StatType is sort of a catch-all of everything in the game. There are obvious stats listed in here, like ActionPoints, Armor, Attack, etc. But there are also concepts like Teleport, Knockback and Explode, which actually move the target on the board in specific ways. Any unique "effect" needs to have a unique stat type, and then be implemented in the AbilityHelper method.
So far the ability system is flexible enough that new abilities can be described in data and will give the game a ton of breadth and range.
You can even come up with new and interesting abilities by combining multiple active effects in interesting ways.
A "charge" ability for a warrior class is implemented like this:
public static Ability getCharge() { ActiveEffect chargeEffect = new ActiveEffect() { name = "Charge", duration = 1, minAmount = 5,maxAmount=5, statType = StatType.Teleport }; ActiveEffect knockbackEffect = new ActiveEffect() { name = "Knockback", duration = 1, minAmount = 1,maxAmount=1, statType = StatType.Knockback }; ActiveEffect damageEffect = new ActiveEffect() { name = "ChargeDamage", duration = 1, minAmount = 10,maxAmount=20, statType = StatType.Damage }; Ability charge = new Ability() { name = "Charge", description = "Charge in a straight line towards an enemy, causing damage", ap = 5, range = 5, uses = 1, targetType = AbilityTargetType.LOSTarget, tilePatternType = TilePatternType.Single, activeEffects = new List<ActiveEffect>() { knockbackEffect, chargeEffect, damageEffect }, passiveEffects = null, }; return charge; }As you can see, the charge has three effects. First, the target is knocked back a space. Then damage is done. Finally, the character teleports to the target's tile.
Tuesday, December 23, 2014
Current Build
Here's a quick demo of the current build. There are a few bugs, but you can see that most of the bullet point items below are operational -
Follow along the development on my Twitch Channel: http://www.twitch.tv/daydalus9/profile
Thursday, December 18, 2014
Streaming Gamedev
I started streaming some gamedev sessions over on twitch. Unfortunatly the first night where I walked through the code, the archiving feature was disabled. Tonight though, it was on, and got about 2 hours of decent coding in. Unfortunately, my mic config was messed up for the first 20 minutes, so there's some loud feedback. But after that, its fine, despite my mumbling and loud banging on the keyboard.
Check out the broadcast here:
Watch live video from daydalus9 on Twitch
Check out the broadcast here:
Watch live video from daydalus9 on Twitch
Monday, December 15, 2014
An approach
Most of the reason I got bogged down building RPGs in the past was because of scope creep.
Big budget RPGs these days have everything. You have procedural world, a dozen classes, all with customizable ability trees and flashy animations. Not to mention thousands of items, enemies and objects. Building all that stuff, let alone balancing it into a playable game, is a mountain of devwork. I'd usually get to a point where I could equip a basic item, attack an enemy, gain some XP, then throw my hands up in the air in burned out frustration.
So the approach with this game is to start tiny. Microscopically tiny. Down to the raw characters in a Console-line app.
This is how the rogue-likes did it - representing the player as the @ symbol, enemies as various other characters, the world as the blocky symbols in the ASCII set * [ ] #.
That's how I'm going about it for now. Everything lives in a 2D tile world.
Here's the scope I'm attempting for the next month or so:
The majority of the work will be on the ability system. The fun of tactical RPGs is all about utilizing abilities in creative ways on top of a 2D grid. So part of each ability will be the area that it covers: the arcing swipe of a Great Cleave, or the large circular blast of a Fireball.
Next post I'll dive into a bit of the design of the ability system, and go over some of the challenges so far.
Big budget RPGs these days have everything. You have procedural world, a dozen classes, all with customizable ability trees and flashy animations. Not to mention thousands of items, enemies and objects. Building all that stuff, let alone balancing it into a playable game, is a mountain of devwork. I'd usually get to a point where I could equip a basic item, attack an enemy, gain some XP, then throw my hands up in the air in burned out frustration.
So the approach with this game is to start tiny. Microscopically tiny. Down to the raw characters in a Console-line app.
Nethack |
That's how I'm going about it for now. Everything lives in a 2D tile world.
Here's the scope I'm attempting for the next month or so:
- Battle game on a 20 x 20 tile grid
- Multiple Enemies, Multiple Players
- Turn based combat, random initiative.
- Players can move, attack, ranged attack, use abilities and items
- Enemies have rudimentary AI - move towards player (using A*), attack, heal if wounded
- No character classes yet
- Players will have access to a range and variety of abilities (Charge Attack, Throw Grenade, Cast Fireball, Teleport, Heal, Group Heal, Group Slow, etc).
- The battle screen, enemies, players, abilities, items are data driven. Data is stored in JSON files, loaded at runtime.
- Display and Player Input will use Console.Write / Console.Read in a .NET command line app.
The majority of the work will be on the ability system. The fun of tactical RPGs is all about utilizing abilities in creative ways on top of a 2D grid. So part of each ability will be the area that it covers: the arcing swipe of a Great Cleave, or the large circular blast of a Fireball.
Next post I'll dive into a bit of the design of the ability system, and go over some of the challenges so far.
Initial Commit
RPGs have always been one of my favorite video game genres.
All the way back to the Gold Box RPGs in the early 90s, and then BioWare classics like Planescape: Torment, Baldur's Gate and Icewind Dale. The genre has changed in the most recent generations, and I'm not sure for the better. Most of the combat has borrowed heavily from action games, amping the visuals and the kinetic feel of the game, but losing a lot of tactical problem solving. And with the advent of Hollywood style cut scenes and voice acting, most of the wildly divergent storytelling has been streamlined into one or two basic paths (good, not-so-good).
I've always wanted to build an RPG. I have tremendous respect for some of the Indie RPG developers out there, including Jeff Vogel and Spiderweb games. His model is one I'd like to emulate - focusing on a hand crafted RPG engine and building series of games with enveloping story and tactical combat, even if the graphics are lacking.
All the way back to the Gold Box RPGs in the early 90s, and then BioWare classics like Planescape: Torment, Baldur's Gate and Icewind Dale. The genre has changed in the most recent generations, and I'm not sure for the better. Most of the combat has borrowed heavily from action games, amping the visuals and the kinetic feel of the game, but losing a lot of tactical problem solving. And with the advent of Hollywood style cut scenes and voice acting, most of the wildly divergent storytelling has been streamlined into one or two basic paths (good, not-so-good).
Gold Box RPG |
Spiderweb Software RPG |
But building an RPG can be a challenge. There aren't any difficult graphical, algorithmic or physics formulas to decipher, in something like a networked FPS. An RPG is just an excercise in coding a large complex system, with lots of moving parts and abstractions. I've made attempts in Objective-C and Javascript before, and both fell apart because working with the language was too painful.
My goal is to build an old-school tactical RPG, using 2D spritesheets and basic particle effects, similar to the Gold Box RPGs of yore. The core of the game is being written in C#, and the graphics and UI will eventually use Unity. But to start, its just going to be a standard .NET Console application. Everything will be open source and up on github.
The last time I wrote a big game, a dev blog was essential. For one - it let me share my work with the wide world, and two - it kept me accountable. Dozens of projects and prototypes have been buried in dusty drive folders simply because I got a little bored, a little burned out, and there was no motivation to continue.
We'll see if I get any farther with this.
So here's to the start.
Follow along here: https://github.com/tdonlan/SimpleRPG
Subscribe to:
Posts (Atom)