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!

Courageous' Random Encounter Engine

Courageous

Wanderer
arul said:
Single.Parse() needs to use the appropriate number format as well.

Whoops. Can you tell me what test data to use? "Do you say ',3' for '.3' and so forth? In which case which language tag should I use for that? Also, is there anything with integers that furriners (you say this like a Texan, "fur-in-urs, yee haaw") care about? :)

C//
 

arul

Sorceror
To be honest I don't know, I faced this issue earlier while developing a Log Reader.
I'll try to find some more informations about the correct number format in Czech ( perhaps even in europe generally ).

Integers should be fine :)

EDIT:
Code:
using System;
using System.Collections.Generic;
using System.Text;
using System.Globalization;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main( string[] args )
        {
            CultureInfo c = CultureInfo.CurrentCulture;
            Console.WriteLine("Current: " + c.NumberFormat.NumberDecimalSeparator);
            Console.WriteLine("en-US: " + new CultureInfo("en-US").NumberFormat.NumberDecimalSeparator);
            Console.ReadLine();
        }
    }
}
Produced this
Current: ,
en-US: .
hope that helps :)
 

Kamron

Knight
I would like to say great job on your project. Even just the idea is fresh and new, and I think its great. I don't know how you coded this, although I would like to inquire about the XML. I think it would be a little bad if you had it reading the XML files every time it wanted a new peice of information. I am not making assumptions to how you coded your system, I am just asking if you coded it so that it imported the XML as objects or what not, and then uses that. That would reduce the hard drive grinding by quite a bit, especially for large shards :)
 

arul

Sorceror
XxSP1DERxX said:
I would like to say great job on your project. Even just the idea is fresh and new, and I think its great. I don't know how you coded this, although I would like to inquire about the XML. I think it would be a little bad if you had it reading the XML files every time it wanted a new peice of information. I am not making assumptions to how you coded your system, I am just asking if you coded it so that it imported the XML as objects or what not, and then uses that. That would reduce the hard drive grinding by quite a bit, especially for large shards :)
It loads the Xml file only once ( initialize method ).
 

Jarrod

Sorceror
brilliant. Thank you for your contribution to the community. I appreciate the effort put into the products released by capable coders, and look forward to any future improvements you care to share with the community.
 

Courageous

Wanderer
XxSP1DERxX said:
I am just asking if you coded it so that it imported the XML as objects or what not, and then uses that.

It loads the XML files as the system is initialized. It then starts a timer. This timer periodically looks out to your XML file and sees if you changed it. If you did, it reloads the XML file. This is so you don't have to "bounce" (i.e., reboot) your shard in order to change the system. This is supposed to be safe. Any errors in the XML file should be caught, worst case meaning random encounters stop happening until you fix the problem.

Internally the system creates templates from the xml, which are then "picked" when an encounter occurs by a sort of factory method that binds the range and probability to an actual description of an encounter. I.e., if you said "1:3", it picks 1,2, or 3. If you said ".25", it draws a random number to see if you get that.

Once the template is expanded, it tries to push the mobiles and items into the world.

In order to accomplish this, it uses a spiral search pattern around the player.

It searches inwards from the described range in order to place top level mobiles and items. I did it this way because of dungeon passages. The tightness of a corridor means their could be more, not less, unplaceable terrain the further you go out.

Once a top level mobile is placed, sub mobiles are placed nearby (searching outwards).

Sub items are always placed in their parent item.

Items can be sub items of either mobiles or items.

Hope this helps.

C//

p.s., if you want to have a little fun, go into the SpawnFinder code, and turn on the bit of code that animates the search cursor. I needed this at first to make sure the searcher is working. It's fun to watch.
 

etherkye

Wanderer
This is a great idea, and a great script. Although as i don't normaly have many people on my shard the players are trailing around lines of birds, cats, dogs, and so on. Kinda funny to watch mind you but realy very practal. What it needs is some way to se how many encounters someone already has, and to cap it at a certain amount.

Also, i wish i has some way to edit the xml files...
 

Courageous

Wanderer
etherkye said:
This is a great idea, and a great script. Although as i don't normaly have many people on my shard the players are trailing around lines of birds, cats, dogs, and so on. Kinda funny to watch mind you but realy very practal. What it needs is some way to se how many encounters someone already has, and to cap it at a certain amount.

Also, i wish i has some way to edit the xml files...

Hrm. Well, it's intended that you tune the rate and probabilities by quite a bit. What you're describing to me says to me that you haven't done sufficiently well enough yet. For one, I would suggest that you set the cleanup period to be shorter than the interval.

Once I get a bit more into the UO groove (I haven't played since a year after the beta), and I figure out where what kinds of creatures are intended to spawn in the world, I'll be publishing more thorough encounter map as a base. This may be a while, though, so perhaps someone can share.

You do know that the base xml file is just a short example, right?

The current intervals are set to high frequency so that you can see the system working.

C//
 

Courageous

Wanderer
XxSP1DERxX said:
Thanks for the info, it sounds awesome. I like this alternative to spawners as well. Nice idea

Yes, I've toyed with the thought that one could generate many regions across the map (naming them differently), with various themes for them, instead of spawners in some cases.

I think that you would likely not want to replace spawners entirely.

But considering the idea for a moment, I think that one might want certain regions to spawn more frequently (not simply more likely). This could be achieved by pushing the "interval" to the facet, or deeper to the "region" as an option. This would require either more timers, or a super timer, that ticked frequently enough to slice to the others.

C//
 

Kamron

Knight
No difference with spawners. Spawners are simply items which contain their own timer(s) ;) So if you optimized it properly, you could base it off of the same principle. Super timers are ineffective, because of the sporaticism of the ticking.
 

Jarrod

Sorceror
If we could merge this type of ideaology into a "regular" spawner, I would argue that this would effectively free up system resources.

Where there are no players, there are no monsters.
Where there are no monsters, there are no "AI Activities".

so basically you would have a world full of spawners that pop out monsters when the players get within a screen of it. When the players leave again... The Langoliers eat everything
 

Kamron

Knight
That is how spawners are supposed to work already... granted people don't code like a pile of poop...

btw, I love the grinding noise that Langoliers make (tears paper apart slowly).
 

RavonTUS

Sorceror
Greetings,

I've been using your script and tweaking my own XML file. I have a couple of suggestions/comments.

1) It seems to me that ITEMS do not get cleaned up. I've noticed several chest laying around the shard that should have been clean after the spawn disappears.

2) I would like to see an option for random distance. I'm not too familar with XML, so bare with me. Maybe if distance="" or distance="0", then pick random distance, or make it like you do for 'p=1:3' settings, distance="4:10".

Currently...
Code:
- <Encounter p=".1" distance="4">
  <Mobile n="1:3" pick="Spider" /> 
  </Encounter>

Suggested...
Code:
- <Encounter p=".1" distance="4:10">
  <Mobile n="1:3" pick="Spider" /> 
  </Encounter>

I think the code would be something like this (not tested)...
Code:
            m_Distance = Int32.Parse(distance);
            //modified from orginal to add random distance if left blank
            if (m_Distance = null)
            {
                m_Distance = Utility.RandomMinMax(4, 10);
            }

I do like this idea better than spawns for certain areas, dungeons in my case.

Thank you,
-Ravon
 

Courageous

Wanderer
Thank you for your suggestions, Ravon.

I'll implement the random range functionality immediately upon my return from my weekend trip. It's easy enough to implement. Internally, to pull the range value, you just use string.Split(':') (look around for it in the code to see how it was done) and yes, the RandomMinMax call is precsiely what I'd use.

You're correct. Items are not cleaned up. This is, perhaps, my own ignorance of the RunUO core. I was assuming that they would decay, and that I had to do nothing further. Is this not true?

I will certainly fix this as well if there is a problem.

C//
 

Kamron

Knight
World items will always decay if they are placed in a map/region which is designated as decayable and are movable.
 

etherkye

Wanderer
where do you change delay? i thought it was lines 431-435 in randomencounter.cs, but it doesn't means to be working
 

Courageous

Wanderer
Delay is the amount of time before the interval begins ticking. You should just change it in the xml, unless you are experimenting. Look for delay, Delay, and m_Delay. It defaults to 60 seconds, and the only thing I do with the value is pass it on through to the Timer, through the :base constructored, defined at the beginning of the file.

My file is slightly different than yours, but you are in the right area.

I've been a bit confused about the timer's base functionality. Typically patterns like these are supposed to be "initial pause, tick, wait interval, tick...". I think this one works like "initial pause, wait interval, tick...". Note that in the first example, if the initial pause is zero, then the first tick is skipped. The first pattern has a bit more flexibility. But I I'm write about how it works, at this point so many people are using timers, I'd think there'd be risk in changing the semantics...

C//
 
Top