|Wall hit with evennia scripts.||Geoff||1/11/12 2:15 PM|
Ok, so in a nutshell I have sentinel scripts that sit on my mobs which
do a couple things but mainly act as a gateway for my spell effects
manager to check itself and increment timer variables etc. As you can
imagine, I need these scripts to run every second. So, one script per
mob running every second...you can see where I am going.
Long story short, when I build a very small zone with only about 6-12
mobs (therefore 6-12 scripts), the processor usage for the twistd
process just skyrockets to 30-40% consumption. These scripts aren't
doing much but checking some variables and maybe massaging some data
if a threshold is met. however, 90% of the time they run, check,
return. After effing around with certain aspects of the script, i
decided to turn the interval up to 30 seconds, just to see if it was
part of the problem. Once I did this, cpu consumption returned to a
normal < 10%.
Is there anything I can dig into on the server side for possible
optimization? Am I crazy for even setting a system up like this?
(this is my first game development attempt, and my first time using
python in such a large scale.).
Worse comes to worse I can always use some math trickery/function
callback to check my spell effects thereby eliminating this need, but
this way would be a whole lot easier.
|Re: Wall hit with evennia scripts.||Griatch Art||1/28/12 11:58 AM|
Scripts are pretty optimized while it's running already as it is (they are primarily twisted LoopingCall's that knows database access), but it's definitely worth looking into further.
Running a separate script once per second on every mob in you entire game is probably always going to be expensive however. There is an alternative design you might want to test - and that is to use a single script instead of one per mob. The script holds a list with references to "subscribing objects", and when it fires, it goes through this list, calling a given update function on each object in the list. So when you create a mob that requires monitoring, you let this mob assign itself to the central "mob runner" script.
The script could then be optimized to work something like this (haven't tested it, but the principle does work, I have used this for weather systems):
from src.utils import search
self.ndb.mobs = [search.search_objects(dbref) for dbref in self.db.mobs]
[mob.update() for mob in self.ndb.mobs if mob.should_update]
I.e. when the script starts, it takes it database-stored dbrefs (db.mobs) and does a db search so as to produce references to the Typeclassed objects (search.search_objects always returns a typeclassed object). These are stored in memory (self.ndb.mobs).
Next, when at_repeat() fires, the script runs a a quick loop through all stored mobs on the script, calling their update() method. But first it checks if the boolean should_update is True. This might be useful if the mob only acts in certain situations and external factors control this - if there is no PC nearby, maybe the mob doesn't need to update at all, for example. Or maybe the mob only needs this fast counter if it is attacked. And so on.
This method is commonly known as a "global tick", but you can of course have many different tickers running at the same time handling different things. Scripts are otherwise designed to double as passive state-machines - that is, reacting to external stimuli rather than having to actively look for that stimuli over and over again. Some effects might perhaps be possible to handle that way instead.
Just to avoid silly mistakes (not having seen your code), when you e.g. have a spell effect that will last for 30 seconds, the way to monitor this is NOT to have a one-second timed script tick 30 times, repeatedly checking if it is done or not - this is VERY expensive. No, what you do is set a one-time-use script with a interval of 30 seconds and start_delay=True. Such a script takes very few resources until it fires 30 seconds later.
Hope that helps!
|Re: [Evennia] Re: Wall hit with evennia scripts.||Geoff||1/28/12 3:35 PM|
Yes very helpful indeed and I do appreciate the response. After doing some tweaking I think I figured out what needs to be done. A lot of it was rookie mistakes/bad code engineering choices by me. The script handler works awesome when you do not abuse it as I have been doing :)
I hope to have a playable alpha up sometime in the near future for my game. Thanks again for the in depth response. I think the global tick is what I really need to move towards.
|Re: [Evennia] Re: Wall hit with evennia scripts.||Griatch Art||1/29/12 2:11 AM|
Glad it was helpful. :) Your comment makes me think though - clearly something in the script design set you off on a path that was less than optimal. It's great that you took the time to ask and not give up, but others might just decide the script system sucks and drop Evennia entirely.
Clearly we (that is, I) need to write some sort of help/tutorial on how to do this, so people don't loose time with a sub-optimal design when first trying this out. Do you have any suggestions as to what routes you went down and could go into a script tutorial as things "not to do?" What confused you, what needs more explanation or clearer code?
Any help with this would be great - since I coded this thing it's sometimes a bit hard for me to determine what is difficult to get one's head around as a newcomer to the code. :) This is true for all the documentation of course.
Also, excellent to hear you have an alpha on the way, will be looking forward to seeing it!
|Re: [Evennia] Re: Wall hit with evennia scripts.||Geoff||1/30/12 6:22 AM|
I think a lot of this was just due to me never having coded anything on this scale/never coded a large game. I am largely a systems guy, so small scripts here and there, mostly likely horribly coded just to get the job done. So all of this is just a huge learning experience. I dont think anything particularly forced me down the path I chose other than myself, i mean the more I think about it, the worse of an idea it seems so I most likely would have came to the conclusions you outlined above, eventually on my own. :D
|Re: Wall hit with evennia scripts.||Geoff||2/1/12 9:36 AM|
So I saw some chatter on the irc logs about this.
Basically, I had gone about designing my systems to constantly be
watching objects they were placed on just to do basic attribute checks
and the like (am I in combat? Was I in combat and my target ran away?
etc etc). So each mob had a sentinel script that ran every three
seconds, then a script to control its ai which fired every 5, and
finally a script to keep the mob aggressive or KOS to players in its
This is insane, i realize this now. I don't really want to get into
specifics just cause you can read through my code and pretty easily
figure it out, but you are all right when you said it was something I
was doing within my code, specifically my loops. I had some pretty
heavy loops going on in those scripts, as well as my zone manager
scripts that basically just beat the shit out of the cpu since it was
firing so often. Now that I have refactored most of that stuff out of
those object-individual scripts into global tickers, everything runs
Also, my code, in read only format can be found at my project page:
Don't judge too harshly, some of that code is bad :) This is a hobby
project and a lot of the time im just trying to test out different
ways of doing things etc before I settle on a final, definite system.
So some of the code isnt used anymore/is outdated. It is what it is.
Im having a ton of fun bringing the game world to life in general, so
thanks a ton for all your guy's hard work on this server. It is
amazingly awesome to use and interact with.
|Re: Wall hit with evennia scripts.||Griatch Art||2/2/12 9:01 AM|
Thanks for posting the link! Great to see an example of Evennia used "in the wild" so to speak.
Using it as a hobby project is perfect and just what we aim for. Thanks for elaborating more on what caused the slowdown, if you use heavy, blocking loops for every call it's understandably things slow down, it's a learning process, asynchronous work is not easy! :-)
I should probably make a little tutorial on best-practices of writing scripts etc, just to help avoid hitting mines like this, we'll see.
Looks like a fun game concept, I like the idea of players building their own structures! Will be looking forward to seeing how it goes. And of course if you need any help or think something in the docs is unclear, don't hesitate to say so. :)