Platform Tutorial Defining Mobs
From Multiverse
| Contributed by: Multiverse | Last Tested: 23 Apr 08 | Tested By: SteveJ | Tested With: 1.5 |
This section describes how to add mobs to the world and how to give them behaviors. The second half of this article goes on to explain how to use spawn generators to create multiple mobs and respawn them when they are killed. You must have a Multiverse server suite set up with the sample world files. You must also configure a client to log into your world with the sample world assets.
| MARS |
| Mob Server |
| Object Manager |
| Combat Server |
|
Abilities and Combat Plugin • Combat Statistics • Extending the MARS Combat System • Group System • Trainer Plug-in • Professions • Experience System |
| Tutorials |
|
Defining Quests • Scripting Mobs • Defining Items |
| Other Examples |
|
Triggering an Action with a Mouseclick • Scheduled Execution • Working with Sound • Creating a Teleporter |
Contents |
Create a single mob
To create a new mob, you must:
- Define a display context to describe how the mob will be displayed in the world.
- Define a template describing the mob,.
- Use the template to create an instance of that mob.
- Add behaviors to the mob.
Define a display context
A display context describes the look of a object in the world. It
contains information about the mesh file the client loads and which
submeshes and materials the client will display for this
object. Display contexts for mobs are created in the
templates.py script for your world. By default, this
script is located in the mv-home/config/worldname
directory. So, for Sampleworld, this file is
mv-home/config/sampleworld/templates.py.
The following code creates the display context for the brax mob. The necessary asset files are already included in the complete SampleAssets (see Downloading asset repositories for more info):
brax_base_DC = DisplayContext("brax.mesh", True)
brax_base_DC.addSubmesh(DisplayContext.Submesh("braxBodyShape-lib.0", "brax.phong1"))
brax_base_DC.addSubmesh(DisplayContext.Submesh("braxHeadShape-lib.0", "brax.phong1"))
brax_base_DC.addSubmesh(DisplayContext.Submesh("braxTailShellTopShape-lib.0", "brax.phong1"))
brax_base_DC.addSubmesh(DisplayContext.Submesh("braxTailShellShape-lib.0", "brax.phong1"))
brax_base_DC.addSubmesh(DisplayContext.Submesh("braxTailShape-lib.0", "brax.phong1"))
brax_base_DC.addSubmesh(DisplayContext.Submesh("braxLadenBoxesShape-lib.0", "brax.brax_box_006_lambert5"))
In this example, "braxBodyShape-lib.0" is the submesh for
the brax body and "brax.phong1" is the corresponding
material; "braxHeadShape-lib.0" is the submesh for the
brax's head, which also used "brax.phong1" as the
material; and so on for the additional 4 submeshes.
You can see the submeshes and corresponding materials in any model by loading the mesh into the Multiverse Model Viewer. To see the material name, just click on the submesh in the Model Viewer's list of submeshes.
A display context is defined by the multiverse.server.objects.DisplayContext class.
Define a mob template
The object manager creates objects from templates that describe them. A template specifies the display context for the object and whatever attributes that object will have. By convention, mob templates are defined in the mv-home/config/world-name/templates.py script.
tmpl = Template("Brax")
tmpl.put(WorldManagerClient.NAMESPACE, WorldManagerClient.TEMPL_DISPLAY_CONTEXT, brax_base_DC)
tmpl.put(WorldManagerClient.NAMESPACE, WorldManagerClient.TEMPL_OBJECT_TYPE, ObjectTypes.mob)
A mob template is defined by the multiverse.server.objects.Template class.
Although the brax doesn't have any inventory, to see how to provide inventory to a mob, inspect the line for the "Quest Giver" ("Human Female Leather") mob:
tmpl.put(InventoryClient.NAMESPACE, InventoryClient.TEMPL_ITEMS, "Leather Tunic; Leather Pants; Leather Boots")
This specifies that the mob has a Leather Tunic, Leather Pants, and Leather Boots in its inventory. The templates for each of the items are defined later in the templates.py file.
To make the brax attackable and give it attributes necessary for combat such as health, you can use the following lines:
tmpl.put(CombatClient.NAMESPACE, "health-max", MarsStat("health-max", 100))
tmpl.put(CombatClient.NAMESPACE, "health", MarsStat("health", 100))
tmpl.put(CombatClient.NAMESPACE, "mana-max", MarsStat("mana-max", 100))
tmpl.put(CombatClient.NAMESPACE, "mana", MarsStat("mana", 100))
tmpl.put(CombatClient.NAMESPACE, CombatInfo.COMBAT_PROP_AUTOATTACK_ABILITY, "attack ability")
tmpl.put(CombatClient.NAMESPACE, CombatInfo.COMBAT_PROP_REGEN_EFFECT, "regen effect")
tmpl.put(CombatClient.NAMESPACE, "attackable", Boolean(True))
tmpl.put(CombatClient.NAMESPACE, "combat.mobflag", Boolean(True))
Having defined the Brax template, it must be registered. Follow the definition lines with the call to perform registration:
ObjectManagerClient.registerTemplate(tmpl)
Create and spawn a mob
Now that you have defined a template, you can create a mob as an instance of that template. The simplest way to create a mob is to add a single instance. However, in practice this is rarely useful because you usually want to create a spawn generator.
To do this, first create a marker in World Editor. Call it "mybraxmarker." Then, add the following code to multiverse/config/worldname/mobserver.py to create a single instance of the mob. The first line gets the location of a marker defined in the World Editor. You must know the instance into which you want to spawn the mob, identified here by 'instanceOid'. The call to setY() ensures that the mob is created at ground level:
braxloc = InstanceClient.getMarkerPoint(instanceOid, "mybraxmarker") braxloc.setY(0)
Then, these two lines create the object using the "Brax" template at the location of the "mybraxmarker" marker:
myOid = ObjectManagerClient.generateObject("Brax", instanceOid, braxloc)
WorldManagerClient.spawn(myOid)
See World Instancing and multiverse.server.plugins.InstanceClient for more on instancing.
Create mobs with a spawn generator
While creating single mobs can be useful, the most common way to create mobs is with a spawn generator. Spawn generators create a group of mobs and respawn them if they are killed.
Create an object factory
A spawn generator uses an object factory to create mobs. An object factory is a simple class that has a makeObject method for creating mobs from a template. For example, add this ObjectFactory sub-class to create a brax spawn generator:
class BraxFactory (ObjectFactory):
def makeObject(self, spawnData, instanceOid, loc):
obj = ObjectFactory.makeObject(self, spawnData, instanceOid, loc)
braxloc = InstanceClient.getMarkerPoint(instanceOid, "mybraxmarker")
behav = PatrolBehavior()
behav.addWaypoint(braxLoc)
behav.addWaypoint(loc)
obj.addBehavior(BaseBehavior())
obj.addBehavior(behav)
obj.addBehavior(CombatBehavior())
return obj
ObjectFactory.register("BraxFactory", BraxFactory("Brax"))
Creating a spawn generator
A spawn generator can create multiple copies of a mob and respawn them when they are killed.
A spawn generator is an instance of the multiverse.mars.objects.SpawnGenerator class. It uses an object factory such as the one defined above.
Spawn generators are created when instances are created or loaded. This is typically done in the instance init and load scripts. The following lines associate the object factory with a spawn generator, and then set the spawn settings. In this case, two brax are spawned within 30 meters of the marker, with a respawn time of 60 seconds. Add this code to your instance init script.
instance = Instance.current()
instanceOid = Instance.currentOid()
braxMarker = instance.getMarker("mybraxmarker").clone()
braxMarker.getPoint().setY(0)
spawnData = SpawnData()
spawnData.setFactoryName("BraxFactory")
spawnData.setInstanceOid(Long(instanceOid))
spawnData.setLoc(braxMarker.getPoint())
spawnData.setNumSpawns(2)
spawnData.setSpawnRadius(30000)
spawnData.setRespawnTime(60000)
MobManagerClient.createSpawnGenerator(spawnData)
See World Instancing and multiverse.server.plugins.InstanceClient for more on instancing.
Add behaviors to a mob
If you want a mob to do something, you must add behaviors to it before you spawn it. multiverse.server.engine.BaseBehavior provides low level movement handling for mobs, to allow them to handle "goto" and "follow" commands from other behaviors. multiverse.server.engine.PatrolBehavior is a simple behavior that generates a "goto" command to make a mob follow a patrol route. You must add behaviors before spawning an object.
So, replace the behaviors from the BraxFactory with the following:
behav = BaseBehavior() obj.addBehavior(behav) behav = PatrolBehavior() behav.addWaypoint(Point(95926, 88657, 3846780)) behav.addWaypoint(Point(100956, 88657, 3846780)) behav.addWaypoint(Point(100956, 88657, 3859780)) obj.addBehavior(behav)
Additional behavior settings
For information about behavior settings, see these classes in the API:
-
multiverse.server.engine.BaseBehavior- provides basic movement behavior: moving to a particular location or following a mob. Responds to messages sent by other behaviors. -
multiverse.mars.behaviors.CombatBehavior- basic combat behavior. If something attacks, will cause mob to attack back, and so on. -
multiverse.server.engine.PatrolBehavior- moves in a set patrol pattern. -
multiverse.mars.behaviors.QuestBehavior- handles quest messages; required for any NPC that begins or ends a quest. -
multiverse.mars.behaviors.RadiusRoamBehavior- roams randomly within a circular area defined by a center point and radius.
For example, you can set additional PatrolBehavior settings:
behav = BaseBehavior() obj.addBehavior(behav) behav = PatrolBehavior() behav.setLingerTime(10000) behav.setMovementSpeed(10000) behav.addWaypoint(Point(95926, 88657, 3846780)) behav.addWaypoint(Point(100956, 88657, 3846780)) behav.addWaypoint(Point(100956, 88657, 3859780)) obj.addBehavior(behav)
Putting it all together
To add brax to your game world:
-
Copy
templates.py,mobserver.py, andinstance_load.pyfrommv-home/config/sampleworldtomv-home/config/world-name, where world-name is the name of the directory containing your terrain and game world files. - Edit
templates.py. Add the following lines of code before the last line:braxDC = DisplayContext() braxDC.setMeshFile("brax.mesh") braxDC.addSubmesh(DisplayContext.Submesh("Zombie_Body2-obj.0", "Zombie.Zombie_Body")) braxDC.addSubmesh(DisplayContext.Submesh("Zombie_Clothes2-obj.0", "Zombie.Zombie_Clothes")) tmpl = Template("Brax") tmpl.put(WorldManagerClient.NAMESPACE, WorldManagerClient.TEMPL_DISPLAY_CONTEXT, braxDC) tmpl.put(WorldManagerClient.NAMESPACE, WorldManagerClient.TEMPL_OBJECT_TYPE, ObjectTypes.mob) ObjectManagerClient.registerTemplate(tmpl) - In the World Editor, add a marker named "mybraxmarker" (or whatever you want to call it).
- You will also need to add markers for the Brax patrol route. The code assumes they're named "braxpatrol1", "braxpatrol2", and "braxpatrol3".
- Edit
mobserver.py. Add the following lines of code before the last line:class BraxFactory (ObjectFactory): def makeObject(self, spawnData, instanceOid, loc): obj = ObjectFactory.makeObject(self, spawnData, instanceOid, loc) braxPatrol1 = InstanceClient.getMarkerPoint(instanceOid, "braxpatrol1") braxPatrol2 = InstanceClient.getMarkerPoint(instanceOid, "braxpatrol2") braxPatrol3 = InstanceClient.getMarkerPoint(instanceOid, "braxpatrol3") behav = BaseBehavior() obj.addBehavior(behav) behav = PatrolBehavior() behav.setLingerTime(10000) behav.setMovementSpeed(10000) behav.addWaypoint(braxPatrol1) //## broken, var not defined behav.addWaypoint(braxPatrol2) behav.addWaypoint(braxPatrol3) obj.addBehavior(behav) return objAdd the following to the end of
instance_load.pybraxMarker = instance.getMarker("mybraxmarker").clone() braxMarker.getPoint().setY(0) spawnData = SpawnData() spawnData.setFactoryName("BraxFactory") spawnData.setInstanceOid(Long(instanceOid)) spawnData.setLoc(braxMarker.getPoint()) spawnData.setNumSpawns(2) spawnData.setSpawnRadius(30000) spawnData.setRespawnTime(60000) MobManagerClient.createSpawnGenerator(spawnData) - Start the server and log into your world. Use the "/setloc x y z" command if necessary to travel to the coordinates of the spawn generator. You should see two brax running around.
