Re: OO and game design questions

2010-11-15 Thread Aahz
In article i9lfbu$1a...@localhost.localdomain,
Martin Gregorie  mar...@address-in-sig.invalid wrote:
On Tue, 19 Oct 2010 19:49:20 -0400, Dave Angel wrote:

 Thanks, that is what I was trying to say.  In the same sense that
 emptying a list makes it quite small, if it's a general purpose object,
 you just want to remove all the attributes.

I think a 'place' (to generalise it) is quite a small object in any case. 
All it needs to contain is a few lists:
- a list of exits, which in some implementations might be simply
  references to other places, but might usefully be objects with
  two sides, each having an appearance and a link to the place 
  where that side appears.
- a list of fixed objects which only serve to describe the place.
- a list of mobile objects that actors can pick up and move
- a list of actors who happen to be there.

plus a describePlace() method and add(), remove() and getItem() methods 
for each list. It may be possible to use a single list for all types of 
object, in which case the object itself would be very small indeed.

Maybe you want a rule-based approach:

http://eblong.com/zarf/essays/rule-based-if/
-- 
Aahz (a...@pythoncraft.com)   * http://www.pythoncraft.com/

Look, it's your affair if you want to play with five people, but don't
go calling it doubles.  --John Cleese anticipates Usenet
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: OO and game design questions

2010-10-23 Thread Gregory Ewing

Jonathan Hartley wrote:


One common way to store delayed actions is as a lambda (an anonymous
function.)


Although note that you don't have to use 'lambda' in
particular -- functions defined with 'def' can be used
the same way.

--
Greg
--
http://mail.python.org/mailman/listinfo/python-list


Re: OO and game design questions

2010-10-21 Thread Jonathan Hartley
On Oct 20, 12:11 pm, dex josipmisko...@gmail.com wrote:
 On Oct 20, 12:25 pm, Jonathan Hartley tart...@tartley.com wrote:



  On Oct 18, 8:28 am, dex josipmisko...@gmail.com wrote:

   I'm building a turn based RPG game as a hobby. The design is becoming
   increasingly complicated and confusing, and I think I may have
   tendency to over-engineer simple things. Can anybody please check my
   problems-solutions and point me to more elegant solution?

   Every item/character/room is a separate object. Items/characters need
   to have references to room they are in, and room needs to have a list
   of references to items/characters that are contained within. I decided
   to use weak references. That way I can destroy object by deleting it,
   I don't have to destroy all references as well. In each object's
   __init__() that object is added to game_object list, and in each
   __del__() they are removed from game_object list. This mechanism keeps
   them safe from garbage collector. How pythonic is this design?

   In turn-based games, the order of action execution in battle can give
   unfair advantage to players. For example, if player's arm is crippled
   before his action is executed, he would do less damage. To offset
   this, I first execute all players' actions and calculate effects in
   first pass, then apply the effects in second pass. The effect can be
   health decrease by 15HP, item pick-up, 30p experience gain, etc. This
   means the player deals the same amount of damage no matter what
   happens to him in that turn. The difficult part is keeping track of
   various effects. I had to make separate class for various types of
   effects (ChangeAttributeEffect, GetItemEffect, LooseItemEffect). Each
   class stores weak reference to target object and has apply() method
   that applies the effect to object. I'm not satisfied with this as it's
   limiting, error-prone and uses metaprogramming. Is there a design
   pattern that would remember changes to an object, and apply them
   later?

   Sorry for the wall of text.

  One common way to store delayed actions is as a lambda (an anonymous
  function.) A lambda defines a new function:

  , and you can call this function later. The created function has no
  name, (but you can assign it to a variable to give it a name if you
  like) and can be called later:

  So in the game, you could have a collection 'effects', each one will
  be a lambda:

    effects = []

  At the start of the round, as each entity makes its moves, they add
  lambdas to this collection.

    effects.append(
        lambda: decrease_hp(monster_a, 4)
    )
    effects.append(
        lambda: lose_item(monster_a, item_b)
    )

  Instead of appending it directly like this, I imagine the lambdas
  could be returned by the monster's 'act' or 'update' method:

    class Monster():
      def act(self):
        # blah and finally
        return lambda: decrease_hp(monster_a, 4)

  Then for the start of a round, first you ask each monster what action
  it is going to perform:

    for monster in room.monsters:
        effects.append(
            monster.act()
        )

  Then for the end of the round, call all the lambdas

    for effect in effects:
        effect()

 Mr. Roy Smith already proposed using closures. I already did a similar
 thing in my code, but instead of decrease_hp() I have AttributeEffect
 class which is able to modify any attribute (in old RPGs some monsters
 could drain your intelligence, in my game laser gun hit will decrease
 HP as well as armor integrity). The first version looks like this
 (missing few checks):

 class AttributeEffect(object):
     '''Effect changes object's attribute by delta'''
     def __init__(self, obj, attrib, delta):
         self.obj = obj               # reference to object the effect
 applies to
         self.attrib = attrib         # name of attribute that effect
 applies to
         self.delta = delta           # change of value for
 object.attribute
     def apply(self):
         value = getattr(self.obj, self.attrib) # todo: try, except
         value += self.delta
         setattr(self.obj(), self.attrib, value)

 Yesterday I learned that Python 3.0 introduces nonlocal keyword which
 would simplify defining effect functions and passing them along. Nice
 improvement.


Very cool, that looks like it would work. The thing I like about the
lambda idea though, is that you don't have to write any classes like
AttributeEffect, (and presumably other such classes, like
LoseItemEffect, etc.) Instead of *modelling* the different kind of
effects that could happen, you just write code that *performs* the
desired effect. (e.g. monster.hp -= damage) To my eyes, lambda's are
therefore more flexible and require less code. But I could be wrong,
and obviously you should do what you think is best for your
circumstances. Very best of luck with it.

Out of interest, is there anywhere you blog about the game
development, or are likely to make 

Re: OO and game design questions

2010-10-21 Thread Jonathan Hartley
On Oct 20, 12:11 pm, dex josipmisko...@gmail.com wrote:
 On Oct 20, 12:25 pm, Jonathan Hartley tart...@tartley.com wrote:



  On Oct 18, 8:28 am, dex josipmisko...@gmail.com wrote:

   I'm building a turn based RPG game as a hobby. The design is becoming
   increasingly complicated and confusing, and I think I may have
   tendency to over-engineer simple things. Can anybody please check my
   problems-solutions and point me to more elegant solution?

   Every item/character/room is a separate object. Items/characters need
   to have references to room they are in, and room needs to have a list
   of references to items/characters that are contained within. I decided
   to use weak references. That way I can destroy object by deleting it,
   I don't have to destroy all references as well. In each object's
   __init__() that object is added to game_object list, and in each
   __del__() they are removed from game_object list. This mechanism keeps
   them safe from garbage collector. How pythonic is this design?

   In turn-based games, the order of action execution in battle can give
   unfair advantage to players. For example, if player's arm is crippled
   before his action is executed, he would do less damage. To offset
   this, I first execute all players' actions and calculate effects in
   first pass, then apply the effects in second pass. The effect can be
   health decrease by 15HP, item pick-up, 30p experience gain, etc. This
   means the player deals the same amount of damage no matter what
   happens to him in that turn. The difficult part is keeping track of
   various effects. I had to make separate class for various types of
   effects (ChangeAttributeEffect, GetItemEffect, LooseItemEffect). Each
   class stores weak reference to target object and has apply() method
   that applies the effect to object. I'm not satisfied with this as it's
   limiting, error-prone and uses metaprogramming. Is there a design
   pattern that would remember changes to an object, and apply them
   later?

   Sorry for the wall of text.

  One common way to store delayed actions is as a lambda (an anonymous
  function.) A lambda defines a new function:

  , and you can call this function later. The created function has no
  name, (but you can assign it to a variable to give it a name if you
  like) and can be called later:

  So in the game, you could have a collection 'effects', each one will
  be a lambda:

    effects = []

  At the start of the round, as each entity makes its moves, they add
  lambdas to this collection.

    effects.append(
        lambda: decrease_hp(monster_a, 4)
    )
    effects.append(
        lambda: lose_item(monster_a, item_b)
    )

  Instead of appending it directly like this, I imagine the lambdas
  could be returned by the monster's 'act' or 'update' method:

    class Monster():
      def act(self):
        # blah and finally
        return lambda: decrease_hp(monster_a, 4)

  Then for the start of a round, first you ask each monster what action
  it is going to perform:

    for monster in room.monsters:
        effects.append(
            monster.act()
        )

  Then for the end of the round, call all the lambdas

    for effect in effects:
        effect()

 Mr. Roy Smith already proposed using closures. I already did a similar
 thing in my code, but instead of decrease_hp() I have AttributeEffect
 class which is able to modify any attribute (in old RPGs some monsters
 could drain your intelligence, in my game laser gun hit will decrease
 HP as well as armor integrity). The first version looks like this
 (missing few checks):

 class AttributeEffect(object):
     '''Effect changes object's attribute by delta'''
     def __init__(self, obj, attrib, delta):
         self.obj = obj               # reference to object the effect
 applies to
         self.attrib = attrib         # name of attribute that effect
 applies to
         self.delta = delta           # change of value for
 object.attribute
     def apply(self):
         value = getattr(self.obj, self.attrib) # todo: try, except
         value += self.delta
         setattr(self.obj(), self.attrib, value)

 Yesterday I learned that Python 3.0 introduces nonlocal keyword which
 would simplify defining effect functions and passing them along. Nice
 improvement.


Very cool, that looks like it would work. The thing I like about the
lambda idea though, is that you don't have to write any classes like
AttributeEffect, (and presumably other such classes, like
LoseItemEffect, etc.) Instead of *modelling* the different kind of
effects that could happen, you just write code that *performs* the
desired effect. (e.g. monster.hp -= damage) To my eyes, lambda's are
therefore more flexible and require less code. But I could be wrong,
and obviously you should do what you think is best for your
circumstances. Very best of luck with it.

Out of interest, is there anywhere you blog about the game
development, or are likely to make 

Re: OO and game design questions

2010-10-21 Thread Jonathan Hartley
On Oct 20, 12:11 pm, dex josipmisko...@gmail.com wrote:
 On Oct 20, 12:25 pm, Jonathan Hartley tart...@tartley.com wrote:



  On Oct 18, 8:28 am, dex josipmisko...@gmail.com wrote:

   I'm building a turn based RPG game as a hobby. The design is becoming
   increasingly complicated and confusing, and I think I may have
   tendency to over-engineer simple things. Can anybody please check my
   problems-solutions and point me to more elegant solution?

   Every item/character/room is a separate object. Items/characters need
   to have references to room they are in, and room needs to have a list
   of references to items/characters that are contained within. I decided
   to use weak references. That way I can destroy object by deleting it,
   I don't have to destroy all references as well. In each object's
   __init__() that object is added to game_object list, and in each
   __del__() they are removed from game_object list. This mechanism keeps
   them safe from garbage collector. How pythonic is this design?

   In turn-based games, the order of action execution in battle can give
   unfair advantage to players. For example, if player's arm is crippled
   before his action is executed, he would do less damage. To offset
   this, I first execute all players' actions and calculate effects in
   first pass, then apply the effects in second pass. The effect can be
   health decrease by 15HP, item pick-up, 30p experience gain, etc. This
   means the player deals the same amount of damage no matter what
   happens to him in that turn. The difficult part is keeping track of
   various effects. I had to make separate class for various types of
   effects (ChangeAttributeEffect, GetItemEffect, LooseItemEffect). Each
   class stores weak reference to target object and has apply() method
   that applies the effect to object. I'm not satisfied with this as it's
   limiting, error-prone and uses metaprogramming. Is there a design
   pattern that would remember changes to an object, and apply them
   later?

   Sorry for the wall of text.

  One common way to store delayed actions is as a lambda (an anonymous
  function.) A lambda defines a new function:

  , and you can call this function later. The created function has no
  name, (but you can assign it to a variable to give it a name if you
  like) and can be called later:

  So in the game, you could have a collection 'effects', each one will
  be a lambda:

    effects = []

  At the start of the round, as each entity makes its moves, they add
  lambdas to this collection.

    effects.append(
        lambda: decrease_hp(monster_a, 4)
    )
    effects.append(
        lambda: lose_item(monster_a, item_b)
    )

  Instead of appending it directly like this, I imagine the lambdas
  could be returned by the monster's 'act' or 'update' method:

    class Monster():
      def act(self):
        # blah and finally
        return lambda: decrease_hp(monster_a, 4)

  Then for the start of a round, first you ask each monster what action
  it is going to perform:

    for monster in room.monsters:
        effects.append(
            monster.act()
        )

  Then for the end of the round, call all the lambdas

    for effect in effects:
        effect()

 Mr. Roy Smith already proposed using closures. I already did a similar
 thing in my code, but instead of decrease_hp() I have AttributeEffect
 class which is able to modify any attribute (in old RPGs some monsters
 could drain your intelligence, in my game laser gun hit will decrease
 HP as well as armor integrity). The first version looks like this
 (missing few checks):

 class AttributeEffect(object):
     '''Effect changes object's attribute by delta'''
     def __init__(self, obj, attrib, delta):
         self.obj = obj               # reference to object the effect
 applies to
         self.attrib = attrib         # name of attribute that effect
 applies to
         self.delta = delta           # change of value for
 object.attribute
     def apply(self):
         value = getattr(self.obj, self.attrib) # todo: try, except
         value += self.delta
         setattr(self.obj(), self.attrib, value)

 Yesterday I learned that Python 3.0 introduces nonlocal keyword which
 would simplify defining effect functions and passing them along. Nice
 improvement.


Very cool, that looks like it would work. The thing I like about the
lambda idea though, is that you don't have to write any classes like
AttributeEffect, (and presumably other such classes, like
LoseItemEffect, etc.) Instead of *modelling* the different kind of
effects that could happen, you just write code that *performs* the
desired effect. (e.g. monster.hp -= damage) To my eyes, lambda's are
therefore more flexible and require less code. But I could be wrong,
and obviously you should do what you think is best for your
circumstances. Very best of luck with it.

Out of interest, is there anywhere you blog about the game
development, or are likely to make 

Re: OO and game design questions

2010-10-20 Thread dex
On Oct 19, 8:08 pm, Carl Banks pavlovevide...@gmail.com wrote:
 On Oct 19, 1:19 am, dex josipmisko...@gmail.com wrote:





   I'm not sure if it's a good idea to let an item disappear from your
   inventory by a weak reference disappearing.  It seems a little shaky
   to not know where your objects are being referenced, but that's yout
   decision.

  OK, imagine a MUD, where players can dig out new rooms. Room A has a
  door that holds reference to newly created room B. By using a door,
  player is transported to room B. At later time someone destroys room
  B.

  Using strong references, I have to remove room B from list of rooms,
  and also remove door to room B, as it holds reference to room B. To do
  that, I have to keep list of doors that lead to room B.

  Using weak references, I don't have to worry about removing all doors
  to room B. They all now have a dead reference, which better models
  actual situation. If part of mine collapses, or if a module on space
  station is destroyed, the passage to that location does not magically
  vanish - it's just obstructed.

  Can you please tell me if there's something wrong with my reasoning?

 Well, you're talking about particulars here whereas I am speaking in
 general.  If something is questionable or even bad in general it
 doesn't mean there are no particular cases for it.

 Generally speaking: in a game there's presumably some conservation of
 objects.  If you drop an item, does it disappear, or does it become an
 object of the room?  Weak referencing won't help you in the latter
 case because you have to take care of references at both ends anyway.
 That's what I mean by shaky: it lets you forget about half of the
 transaction, which might not be the best thing.  YMMV

 Carl Banks

I see your point. I'll think this through and try to build more robust
system.
Thanks for your insight.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: OO and game design questions

2010-10-20 Thread dex
On Oct 19, 6:54 pm, Dennis Lee Bieber wlfr...@ix.netcom.com wrote:
 On Tue, 19 Oct 2010 01:19:48 -0700 (PDT), dex josipmisko...@gmail.com
 declaimed the following in gmane.comp.python.general:



  OK, imagine a MUD, where players can dig out new rooms. Room A has a
  door that holds reference to newly created room B. By using a door,
  player is transported to room B. At later time someone destroys room
  B.

         Out of curiosity, have you looked at any of the older Python
 efforts?

 http://py-universe.sourceforge.net/http://www.strout.net/info/coding/python/poo/index.html(some
  dead
 links)
 --
         Wulfraed                 Dennis Lee Bieber         AF6VN
         wlfr...@ix.netcom.com    HTTP://wlfraed.home.netcom.com/

I will check out your links. I did some research on several MUD
projects (evennia, PyMUD) and gained very little from them. I used MUD
only as example, my game idea is combination of Rogue and Elite, with
Darklands GUI. It's definitely overambitious, but I'm taking it slowly
and learning things on the way.

Thanks for input.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: OO and game design questions

2010-10-20 Thread Jonathan Hartley
On Oct 18, 8:28 am, dex josipmisko...@gmail.com wrote:
 I'm building a turn based RPG game as a hobby. The design is becoming
 increasingly complicated and confusing, and I think I may have
 tendency to over-engineer simple things. Can anybody please check my
 problems-solutions and point me to more elegant solution?

 Every item/character/room is a separate object. Items/characters need
 to have references to room they are in, and room needs to have a list
 of references to items/characters that are contained within. I decided
 to use weak references. That way I can destroy object by deleting it,
 I don't have to destroy all references as well. In each object's
 __init__() that object is added to game_object list, and in each
 __del__() they are removed from game_object list. This mechanism keeps
 them safe from garbage collector. How pythonic is this design?

 In turn-based games, the order of action execution in battle can give
 unfair advantage to players. For example, if player's arm is crippled
 before his action is executed, he would do less damage. To offset
 this, I first execute all players' actions and calculate effects in
 first pass, then apply the effects in second pass. The effect can be
 health decrease by 15HP, item pick-up, 30p experience gain, etc. This
 means the player deals the same amount of damage no matter what
 happens to him in that turn. The difficult part is keeping track of
 various effects. I had to make separate class for various types of
 effects (ChangeAttributeEffect, GetItemEffect, LooseItemEffect). Each
 class stores weak reference to target object and has apply() method
 that applies the effect to object. I'm not satisfied with this as it's
 limiting, error-prone and uses metaprogramming. Is there a design
 pattern that would remember changes to an object, and apply them
 later?

 Sorry for the wall of text.


One common way to store delayed actions is as a lambda (an anonymous
function.) A lambda defines a new function:


, and you can call this function later. The created function has no
name, (but you can assign it to a variable to give it a name if you
like) and can be called later:



So in the game, you could have a collection 'effects', each one will
be a lambda:

  effects = []

At the start of the round, as each entity makes its moves, they add
lambdas to this collection.

  effects.append(
  lambda: decrease_hp(monster_a, 4)
  )
  effects.append(
  lambda: lose_item(monster_a, item_b)
  )

Instead of appending it directly like this, I imagine the lambdas
could be returned by the monster's 'act' or 'update' method:

  class Monster():
def act(self):
  # blah and finally
  return lambda: decrease_hp(monster_a, 4)

Then for the start of a round, first you ask each monster what action
it is going to perform:

  for monster in room.monsters:
  effects.append(
  monster.act()
  )

Then for the end of the round, call all the lambdas

  for effect in effects:
  effect()
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: OO and game design questions

2010-10-20 Thread Jonathan Hartley
On Oct 20, 11:25 am, Jonathan Hartley tart...@tartley.com wrote:
 On Oct 18, 8:28 am, dex josipmisko...@gmail.com wrote:



  I'm building a turn based RPG game as a hobby. The design is becoming
  increasingly complicated and confusing, and I think I may have
  tendency to over-engineer simple things. Can anybody please check my
  problems-solutions and point me to more elegant solution?

  Every item/character/room is a separate object. Items/characters need
  to have references to room they are in, and room needs to have a list
  of references to items/characters that are contained within. I decided
  to use weak references. That way I can destroy object by deleting it,
  I don't have to destroy all references as well. In each object's
  __init__() that object is added to game_object list, and in each
  __del__() they are removed from game_object list. This mechanism keeps
  them safe from garbage collector. How pythonic is this design?

  In turn-based games, the order of action execution in battle can give
  unfair advantage to players. For example, if player's arm is crippled
  before his action is executed, he would do less damage. To offset
  this, I first execute all players' actions and calculate effects in
  first pass, then apply the effects in second pass. The effect can be
  health decrease by 15HP, item pick-up, 30p experience gain, etc. This
  means the player deals the same amount of damage no matter what
  happens to him in that turn. The difficult part is keeping track of
  various effects. I had to make separate class for various types of
  effects (ChangeAttributeEffect, GetItemEffect, LooseItemEffect). Each
  class stores weak reference to target object and has apply() method
  that applies the effect to object. I'm not satisfied with this as it's
  limiting, error-prone and uses metaprogramming. Is there a design
  pattern that would remember changes to an object, and apply them
  later?

  Sorry for the wall of text.

 One common way to store delayed actions is as a lambda (an anonymous
 function.) A lambda defines a new function:

 , and you can call this function later. The created function has no
 name, (but you can assign it to a variable to give it a name if you
 like) and can be called later:

 So in the game, you could have a collection 'effects', each one will
 be a lambda:

   effects = []

 At the start of the round, as each entity makes its moves, they add
 lambdas to this collection.

   effects.append(
       lambda: decrease_hp(monster_a, 4)
   )
   effects.append(
       lambda: lose_item(monster_a, item_b)
   )

 Instead of appending it directly like this, I imagine the lambdas
 could be returned by the monster's 'act' or 'update' method:

   class Monster():
     def act(self):
       # blah and finally
       return lambda: decrease_hp(monster_a, 4)

 Then for the start of a round, first you ask each monster what action
 it is going to perform:

   for monster in room.monsters:
       effects.append(
           monster.act()
       )

 Then for the end of the round, call all the lambdas

   for effect in effects:
       effect()



Also, I second other people's suggestions that you almost never need
to be using __del__ nor weak references in Python, unless you are
writing a project that is specifically related to complex resource
allocation issues. In an rpg game like this, just store references to
the objects that you need (which you have to do anyway, to use them),
and forget about allocation issues.

Don't be afraid to post follow-up questions, (or even to mail me off
list.) I make hobbyist OpenGL games in Python myself, and although I'm
no expert, I'd love to chat more about this for our mutual benefit.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: OO and game design questions

2010-10-20 Thread dex
On Oct 20, 12:25 pm, Jonathan Hartley tart...@tartley.com wrote:
 On Oct 18, 8:28 am, dex josipmisko...@gmail.com wrote:





  I'm building a turn based RPG game as a hobby. The design is becoming
  increasingly complicated and confusing, and I think I may have
  tendency to over-engineer simple things. Can anybody please check my
  problems-solutions and point me to more elegant solution?

  Every item/character/room is a separate object. Items/characters need
  to have references to room they are in, and room needs to have a list
  of references to items/characters that are contained within. I decided
  to use weak references. That way I can destroy object by deleting it,
  I don't have to destroy all references as well. In each object's
  __init__() that object is added to game_object list, and in each
  __del__() they are removed from game_object list. This mechanism keeps
  them safe from garbage collector. How pythonic is this design?

  In turn-based games, the order of action execution in battle can give
  unfair advantage to players. For example, if player's arm is crippled
  before his action is executed, he would do less damage. To offset
  this, I first execute all players' actions and calculate effects in
  first pass, then apply the effects in second pass. The effect can be
  health decrease by 15HP, item pick-up, 30p experience gain, etc. This
  means the player deals the same amount of damage no matter what
  happens to him in that turn. The difficult part is keeping track of
  various effects. I had to make separate class for various types of
  effects (ChangeAttributeEffect, GetItemEffect, LooseItemEffect). Each
  class stores weak reference to target object and has apply() method
  that applies the effect to object. I'm not satisfied with this as it's
  limiting, error-prone and uses metaprogramming. Is there a design
  pattern that would remember changes to an object, and apply them
  later?

  Sorry for the wall of text.

 One common way to store delayed actions is as a lambda (an anonymous
 function.) A lambda defines a new function:

 , and you can call this function later. The created function has no
 name, (but you can assign it to a variable to give it a name if you
 like) and can be called later:

 So in the game, you could have a collection 'effects', each one will
 be a lambda:

   effects = []

 At the start of the round, as each entity makes its moves, they add
 lambdas to this collection.

   effects.append(
       lambda: decrease_hp(monster_a, 4)
   )
   effects.append(
       lambda: lose_item(monster_a, item_b)
   )

 Instead of appending it directly like this, I imagine the lambdas
 could be returned by the monster's 'act' or 'update' method:

   class Monster():
     def act(self):
       # blah and finally
       return lambda: decrease_hp(monster_a, 4)

 Then for the start of a round, first you ask each monster what action
 it is going to perform:

   for monster in room.monsters:
       effects.append(
           monster.act()
       )

 Then for the end of the round, call all the lambdas

   for effect in effects:
       effect()

Mr. Roy Smith already proposed using closures. I already did a similar
thing in my code, but instead of decrease_hp() I have AttributeEffect
class which is able to modify any attribute (in old RPGs some monsters
could drain your intelligence, in my game laser gun hit will decrease
HP as well as armor integrity). The first version looks like this
(missing few checks):

class AttributeEffect(object):
'''Effect changes object's attribute by delta'''
def __init__(self, obj, attrib, delta):
self.obj = obj   # reference to object the effect
applies to
self.attrib = attrib # name of attribute that effect
applies to
self.delta = delta   # change of value for
object.attribute
def apply(self):
value = getattr(self.obj, self.attrib) # todo: try, except
value += self.delta
setattr(self.obj(), self.attrib, value)

Yesterday I learned that Python 3.0 introduces nonlocal keyword which
would simplify defining effect functions and passing them along. Nice
improvement.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: OO and game design questions

2010-10-19 Thread dex
 I'm not sure if it's a good idea to let an item disappear from your
 inventory by a weak reference disappearing.  It seems a little shaky
 to not know where your objects are being referenced, but that's yout
 decision.

OK, imagine a MUD, where players can dig out new rooms. Room A has a
door that holds reference to newly created room B. By using a door,
player is transported to room B. At later time someone destroys room
B.

Using strong references, I have to remove room B from list of rooms,
and also remove door to room B, as it holds reference to room B. To do
that, I have to keep list of doors that lead to room B.

Using weak references, I don't have to worry about removing all doors
to room B. They all now have a dead reference, which better models
actual situation. If part of mine collapses, or if a module on space
station is destroyed, the passage to that location does not magically
vanish - it's just obstructed.

Can you please tell me if there's something wrong with my reasoning?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: OO and game design questions

2010-10-19 Thread Dave Angel

 On 2:59 PM, dex wrote:

I'm not sure if it's a good idea to let an item disappear from your
inventory by a weak reference disappearing.  It seems a little shaky
to not know where your objects are being referenced, but that's yout
decision.

OK, imagine a MUD, where players can dig out new rooms. Room A has a
door that holds reference to newly created room B. By using a door,
player is transported to room B. At later time someone destroys room
B.

Using strong references, I have to remove room B from list of rooms,
and also remove door to room B, as it holds reference to room B. To do
that, I have to keep list of doors that lead to room B.

Using weak references, I don't have to worry about removing all doors
to room B. They all now have a dead reference, which better models
actual situation. If part of mine collapses, or if a module on space
station is destroyed, the passage to that location does not magically
vanish - it's just obstructed.

Can you please tell me if there's something wrong with my reasoning?

Simply replace room B with a destroyed room object.  That can be quite 
small, and you only need one, regardless of how many rooms are thus 
eliminated.


DaveA
--
http://mail.python.org/mailman/listinfo/python-list


Re: OO and game design questions

2010-10-19 Thread Roy Smith
dex josipmisko...@gmail.com wrote:

 I'm building a turn based RPG game as a hobby. The design is becoming
 increasingly complicated and confusing

Such is often the case in real life code :-)

 In turn-based games, the order of action execution in battle can give
 unfair advantage to players. [...] Is there a design
 pattern that would remember changes to an object, and apply them
 later?

This sounds like a database transaction.  Perhaps what you want is for 
each object to include a delayedActions list.  Each time something 
happens to an object, you push a closure onto the list.  At the end of 
the turn, you run

for obj in global_object_list:
   obj.apply_delayed_actions()

 Sorry for the wall of text.

No problem.  The newsgroup ducks, swivels around on its Content-Type 
header, hides behind an NNTP outcropping on the server, and just barely 
avoids being hit by the oncoming wall.  You roll 2d10 and make your 
saving throw against Magical Text Wall, preventing any residual effects 
of the attack.  Whew, that was close!

In another article, Dave Angel suggested:

 Simply replace room B with a destroyed room object.  That can be quite 
 small, and you only need one, regardless of how many rooms are thus 
 eliminated.

I worked with an OODB system which did exactly this.  Each object class 
had a Class::Deleted singleton.  Whenever an object was deleted, 
references to it were replaced by references to the Deleted object.  For 
the most part, this worked, but resulted in a 4-byte memory leak for 
each reference (there was still a C++ pointer to Class::Deleted).

This memory leak was a known problem, but deemed to be small enough that 
we could live with it.  In the particular application domain we were 
working in, object deletions were rare.  I don't know if that's the case 
in your MUD.  I would assume that the physical structure of the world 
(rooms, corridors, doors) for the most part get created and rarely 
deleted, but that may not be true of other objects in the game?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: OO and game design questions

2010-10-19 Thread Ian Kelly
On Tue, Oct 19, 2010 at 5:37 AM, Dave Angel da...@ieee.org wrote:

  On 2:59 PM, dex wrote:

 Using strong references, I have to remove room B from list of rooms,
 and also remove door to room B, as it holds reference to room B. To do
 that, I have to keep list of doors that lead to room B.

 Using weak references, I don't have to worry about removing all doors
 to room B. They all now have a dead reference, which better models
 actual situation. If part of mine collapses, or if a module on space
 station is destroyed, the passage to that location does not magically
 vanish - it's just obstructed.

 Can you please tell me if there's something wrong with my reasoning?

  Simply replace room B with a destroyed room object.  That can be quite
 small, and you only need one, regardless of how many rooms are thus
 eliminated.


How does this avoid the problem of having to keep a list of doors that lead
to room B?  You can't just replace one object with another.  You would have
to replace every reference to B with a reference to the new object.  This is
no simpler than deleting the references or replacing them with None.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: OO and game design questions

2010-10-19 Thread Carl Banks
On Oct 19, 1:19 am, dex josipmisko...@gmail.com wrote:
  I'm not sure if it's a good idea to let an item disappear from your
  inventory by a weak reference disappearing.  It seems a little shaky
  to not know where your objects are being referenced, but that's yout
  decision.

 OK, imagine a MUD, where players can dig out new rooms. Room A has a
 door that holds reference to newly created room B. By using a door,
 player is transported to room B. At later time someone destroys room
 B.

 Using strong references, I have to remove room B from list of rooms,
 and also remove door to room B, as it holds reference to room B. To do
 that, I have to keep list of doors that lead to room B.

 Using weak references, I don't have to worry about removing all doors
 to room B. They all now have a dead reference, which better models
 actual situation. If part of mine collapses, or if a module on space
 station is destroyed, the passage to that location does not magically
 vanish - it's just obstructed.

 Can you please tell me if there's something wrong with my reasoning?

Well, you're talking about particulars here whereas I am speaking in
general.  If something is questionable or even bad in general it
doesn't mean there are no particular cases for it.

Generally speaking: in a game there's presumably some conservation of
objects.  If you drop an item, does it disappear, or does it become an
object of the room?  Weak referencing won't help you in the latter
case because you have to take care of references at both ends anyway.
That's what I mean by shaky: it lets you forget about half of the
transaction, which might not be the best thing.  YMMV


Carl Banks
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: OO and game design questions

2010-10-19 Thread Terry Reedy

On 10/19/2010 1:46 PM, Ian Kelly wrote:

On Tue, Oct 19, 2010 at 5:37 AM, Dave Angel da...@ieee.org
mailto:da...@ieee.org wrote:

  On 2:59 PM, dex wrote:

Using strong references, I have to remove room B from list of rooms,
and also remove door to room B, as it holds reference to room B.
To do
that, I have to keep list of doors that lead to room B.

Using weak references, I don't have to worry about removing all
doors
to room B. They all now have a dead reference, which better models
actual situation. If part of mine collapses, or if a module on space
station is destroyed, the passage to that location does not
magically
vanish - it's just obstructed.

Can you please tell me if there's something wrong with my reasoning?

Simply replace room B with a destroyed room object.  That can be
quite small, and you only need one, regardless of how many rooms are
thus eliminated.


How does this avoid the problem of having to keep a list of doors that
lead to room B?  You can't just replace one object with another.  You
would have to replace every reference to B with a reference to the new
object.  This is no simpler than deleting the references or replacing
them with None.


One should rather *change* (not replace) the room into a 'destroyed 
room' or 'collapsed passage' or whatever, that cannot be entered. The 
keeps the room around but allows it to be repaired, rebuilt, cleared, or 
whatever.


--
Terry Jan Reedy

--
http://mail.python.org/mailman/listinfo/python-list


Re: OO and game design questions

2010-10-19 Thread Dave Angel

 On 2:59 PM, Terry Reedy wrote:

On 10/19/2010 1:46 PM, Ian Kelly wrote:

On Tue, Oct 19, 2010 at 5:37 AM, Dave Angel da...@ieee.org
mailto:da...@ieee.org wrote:
snip



Simply replace room B with a destroyed room object.  That can be
quite small, and you only need one, regardless of how many rooms are
thus eliminated.


How does this avoid the problem of having to keep a list of doors that
lead to room B?  You can't just replace one object with another.  You
would have to replace every reference to B with a reference to the new
object.  This is no simpler than deleting the references or replacing
them with None.


One should rather *change* (not replace) the room into a 'destroyed 
room' or 'collapsed passage' or whatever, that cannot be entered. The 
keeps the room around but allows it to be repaired, rebuilt, cleared, 
or whatever.


Thanks, that is what I was trying to say.  In the same sense that 
emptying a list makes it quite small, if it's a general purpose object, 
you just want to remove all the attributes.


DaveA

--
http://mail.python.org/mailman/listinfo/python-list


Re: OO and game design questions

2010-10-19 Thread Martin Gregorie
On Tue, 19 Oct 2010 19:49:20 -0400, Dave Angel wrote:

 Thanks, that is what I was trying to say.  In the same sense that
 emptying a list makes it quite small, if it's a general purpose object,
 you just want to remove all the attributes.

I think a 'place' (to generalise it) is quite a small object in any case. 
All it needs to contain is a few lists:
- a list of exits, which in some implementations might be simply
  references to other places, but might usefully be objects with
  two sides, each having an appearance and a link to the place 
  where that side appears.
- a list of fixed objects which only serve to describe the place.
- a list of mobile objects that actors can pick up and move
- a list of actors who happen to be there.

plus a describePlace() method and add(), remove() and getItem() methods 
for each list. It may be possible to use a single list for all types of 
object, in which case the object itself would be very small indeed.


-- 
martin@   | Martin Gregorie
gregorie. | Essex, UK
org   |
-- 
http://mail.python.org/mailman/listinfo/python-list


OO and game design questions

2010-10-18 Thread dex
I'm building a turn based RPG game as a hobby. The design is becoming
increasingly complicated and confusing, and I think I may have
tendency to over-engineer simple things. Can anybody please check my
problems-solutions and point me to more elegant solution?

Every item/character/room is a separate object. Items/characters need
to have references to room they are in, and room needs to have a list
of references to items/characters that are contained within. I decided
to use weak references. That way I can destroy object by deleting it,
I don't have to destroy all references as well. In each object's
__init__() that object is added to game_object list, and in each
__del__() they are removed from game_object list. This mechanism keeps
them safe from garbage collector. How pythonic is this design?

In turn-based games, the order of action execution in battle can give
unfair advantage to players. For example, if player's arm is crippled
before his action is executed, he would do less damage. To offset
this, I first execute all players' actions and calculate effects in
first pass, then apply the effects in second pass. The effect can be
health decrease by 15HP, item pick-up, 30p experience gain, etc. This
means the player deals the same amount of damage no matter what
happens to him in that turn. The difficult part is keeping track of
various effects. I had to make separate class for various types of
effects (ChangeAttributeEffect, GetItemEffect, LooseItemEffect). Each
class stores weak reference to target object and has apply() method
that applies the effect to object. I'm not satisfied with this as it's
limiting, error-prone and uses metaprogramming. Is there a design
pattern that would remember changes to an object, and apply them
later?

Sorry for the wall of text.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: OO and game design questions

2010-10-18 Thread Carl Banks
On Oct 18, 12:28 am, dex josipmisko...@gmail.com wrote:
 Every item/character/room is a separate object. Items/characters need
 to have references to room they are in, and room needs to have a list
 of references to items/characters that are contained within. I decided
 to use weak references. That way I can destroy object by deleting it,
 I don't have to destroy all references as well.

You're aware Python can collect reference cycles, correct?  You don't
have to delete references; Python will get them eventually.  If you
feel you're overengineering things perhaps getting rid of weak
references would be a substantial simplification.

 In each object's
 __init__() that object is added to game_object list, and in each
 __del__() they are removed from game_object list. This mechanism keeps
 them safe from garbage collector. How pythonic is this design?

I would say overriding __del__ is not particularly Pythonic at all.

Using __del__ has some undesirable side-effects (like potential for
memory leaks), and is unreliable (there are different reasons it might
not be called at all).  I recommend that only experts deeply familiar
with these issues override it, and then only for objects whose sole
purpose is to own a resource.  It's tricky to get right.

Instead, I'd recommend managing the lifetime of all objects (creating
and destroying) through game_object methods.  To create an object,
don't call its constructor, call obj =
game_object.create(object_type,args) and game_object.destroy(obj).
(If you really want to be strict about it, you can override __init__
to raise an exception (thus disabling the normal way to create an
object), and create the objects in you create method by calling the
class's __new__ method directly.)

More generally, Python's dynamicism makes it hard for the language to
manage resources other than RAM automatically; this is something we
give up to get dynamicism's benefits.  Therefore, the Pythonic
approach is to manage resources with constructs like with and
try...finally, although sometimes that's not possible so you have to
just release the resource by hand.  In your case, it'd be hard to
manage the resource, i.e., an entry in youg game_object list, with
try...finally because presumably the object lives for an indefinite
abount of time.


One thing I do in my games--you may or may not find this helpful--is
to distinguish between lightweight and heavyweight objects.
Lightweight objects do not need any sort of finalization and I use
them whenever possible.  Heavyweight objects not only need to be
finalized but it must be explicit.  I have a base class for
heavyweights (written in C) that checks if the finalization occurred
as a debugging aid, but it can't clean up automatically for various
reasons.


 In turn-based games, the order of action execution in battle can give
 unfair advantage to players. For example, if player's arm is crippled
 before his action is executed, he would do less damage. To offset
 this, I first execute all players' actions and calculate effects in
 first pass, then apply the effects in second pass. The effect can be
 health decrease by 15HP, item pick-up, 30p experience gain, etc. This
 means the player deals the same amount of damage no matter what
 happens to him in that turn. The difficult part is keeping track of
 various effects. I had to make separate class for various types of
 effects (ChangeAttributeEffect, GetItemEffect, LooseItemEffect). Each
 class stores weak reference to target object and has apply() method
 that applies the effect to object. I'm not satisfied with this as it's
 limiting, error-prone and uses metaprogramming. Is there a design
 pattern that would remember changes to an object, and apply them
 later?

Your objects should have two sets of attributes (beginning of round,
end of round) and a method to copy the end-of-round attributes to the
beginning-of-round area at the end of the round.


Carl Banks
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: OO and game design questions

2010-10-18 Thread Jean-Michel Pichavant

dex wrote:

 In each object's
__init__() that object is added to game_object list, and in each
__del__() they are removed from game_object list. This mechanism keeps
them safe from garbage collector. How pythonic is this design?
  
You don't have to manage memory with python, I don't know if you wrote 
C++ in the past (looks like) but consider that python is taking care of 
everything and you'll be fine.


So do not override __del__ (anyway it is not called as you may expect it).


Keep a game_object list only if you need the game to know wich objects 
are in the game, not to keep references.


JM
--
http://mail.python.org/mailman/listinfo/python-list


Re: OO and game design questions

2010-10-18 Thread dex
 You're aware Python can collect reference cycles, correct?  You don't
 have to delete references; Python will get them eventually.  

I'm not sure I understand this part? If I don't delete all strong
references, the object will not be deleted.
It will persist and occupy memory as long as there's at least one
reference to it (it could be part of inventory, or target of some
action).


 Instead, I'd recommend managing the lifetime of all objects (creating
 and destroying) through game_object methods.  To create an object,
 don't call its constructor, call obj =
 game_object.create(object_type,args) and game_object.destroy(obj).
 (If you really want to be strict about it, you can override __init__
 to raise an exception (thus disabling the normal way to create an
 object), and create the objects in you create method by calling the
 class's __new__ method directly.)

This makes sense, I will make these modifications.

 Your objects should have two sets of attributes (beginning of round,
 end of round) and a method to copy the end-of-round attributes to the
 beginning-of-round area at the end of the round.

Perhaps I could utilize properties. Make getters return start-of-round
attributes
and setters set end-of-round attributes. Things would get a bit messy
if two or more players modify the same attribute or chest content.
I need to think about this some more.

Thanks for your thoughts.


-- 
http://mail.python.org/mailman/listinfo/python-list


Re: OO and game design questions

2010-10-18 Thread Benjamin Kaplan
On Mon, Oct 18, 2010 at 9:50 AM, dex josipmisko...@gmail.com wrote:
 You're aware Python can collect reference cycles, correct?  You don't
 have to delete references; Python will get them eventually.

 I'm not sure I understand this part? If I don't delete all strong
 references, the object will not be deleted.
 It will persist and occupy memory as long as there's at least one
 reference to it (it could be part of inventory, or target of some
 action).


No it won't. Python has a garbage collector. The object will persist
as long as it is reachable through code. If it becomes unreachable,
the garbage collector will delete it even if there is a reference
cycle.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: OO and game design questions

2010-10-18 Thread Carl Banks
On Oct 18, 6:50 am, dex josipmisko...@gmail.com wrote:
  You're aware Python can collect reference cycles, correct?  You don't
  have to delete references; Python will get them eventually.  

 I'm not sure I understand this part? If I don't delete all strong
 references, the object will not be deleted.
 It will persist and occupy memory as long as there's at least one
 reference to it (it could be part of inventory, or target of some
 action).

I was assuming the weak referencing was used to avoid reference
cycling.

I'm not sure if it's a good idea to let an item disappear from your
inventory by a weak reference disappearing.  It seems a little shaky
to not know where your objects are being referenced, but that's yout
decision.


Carl Banks
-- 
http://mail.python.org/mailman/listinfo/python-list