0
\$\begingroup\$

I am creating a browser game that allows players to fight monsters using Nodejs, Socket.io and Express. However I can't seem to figure out how to implement the turns of combat.

My train of thought and workflow is as follows:

  • The player declares an attack on a monster (Client makes a Post request.) - Working
  • The server get's the player's stats as well as the monster's. - Working

  • The player selects his action and attacks, then it's the monster's turn and so on. - Can't figure this out

How would such a functionality be implemented?

\$\endgroup\$
  • \$\begingroup\$ What specific parts are you having trouble with? What is the trouble beyond just submitting the commands to the server and then having the server simulate the combat and send the results to the player(s), and notifies the player(s) when its their turn to select new actions? \$\endgroup\$ – Sean Middleditch Jan 18 '18 at 19:41
1
\$\begingroup\$

This is just an exercise in modeling the objects you want to represent your game.

At the very least, you need a concept of the battling entities (players and creatures) and individual battles.

The Creature / Player will be objects that have attributes like HP and Attack power.

The Battle class will track things like turn count, whose turn it is, etc.

When the player initiates the battle, you should create a new battle object to track the turns.

In the following example code, I'm using javascript functions as examples, but you can map them to REST endpoints or whatever. for example, POST /battles/new with data attacker_id=2&target_id=1 for function initiateBattle.

 // Starts a Battle -- could throw an exception if either combatant is already in combat.
 function initiateBattle(attacker, target) {
    var battle = new Battle(attacker, target);
    game.globalBattlesList.add(battle);
    return {battle: {
       id: battle.id, 
       current_turn: { 
          owner: attacker,
          number: 1,
       }}};
 }

 // Send an attack in a battle
 function attack(battle, attacker, target) {
     if (battle.current_turn.owner != attack) { 
        return {result: "error", message: "It's not your turn!"};
     }

     target.HP -= attacker.ATK;

     if (target.HP <= 0) {
        ... 
        game.end_battle(battle);
        return {
           status: "OK", 
           winner: attacker,
           message: "${attacker.name} wins in ${battle.current_turn.number} turns!"
        };
     }

     // change turn
     battle.current_turn = {owner: target, number: battle.current_turn.number + 1};

     // does the AI have a delay?
     setTimeout(function() { 
         // do_enemy_turn will choose an action for the AI 
         // and set battle.current_turn back to 
         do_enemy_turn(battle, target, attacker);
     }, target.attack_delay);

     return { 
         result: "continue", 
         message: `target is at ${target.HP} HP`
     };
 }
\$\endgroup\$
  • \$\begingroup\$ Looks great, thank you! The Battle class is only for keeping track? How would I implement a new class in node? I am quite new to this. \$\endgroup\$ – Valamorde Jan 19 '18 at 0:53
  • \$\begingroup\$ class Battle { constructor() { ... } } \$\endgroup\$ – Jimmy Jan 19 '18 at 17:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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