Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm an inexperienced programmer creating a "roguelike-like" game in the vein of FTL, using Python (no PyGame as of yet as I'm still only concerned with text).

My game will contain a large number of weapons (around 50 for starters) that yield unique abilities. I am struggling to understand how to structure the object code in a way that is both powerful (in terms of allowing weapons to have radically different effects) and extensible (so that I can easily add more weapons later by eg. dropping them into a folder).

My first instinct was to have a BasicWeapon class, and have different weapons inherit from that class. However, this seems problematic to me: either I have to make the BasicWeapon class so barebones that it's basically useless (the only features all weapons have in common are name and type (pistol, axe, etc)), or I have to predict every unique effect I will ever come up with and code that into BasicWeapon.

The latter is clearly impossible, but the former can still be worked. However, that leaves me with the question: where do I put the code for individual weapons?

Do I create plasmarifle.py, rocketlauncher.py, swarmofbees.py, etc etc, and drop them all into a folder from where the game can import them?

Or is there a way to have a database-style file (maybe something as simple as an Excel spreadsheet) that somehow contains unique code for each weapon - without needing to resort to eval/exec?

In terms of the latter solution (database), I think the fundamental issue that I'm struggling with is that while I understand that it is desirable to maintain separation between code and data, I feel like the weapons blur the line between "code" and "data" a little bit; they represent the great variety of similar things that can be found in the game, in which sense they are like data, but most of them will require at least some unique code not shared with any other item, in which sense they are, naturally, code.

A partial solution I have found elsewhere on this site suggests giving the BasicWeapon class a bunch of empty methods - on_round_start(), on_attack(), on_move() etc - and then overriding those methods for each weapon. At the relevant phase of the combat cycle, the game will call the appropriate method for every character's weapon, and only the ones that have methods defined will actually do something. This helps, but it still does not tell me where I must put the code and/or data for each weapon.

Is there a different language or tool out there that I can use as a sort of half-data, half-code chimera? Am I completely butchering good programming practice?

My understanding of OOP is sketchy at best, so I would appreciate responses that are not too computer science-y.

EDIT: Vaughan Hilts has made it clear in his post below that what I'm essentially talking about is data-driven programming. The essence of my question is this: how can I implement a data-driven design in such a way that the data can contain scripts, enabling new weapons to do new things without changing the main program code?

share|improve this question
3  
Related: gamedev.stackexchange.com/questions/17276/… –  Byte56 Mar 11 '13 at 22:11
    
@Byte56 Related; but I think this is what the OP is trying to avoid. I think they're trying to find a more data driven approach. Correct me if I'm wrong. –  Vaughan Hilts Mar 11 '13 at 22:12
    
I agree they're trying to find a more data oriented approach. Specifically, I like Josh's answer to that question: gamedev.stackexchange.com/a/17286/7191 –  Byte56 Mar 11 '13 at 22:15
    
Ah, sorry about that. :) I have a bad habit of reading the "accepted answer". –  Vaughan Hilts Mar 11 '13 at 22:24
add comment

2 Answers

up vote 15 down vote accepted

You want a data-driven approach almost certainly unless your game is going to be completely un-expected and/or procedural generated to the core.

Essentially, this involves storing information about your weapons in a markup language or file format of your choice. XML and JSON are both good, readable choices that can be used to make editing fairly simple without the need for complicated editors if you're just trying to get a quick start. (And Python can parse XML pretty easy, too!) You'd set attribute like 'power', 'defense', 'cost', and 'stats' that are all relevant. The way you structure your data will be up to you.

If a weapon needs to add a status effect, give it a Status effect node, and then specify the effects of a status effect through another data-driven object. This will make your code less reliant on the specific game and making editing and testing your game trivial. Not having to recompile all the time is a bonus, too.

Supplemental reading is available below:

share|improve this answer
2  
Kind of like a component based system, where the components are read in through scripts. Like this: gamedev.stackexchange.com/questions/33453/… –  Byte56 Mar 11 '13 at 22:17
2  
And while you're at it, make a script part of that data so that new weapons can do new things with no main code changes. –  Patrick Hughes Mar 12 '13 at 3:57
    
@Vaughan Hilts: thank you, data-driven seems to be exactly what I intuitively understood I needed. I'm leaving the question open for a while longer as I still need answers, but will probably choose this as the best answer. –  henrebotha Mar 12 '13 at 7:21
    
@Patrick Hughes: that's exactly what I want! How do I do that? Can you show me a simple example or tutorial? –  henrebotha Mar 12 '13 at 7:22
1  
First you need a script engine in your engine, many people choose LUA, that accesses gameplay systems like effects and statistics. Then since you're already recreating your objects from a data description you can embed the script that your engine calls whenever your new object is activated. In the olden days of MUDs this was called a "proc," (short for Process). The hard part is making your gameplay features in the engine flexible enough to be called from outside and with enough features. –  Patrick Hughes Mar 12 '13 at 14:37
add comment

(I'm sorry to submit the answer instead of a comment, but I don't have rep yet.)

Vaughan's answer is great, but I'd like to add my two cents.

One of the main reasons you'd want to use XML or JSON and parse it in runtime is to change and experiment with new values without having to recompile the code. As Python is interpreted and, in my opinion, pretty readable, you could have the raw data in a file with a dictionary and everything organized:

weapons = {
           'megaLazer' : {
                          'name' : "Mega Lazer XPTO"
                          'damage' : 100
                       },
           'ultraCannon' : {
                          'name' : "Ultra Awesome Cannon",
                          'damage' : 200
                       }
          }

This way you just import the file/module and use it as a normal dictionary.

If you want to add scripts, you can make use of the dynamic nature of Python and 1st class functions. You could do something like this:

def special_shot():
    ...

weapons = { 'megalazer' : { ......
                            shoot_gun = special_shot
                          }
          }

Although I believe that would be against data driven design. To be 100% DDD you'd have infomation (data) specifying what would be the functions and code that specific weapon would use. This way you don't break DDD, as you don't mix data with functionality.

share|improve this answer
    
Thank you. Just seeing a simple code example helped it to click. –  henrebotha Mar 13 '13 at 16:06
1  
+1 for the nice answer and for you to have enough rep to comment. ;) Welcome. –  ver Mar 21 '13 at 10:37
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.