Jump to content
  • Advertisement
Sign in to follow this  
AmagicalFishy

Structure of object-to-object interaction? (And other questions!)

This topic is 1210 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've begun making a text-RPG by creating the general logic of objects (rooms, creatures, items), but haven't much interaction between items yet. I can think of a couple of ways to do this, but am not that sure which is best.

 

Consider the situation wherein a creature attacks another creature (say Creature A attacking Creature B). It's easy for the objects to interact if we call a method in Creature A that directly affects Creature B. Something like:

 

Creature A::attack( Creature B ) {

    Creature B.changeHP( - 5 );

 

While this is easily implemented, part of me doesn't think it's... good. What I'd like to do is have there be something like a middle-man that sees Creature A's attack, that Creature B exists, then applies the results of Creature A's attack to Creature B (is this what an event-handler does?) If instead that is a better idea—what is the general implementation of such a structure? Do Creature A's methods throw some flag, and send data to the "world," and then the world applies this to Creature B accordingly?

 

Eventually, I'd like to move on from a simple text-RPG. That is, even if one isn't typically considering these things when creating a text-RPG, I think this is a good opportunity to familiarize myself with them. In another thread, someone mentioned "designing the game as a client-server application and running the single player game in localserver host." Maybe that is a little bit above my ability (for now), but what paradigm can I embrace that would best accommodate such a thing?

 

Right now, everything is still pure from-scratch (except STL) C++; I assume it will be for a while. But, at what point should I really start considering moving to something more specific and less fundamental? When I get into graphics? Or is networking, even, something that I shouldn't even try tackling without some kind of heavy tool-set?

Share this post


Link to post
Share on other sites
Advertisement

Creature A::attack( Creature B ) {
    Creature B.changeHP( - 5 );
}


While I currently don't have the time and coffee level to deal with the questions you asked, one detail: the code you posted above does not work the way you intend to. If you have
Creature player(...whatever...);
Creature goblin(...whatever...);

player.attack(goblin);
then the goblin will never lose hitpoints. B is passed by value to Creature::attack which means the compiler generates a copy of goblin, modifies the copy's hitpoints and then discards the copy since the scope ends. You also seem to be returning a Creature from the function which does not have much use in my opinion and is actively dangerous because you do not return anything.
What you want is something like this:
void Creature::attack(Creature& victim) { ... }
Look a up references if you don't know what this is about. Pointers can be relevant here too.

Share this post


Link to post
Share on other sites

I know—I just decided that having actual code would have detracted from the question, so threw up a sort of psuedo code.

 

Now that I look at it again the spaces in "Creature A" and "Creature B" do make it look like I'm returning a "Creature" type, haha. I meant it to be a single name, and should have probably put "Creature_A" or something.

Edited by AmagicalFishy

Share this post


Link to post
Share on other sites
It sounds like you need a "room" or more generally nested "containers" (creatures in a box in a cage in a room in the world) as medium.

I am not sure that the medium should do anything besides giving information back and forth, ie creatureA needs to be aware of creatureB, he's not attacking blindly all the time.
All 'things' in the world also need to speak some common base language, at least for exchanging what they are to each other, I think.

You may want to look into adventure authoring systems, there are for example text adventure creation languages, that would need to deal with this problem too, although they might be very player-centric.

Share this post


Link to post
Share on other sites
Rooms is the concept of "near enough you to interact" in general, so it seems to me to be the logical entity to handle presence of other creatures.

I don't know what others do, there are so many options available, at this stage you probably cannot even distinguish the optimal solution, as there is pretty much no information to decide on.

My strategy in development of the unknown is to go where I think gives the best solution, but with each step check whether it all still fits nicely.
If it does, yay!
If it does not, adapt without fear to throw things out if they are wrong (the key information is the thought of the solution, code is easy to write again from a solution). Hanging on to things that are broken gives a lot of misery, and in the end you'll replace it anyway.
To me, the only valid reason to keep a broken thing is a deadline that you must meet.

Share this post


Link to post
Share on other sites

The optimal way to do this depends on your requirements for the system: 

  • Does the creature choose what to attack explicitly, or does it attack in a direction and hit whatever is in that direction?
  • Are there "ranged" attacks - can you attack across multiple rooms?
  • Are there area of effect attacks, which hit multiple creatures, e.g. based on their distance to the attack?

The answers to these questions are your requirements for the attacking subsystem. You can than evaluate your implementation ideas against these requirements.

For example, if the requirements are: "the creature to attack is chosen explicitly and must be in the same room as the attacking creature, there are no ranged or area of effect attacks", then you can resolve the attack directly (similar to what you wrote as pseudocode), and it will work just fine.

 

The other issue is how the attack is resolved. In your pseudocode, I can see two potential problems: CreatureA knows the type of CreatureB - you preferably would do this more abstractly, through a base class interface, or via a component-based system. The other is that the attacker decides exactly what effect the attack has, which is inflexible. I would prefer something along the lines of:

 

Creature::attack(Creature* target)

{

  target->onAttacked(getWeapon()->getDamageType, getWeapon()->getDamage); // the weapon part is just an example, you can vary this however you want

}

 

Creature::onAttacked(DamageType damageType, int damage)

{

  int damageTaken = getArmor()->modifyDamage(damageType, damage); // again, just an example

  reduceHp(damageTaken);

}

Share this post


Link to post
Share on other sites

I think these types of mutual interations are better handled through a mediator.
 

Creature::attack() {
    world.attack(this, enemy, AttackType::MELEE_ATTACK);
}

World::attack(Creature attacker, Creature enemy, AttackType type) {
    attackHandler = attackHandlers.get(attacker, enemy, type);
    if (attackHandler) {
        attackHandler.doAttack();
    }
    else {
        // No AttackHandler found for interation between attacker and enemy
    }
}

MeleeAttackHandler::doAttack() {
    if (attacker.att > enemy.def) {
        enemy.applyDamage(max(0, attack.damage - enemy.shield));
    }

    if (badluck() > 0.1 && enemy.def > 8) {
        attacker.applyDamage(10); // hurt your hand while punching enemy
    }
}

 

This prevents your creatures from directly altering the state of the other creatures and allows you to add specialized attack handlers later on if you want to expand.
A similar system could also be used for other interactions between two or more entities, for example reacting to sounds made by a creature.

Share this post


Link to post
Share on other sites

AmagicalFishy you may take a look at Eric Lippert's article for slightly different approach to your problem http://ericlippert.com/2015/05/11/wizards-and-warriors-part-five/

It is last article of the series that tackles different problems with implementation using example of RPG game.Something like where the attack code belongs to handle edge cases like a paladin attacks werewolf using silver sword during full moon :)

This is written with C# in mind but can be easily adopted to other languages.

 

Definitely worth a read.

Share this post


Link to post
Share on other sites

God damn, gentlemen, that's exactly the type of stuff I was looking for—no more, no less.

 

Thank you!

 

Are there implementations of Inform7 for something other than text-games? Say, do video games use it aswell? (It seems like it'd be useful)

Edited by AmagicalFishy

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!