Code Examples

This section just has a whole bunch of sample code, taken right out of the game. We don't go into enormous detail about the examples - they're here for you to browse and study, but we've focused more on quantity of code than on quality descriptions.

Keep in mind that many of these objects have undergone revisions or bug fixes since we uploaded the code. We'll try to keep them up to date if there are major fixes, but there's no guarantee the real versions of these objects work exactly like this in the game. These are here as tutorials, not spoilers.

Contents

Objects

This section has a few different magical game objects that are implement in Jython.


Cloak of Invisibility

Here's a very simple piece of armor, the Cloak of Invisibility. This cloak makes you invisible when you put it on.

We can't quite use a simple archetype for the cloak, because it has to visually update the wearer (on everyone's screen) when it is worn or removed. So we create a tiny Jython class for it. Here's the source code The class has the following parts:

Notice that in the initialize method, we set "bonus-invisible", which tells it to increment the wearer's "invisible" property when it's worn (and decrement it when it's removed). We also set an "invisible" property, because the cloak itself is invisible.

That's it! All of this could have been done using an archetype, except that we needed that setWorn() function to call the agent's invalidate() method so the screen updates when the agent wears or removes it.


Horn of Plenty

This magical object produces a random piece of food when you apply it. It's a more complicated example. View the source code.

You'll notice a few differences from the Cloak of Invisibility:

The key trick to this class is generating a random piece of food. It does so by calling Kernel.instantiate('random/random_food'). The result is a RandomObject, from package wyvern.lib.classes.random. When you create a RandomObject, you need to invoke the generate() method on the object to turn it into a real game object (in this case, a piece of food). You'll see Kernel.instantiate() a lot, and you'll probably use RandomObjects a lot too.


Crystal Ball

This is a fairly complicated object. It lets you type "view" and a player's name, and you can spy on the player. It uses some of the game's fancy extension mechanisms to do this trick.

View the source code.

The key concepts in this class are:

The crystal ball is a pretty complicated example, and we include it so you can see just how powerful the game engine is when it needs to be.


Amulet of Lifesaving

The Amulet of Lifesaving listens for when you die, and prevents it. After it saves your life, it crumbles to dust.

The source code for this is amulet_lifesaving.py. This object is a simple HookCallback - it gets on the death pre- and post-hooks. It uses the deathPreHook to veto your death, and it uses the deathFailedPostHook to crumble away and restore your HP and SP.

We could have done everything on the deathPreHook. The only reason we wait to save their life on the deathFailedPostHook is that there's a (remote) possibility that another HookCallback, also on the deathPreHook, would want to prevent the amulet from working. So we respect that and only do our work when we know our veto was successful.

Keep in mind that having multiple HookCallbacks for the same pre-hook is not guaranteed to work the same way every time, since the callback objects could be invoked in any order. So it's a pretty rare case we're coding for here - it might have been better to have used the deathPreHook for everything.


Staff of Striking

View the source code.

The Staff of Striking is a silly artifact that makes the player think they're doing tons of damage, when in fact it's not doing much at all.

It's also a HookCallback, and it works by hooking the damagePreHook and changing the damage message before the event is executed.


Traps

Traps almost all function the same way - they have a steppedOn method that gets called when a player or monster triggers the trap.

Anti-Magic Trap

View the source code.

The main concepts are:

That's all there is to it!

Magic Trap

This is a much more complicated trap. When you step on it, it produces random magical effects - some good, some bad.

View the source code.

The main concepts are:

This trap is definitely more involved, and demonstrates different features of the game engine.


Spells

This section has a bunch of spell examples. Nearly all the spells in the game (well over 100 of them) are written in Jython. The spells all inherit from the base class wyvern.lib.classes.magic.Spell, which has utility functions for propagating the spell and damaging monsters.

There are several "area-effect" subclasses of Spell, including:

Many spells are timed, so they implement the Timed interface and set timers using the Kernel class.

All spells have one Art and one or more Elements. We try to code spells so that if you've got extra points in the Element(s) for that spell, it improves the spell effect.


Blink

This is one of the simplest spells you can cast. It teleports the player to a random, nearby location.

View the source code.

The main concepts are:


Firebolt

This spell is a pretty typical BoltSpell.

View the source code.

The main concepts are:


Firespray

This spell is a pretty typical ConeSpell.

View the source code.

The main concepts are:

Again, pretty simple. Damaging the monsters is all taken care of by the superclass - you just have to make sure you've set the weapon class for the spell.


Free Action

This spell makes the caster temporarily immune to being slowed or paralyzed.

View the source code.

The main concepts are:

The spell also checks the agent's skills in the spell's elements, and makes it slightly better if they have those skills.


Destruction

This powerful spell does magic damage to every monster within a certain distance of the caster.

View the source code.

The main concepts are:

We coded the spell so that it only damages each monster once. However, when the spell loops through every location, it will find large monsters more than once. So we create a cache, using a java.util.HashSet, and put the monsters in the cache when we damage them. We don't damage a monster that we find in the cache.


Enchant Weapon

This spell permanently improves a weapon by increasing its accuracy and damage.

View the source code.

The main concepts are:

If we blow up the weapon, it invokes the WieldCommand (from package wyvern.kernel.combat) to force the weapon to become unwielded. This is the proper way to unwield a weapon - if you don't do it this way, the player will not be able to wield anything else during that session.


Static Blade

This spell puts a powerful electric charge on a weapon, which discharges the first time the weapon hits a monster.

View the source code.

The main concepts are:


Pacify

This spell stops a hostile monster in its tracks. The monster will stop attacking until it's attacked again. It's a fairly complicated spell.

View the source code.

The main concepts are:

How would you have known how to code the spell this way? The answer is (hopefully) that the combat system classes are thoroughly documented, and they tell you what properties they set and what actions can be hooked and vetoed.


Miscellaneous

Here are some jython classes that don't fit into any particular category.

Speech Filter

View the source code.

This is a speech filter that makes you quack like a duck. Speech Filters are simple to use - you just add one to a player's property list, using any name, and they just work.

A Speech Filter only has one required method - applyFilter(), which takes the string to filter, and returns the filtered version.

This filter is uncomplicated, but you can imagine all sorts of filters that do fancier things to the player's speech.

Dungeon Populator

View the source code.

This is a utility class that Kiz wrote for populating a map with random monsters of the appropriate level. You just drop one into your map and it'll create monsters.

There's still some debugging code in there, commented out.

Java Examples

Following are some examples of how to do things in the game, where we didn't have any Jython code handy, so we're just including a sample in Java instead. The syntax is different, but the basic approach is the same.

Halfling Skills

View the source code.

This is a simple Skill object that gives halflings the "hide" and "unhide" commands, which turn invisibility on and off. The basic approach for creating a Skill is to code a class that implements AddRemoveNotify, and then code a way to have an instance of your class added to the player's property list.