[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[pygame] Live coding



Hi,

A while ago there were some blog posts made about using live coding
with PyGame which used the approach of continually reloading a
give module:

http://disruption.ca/archives/live-coding-games-in-python/
http://disruption.ca/archives/live-coding-continued/

Since a friend and I had written the base of a system to put code
changes into place, I thought I might polish it up, fix the bugs and
release it in case others might find it useful.

For instance, if you change the code in a class, when the file is
processed all existing instances of that class will have the code
updated transparently.  No need to use metaclasses.

You can find it here:
http://code.google.com/p/livecoding/

And would use it in the following manner:

 import livecoding
 cm = livecoding.CodeManager(detectChanges=True)
 cm.AddDirectory("c:\pygames\blah", "gamelib")

You might notice the AddDirectory call.  This is because in order
to be able to update the code for imported classes, this library needs
to have controlled its importing.  So what this call will do is add the
contents of the given directory in a hierarchical manner under the
'base' namespace.

So for instance, if you had these files with the given contents:

c:\pygames\blah\main.py
 GameEngine (class)
c:\pygames\blah\entity.py
 Entity (class)
c:\pygames\blah\entities\alien.py
 Alien (class, derived from Entity)
c:\pygames\blah\entities\player.py
 Player (class, derived from Entity)

Then the following importable namespace would be available:

 module: gamelib
 class: gamelib.GameEngine
 class: gamelib.entities.Alien
 class: gamelib.entities.Player

And you could of course do:

 from gamelib import GameEngine
 from gamelib.entities import *

So you might have a simple startup script (outside this blah
directory) which does the following:

 import livecoding
 cm = livecoding.CodeManager(detectChanges=True)
 cm.AddDirectory("c:\pygames\blah", "gamelib")

 import gamelib

 engine = gamelib.GameEngine()
 engine.Run()

And theoretically all your code should (within some undescribed
constraints) where it is defined in the custom imported scripts
in the 'blah' directory, be put into play almost as soon as it is
changed (by default set to a 1 second delay between checks).

Just to highlight the sort of change this library puts into place
transparently for the sake of completeness.

Let's say the Entity class had the following function:

 class Entity:
     ...
     def ApplyDamage(self, amount):
         self.hp -= amount
     ...

And your game was running, but you wanted it to continue to
run, but no damage to be applied to anything, so you might
edit c:\pygames\blah\entity.py to work the following way:

 class Entity:
     ...
     def ApplyDamage(self, amount):
         pass # self.hp -= amount
     ...

And at most a second later, all entities in the game would
stop taking damage.

Of course this is a very simplistic example, ideally you would
be able to develop the game to an extent just by building it up
with the changes being added as you make them.  Although
as mentioned above there are some undescribed
constraints.

Anyway, hope this is of use to someone,
Richard.