Script parent questions

21 views
Skip to first unread message

Starkiel

unread,
Apr 24, 2009, 7:50:50 PM4/24/09
to Evennia
Hi,

I was putting together some more elaborate example scripts for using
the pluggable command system (including the auto-help system) and the
script parent system, using the new at_player_creation/destruction etc
functions. Doing this I came across some weird behaviour in the script
parent system. I think I've fixed most of them, but I thought I should
ask to make sure I'm really doing this right before submitting, the
script-parent system is a bit tricky conceptually to me.

- Except for @parent, it doesn't seem to be a way to *create* an
object of a particular type (i.e. as a child of a particular script
parent). The @parent command is no good, it kicks in after an object
is already created and thus it does not call at_object_creation()
which is the main function for customizing object parents I reckon. I
have an implementation here which adds this ability to the @create
command; the syntax is @create object=parentpath.

- There was no error checking at all for setting the script parent
using set_script_parent(). Setting this with a non-valid script path
causes *havoc* -- you cannot do anything with the object. You can't
even destroy it since it throws an exception trying to call
obj.scriptlink.at_object_destruction(); Database reboot seems the only
way to get rid of such messed up items. So to prevent the system to
add a nonsense script path to the object, I added a direct error check
in set_script_parent(). The check (using the relevant scripthandler
method to see if the module is loadable) causes the script to be
cached immediately upon addition. I think that's a reasonable price to
pay.

- A less severe, but annoying thing is also the confusion in
nomenclature. why is it called "script parent" in some places, whereas
it's called "script link" in others? Should not either of
set_script_parent() and get_script_link() really be renamed to match,
for example?


Two final things I wonder about are related to the parented objects
themselves and the so-called event system. I thought I understood how
this worked, but creating an extension of example/red_button.py to
make the button flash regularly met with no success. I supply my code
below.

Same goes with having "local commands" on an object, is the object's
command_table variable really executed somewhere? At any rate,
commands defined in the ways I tried didn't do anything (I assume just
writing 'press' or maybe 'press button' should work if the button is
in the same room?)


Here is my version of the parent script file parents/examples/
ref_button.py, note that I wrote the comments to work as an example
text; but they are currently only written with how I understood it to
work -- and clearly it doesn't, so don't trust the comments,
folks! :-)

http://pastebin.com/f3bd35922

.
Starkiel

Greg Taylor

unread,
Apr 25, 2009, 12:54:05 AM4/25/09
to eve...@googlegroups.com
Hello, replies are inline below.

> - Except for @parent, it doesn't seem to be a way to *create* an
> object of a particular type (i.e. as a child of a particular script
> parent). The @parent command is no good, it kicks in after an object
> is already created and thus it does not call at_object_creation()
> which is the main function for customizing object parents I reckon. I
> have an implementation here which adds this ability to the @create
> command; the syntax is @create object=parentpath.

This is definitely needed. Feel free to commit your implementation and
we'll poke at it. To be honest, I'm not sure what will happen when you
add the event as you have. I'm thinking we may see some issues, but
it's worth a shot. To get the affect you're looking for, the current
way to do it would be to have your events in a separate module that
searches for the relevant objects and runs stuff through their script
parent. Coming from a MUX/MUSH background, I grew into the habit of
trying to keep to the looping interval events to an absolute minimum,
so I hadn't spent much time trying to figure out how to make such
things easier.

>
> - There was no error checking at all for setting the script parent
> using set_script_parent(). Setting this with a non-valid script path
> causes *havoc* -- you cannot do anything with the object. You can't
> even destroy it since it throws an exception trying to call
> obj.scriptlink.at_object_destruction(); Database reboot seems the only
> way to get rid of such messed up items. So to prevent the system to
> add a nonsense script path to the object, I added a direct error check
> in set_script_parent(). The check (using the relevant scripthandler
> method to see if the module is loadable) causes the script to be
> cached immediately upon addition. I think that's a reasonable price to
> pay.

Yeah, @parent is still extremely rough around the edges. I don't see
any problem with loading on demand. As you mentioned, after the first
cache, you're good to go.

>
> - A less severe, but annoying thing is also the confusion in
> nomenclature. why is it called "script parent" in some places, whereas
> it's called "script link" in others? Should not either of
> set_script_parent() and get_script_link() really be renamed to match,
> for example?

The idea is that the script link is what you use to get to an Object's
script parent. The link handles all of the transparent caching or
returning the default script parent if none is specified. The actual
script parent is the Python module that determines the object's
behavior. I probably have interchanged the two terms a few times where
I shouldn't be. Feel free to point out or fix these crosses.

> Two final things I wonder about are related to the parented objects
> themselves and the so-called event system. I thought I understood how
> this worked, but creating an extension of example/red_button.py to
> make the button flash regularly met with no success. I supply my code
> below.

I'm not too sure it'll work as you've got it outlined. You will
probably need to break the IntervalEvent and the add_event() call out
into another module. To test this theory, create a bogus module that
searches for anything with the script parent you're wanting to beep or
blink, and have it do its stuff with those objects rather than putting
the event code in the script parent. Import it from either your script
parent (which means the event will be added once you interact with a
button), or toss it in another arbitrary module for the sake of
testing. See src/imc2/events.py for a relatively simple example. Once
that module gets imported, it inserts that event.

> Same goes with having "local commands" on an object, is the object's
> command_table variable  really executed somewhere? At any rate,
> commands defined in the ways I tried didn't do anything (I assume just
> writing 'press' or maybe 'press button' should work if the button is
> in the same room?)

The local command table stuff is pretty high priority, I've just been
putting it off (which is bad). This is theoretically 95% ready to go,
it just needs to start looking stuff up. I'll get this handled very
soon and this portion of things will be ready to rock.

If you'd like, commit your @create and @parent changes and we'll test
and adapt from there. I'll kick myself into getting local command
table searching ready to go very soon.

Greg

Starkiel

unread,
Apr 25, 2009, 5:52:22 PM4/25/09
to Evennia
Thanks for the reply!

I committed changes to @parent and @create as well as a few other
things.

After some more experimentation it turns out that my initial way of
writing the event handler works just fine -- problem is that the
moment you restart your server all events are forgotten since they
were only loaded upon object creation.
So I tried as you suggested, splitting the event class into a separate
file. In principle one need not have it separate, it loads fine just
doing the add_event() in the parent file (now that you added the
functionality to reload script parents to @reload - nice!). But if one
use the event stricty without any game logics, you only need a few
events -- they are only separated by how often they are called. Each
event calls the objects with the wanted script parents, using any
custom method they define. I made an example of this in a new folder /
gamesrc/events/example.py.

There is something weird in the event handler which I came across.
Basically, if the function it calls fails with a traceback, the
counter continues past into negative values. I've not been able to
track that one down, but it's not good that the event queue (which can
service many different objects) can be messed up like that because of
one single buggy parent object.

The object-command table works now, thanks for the update, that was
quickly done. :) It's a bit inconcistent that one must use the
__init__ function for initializing it though, considering
at_object_creation() was recommended for everything else; for
cleanliness of expansion if nothing else, it would be nice if one
either went with one or the other for setting up a script parent.

Overall the lazy script loading causes all sorts of unexpected
behaviour. I eventually had the @parent obj=newparent functionality
call at_object_creation() since it makes sense that changing the
parent should give an object access to all the initialized attributes
the parent might have (I guess in practice, this is a sort of fake way
to create a multiple inheritance, actually). Thing is that no
attributes are actually added to the object -- unless you call the
function twice ... ^_^;


I minor thing; would it be viable to implement multi-word command
names? "press button" would be a much nicer and intuitive command than
pressbutton, for example (I tried both, but only the second works)?
Once could of course call the command "push" and do a check in the
function body that "button" was given as an argument, but it's an
extra layer of complexity it would be nice to avoid.

.
Starkiel

Griatch

unread,
Apr 30, 2009, 12:17:04 PM4/30/09
to Evennia
The event system is really delicate when it comes to tracebacks. I
added some more exception handling to the example as well as wrote
some more about it in the wiki.

Oh, and this is my main account, I will try to use it from now on.
.
Griatch / Starkiel
Reply all
Reply to author
Forward
0 new messages