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
Courageous' Random Encounter Engine

Random Encounter Engine V 0.9.7B
=======================

COPYRIGHT JOE KRASKA aka 'Courageous', November, 2005

Permission to use this script (and modify it) in a RunUO private shard is hereby granted, without restriction. However no rights to redistribute this script are granted, except for any temporary (and revokable) implied redistribution rights granted by the act of posting this to a redistribution site by the original author.

UPDATED 22 FEB 2006

Updates to 0.9.8B:
  • Added the ability to differentiate players by "class," where certain values in certain skills make the player qualify for certain kinds of encounters according to class names. The system currently supports Fighter, Ranger, Mage, Necromancer, Thief, and Overall (which is the default). Note that the Ranger class is determined by outdoors skills (tracking, animal lore and taming and the like, and not any combat skills).
How it works:

The system examines a subset of a mobile's skills, multiplying them by a weighting factor. The result is a figure approximately 1-10 that rates the mobile according to a specific "class". This "class" rating can later be used in conjunction with the level= tag to determine if a player qualifies for an encounter. Here is an example:

level="8:Necromancer"

UPDATED 20 FEB 2006

Updates to 0.9.7B:
  • Fixed a bug in the previous version which could cause too many spawns to occur, particularly if a very low probability draw occurred.
  • Added support for tagging encounter difficulty by an inferred "level" of the character.
  • Added supported for scaling up encounters based on character "level"
UPDATED 19 FEB 2006

Updates to 0.9.6B:
  • Fixed a problem where non-decayable items created by the system might (theoretically) never be cleaned up by the system in the rare event the server crashed after they were spawned but before they were cleaned up by the cleaner.
  • Added the ability to mark spawns for specific times during the day/night cycle, including Night, Twilight, Day, and (the default) AnyTime.
  • Added the ability to more accurately specify the player's location for certain types of spawns. Currently supporting: Water, OnRoad, OffRoad, and (the default) AnyLand.
NOTE CAREFULLY:

The old tag for water based encounters (water="true") is now deprecated. It will continue to work for a version or two, but you should use landType="Water" in the future.

As part of non decaying item solution, I have lifted (with permission) Arte Gordon's XmlAttachment system. RandomEncounters now has a subdirectory "ArteGordon". If you already have XmlSpawner or plan to get it, you'll need to delete this directory from RandomEncounters.

The landType= tag is now an option on each encounter. It is case sensitive. You can set it to Water, OnRoad, OffRoad, or AnyLand. AnyLand is the default and means either on or off road.

The time= tag is also now an option on each encounter. You can set it to Day, Night, Twilight, or AnyTime. AnyTime is the default, and it means literally any time of day.

FEATURES NOT INCLUDED:

One user requested that young players not be given encounters. This request was based on the particulars of his shard, and so is not yet implemented. There is some code in the expected place that can be commented-in if desired. I'm considering allowing shard admins to mark encounters directly to determine if they are or are not for young players.

Another user requested cleanup support for mobiles spawned by OrcBrutes. This turned out to not be feasible to do except at system start up time, because the sheer number of mobiles on a shard could cause a significant lag hiccup at the cleanup point. Also, it turned out to be impossible to know which creatures were children of creatures created by random encounters.

I'm still thinking about both of these items.

FUTURE WORK

A difficulty-based scaling and limits system is currently in progress.

UPDATED 7 JAN 2006

Updates to 0.9.5B:
  • Added separate intervals for the different supported region types. The system will now currently supported separate timer rates for dungeons, wildernes, and guarded regions.
There is still an ongoing an issue that can arise with item spawning, where if the shard crashes before the item is cleaned, and the item does not decay, it will permanently litter the shard.

UPDATED 3 JAN 2006

Updates to 0.9.4B:
  • Resolved an issue where mobiles would sometimes inappropriately spawn on boats that were in coastal territories.
  • Resolved an issue where very long combats would sometimes result in the encounter being deleted during combat.
  • Made it so that debug mode doesn't display failed spawn attempts.
UPDATED 2 JAN 2006

Updates to 0.9.3B:
  • Added some tests in the spiral finder to determine the "right" level of Z to spawn elements at; tested this in caves and towers.
  • Added a catch for an exception that could arise when a mobile was described in the encounter system, but that mobile did not have a default constructor; prints a diagnostic and ignores the mobile.
  • In debug mode, the spiral finder animates its search (if this is an annoyance, let me know).
RANDOM ENCOUNTERS

This is a D&D style "random encounter" engine for RunUO.

Note that encounters do not have to be hostile. For example,
this is a good way to make your world "come alive". You can
set it up so that wilderness creatures frequently appear near
the player when the player is in the wilderness. Since these
creatures are only spawned at or near where an active player
can see them, no CPU is wasted. It also adds an element of
unpredictability to the shard.

The system is fully configurable, by facet, by region type,
and by named regions (if desired). This allows the administrator
to control what kind of encounters appear where.

The system runs off a configuration file; the system rescans
this file periodically, if it notices that the file has been
written. So your shard does not have to be bounced for you to
make configuration changes.

INSTALLATION
============

Extract the zip file into your Scripts/Custom directory. Nothing else
is required. Note that the configuration file "RandomEncounters.xml" is
expected to reside in $RUNUO_INSTALL_DIR/Scripts/Custom/RandomEncounters.
If you want to put it somewhere else or name it something else, find the variable
"m_EncountersFile" in the RandomEncounterEngine class and fiddle with it.

HOW TO
======

The Random Encounter Engine is entirely controlled by its configuration file,
so understanding its format is essential. Before we talk aboutthat, though, a few
preliminaries:

The system is controlled on a common clock that periodically checks to see
if players (player mobiles with access level == Player, not staff members!)
qualify for a random encounter. To see if they qualify, first the system
decides which picker is in use. There are two.

The first picker is the "sqrt" (square root) picker. Its the default. When
the sqrt picker is in use, the system finds the square root of the number of
players online. The system then picks this many players to see if they further
qualify for a random encounter. No more than one encounter per player.

The second picker is the "all" picker. Using the all picker, the system
considers all players online for a random encounter.

Note switching between pickers is a dramatic event, which will GREATLY
impact the number of random encounters your player see; you should decide
early which picker you're going to use.

A player qualifies for a random encounter when:

1. The facet name, region type, and region name the player is in has
encounters described for it (example, the player is on Facet the
facet named "Felucca", in a "Dungeon" region named "Covetous").

2. Failing #1 above, the the system finds a region named "default" that
otherwise qualfies by facet name and region type (example, the
player is in a Felucca Dungeon, and is in Covetous, but the administrator
did not define a named region for Covetous. If there is a default
region for Felucca Dungeons, this will be used instead).

3. The system draws a random number 0.0-1.0, and searches for the LOWEST
probability encounter it can match.

If all of the above fail, the player has no encounter.

Now on to the details. Consider the following example:

Code:
<!--mycomment-->
<RandomEncounters picker="sqrt" delay="15.0" interval="15.0:25.0:35.0" cleanup="300.0" debug="true">
    <!--mycomment-->
    <Facet name="Felucca">
        <Region type="Wilderness" name="default">
            <Encounter p="1.0" distance="7">
                <Mobile pick="OrcCaptain,OrcishLord">
                    <Mobile n="1:3" pick="Orc"/>
                    <Mobile p=".25" pick="OrcishMage"/>
                </Mobile>
                <Item pick="WoodenTreasureChest">
                    <Item pick="OrcHelm"/>
                    <Item pick="ChainChest,BattleAxe"/>
                </Item>
            </Encounter>
            <Encounter p=".05" distance="7">
                <Mobile pick="EvilMage"/>
                <Mobile n="2:3" pick="Brigand"/>
            </Encounter>
        </Region>
    </Facet>
</RandomEncounters>

This is a standard nested tag formatted xml file. It supports the following tags:

"RandomEncounters" tag. This supports the following attributes and defaults:

picker = the picking method, defaults to "sqrt"
language = the globalization code, defaults to "en-US".
skiphidden = tells the system to exclude hidden players from encounters, defaults to FALSE
delay = amount of secs before encounters begin after server start, defaults to "60"
interval = frequency in secs encounters are checked, defaults to "1800". This field can be separated into as many as 3 values, one each for dungeons, wilderness, and guarded regions. Separate with ":"
cleanup = how long to wait before shutting down spawned mobiles, defaults to "300"
debug ="false" (print out extra debugging information)

"Facet" tag.

name =[None] (mandatory tag naming the facet)

"Region" tag.

type =[None] (mandatory tag specifying region type; can be "Guarded", "Dungeon", and "Wilderness")
name =[None] (mandatory tag naming the region; use "default" to pick up generic)

"Encounter" tag.

p = probability of encounter, default of "1.0", which means 100%. If p is set to * (e.g., p="*"), the encounter will always be had in addition to any other encounter the player might have for the region
distance = the preferred distance from the player for the encounter, a number or a range (example "1" or "0:2" or "1:3"). Default is "7".
water = water mobiles can't spawn without this; land mobiles can't spawn with it, default is "false" DEPRECATED
landType= Water, OnRoad, OffRoad, or AnyLand. Default is "AnyLand".
time=Night, Twilight, Day, or AnyTime. Default is "AnyTime".
level=notional level of the character required to have the encounter; defaults to 1. An optional second argument can be sent to the level indicating class after a separating colon. E.g., "8:Necromancer". Valid current class names are Fighter, Ranger, Mage, Necromancer, Thief, and Overall.
scaleUp=true/false, whether or not to scale up encounters that are waker than the player; defaults to false. Never more than triples an encounter.

"Mobile" tag.

p = probability of the mobile being included in a picked encounter, default is "1.0"
pick =[None] (a list of mobiles to pick from (NO SPACES!); one is picked randomly)
n = a number or a range (example "1" or "0:2" or "1:3"), default is "1"

"Item Tag"

Same as Mobile tag.

Note how Mobiles and Items can appear embedded in one another. To know the rules, use
some common sense. An Item can be in a Mobile (e.g., "orc has a Sword"), and an Item can
be in an Item (e.g., "sword in a chest"), but a Mobile cannot be in an Item! A Mobile,
however, might belong to another Mobile's team...

Now a little word on picking. Consider the following (modified) fragment:

Code:
<Mobile n="2" pick="OrcCaptain,OrcishLord">
    <Mobile n="1:3" pick="Orc"/>
    <Mobile p=".25" pick="OrcishMage"/>
</Mobile>
The above says "pick 2, each randomly from OrcCaptain and OrcishLord. Then
for each leader, attach 1-3 Orcs, and likewise for each leader, offer a
.25 chance to have an OrcishMage. This calculates to a maximum of 10
Mobiles for the whole encounter.

Sub items spawn IN their parent items. Sub mobiles spawn NEAR their parent
mobiles.

(note that if a valid spawn point can't be found, a mobile or item might not
be spawned, and if this happens, the remaining part of a whole encounter might
be skipped).

EQUAL PROBABILITIES
================

It's both possible and okay to list two encounters in the same region with the same probability. In this particular case, the system draws randomly from all matching probability levels, so you don't get the wierd case where one is always preferred over the other. This also makes it so that you don't have to do gymnastics to separate all the possibilities. One could just use ".3" ".2" and ".1" for everything, letting the system sort out the equal probability encounters...
 

Attachments

  • RandomEncounters-0.9.7B.zip
    49.6 KB · Views: 72
  • RandomEncounters-0.9.8B.zip
    50.1 KB · Views: 75
  • RandomEncounters-0.9.9B.zip
    50.3 KB · Views: 156
right on i am going to think about restarting my shard (its new but i never got around to doing anything real grand for it) back up and implementing this

and thats saying alot after i said it would prolly take god himself/herself to git me to git a shard going again after it got hacked
 

Courageous

Wanderer
Deaths Advocate said:
right on i am going to think about restarting my shard (its new but i never got around to doing anything real grand for it) back up and implementing this

and thats saying alot after i said it would prolly take god himself/herself to git me to git a shard going again after it got hacked

Did the core get hacked? Or did someone pierce your computer from remote? If it were me, I'd run the shard through a hardware firewall that ONLY exposed the UO port. I'd run my webserver on different hardware entirely (exposing only port 80 and related).

Anyway, the sytem is EASY to configure. Go ahead and try, and if things get screwy, I'll attend to it right away (as in RUN your config file myself).

You'll get a laugh out of the examples; Trammies only get animals. :)

Don't forget to use a Staff Cloak or something to see the randomness. I have the rate set up way high in the default installation just so that I can see encounters. I wouldn't leave your shard that way. :)

C//
 
to tell ya the truth im not sure one minute my shards running next minute (now keep in mind im the only admin) theres 4 admins and they all shut down server and then i try to git back up and it tells me to create a new account then when i do same thing so i deleted it got my isp switched blah blah blah ect. and im here now
 

Courageous

Wanderer
Deaths Advocate said:
im getting an error that the childnode cant be found yo

Yes, I discovered that just now. That's what I get for regenning my zip (from current source without testing the current image). Posted a new one. I think I'm going to have to create a "releases" directory. EWE. :)

C//
 
heh ight man just yell at me when its done i defintly wanna test this beast out im no hardcore scripter or id try to edit it and stuff (already tried and failed miserably)
 

Courageous

Wanderer
Deaths Advocate said:
heh ight man just yell at me when its done i defintly wanna test this beast out im no hardcore scripter or id try to edit it and stuff (already tried and failed miserably)

I was "cleaning up", and changed "childNode" to "regionNode", but didn't finish the name substitutions last night. It should be good now. You shouldn't have to touch the .cs files, ONLY the XML file.

I also just tested out the "don't delete pets" thing for the despawner.

C//
 

PerfectWing

Wanderer
This is really impressive work. I'll give it some time before giving it a shot on my runtime shard, but from skimming through everything it seems it could be quite versatile. ++Karma, buddy.
 

Courageous

Wanderer
PerfectWing said:
I'll give it some time before giving it a shot on my runtime shard, but from skimming through everything it seems it could be quite versatile.

Yeah, I was thinking after I got it going that in some cases, you could replace spawners entirely with named regions that support random encounter sets.

A variation of this idea would allow one to place a specific spawn point that ALWAYS spawns (like a typical spawner), but picks from a facet/regional description in the spawner.

I don't recommend you take this live with a large shard yet, I haven't tested it for long run times yet, for example.

C//
 

arul

Sorceror
I've found a bug in your script.
Code:
29.11.-19:20:15 System.FormatException: Input string was not in a correct format
.
   at System.Number.ParseSingle(String s, NumberStyles style, NumberFormatInfo i
nfo)
   at System.Single.Parse(String s, NumberStyles style, IFormatProvider provider
)
   at Server.Misc.RandomEncounterEngine.LoadXml()
   at Server.Misc.RandomEncounterEngine.MaybeLoadXml()
29.11.-19:20:15 RandomEncounters: failed initialization!

This will need a little fix for non-US people.
Open the RandomEncounters.cs, then put at the above of the script this
Code:
using System.Globalization;
then search through the file for this ( it's there four times )
Code:
float.Parse( [I]something[/I] );
and replace it with
Code:
float.Parse([I]something[/I],  new CultureInfo("en-US"));
also there is Single.Parse() method in use at the line +/- 150 so find it and replace with this
Code:
Single.Parse(probability, new CultureInfo("en-US"));

and.... it works now, although it would be better to make the cultureinfo static in the configuration class and refer to it instead of creating the new instance every time it's needed.

However, great idea and well coded, good job Courageous.
 

Courageous

Wanderer
However, great idea and well coded, good job Courageous.

I'm glad you like it.

Is the crash because the foreign representation of numbers sometimes uses commas and periods in places where some of us do not?

I'm interested in the various test cases.

C//
 

arul

Sorceror
Courageous said:
I'm glad you like it.

Is the crash because the foreign representation of numbers sometimes uses commas and periods in places where some of us do not?

I'm interested in the various test cases.

C//
that's right, so I needed to force the parser to use another format provider.
 

RavonTUS

Sorceror
Greetings,

I think this is a cool idea. I have been playing around with the spawns and creating a more natural feal. However, it looks like you bet me too it.

I loaded it tonight and began to use it, on my shard. Sorry, it's a small world and I can't help you with bulk testing.

I have a suggestion, check to see if the player has changed location or is hidding. If the "probability of encounter" is set high, then it appears that a group of people could stand still or hide until alot of "mobs" show up.

Agh, I just died. I guess that's what i get for standing around typing...lol.

Good Job.

-Ravon
Play at An Nox, the cure for the UO addiction.
 

Courageous

Wanderer
I can see how someone who is hiding probably ought not have a random encounter, yes.

You can avoid the problem you describe by making sure the despawner doesn't take too long. But I'm adding a "skipphidden" option to the engine so that one can have it that way if one wants.

C//
 
Top