Text rpg combat system

Hello! I started learning c++ a couple of months ago and last week I decided to start with a little project: I decided to start making a text-RPG. Well, I've done the menu and character selection, etc. and now I have started making a combat system(turn based). I've written code where the character meets a goblin and he/she gets to choose whether to attack or not and I managed to figure out how to add health and damage, but I have a problem. I've tried searching online for answers, but no threads/sites had the answer I was looking for. The problem is that I can attack/get attacked by the goblin, eg.

You attack Goblin.
The goblins HP is now 15.

The goblin attacks you.
Your HP is now 45.


But I can't figure out how to make it so that you can attack again. I tried return goblinBattle();, but when I do that the hp resets. I don't know how else to explain it. If there is anyone who knows how I could fix this or make it better, I would be really greatful for an answer.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
  #include <iostream>
#include <cstdlib>

using namespace std;

int goblinBattle();
int showEnemyHp(int enemyhp, int attack);
int showHp(int hp, int enemyattack);

int main()
{
    int battle;
    system("Title        Goblin battle         ");
    system("Color 3");
    cout << "\nYou have met a goblin. Attack goblin?\n Yes = 1\n No = 2\n";
    cin >> battle;
    if(battle==1)
    {
        cout << goblinBattle();
    }
    else if(battle==2)
    {
        cout << "You chose to not attack the goblin.\n";
    }
    else
    {
        cout << "That is not a valid choice.\n\n";
        return main();
    }

system("pause");
return 0;
}

int goblinBattle()
{
    int hp = 50, enemyhp = 25, attack = 10, enemyattack = 5;

    int hitGoblin;
    cout << "\nHit goblin?\n Yes = 1\n No = 2\n";
    cin >> hitGoblin;
    if(hitGoblin==1)
    {
      cout << "\nYou hit the goblin.\n";
      cout << "The goblin now has " << showEnemyHp(enemyhp, attack) << "HP left.\n\n";
      cout << "The goblin hit you back.\n";
      cout << "You now have " << showHp(hp, enemyattack) << "HP left.\n\n";
    }
    else if(hitGoblin==2)
    {
        cout << "You chose not to hit the goblin so he hit you instead\n";
        cout << "You now have " << showHp(hp, enemyattack) << "HP left.\n\n";
    }
    else
    {
        cout << "That is not a valid choice.\n\n";
    }
}

int showEnemyHp(int enemyhp, int attack)
{
    return enemyhp - attack;
}
int showHp(int hp, int enemyattack)
{
    return hp - enemyattack;
}
Have you tried implementing a do-while loop?
First remark, your int goblinBattle() function does not return an int value. Also, I recommend that you make you variables of type static or declare them as global variables, because I believe that when ever you re call your function goblinBattle the variables will be reset to their respective values.

Now for a continuous battle system you would want to use a while loop or do while. For Example:
1
2
3
4
5
6
7
while( GoblinHp() /*Maybe create a function to return goblin Hp or just use the variable it self */> 0){

//call combat function here
//Make a case to quit loop if human hp is 0
if(human_hp <= 0 )
break;
}
Ok, so I tried making it a do-while loop, but I think I've done something wrong. The code compiles, but it runs the same way as before

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
int goblinBattle()
{
    int hp = 50, enemyhp = 25, attack = 10, enemyattack = 5;
    int hitGoblin;

   do
   {
    cout << "\nHit goblin?\n Yes = 1\n No = 2\n";
    cin >> hitGoblin;
    if(hitGoblin==1)
    {
      cout << "\nYou hit the goblin.\n";
      cout << "The goblin now has " << showEnemyHp(enemyhp, attack) << "HP left.\n\n";
      cout << "The goblin hit you back.\n";
      cout << "You now have " << showHp(hp, enemyattack) << "HP left.\n\n";
    }
    else if(hitGoblin==2)
    {
        cout << "You chose not to hit the goblin so he hit you instead\n";
        cout << "You now have " << showHp(hp, enemyattack) << "HP left.\n\n";
    }
    else
    {
        cout << "That is not a valid choice.\n\n";

    }

   }
   while(hp > 0 && enemyhp > 0);

return 0;
}
Make your function goblinBattle type void, since you really are not returning anything. I think the return 0; is messing it up
I tried changing out the int in front of goblinBattle() to void, but I got a ton of errors.
make sure you remove return 0; on line 31 and in your int main juse do this :

goblinBattle(); without cout<<
I don't know why, but I still can't get it to work:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <iostream>
#include <cstdlib>

using namespace std;

void goblinBattle();
int showEnemyHp(int enemyhp, int attack);
int showHp(int hp, int enemyattack);

int main()
{
    int battle;
    system("Title        Goblin battle         ");
    system("Color 3");
    cout << "\nYou have met a goblin. Attack goblin?\n Yes = 1\n No = 2\n";
    cin >> battle;
    if(battle==1)
    {
        goblinBattle();
    }
    else if(battle==2)
    {
        cout << "You chose to not attack the goblin.\n";
    }
    else
    {
        cout << "That is not a valid choice.\n\n";
        return main();
    }

system("pause");
}

void goblinBattle()
{
  int hp = 50, enemyhp = 25, attack = 10, enemyattack = 5;
  int hitGoblin;

   do
   {
    cout << "\nHit goblin?\n Yes = 1\n No = 2\n";
    cin >> hitGoblin;
    if(hitGoblin==1)
    {
      cout << "\nYou hit the goblin.\n";
      cout << "The goblin now has " << showEnemyHp(enemyhp, attack) << "HP left.\n\n";
      cout << "The goblin hit you back.\n";
      cout << "You now have " << showHp(hp, enemyattack) << "HP left.\n\n";
    }
    else if(hitGoblin==2)
    {
        cout << "You chose not to hit the goblin so he hit you instead\n";
        cout << "You now have " << showHp(hp, enemyattack) << "HP left.\n\n";
    }
    else
    {
        cout << "That is not a valid choice.\n\n";
        return goblinBattle();
    }

   }
   while(hp > 0 && enemyhp > 0);
}

int showEnemyHp(int enemyhp, int attack)
{
    return enemyhp - attack;
}
int showHp(int hp, int enemyattack)
{
    return hp - enemyattack;
}
Last edited on
closed account (j3Rz8vqX)
Okay, did a quick debug.

The reason why damage isn't being calculated, is because it simply isn't.

(hitGoblin==1)
Display that the goblin was hit.
Display that you were hit.
Display your health.
But never stores it.

(hitGoblin==2)
Display goblin hit you because you did nothing.
Display your health.
But never stores it.

---

Optional work around (not the only ones)

Do the actual calculation and set hp equal to the calculation. (Remember, if you want hp to change, you're going to have to assign it to something else ^^.

1) You can do the calculations before the displaying of hp then display his (resulted) hp instead.
1
2
hp = hp - enemyattack;
cout << "You now have " << hp << "HP left.\n\n";

2) You can do the calculations during the displaying of hp. Pass by reference '&' and actually calculate the damage into hp; the result is still returned for display purposes - no loss in your efforts of learning functions.
1
2
3
4
5
6
7
8
9
10
11
12
//Remeber hp can be anyones hp, not limited to hero - it just depends what you passed it. So technically you only need one showHp function.
int showHp(int &hp, int attack)//using reference to hp because we want hp's value to actually take effect.
{
    hp = hp - attack;
    return hp;
}
//then you would just have to pass in different hp(s) and damage

for you:
showHp(hp, enemyattack);
for your enemy:
showHp(enemyhp,attack);


Your program can be greatly improved in many ways, but let's not get into that as of yet.

Hope this helps.
Last edited on
Pass your variables. that you want to be changed and to hold new value throughout the program by reference

Your passing them by value
Last edited on
Then again, why pass by value when its returning something anyway? You could just change your statements to this (for example):
 
cout << "You know have " << (hp = showHP(hp, enemyAttack)) << "HP left.\n";


Or, even better:
1
2
3
4
5
if (hitGoblin == 1) {
    enemyhp = showGoblinHP(enemyhp, attack);
    hp = showHP(hp, enemyAttack);
    // output statements
}
Last edited on
@NT3

That actually seems to work, but the value of my variables are acting really weird. It now goes:

"You hit the goblin.
The goblin now has 5 hp left.
The goblin hit you back.
You now have 15 hp left

You hit the goblin.
The goblin now has 0 hp left.
The goblin hit you back.
You now have 10 hp left
You hit the goblin.
The goblin now has -5 hp left.
You won!"


when really it should be:

"You hit the goblin.
The goblin now has 10 hp left.
The goblin hit you back.
You now have 20 hp left
yadda yadda
You hit the goblin.
The goblin now has 0 hp left.

And then it ends.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
void goblinBattle()
{
  int hp = 25, enemyhp = 15, attack = 5, enemyattack = 5;
  int hitGoblin;

   do
   {
    cout << "\nHit goblin?\n Yes = 1\n No = 2\n";
    cin >> hitGoblin;
    if (hitGoblin == 1)
    {
    enemyhp = showEnemyHp(enemyhp, attack);
    hp = showHp(hp, enemyattack);
    cout << "\nYou hit the goblin.\n";
    cout << "The goblin now has " << showEnemyHp(enemyhp, attack) << "HP left.\n\n";
    if(enemyhp<=0)
    {
        cout << "You won!\n";
    }
    else
    {
       cout << "The goblin hit you back.\n";
       cout << "You now have " << showHp(hp, enemyattack) << "HP left.\n\n";
    }
    }
    else if(hitGoblin==2)
    {
        cout << "You chose not to hit the goblin so he hit you instead\n";
        cout << "You now have " << showHp(hp, enemyattack) << "HP left.\n\n";
    }
    else
    {
        cout << "That is not a valid choice.\n\n";
        return goblinBattle();
    }

   }while(hp > 0 && enemyhp > 0);
}

int showEnemyHp(int enemyhp, int attack)
{
    enemyhp = enemyhp - attack;
    return enemyhp;
}
int showHp(int hp, int enemyattack)
{
    hp = hp - enemyattack;
    return hp;
}
Last edited on
Text RPGs aren't easy.
Also, you lack objects. Without objects, creating RPG will be even harder.
Take a look at:
4: http://www.gamasutra.com/
http://www-cs-students.stanford.edu/~amitp/gameprog.html
5: http://gameprogrammingpatterns.com/index.html
3: http://gamedev.stackexchange.com/questions/854/what-are-good-games-to-earn-your-wings-with/1047#1047
1: http://www.3dbuzz.com/training/view/c-plus-plus-complete/intro-to-game-dev
2: www.sloperama.com
2: http://www.holub.com/goodies/rules.html

If you want to create text-based RPG game, you may also want to use curses libarary:
http://sourceforge.net/projects/pdcurses/
http://tldp.org/HOWTO/NCURSES-Programming-HOWTO/

Here you are, resources for making text-based RPG. Sorry for throwing many links at you, but it's both easier for me(I don't have to write again the same things), and for you(these people explain things well).

Many people, when start programming, want to create games... quickly. So as soon as they have basics understanding of language itself - not programming as whole - they want to make first games. It's okay, but unfortunately, their first choose if text-based RPG. I think that's really poor choice - I did this mistake by myself - but you see, text RPG is simple when it comes to visuals. You have console. What can be hard about coding to console? Well, turns out, it can be. If you want to make text-based RPG that is really nice and you want people to play your game with pleasure, you will have to implement many things that aren't easy or obvious for beginner. Creating Snake, Tetris or Arcanoid is probably much simpler then text-based RPG - it's just the genre that is highly structured, hence not easy.

You will probably either realize that, and abandon your current project, create few simple games to get feeling what game should look like, and then maybe come back at RPG but with different view, or you will finish your current project, but depending on your stubbornness, intelligence and few other things, you may either put a lot of effort into it and get nice game(but that's least likely option) or you will either end up with game that will be terribly designed(and maintaining the code/adding anything will be a nightmare), or your game will not be too fun to play. I recommend you looking at these links and reconsidering writing text-based RPGs. If you don't know what class is - then first go through C++ tutorials, and after you can say you understand polymorphism(just go through 3D buzz tutorial I included, it guides you through process of creating simple yet fun and nicely designed game), then you can try writing game.

Cheers!


PS. Actually, I've read your OP once again. I highly recommend abandoning dreams of creating textRPG for now, and learning more C++ and GameDev related stuff. Your game does not even have a game loop, and it's a must.

I would recommend you going through my links in the order that numbers before links show(and twice the number means that you can check out both sites at once; these are generally some advices, not lessons or tutorials).
You will find it a lot easier when you make some games at first(and learn the hard way what you need to use, and what to avoid).

PPS. And Amit's site is just extension to my post - it has even more links. :)
Last edited on
closed account (j3Rz8vqX)
Try this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
void goblinBattle()
{
  int hp = 25, enemyhp = 15, attack = 5, enemyattack = 5;
  int hitGoblin;

   do
   {
    cout << "\nHit goblin?\n Yes = 1\n No = 2\n";
    cin >> hitGoblin;
    if (hitGoblin == 1)
    {
    enemyhp = showEnemyHp(enemyhp, attack);
    hp = showHp(hp, enemyattack);
    cout << "\nYou hit the goblin.\n";
    cout << "The goblin now has " << enemyhp << " HP left.\n\n";
    if(enemyhp<=0)
    {
        cout << "You won!\n";
    }
    else
    {
       cout << "The goblin hit you back.\n";
       cout << "You now have " << hp << " HP left.\n\n";
    }
    }
    else if(hitGoblin==2)
    {
        cout << "You chose not to hit the goblin so he hit you instead\n";
        cout << "You now have " << hp << " HP left.\n\n";
    }
    else
    {
        cout << "That is not a valid choice.\n\n";
        return goblinBattle(); //This is going to reset the hp of you/goblin
    }

   }while(hp > 0 && enemyhp > 0);
}

int showEnemyHp(int enemyhp, int attack)
{
    enemyhp = enemyhp - attack;
    return enemyhp;
}
int showHp(int hp, int enemyattack)
{
    hp = hp - enemyattack;
    return hp;
}

Last edited on
@MatthewRock

I honestly thought making a game like tetris, snake, etc. was a lot harder than making a text-rpg that just uses some if-statements and a story.

Many people, when start programming, want to create games... quickly. So as soon as they have basics understanding of language itself - not programming as whole - they want to make first games.


While this may be somewhat true, making games wasn't tthe first thing I tried to do when I started learning c++; I played around a lot with what I learned from a couple tutorials and tried to understand what all the functions and statements meant and did. This text-rpg is mostly a project for myself where I can try out new stuff I just learned and learn new things more effectively.

Anyways, thanks for the links and information; It'll help a lot!

On-Topic:

I figured out how to fix it. Here is my final code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <iostream>
#include <cstdlib>

using namespace std;

void goblinBattle();
int showEnemyHp(int enemyhp, int attack);
int showHp(int hp, int enemyattack);

int main()
{
    int battle;
    cout << "\nYou see a goblin in the distance. Attack goblin?\n Yes = 1\n No = 2\n";
    cin >> battle;
    if(battle==1)
    {
        goblinBattle();
    }
    else if(battle==2)
    {
        cout << "You chose to not attack the goblin.\n";
    }
    else
    {
        cout << "That is not a valid choice.\n\n";
        return main();
    }

system("pause");
}

void goblinBattle()
{
  int hp = 25, enemyhp = 15, attack = 5, enemyattack = 5;
  int hitGoblin;

   do
   {
    cout << "\nHit goblin?\n Yes = 1\n No = 2\n";
    cin >> hitGoblin;
    if (hitGoblin == 1)
    {
    enemyhp = showEnemyHp(enemyhp, attack);
    hp = showHp(hp, enemyattack);
    cout << "\nYou hit the goblin.\n";
    cout << "The goblin now has " << enemyhp << "HP left.\n\n";
     if(enemyhp <= 0)
     {
        cout << "You won!\n";
     }
     else if(enemyhp > 0)
     {
       cout << "The goblin hit you back.\n";
       cout << "You now have " << hp << "HP left.\n\n";
     }
    }
    else if(hitGoblin == 2)
    {
        cout << "You chose not to hit the goblin so he hit you instead\n";
        cout << "You now have " << showHp(hp, enemyattack) << "HP left.\n\n";
    }
    else
    {
        cout << "That is not a valid choice.\n\n";
        return goblinBattle();
    }

   }while(hp > 0 && enemyhp > 0);
}

int showEnemyHp(int enemyhp, int attack)
{
    enemyhp = enemyhp - attack;
    return enemyhp;
}
int showHp(int hp, int enemyattack)
{
    hp = hp - enemyattack;
    return hp;
}
Programmers care about efficiency - it's just that we were born this way :) When you create text RPG - it of course depends on your definition of RPG, but I'll go with mine, which goes like "Game where you can go through various locations, meet NPCs or monsters, fight, talk, have equipment, develop your character, world is presented to player in text form, and communication is based on text commands" - you will notice it takes more then few "ifs" to get things done. You may create really really simple RPG, but you will see that without proper loop and structure of game, it's really hard to change anything - as making one change/addition affects the whole, most likely creating many bugs.

I think that the most important thing when you are learning to create games, is to write games, but not in purpose of making it really good game, but in purpose of learning. If you made buggy snake, but it works, and you learned something - it's okay. This snake can be counted as successfull project. It does not matter that sometimes it hangs, that you have no menu, that after loss game just quits - you learned something, and that's what counts.

If you decide to develop your project further, you will also learn -at least that's my guess; you will learn that game is more complicated to create then writing few "ifs", and that game structure is really important.

They say that when you want to write program, you should start with pen and paper. It's true - if you organize your program at the beginning , you may see the problems before they are too hard to fix. First game I created, Tic-Tac-Toe was terribly designed. But I learned something, and it worked, so it's a success. Next games were better organized, and I was learning something new every new project.

As to your quote:

I honestly thought making a game like tetris, snake, etc. was a lot harder than making a text-rpg that just uses some if-statements and a story.

I also did. But because it does not involve graphics, it does not mean it is easier. Snake can be made basing on tiles, so collision detection will require no maths but simple comparison, and creating classes for snake is much simpler then for RPG.

I am telling you what I think basing on my experience. You may do whatever you want. I abandoned my first text RPG, and I consider it a good decision. I might have get it working, but I would design things completely wrong, hence I would not learn too much - I would waste my time on looking for workarounds of problems that would never be there if I used correct patterns in the first place.

Anyway, good luck. I hope you succeed in whatever you do.
closed account (j3Rz8vqX)
1
2
3
4
5
6
7
8
9
10
    else if(hitGoblin == 2)
    {
        hp = showHp(hp, enemyattack);
        cout << "You chose not to hit the goblin so he hit you instead\n";
        cout << "You now have " << hp << "HP left.\n\n";
    }
    else
    {
        cout << "That is not a valid choice.\n\n";
    }

Topic archived. No new replies allowed.