RPG Q involving types, damage, etc.

BlitzPlus Forums/BlitzPlus Programming/RPG Q involving types, damage, etc.

Lelldorianx(Posted 2007) [#1]
Hello all,

I am working on a text-based RPG for a few friends and myself, currently meant only to be single player. It is supposed to be simple, mostly text, with hack and slash thrown in the mix.

However, I am having problems with my actual battle engine, and was looking for help. Particularly on how to have the game actually detect which weapon the player has; so it can understand how much damage to do.

I am a Dungeons & Dragons player, pen & paper style; and have borrowed the engine ideas from D&D, as far as attacking.

So for example, if the player chooses their weapon to be a 'bow' they would have the following type loaded.

Type Bow

damage = SeedRnd(1,8);the amount of damage done (1-8)


They do 1d8 (1 die 8, an 8 sided die) of damage. So randomly, 1-8 damage, + any additional modifiers from bonuses in the weapon itself.

Here is the problem:

Print "What weapon would you like?  <Bow, Dagger, Shortsword, Longsword, Rapier, Axe>


If they choose one of those weapons, how would I have the game understand which type they chose, to know how much damage is done. That way, later on in a fight against a goblin it would say something like:

Print "You use your " + weapon$ + " to slash at the goblin, for a total of " + dmg + level + "."  


In theory, that should say how much damage they did. It adds the WEAPON's damage (it has to know which weapon it is, to know how much damage that weapon gets, i.e some have 1-6) to the player level, for additional damage.

However, I do not know how to actually have the game understand which weapon it is and how much damage it does.

Anyone have a suggestion for game engines/battle engines? Should I use types & fields?

I could have it so when they "Equip Bow" or "Equip Shortsword" it *sets variable dmg to 1d8 or 1d6*. How, though, would I 'set' the variable 'dmg' to a specific number according to the weapon? Thanks!


deps(Posted 2007) [#2]
seedrnd is not used like that, is it? SeedRnd is used to randomize the random number generator. You want rand() or rnd() instead.

if weapon$ = "bow" then dmg = bow_weapon\damage
if weapon$ = "sword" then dmg = sword_weapon\damage

print "You kick his arse using your " + weapon$ + " and inflicting " + dmg + " points of damage!"

Not sure that's how to use the Types in Blitz+, but I would do what you ask like that.
bow_weapon and sword_weapon should be created like this
sword_weapon = new Sword
bow_weapon = new Bow

and so on


deps(Posted 2007) [#3]
Or how about dissing the hole idea of types and do it using arrays instead? Types doesn't really fit this kind of problem if you ask me

const LOW_DMG = 0
const HIGH_DMG = 1

const DAGGER = 0
const BOW = 1
const SWORD = 2

dim weapons[ 3, 2 ]
dim wnames[3]

; init the tables
wnames[ DAGGER ] = "Rusty old dagger"
wnames[ BOW ] = "Elven bow"
wnames[ SWORD ] = "Big chop chop"

weapons[ DAGGER , LOW_DMG ] = 1
weapons[ DAGGER , HIGH_DMG ] = 3
weapons[ BOW , LOW_DMG ] = 3
weapons[ BOW , HIGH_DMG ] = 7
weapons[ SWORD , LOW_DMG ] = 5
weapons[ SWORD , HIGH_DMG ] = 10

; Get damage
function get_damage( w )
  return rand( weapons[w,LOW_DMG], weapons[w,HIGH_DMG] )
endfunction

; During game

wep = SWORD

dmg = get_damage( wep )
print "Gave him hell for " + dmg + " points using " + wnames[ wep ]


There's a million ways of doing things like this. :)
I might be rambling a bit now. I'm working the nightshift and is a bit tired. :P


EDIT: Oh, and after reading your post again, to get user input in a text environment, you use input:

w$=Input$("What do you want to attack with? ")
if w$ = "sword" then wep = SWORD
...



Lelldorianx(Posted 2007) [#4]
Brace yourself xD


Wow great input.

I just came back to BlitzBasic after a 2 year break (I was too young to comprehend all of it), and now understand much more.

However, I took the dive-in headfirst method because I thought that I would still remember half of this stuff. It seems I am referencing the manual for about 65% of what you just said :).

I am trying to work it in though. Although, about half of what you said I can use instantly, the rest needs deciphering.

I understand constants, but not how to use the following:
const LOW_DMG = 0
const HIGH_DMG = 1

const DAGGER = 0
const BOW = 1
const SWORD = 2


I understand perfectly the randomization as seen in your code below, except the ( w ). Is that a variable for damage? I do not see w anywhere else in there except for that segment, so have been left hanging :P

; Get damage
function get_damage( w )
  return rand( weapons[w,LOW_DMG], weapons[w,HIGH_DMG] )
endfunction


The piece above has been most useful, thanks for that!

Also, are the numbers next to the weaponry also for damage amounts? As in, dagger's base damage is 0?

dim wnames[3]


I understand the above, 3 wnames. Why the array? :S
dim weapons[ 3, 2 ]


However, in the manual & my book here at home I see no examples with a , in the middle of the numbers. Can you explain?

If you could break down the array a bit more, and give an in game example for the get damage, that would be excellent.

As of now, however I am milking this information for all I can get - and redoing the whole tutorial book (Game Programming For Teens Second Edition). Sorry for the bombardment of questions, and ripping your code to pieces with them, but I obviously do not recall near as much as I had thought.

Time to go back to the tutorial, any further help will be highly appreciative as it may decrease time needed to be spent *reading the whole book over again*. :P

Nice website, btw, deps. I like the games.

Thanks again!

~Steve.

EDIT:

Also, I will have mana & hitpoints regenerate overtime. Should I use one of the 'timer' commands to do this?

For example, every one minute you gain 1hp, every 1 minute you gain 1 mp (mana point).

If race$ = Elf Then
managain = 2 ;whatever the command is for per minute


Some Races gain racial bonuses such as faster regenerating mana or hitpoints, but that is not really needed information. Kind of getting off track.

Thanks.

Final Edit: I've been doing this with a DOS prompt (i.e Print not Text, no graphics etc) but want to switch to Graphics. Would you recommend it? Is there any easy way to make a client similar (as far as graphical output) to this: http://www.dragonstone.org/client/index.html


deps(Posted 2007) [#5]
Hi again.

I understand the above, 3 wnames. Why the array? :S

It looks much better to put things in an array, instead of a bunch of ifs or selects.
; Ugly
if w = 0 then weapon$ = "My cool dagger+2"
if w = 1 then weapon$ = "Silly human bow"
if w = 3 then weapon$ = "Big badass sword!!1"

; Better
weapon$ = wnames$(w)

; But you must initiate the array somewhere first. Example:
dim wnames$(5)
wnames$(0) = "Plastic dagger"
wnames$(1) = "TNT shooting bow"
wnames$(2) = "Meat cleaver"
wnames$(3) = "Pointy stick"
wnames$(4) = "A copy of the phonebook"


However, in the manual & my book here at home I see no examples with a , in the middle of the numbers. Can you explain?

The array weapons is a two-dimensional array. For example, think of a chessboard. (or, to show a chessboard in code: dim chess(8,8) )

More info here: http://blitzmax.com/bpdocs/command.php?name=Dim&ref=2d_cat

In my example, weapons contains three weapons. Each one have two values. weapons(0,0) is the lover limit of the damage for the dagger, weapons(0,1) is the upper limit.
weapons(2,0) and weapons(2,1) is the lower and upper damage limit for the sword.

But numbers looks a bit confusing sometimes, therefore I added the constants. weapons(1,0) and weapons(BOW, LOW_DMG) is exactly the same, since the compiler will replace every BOW with the number 1, for example.


quick, untested, example:
; constants, so we better see whats we're doing
const DAGGER = 0
const BOW = 1
const SWORD = 2

const LOW = 0
const HIGH = 1

; Contains the names
dim wname$(3)
wname$(DAGGER) = "dagger"
wname$(BOW) = "bow"
wname$(SWORD) = "sword"

; The damage they do
dim damage(3,2)
damage(DAGGER, LOW) = 1 : damage(DAGGER,HIGH) = 3
damage(BOW,LOW) = 2 : damage(BOW,HIGH) = 5
damage(SWORD,LOW) = 1  : damage(SWORD,HIGH) = 4
done = 0 ; Done killing orc?

; What we're up against
enemy_name$ = "Ugly one-eyed orc"
enemy_hp = 10

; Keep doing this until the fight is over
while done = 0
  ; Randomly select a weapon, just for fun
  your_weapon = rand(DAGGER,SWORD)
  ; will return 0, 1 or 2 (DAGGER, BOW or SWORD, remember?)

  ; Announce what we're doing
  print "You bravely attacks " + enemy_name$ + " with your trusty old " + wname$(your_weapon)

  ; calculate damage
  low_limit = damage( your_weapon, LOW ) 
  high_limit = damage( your_weapon, HIGH )
  dmg = rand( low_limit, high_limit )

  ; make him pay
  enemy_hp = enemy_hp - dmg
  print "You inflicted " + dmg + " points of damage, leaving the creature with " + enemy_hp + " left"

  if enemy_hp < 1 then done = 1 ; are we done here?

wend
print "Your work here is done!"



You could use MilliSecs() to see if it's time to gain hp/mana
last_gain_time = millisecs()
player_hp = 1

; somewhere in your code:
if millisecs() > last_gain_time + 60000 ; 60 seconds
  player_hp = player_hp + rand(1,3) ; 1,2 or 3 hp gained
  last_gain_time = millisecs()
endif


However, HERE is a nice place to use types. Please read other tutorials/books or the manual on how to use them properly. But it could look something like this:

Type player_character
  field name$
  field race$
  field class$
  field hp
  field mana
  field mana_gain_time
  field current_weapon
endtype

player = new player_character
player\name$ = "Bob"
player\race$ = "Human"
player\class$ = "Pimp dady"
player\hp = 10
player\mana = 15
player\current_weapon = CANE

; From time to time in your code:
update_character( player )


; Somewhere else
function update_character(  c )
  if millisecs() > c\mana_gain_time+60000 then
    c\mana_gain_time = millisecs()
    c\mana = c\mana + 1
  endif
endfunction



want to switch to Graphics. Would you recommend it?

Sure. Graphics is not everything. Gameplay is. But graphics can make a good game nice to look at.


Nice website, btw, deps. I like the games.

Thanks for the kind words about my neglected webpage. I should really update it someday. :)


Also, take everything I write here with a grain of salt.
1) I have never used Blitz+
2) I have never done anything like this
3) There's a lot of ways to do things like this and the way I do it here may or may not be the best one.
4) Things like this needs a lot of planning. I haven't done any at all while writing the examples. ;)
5) I'm dead tired. Been working nightshifts and not been able to catch much of the much needed sleep. :P

What you should do is to read that book, and some tutorials. Write small programs where you try out how arrays, constants, functions, etc. works. Do it before you start writing a game since there's not much fun in rewriting a large bit of the game just because you didn't understand the language completley. :)
(Been there, done that, learned a lesson)


Lelldorianx(Posted 2007) [#6]
I cannot thank you enough for the time you have put into helping me here, deps!

I understand fully everything in the above post, and will do as recommended. I am going to reread my book, do some tutorials, and study your code until I -completely- know why everything is there. I may understand what it means, but knowing why something is there could be equally important.

I think after a few beginning tutorials from my old book, especially the ones like Space Invaderz, and other tuts that involve health/damage, I will make a simple arena game. Purely to test your big help posted above, I will use the arena game to test damage, weapons, etc. While it won't be much fun, particularly, it will give me a chance to learn and understand before I dive into a nine foot deep pool with only a small understanding of how to swim.

I will use everything you have posted, in some way or another, whether it is purely to learn - or to use in my program; it is appreciated.

As far as your webpage, I know how that goes. I run a global gaming clan webpage (www.DawnofthePhoenix.net) and have neglected it recently as well, due to this blitz programming urge that came over me. I also run a D&D website for my party (www.Vanelan.net), however that one is more frequently updated.

Please let me know if you ever need any help with web design or any tips at all; for that is an area I understand. I will have no problem helping you with it, just email me here: teslacoil@...

Thanks again for your help, I will start working right away!

Hope your work goes better the next few days, get some more sleep!

~Steve.


Edit: I created a simple arena game, using your above battle engine, and noticed the following:

Each time I played through the quick battle, even after restarting the game, it would do damage as follows,
3 dmg
2 dmg
3 dmg
1 dmg
2 dmg
3 dmg

etc. It never changed, it was not random. Also, I could not while.. wend, it popped the error for "Wend without While" after fudging with it for about 30 minutes, I found the best fix was simply to let it go, and use Goto (even if it is more sloppy, it worked).

Furthermore, what would be the best way to do random damage? If I were to rid of "low" and "high" and instead replace it with completely random (1, 6) [ 1 through 6 damage] plus the weapons base damage (dagger = 1- 4 damage), would it be easy, or easier to keep your system?

Thanks, I promise this is the last set of questions for a while :)

I will go work on learning, and I'll be back in a week or so with more questions for you (if you don't mind).

By that time, I should have a good understanding of everything, and won't need so much cleared up - and hopefully; I will be asking you more questions like "Would it be easier to do it this way? xxxxx or this way? xxxxxxx?" versus, how should I do it?

Thanks man!

My website offer still stands.

Final Edit: Is there a tutorial on how to create a client (for later on when I am more advanced) such as the one displayed in these screenshots?

www.dragonstone.org/client/index.html

Thanks.


deps(Posted 2007) [#7]
It never changed, it was not random.

You need SeedRnd for that.
SeedRnd Millisecs()

Run that once, at the beginning of the game.

If I were to rid of "low" and "high" and instead replace it with completely random (1, 6) [ 1 through 6 damage] plus the weapons base damage (dagger = 1- 4 damage), would it be easy, or easier to keep your system?


low and high is there to make it more readable, so no need to get rid of it.
damage(DAGGER, LOW) = 1 : damage(DAGGER,HIGH) = 3
; Think it's too low? Easy:
damage(DAGGER, LOW) = 10 : damage(DAGGER,HIGH) = 300
; Now the dagger does 10 to 300 in damage for each stab. Frag feast!

And to add a random value to the base damage:
  dmg = get_damage( DAGGER ) + rand(1,6)


"Wend without While"

That is most likely because I haven't used Blitz+. At all. :)
I think it might be because the if ... then line just above wend. But it's not important. The important thing is that you get a grasp of how things work.


But, feel free to code things in any way you like. If you don't understand how I'm doing things here, or if you think something else looks prettier (how code looks is important for the motivation) then code it that way. :)

Good luck.