Author Topic: Kick command and other commands requiring interaction with the map  (Read 8008 times)

mike3

  • Rogueliker
  • ***
  • Posts: 125
  • Karma: +0/-0
    • View Profile
    • Email
Hi.

I was wondering about this now. On this thread:

http://forums.roguetemple.com/index.php?topic=3212.30

I discussed some stuff with regards to how to program movement in a roguelike without the "critters" containing a reference to the map which they're on. One suggestion was to have a move method on the map itself, but what about other commands that require detecting if another critter or object is on the map, like kick? It seems that adding "kick" now to the map starts to sound like too many responsibilities for the map! Doesn't it make more sense to have that on the critter?

The discussion also went to the topic, which I discussed some more in later threads, of "component" architecture. It was mentioned in the referenced thead also that "throwing away code" is not a good idea (since I'm not using a component system now), but also was said "You might try encapsulating a few of the ideas into what you already have-- breaking the logic of your game into component-systems is a very good idea whether you are OOP or DOP.". Though I don't still yet have a good, strong feel for the component architecture, but it was mentioned that the systems in component architecture should be just stateless functions operating on a database... isn't that DOP? What would be the way to handle these kinds of commands (kick, talk, etc.) both in a component and also a more "traditional" non-component setup like I have now, since it seems a move to component would be a total redo of all the progress acquired so far?
« Last Edit: August 20, 2013, 04:33:51 AM by mike3 »

TheCreator

  • Rogueliker
  • ***
  • Posts: 370
  • Karma: +0/-0
    • View Profile
    • Fame
    • Email
Re: Kick command and other commands requiring interaction with the map
« Reply #1 on: August 20, 2013, 05:52:14 AM »
I discussed some stuff with regards to how to program movement in a roguelike without the "critters" containing a reference to the map which they're on. One suggestion was to have a move method on the map itself, but what about other commands that require detecting if another critter or object is on the map, like kick? It seems that adding "kick" now to the map starts to sound like too many responsibilities for the map! Doesn't it make more sense to have that on the critter?

It depends how you define "more sense". When there's some interaction between two or three objects, there is always a question where to put the code. Probably the best answer is that, in general, it doesn't matter. Place your code anywhere. If at some point in the future you feel that it doesn't fit there, refactor. It is OK to have some mess in the code as long as you still remember which objects has which method. Trying to achieve perfect OOP from the very start is a common mistake in programming.
Fame (Untitled) - my game. Everything is a roguelike.

miki151

  • Rogueliker
  • ***
  • Posts: 264
  • Karma: +0/-0
    • View Profile
Re: Kick command and other commands requiring interaction with the map
« Reply #2 on: August 20, 2013, 04:15:26 PM »
Yes, it makes sense to put the "kick" method on the critter. Especially if you're going to check for prerequisites like if the critter has legs. One way to do it is to add a kick(critter, direction) method to the map and kick(enemy) on the critter.

Map.kick(critter, direction) {
  enemy = [get the critter in the given direction]
  if (enemy == null) // no enemy
    return;
  critter.kick(enemy);
}

Critter.kick(enemy) {
  if (!hasLegs)
    return;
  damage = [calculate damage based on strength, bonus from metal boots, etc]
  enemy.inflictDamage(damage);
}

This way you are also free to override the Critter.kick method if you add a special kick attack or something.

Ps. personally I don't go for this kind of ultra-clean design, as it takes more typing, add complexity to the code, and there's a high chance you'll need to break it because of some corner case later (especially in roguelikes). So I just keep a backreference from critter to map, there are many dirtier places in my code anyway.
« Last Edit: August 20, 2013, 04:23:13 PM by miki151 »
KeeperRL, Dungeon Keeper in roguelike style:
http://keeperrl.com

tuturto

  • Rogueliker
  • ***
  • Posts: 259
  • Karma: +0/-0
    • View Profile
    • pyherc
Re: Kick command and other commands requiring interaction with the map
« Reply #3 on: August 26, 2013, 08:53:06 AM »
There's always an option of putting it somewhere else than Map or Critter too. Like rules.actions.kick(critter, direction) for example. I usually have methods on objects that directly manipulate only that specific object. If there's a method that requires an interaction between several objects of different types, then the code goes to somewhere else. However, I try to avoid having a KickManager objects :)
Everyone you will ever meet knows something you don't.
 - Bill Nye

wire_hall_medic

  • Rogueliker
  • ***
  • Posts: 160
  • Karma: +0/-0
    • View Profile
Re: Kick command and other commands requiring interaction with the map
« Reply #4 on: August 26, 2013, 03:45:24 PM »
I like to compartmentalized code; it makes it easier to remember where I left specific functions if they're thematically grouped.

I like to have the AI be a separate class, with a reference to the owning actor; the map and actor list are global variables.  The AI determines which action the actor should perform, and passes that to the actor.  The actor then executes it (changing their own location internally if moving, attacking another actor if attacking, toggling a door, etc).

If I were doing procedural programing, I'd keep the map and actor list global, and make the AI a function which is passed an actor and returns an action.

Krice

  • (Banned)
  • Rogueliker
  • ***
  • Posts: 2316
  • Karma: +0/-2
    • View Profile
    • Email
Re: Kick command and other commands requiring interaction with the map
« Reply #5 on: August 26, 2013, 04:05:59 PM »
Mike, you need to relax and try to overcome your autism on this subject. There are more than one way to do this. However, in logical sense I would break kicking into two parts:
1. Kicker (what is happening to him when he kicks)
2. The target (what happens to it when kicked)

Following that logic I would say it could be useful to make map tiles and other objects take damage in form of a kick. Even then it's difficult to completely separate these two, because enemies need to know who kicked them.