RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

Xmlspawner2 v2.22

Status
Not open for further replies.

Quantos

Lord
XxSP1DERxX said:
With these new XMLSpawners? I have 2,242 or so.

I just double checked and I don't have a single spawner that spawns fewer than 15 mobiles. The average is 36 mobiles.
 

ArteGordon

Wanderer
its quite possible. I am running some longer term tests with a larger spawn count to make steady-state comparisons. The numbers I gave earlier were for initial resource use.
 

ArteGordon

Wanderer
ok, ran a few more tests.
Started with a fresh server restart on an empty shard, created 1000 spawners each making 10 orcs at a rate of 1 per minute. Load is internally reported memory usage.

After 13 minutes, there were 10K mobs, 46K items

Using distro spawners the load was 67.2M
With xmlspawners it was 65.4M

after 30 mins

distro spawners 66.5M
xmlspawners 66.1M

so you can see that there is essentially no difference.

I know it seems like the spawners have a lot of features that dont get used all the time, and that something must be suffering for it, but the actual cost is minor if any, so I wouldnt worry about it.
 

DeepFreez

Wanderer
On the issue of resource usage, I am not too surprised that the xmlspawner is pretty much just as efficient as the normal one. After all, the big difference is in the code, and the code gets loaded only once. The rest of the difference should be accounted by the extra instance properties, and those are minimal.

My motivation for suggesting the split of the spawner and the trigger is based on design principles. A spawner and a trigger are not the same thing. They are aware of each other and use each other, but they are not one concept. As such they should be two seperate entities in the code too.

If I wanted to make a quest thingy where I do not need to spawn anything, I use a spawner?!?

If I wanted to make a normal set of skelletons that replenish over time, I use something that looks like a trigger?!?

Seperating the two will make documentation MUCH easier and make the tool much easier to use. Seperation of the issues of design helps people design more complex things.

Lastly, seperating the trigger code from the spawner code allows for some new functionality that would not fit very well with a spawner-trigger. For instance having a trigger that fires more than one spawner (from a list) or for that matter fires a random spawner (from a list). Using triggers for things other than spawners.

As a thougth experiment, try to create an inheritance hirarchy that includes a spawner, a trigger and a spawner-trigger. You will find that there is no commonality (except Item) in content, only in their use. This should indicate that they should be seperate entities. If you abstract the interface between the two you could in fact reuse it elsewhere. XMLSpawner implements ITriggerEvent. But now you can have an NPC that implements ITriggerEvent too, or something more complex than the combination lock thingy that actually has a state machine inside.... A lot of possabilities open up :)

If I split the code would you mind if I posted it?
 

ArteGordon

Wanderer
Damn it's hard to argue with you because you have so many good ideas :)
First point is that I have been implementing an external/internal triggering interface based on your earlier suggestion which I liked a lot, but I wont be splitting xmlspawner into separate triggering and spawning objects, and here are my arguments.

While from a design perspective, the code can be easily segregated, your examples point out why in practice they are actually related, and from my view best left integrated.

Some of the confusion on this comes from the view of the term "spawning" as item/mob generation alone. While this has been the case in the past,
spawning can be thought of more broadly as just another term for event generation, and these events can either be instances of items and objects (conventional spawning), or action events that can alter target objects, or trigger other events (extended spawning).
This is the current design, and from that perspective, integrating an event-generator with an event-trigger makes sense.

For example, your scenario
Lastly, seperating the trigger code from the spawner code allows for some new functionality that would not fit very well with a spawner-trigger. For instance having a trigger that fires more than one spawner (from a list) or for that matter fires a random spawner (from a list). Using triggers for things other than spawners.
you can do that now, because of the present design. By setting up a spawn list of SET keywords, with spawners as targets, you can activate them as a group, or randomly, or randomly with uneven probability distributions.
The spawner-trigger actually facilitates this by allowing you to "spawn" triggering SET events, as it is currently implemented. It even gives you the interface into the list itself.

Another of your examples,
If I wanted to make a quest thingy where I do not need to spawn anything, I use a spawner?!?
again, dont think of it as spawning "things", but rather events. The GUMP keyword is an example of the type of event that is "spawned", i.e. generated, that would be of use in a quest-like scenario. Another example would be unlocking a door on a keyword, or taming a creature, in which unlocking the door, and taming the creature are actions that are generated (spawned) as a result of triggering.

The last example you give
If I wanted to make a normal set of skelletons that replenish over time, I use something that looks like a trigger?!?
is really a resource argument, since this is a case of clock triggering of mob events, which is just the simplest example of combined event triggering/generation, but is a coupling of the two functions nonetheless. Just happens to be one of the simplest.

The real question is whether there are event-triggering scenarios, in which you do not want the capacity for flexible event generation (i.e. spawning)?

My suggestion would be, if you want to make a triggering class object, just make it an XmlSpawner class. It will be essentially the same, from the standpoint of resouce utilization, as a triggering class alone, but gives you all of the capacity for event generation that XmlSpawner provides.
The external/internal triggering interface will allow an object of this class to implement additional independent triggering features (internal trigger control), as well as providing the means for external objects to influence triggering (external trigger control), as well as the ability to influence other objects of the XmlSpawner class in the same way, essentially your cascading state-machine scenario.

So, when you think of the two functional components of the current spawner, think of them as one that is triggered by events (trigger), and other that generates triggering events (spawn) and you can see why I feel they practically fit together, even though they seem to be logically segregated.

And because from a resource perspective, it really doesnt cost anything to integrate them, I dont see the point in having an event-generator (spawner), that doesnt have triggering, or even having an event-trigger without the event-generating features of the current xmlspawner seems limiting to me, particularly when it comes at essentially no cost.

I think that the internal/external triggering interface resolves the need to split them based upon the argument of ease of user-extension since a user can expand the triggering functionality without having to worry about the existing implementation, and by providing a consistent interface it will remain stable with upgrades etc.

Would I object to you or anyone else fiddling with the code? Not at all. I'm sure that it will lead to confusion if the two entities independently evolve, but then again, people might find use for what you put together.
 

ArteGordon

Wanderer
I know that I already threw in my 2 cents, but I realized I still had some loose change in my pocket.

While splitting functions into separate items at first might seem as though it is simplifying things, there is real potential for actually introducing additional complication.
For example, right now, if you have a bunch of spawners in a graveyard, you can set them to spawn only at night simply by setting the TOD properties. Currently, this is a permissive attribute, which means it doesnt actually trigger anything, but simply allows triggers that have been activated (clocks, players, items, etc.), to generate events/spawns. This would be a spawn-side feature, so you would leave it there, but it is also a trigger-side feature, so you would have it there as well.
Other things such as refractory period, are also permissive and would have to be duplicated and coordinated, synchronizing refractory periods on two separate items.
Spawner state itself represents a permissive condition which you would like to have, for example on a full spawner, preclude generation of a triggering signal.

Basically, for all of these and any other type of permissive feature, the communication of triggering information would also have to go from spawner to trigger.
These are all handled easily in the integrated structure, but would have to be negotiated with an inter-object protocol for transfer of state information (essentially an expanded bi-directional ITriggerEvent protocol).

Finally, you would have to leave some residual triggering capacity on the spawner item anyway, such as clocked triggering otherwise all conventional spawners become two-item assemblies, and then the clean separation between triggering and spawning functionality is broken, again requiring spawner-to-trigger state communication.

As I said, I think the code can be easily split, but, like old friends, it will be hard to really keep them apart.
 

Fury

Wanderer
i agree with they should be together... kinda like id rather have a swiss army knife rather than fill a pocket with screwdrivers/clippers/a saw/knives/corkscrew etc. My work on the editor is going as if it is all one as well..
 

Avelyn

Sorceror
User manual?!

With as complicated as these spawners are getting, can we get some kind of a doc or Faq so we can at least know what type of input the fields in the [props want. I was able to spawn things with no problem, but I can't get the triggers working. I thought speech would be simple but it's not working. I'm sure I just entered something wrong.

Thanks
 

DeepFreez

Wanderer
Ok, after some more thought and some fiddling with the code I have come to som new insights :)

There are actually three basic concepts here.
  • (BaseTriggered) Something that can handles events based on permissions
  • (Spawner)Something that spawns stuff in its event handler
  • (Trigger)Something that generates events based on external factors
    [/list:u]

    The BaseTriggered will implement all the permissions and declare an abstract method for receiving events. It has the refraction timer, on/off state and TOD permissions implemented.
    The Spawner derrives from BaseTriggered, and thus has all the persmissions. What is added is an internal timer for the spawner and all the spawning stuff.
    The Trigger derrives from BaseTriggered too. This means it has the same permissions available. This implements all the activation checks, could add its own timer for periodic checks etc etc. It will have a list of effects and/or a list of things to be triggered (BaseTriggered)

    I agree with you that all the above things can be done from one Item, but the design becomes a bit cluttered. Seperation makes the design cleaner and thus the code easier to maintain or extend.

    The XML code might be a bit messier tho.. havnt looked at that.
 

ArteGordon

Wanderer
yes, the logical breakdown is having everything derive from a base trigger class. The only problem is that it would change ser/deser and so would require a conversion step (probably via abandoning the XmlSpawner class for a new one and substituting objects), and the xml would get more complicated.
For code maintenance, and making it easy for other people to look at, the easiest thing is just internal aesthetic reorganization (grouping and organizing into #regions), and I do need to do that.

Avelyn, DeepFreez put together a nice doc, but it is buried on page 10.
Perhaps I could ask if I could include it in the package (DeepFreez?)

I'm guessing you forgot to set proximityrange to something greater than -1 (which means off by default).
That is the range in which the spawner will respond to a player, and most of the triggering requires that.
Also note that once you trigger, the delaymin/delaymax props will determine when the spawn actually occurs, so you might want to make them small.
 

dominus

Wanderer
Crash

I wrote this command: [xmlspawnersave xml_saves\test
[code:1]
Exception:
System.IO.DirectoryNotFoundException: A part of the access route cannot be found "C:\RunUo-Server\xml_saves\test".
at System.IO.__Error.WinIOError(Int32 errorCode, String str)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, Boolean useAsync, String msgPath, Boolean bFromProxy)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
at System.Xml.XmlTextWriter..ctor(String filename, Encoding encoding)
at System.Data.DataSet.WriteXml(String fileName, XmlWriteMode mode)
at System.Data.DataSet.WriteXml(String fileName)
at Server.Mobiles.XmlSpawner.SaveSpawns(CommandEventArgs e, Boolean SaveAllMaps)
at Server.Mobiles.XmlSpawner.Save_OnCommand(CommandEventArgs e)
at Server.Commands.Handle(Mobile from, String text)
at Server.Mobile.DoSpeech(String text, Int32[] keywords, MessageType type, Int32 hue)
at Server.Network.PacketHandlers.UnicodeSpeech(NetState state, PacketReader pvSrc)
at Server.Network.MessagePump.HandleReceive(NetState ns)
at Server.Network.MessagePump.Slice()
at Server.Core.Main(String[] args)[/code:1]

sorry :oops:
 
dominus said:
Crash

I wrote this command: [xmlspawnersave xml_saves\test

Exception:
System.IO.DirectoryNotFoundException: No se puede encontrar una parte de la ruta de acceso "C:\RunUo-Server\xml_saves\test".

C'mon, you can figure this one out, right?

Cheers,
Ignacio
 

ArteGordon

Wanderer
sorry, thats was one from the original xmlspawner that I forgot to fix. Crashing the server when it cant find the directory is obviously a bit harsh :)
Fixed for the next release.

Note that the directory search will start at the base runuo directory (wherever you installed it).
 

DeepFreez

Wanderer
ArteGordon said:
Avelyn, DeepFreez put together a nice doc, but it is buried on page 10.
Perhaps I could ask if I could include it in the package (DeepFreez?)
By all means :) Its a bit out of date. Will see if I can update it this evening.

Btw, Where to post spawn packs? Some areas of the maps are not spawned by the example spawners that come with the script. I am sure the users of this script all have something to share :D
 

ArteGordon

Wanderer
DeepFreez said:
ArteGordon said:
Avelyn, DeepFreez put together a nice doc, but it is buried on page 10.
Perhaps I could ask if I could include it in the package (DeepFreez?)
By all means :) Its a bit out of date. Will see if I can update it this evening.

Btw, Where to post spawn packs? Some areas of the maps are not spawned by the example spawners that come with the script. I am sure the users of this script all have something to share :D

That would be great. I'll try to put together some documented examples as xml files for doing some of the straightforward things like speech triggering, object triggering, player triggering etc.

I thought about making a thread just for people to share their xml files, like the little blather mini-quest examples that I included in the release.
Then I could collect them (or maybe you could do it :) )and they could get added into a usercontribution package that could be updated as a separate submission.

This would be the right forum for it, but not sure what the moderators would think about the idea.
 

Avelyn

Sorceror
DeepFreez said:
ArteGordon said:
Avelyn, DeepFreez put together a nice doc, but it is buried on page 10.
Perhaps I could ask if I could include it in the package (DeepFreez?)
By all means :) Its a bit out of date. Will see if I can update it this evening.

That would be great guys... A lot of those fields are just an entry field and it would be nice to know what can go in them and what they do! :D

Thanks for the info about the proximity ArteGordon.
 

DeepFreez

Wanderer
A few suggestions that I can make after updateing the docs.

The GIVE and ADD commands could be even better if you could specify an amount to add for stackable items. I know the StackMount is used by default, but this is a bit limiting I think, especialy if you want say create 100 gold and 10 ginseng.
It IS possible to do this by setting the spawners OWN properties before spawning the GIVE (or ADD) command, but that is a hack :D

The TAKE command should also have an amount option. This will allow one to take say 100 gold, instead of ALL of the gold, like TAKE/goldcoin would do at the moment.

There is a bug in the BaseEscortable setup that came with the original xmlspawner. To fix it you unforutnately need to make to BaseAI :( Cant seem to find the link to that fix right now hehehe.
 
Status
Not open for further replies.
Top