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!

[RunUO 2.0 RC1] Courageous Random Encounter System

Courageous

Wanderer
Courageous Random Encounter System

Courageous' (aka Joe Kraska)
Random Encounter Engine 1.3


Version: 1.3


This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

UPDATED 28 OCT 2006

Major update. This version of the Random Encounter Engine now includes a fully populated distro. This distro follows directly from Nerun's but inserts the encounters as region-based, probability-based, level-limited entries into the classic encounter system.

Removed a crash bug associated with the prior version of the cleanup system.

PLEASE NOTE: YOU NEED TO INSTALL THE SEARCHES SCRIPT SYSTEM FOR RANDOM ENCOUNTERS TO WORK NOW.

UPDATED 22 OCT 2006

Substantially overhauled the cleanup system. It is now totally persistent, and functions on a unified (single) timer. Also changed the cleanup cycles somewhat. If players are in range of to-be-cleaned up encounter material (items or mobiles), these will not be cleaned up for count cleanupGrace="n" (a new configuration variable) number of times. If this variable is set to "0", the local presence of a player always squelches cleanup.

Tamed creatures are never cleaned up, even if they later become untame. Items, once owned by any mobile, are never cleaned up, even if they are disgarded and dropped on the ground.

UPDATED 7 OCT 2006

Fixed a bug that caused general encounter areas (like default wilderness) to override more specific encounter areas (like wilderness covetous entrance).

Allows the graphical debug animation effect to be controlled separately from the text logs.

Allows specific mobile spawns to have custom animations with hues (a daemon spawned in a pillar of fire, for example).

Allows the spawn to be forced to attack the player right away, to eliminate spawn/attack delay.

UPDATED 11 SEP 2006

Fixed a small bug that caused small animal's to attack players during a random encounter. This system is no NO LONGER BETA.

[many other updates deleted]

ABOUT RANDOM ENCOUNTERS...

This is a region-based "random encounter" engine for RunUO. It operates based on named regions of interest, probababilities, understanding of the character's "level," and night, day, on road, off road, on-water, and other parameters.

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). Additional options include level limitation (the player must be at least a "5th level" mage), time limitation (encounter only occurs at Night), road limitation (this encounter only occurs either on-road or off-road), and encounter scaling (this encounter scales up to match the player's ability). These features allow the administrator great control over who has what encounters, when and where.

For example, one might set up the 4th level of dungeon Covetous to have a few random dangerous encounters.One might further set it up so that one has to be at least "3rd level" to get the encounter, and that if one is a significantly higher "level", the encounter scales up to match the player's abilties.

Clever admins will note that, with the help of a region creation tool, one can combine Random Encounter regions with novel new regions of one's own creation. For example, create a custom named region called "Evil Swamp," over an area of swamp you want to have area-based encounters for, and add an entry to the RandomEncounters.xml file. Voila! No more point-based spawners.

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

INSTALLATION

Extract the zip file into your Scripts/Custom directory. Extract the Searches.zip into your Scripts/Custom directory. Note that the configuration file "RandomEncounters.xml" is expected to reside in 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)
  • debugEffect="false" (display an animation on screen with every spawn)
  • RTFM="false" (you have read and configured your config file)
"Facet" tag.
  • name = (mandatory tag naming the facet)
"Region" tag.
  • type = (mandatory tag specifying region type; can be "Guarded", "Dungeon", and "Wilderness")
  • name =(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... use landType="Water" instead please)
  • 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 = (a comma-separated 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"
  • effect=Smoke, Fire, Vortex, Swirl, Glow, None (default is None); a colon in the string with an optional integer value indicates hue (e.g., "Smoke:96").
"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...

SPECIAL THANKS

Thanks to Arte Gordon for his contribution of pieces of Xml Spawner to this code base.

Thanks to Nerun, who's spawners I imported to create the distro.

Thanks to Gandalf Parker for pointing me to RunUO and inspiring this code to be written in the first place, due to his disgruntled mumblings about the inadequacy of point-based spawners.
 

Attachments

  • Searches-1.0.zip
    25.6 KB · Views: 835
  • RandomEncounters-1.3.zip
    102.7 KB · Views: 437

Courageous

Wanderer
Updated with a small bug fix for animal (and vendor) encounters.

This is the 1.0 "believed to be totally bug free" release.

Thank you for everyone who's tested and used.

This system is no longer in active development, but I do consider feature requests.

C//
 

Joeku

Lord
Well, I installed it and everything seems fine. I am using the default spawn xml file. First, I went into Covetous:
Code:
RandomEncounters: Picking encounter for player="assssssss, map="Felucca" ...
RandomEncounters: generating instances: Felucca:Dungeon:Covetous:AnyLand:AnyTime
:p=0.9:level=1:class=Overall:scaleUp=False:distance=(1:10=2):at=(26,14) ...
    Felucca:Dungeon:Covetous:AnyLand:AnyTime:p=0.9:level=1:class=Overall:scaleUp
=False:distance=(1:10=2):at=(26,14)
        Mobile:p=1:pick=IceElemental:id=0:at=(27,18):min=1:max=1:n=1
            Mobile:p=1:pick=SnowElemental:id=0:at=(28,22):min=1:max=3:n=3
            Mobile:p=1:pick=SnowElemental:id=0:at=(28,22):min=1:max=3:n=3
            Mobile:p=1:pick=SnowElemental:id=0:at=(28,22):min=1:max=3:n=3
            Mobile:p=1:pick=ArcticOgreLord:id=0:at=(29,22):min=1:max=1:n=1
        Item:p=1:pick=WoodenTreasureChest:id=0:at=(31,18):min=1:max=1:n=1
            Item:p=1:pick=Gold:id=0:at=(32,22):min=1:max=1:n=1
            Item:p=1:pick=BattleAxe:id=0:at=(33,22):min=1:max=1:n=1
That worked fairly well. I ran out of the dungeon in fright... then noticed that nothing was spawning at the entrance:
Code:
RandomEncounters: Assigning player "assssssss, map="Felucca" to candidate set for regionType=Wilderness, regionName="Covetous Entrance" ...
RandomEncounters: Generating 1 encounter checks for 1 players in Wilderness region...
RandomEncounters: Picking encounter for player="assssssss, map="Felucca" ...
RandomEncounters: Assigning player "assssssss, map="Felucca" to candidate set for regionType=Wilderness, regionName="Covetous Entrance" ...
RandomEncounters: Generating 1 encounter checks for 1 players in Wilderness region...
RandomEncounters: Picking encounter for player="assssssss, map="Felucca" ...
RandomEncounters: Assigning player "assssssss, map="Felucca" to candidate set for regionType=Wilderness, regionName="Covetous Entrance" ...
RandomEncounters: Generating 1 encounter checks for 1 players in Wilderness region...
RandomEncounters: Picking encounter for player="assssssss, map="Felucca" ...
RandomEncounters: Assigning player "assssssss, map="Felucca" to candidate set for regionType=Wilderness, regionName="Covetous Entrance" ...
RandomEncounters: Generating 1 encounter checks for 1 players in Wilderness region...
RandomEncounters: Picking encounter for player="assssssss, map="Felucca" ...
RandomEncounters: Assigning player "assssssss, map="Felucca" to candidate set for regionType=Wilderness, regionName="Covetous Entrance" ...
RandomEncounters: Generating 1 encounter checks for 1 players in Wilderness region...
RandomEncounters: Picking encounter for player="assssssss, map="Felucca" ...
!

Any ideas?

***EDIT***
Also, a suggestion...

Perhaps you could factor in the player's direction to the general direction where mobiles will spawn? I raised the tile range for monsters in Covetous, and now while I run everything spawns in clumps behind me... :(

***RE-EDIT***
So yeah... how exactly does the cleanup function work?

I was running right towards a few monsters, and then they disappeared right in front of me... :(
 

Courageous

Wanderer
Joeku, if you are using the unedited .xml file, you're going to have problems. RandomEncounters is not a distro, it's just a spawner system.

The cleanup value is the time in seconds after the mobile is spawned that it will be deleted. Set it to a larger number if you like. Mobiles are not deleted if they are attacking the player. I suppose I could change it so that they are not deleted if they are in range of a player also.

My example config files aren't always the same. In the current one on my desktop, the only encounter there spawns only at night.

I'll look into doing a "direction of run" based adjustment to running players. It's possible.

C//
 

Liacs

Sorceror
Question: how do I make the encounters appear outside the screen and not in a flamethingy? I want it to look more natural and real... also how to make that the encounters dissapear when outside sight of the player?

Thanks for your help.

Lia
 

Courageous

Wanderer
Encounters will naturally disappear "cleanup" time later (unless they are attacking a player, in which case they wont). Read my notes at the top of the .xml file for suggestions on actual timing.

The graphic effect you are seeing is because the system is in debug mode (debug="true"). Set debug="false", and it won't do that.

The next release will allow the effect and the debug text to be separatedly controlled. Next release will also allow custom animations for spawns, when you want them for special reasons (a big pillar of fire for a demon, perhaps?).

As for appearing out of range, set the distance to be a large number. Lots of encounters will be missed this way, but to each their own. I might suggest you try it with a moderated distance, like 15, and see how it goes with the debug effect off. I'm betting without the obnoxious vortex, it will look okay to have them appear in range.

C//
 

Liacs

Sorceror
One little thing... when you save and restart the server while an encounter is still in the world, it won't dissapear with restart... means that if there are a lot of encounters and you frequently restart the server (once a day e.g.) you have a lot of encounters you can't track that stay in the world...

I can be wrong though... :)
 

Courageous

Wanderer
Good thinking.

Random encounters marks items and mobiles it creates using (persistent) XmlAttachments. In the event of a save-restore, those items/mobs will be cleaned up.

If you notice that not happening, please let me know.

C//
 

Liacs

Sorceror
hehe... that is why I wrote it... because I still had three rats around me when I restarted... ;) and I waited and waited... and they were not disappearing... :D
 

Courageous

Wanderer
I'll check the Cleaner.

*edit*: Looks like the cleaner only cleans items for whatever reason. I'll look into what the right thing to do here is.

C//
 

Liacs

Sorceror
sorry, that I am so bitchy... I love your system though ;)
Going to use it for sure, once I figured all out.

Btw: I put the distance to 15 and the rats still spawn right next to me... *hmpf* *runs and looks for shelter*
 

Courageous

Wanderer
Re: rats spawning too close.

Can you tell me both where you are on the map, as well as show me your encounter entry? The system spirals around the player from a random position on the clock, spiraling in until it finds an accessible spawn point. When it does, the creatures themselves, if there are more than one, spiral OUT from that same point until they find a location good for them.

Joeku:


My apologies. The last version of random encounters introduced an error that made it so that if a "general" spawn could overrride a specific one, it would. For example, the "Wilderness"/"default" spawn can override the "Wilderness"/"Covetous Entrance" spawn. That's a bug. This is already fixed in my source tree, and will be in the new release (this weekend).

C//
 

Liacs

Sorceror
here we go:

Code:
    <Facet name="Felucca">
        <Region type="Wilderness" name="Covetous Entrance">
            <Encounter p="1.0" distance="20" time="Night">
                <Mobile pick="Ratman">
                    <Mobile n="1:2" pick="RatmanArcher"/>
                    <Mobile n="2:5" pick="SewerRat"/>
                    <Mobile p=".5" pick="RatmanMage"/>
                </Mobile>
            </Encounter>
        </Region>

and I am in 2498 926 0 Covetous. Directly infront of the cave entrance... I can run around there, but the rats still spawn right next to my feet... *eeek*:eek:
 

Courageous

Wanderer
You're encountering the same bug Joeku is. It' s not ratmen you are getting, but SewerRat, right? Look down further in the .xml file. You are encountering the "default" wilderness encounter. You're not getting the Orc or the OrchishLord, because you're not a 7th level Necromancer. You're not getting the brigand, because it's not twilight and you are not on a road. You're getting the sewerrat, because it IS twilight, and you're off the road. The probing distance is 7. Set it to 15.

On or around line 1069 of RandomEncounters.cs, in the function GenerateEncounters(), look for a bit of code like this:

Code:
                foreach( string key in keys1 )
                {
                    //Console.WriteLine("Searching for region key: "+key);
                    if ( m_RegionHash.Contains( key ) ) //  Search to for match against named region;
                    {
                        possibleEncounters = ((RegionRecord) m_RegionHash[ key ]).PossibleEncounters;
                        //Console.WriteLine("Found match for key: {0}, with value: {1}", key, possibleEncounters);
                        break;
                    }
                }

                if( possibleEncounters == null && regionName != "default" )
The last line in yours will be wrong. The above is correct.

I've already made this change, and it will be in the next release. If you twiddle this now, you can move ahead with learning the system a bit better.

C//
 

Liacs

Sorceror
wow, thanks a lot... i will tell you if I find more bugs :D

EDIT: For everybody, who is interested: distance 15 is just great. You see the name of the encounter appearing on the end of the screen. Then you can or: run like hell... or: kill the beast *lol*
 
Top