OO and game design questions

D

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.
 
D

Dennis Lee Bieber

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

Why would items (or even characters) need to have references to the
room... When is an item going to ask "where am I?"... Okay -- if
characters (assuming multiplayer) can be split across rooms, they'd need
to know which room they are in -- otherwise the game just needs to
maintain a single "current room"... But the items in that room would
only be known by "looking" at the room -- Same way you'd find out what
items are in a character inventory (their inventory is just another
container for objects).

Or, looking at it from another point... A boobie trap is not going
to scan a room to see when someone enters it. Rather, the room itself
will invoke some update action on all objects in the room when a
character enters, and that action would be what triggers the boobie
trap... Or the trap triggers when some character performs some action
with the object: self.take(room.inventory.item) invokes, say, an
item.taken(self) operation (which triggers any special behavior for
traps, or adds the item to the character inventory) and also a
room.inventory.remove(item) operation.

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

In a true "turn-based" game, to me at least, the CURRENT player's
turn should complete /everything/ before another player's action is even
considered... That /is/ what "turns" mean -- "it's my turn, so stand
there and take whatever I do..."

OTOH, a game using "rounds" tends to use player (and adversary)
characteristics (initiative, dexterity, speed) to order the action time
within the round... all characters commit to an action at the start [to
be more realistic, the slower acting characters should commit first,
allowing the faster reacting ones to "read" the planned action and set
their action in response]. Then the actions take place in order of
fastest reacting to slowest -- if a fast character manages to abort a
slower characters action, so be it [I'm guessing there is still some
randomized success/fail criteria so it is not assured that a fast
character can abort a slower opponent every time].
effects (ChangeAttributeEffect, GetItemEffect, LooseItemEffect). Each

BTW: I suspect you mean LoseItemEffect (or, in a closer counter to
the "GetItemEffect -- DropItemEffect)... And not "Loose" as in "the
chickens are running loose in yard"

I also get the impression this will be another game with a heavy D&D
bias -- wherein practically anything desirable has some magical
enhancement... (I much preferred the realism of RuneQuest -- no magic
weapons, no magic armor, and no artificial "levels"... I mean, what
realism is there in a game system when one uses a greatsword in all
fights, gains enough experience with that sword to go up a few levels,
and due to the level system now has improved ability with never used
rapier and main gauche... Not to mention that putting on heavy armor
makes one /harder to hit/, but did nothing for damage if one is hit? RQ
had no levels; experience with a weapon allowed a chance afterwards to
increase one's skill with just that class of weapon... You could be 80%
with that greatsword, but the first time you pick up the rapier/main
gauche you start back at 5%... And heavy armor actual caused a reduction
in one's reaction speed but absorbs damage from a hit [and RQ was
precise enough that one could have different armor on each arm, leg,
chest, abdomen, and head])
 
C

Carl Banks

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
 
J

Jean-Michel Pichavant

dex said:
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
 
D

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.
 
B

Benjamin Kaplan

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.
 
C

Carl Banks

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
 
D

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?
 
D

Dave Angel

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
 
R

Roy Smith

dex said:
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?
 
C

Carl Banks

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
 
T

Terry Reedy

On Tue, Oct 19, 2010 at 5:37 AM, Dave Angel <[email protected]

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.
 
D

Dave Angel

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
 
M

Martin Gregorie

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.
 
D

dex

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.
 
D

dex

        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)

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.
 
J

Jonathan Hartley

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()
 
J

Jonathan Hartley

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.
 
D

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.

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,045
Latest member
DRCM

Latest Threads

Top