topnav

XML: The Core of the Skotos StoryBuilder Server

Whys, Hows, and Wherefors

There's a new buzz word going around the Internet community right now. It's XML, which is short for the eXtensible Markup Language. It's a close cousin to HTML, the markup language at the heart of most Internet web pages.

The Skotos StoryBuilder Server is built upon XML. Whenever a StoryBuilder creates anything – be it an object, like a person, place or thing, or a part of speech, like a verb or an adverb, or even a help file – an XML file is created. StoryBuilders can choose to edit the raw XML files or they can choose to use slightly prettier web-based interfaces – but in either case, it's always there.

There are a number of documents available on XML – from books to websites. http://dir.yahoo.com/Computers_and_Internet/Data_Formats/XML/ offers a good starting point. Rather than trying to explain the format, this article talks about our reasons for adopting it and how we've modified the basic ideas, and also give an example of our usage.

XML: Why

Skotos Tech isn't using XML because it's sexy, nor because it will allow us to communicate with other companies running XML, nor because it might help us getting funding. These factors aren't particularly relevent to the online gaming industry.

Instead, we are using XML because it precisely meets our goals as a company. We want to make the creation of online games very accessible to game designers who aren't programmers. By the end of 2001, we want to become a GeoCities or an EditThisPage, but for online games. We want to empower users who couldn't otherwise create massively multiplayer online games by providing them with a simple method to do so – and XML allows that.

With our XML-backed StoryBuilder Server, game designers will be able to create very complex objects and add additional behaviors to objects without engineering assistance. However, we feel that the advantages of XML don't stop there. It offers us numerous other perks:

  • XML will allow consistency. Everything in our games is an object, and every object can be represented in XML.
  • XML can easily be parsed and then output via web forms. This gives designers an even simpler way to develop their game.
  • XML objects can be exported from one game server and imported to another. This is crucial because we expect to have tens of games sharing the same core libraries.
  • XML can be edited offline. Thus, a constant, high-speed connection to the net is not required for our game designers.
  • XML is ... extensible. We've already created a very simple programming language in XML that we call Active Markup; it supports <if></if>, <foreach></foreach> and other simple commands. We've also begun to implement XML-RPC, which will allow one game server to talk to another directly.

XML: How

Though we have used XML as a general model, we haven't stuck rigidly to the XML specifications. Instead, we've struck a middle ground which we think is ideal for our games. A few notes on how our XML differs from the specs:

Headers & DTD. We don't at this point do all the proper header things for the top of a standard XML file, such as xmlns:edi='http://www.skotos.net/schema'.

In addition, we don't use proper DTDs internally. We didn't like DTDs when we started because they themselves could not be described in XML, so instead we created something we call the SID (State Information Database).

The SID is in XML and serves a similar purpose to DTDs. SID is an explicitly objectstate-oriented expansion of the DTD concept. It include a variety of useful information, including what functions are called to populate the data tags. Now that some schema proposals are reaching maturity we'll consider switching out SID at some point and using one of them instead.

Attributes. Since we have a lot of people editing the XML by hand, we use attributes more than seems to be the norm with XML.

For example, a fairly standard XML tag in our system would be:

<description type="brief">
    frog
</description>

The standard approach seems to be:

<description> 
  <type>
      brief
  </type> 
  <content>
      frog
  </content> 
</description> 

To be honest, we're not precisely sure why others do things the latter way.

And Other Stuff. Though we're using the basic ideas of XML, we haven't poured over the XML specs in ultimate detail. We don't actually need to comply to the XML specs. Thus there may well be other things we do in our system that's off-spec.

XML: An Example

Our first online game, Castle Marrach, had its beta launch on September 21, 2000. It includes over 10,000 XML-described objects and ultimately may handle 100,000 or more objects.

Below is the XML of a fairly simple item in Castle Marrach – a sword. Other objects, especially rooms and players, can be much more complex. This sword is a fairly accessible example.

Note that the sword contains descriptions for a number of different "details" that the players can investigate. Besides the prime detail (the sword), there's a blade, a grip, a guard, and a pommel. In addition, a number of names and adjectives are supported for each detail. There's also information on allowable prepositions (other objects may be put "near" the sword, but not "under" it), weight, combat stats, and much more.

And the whole thing is readable to a non-programmer, especially if parsed into web forms, which was the whole point of the exercise.

<object id="OBJ(Marrach:Props:sword-solaris)">
<context/>
<Base:Thing>
  <Ur:UrObject/>
  <Base:Misc gender="neuter" volition="false" weapon="true">
    <Base:Edible value="false"/>
    <Base:Potable value="false"/>
    <Base:ClothesExpected value="false"/>
    <Base:DieMessageFirst/>
    <Base:DieMessageThird/>
  </Base:Misc>
  <Base:Events/>
  <Base:Details>
    <Base:Detail id="sword-solaris" prime="true" def="false" abstract="false"
hush="0">
      <Base:Preposition close="true" against="true" under="false" on="true"
inside="false" near="true" over="false" behind="false" before="true"
beside="true"/>
      <Base:Names>
        <Base:Name sname="sword" pname="swords"/>
        <Base:Name sname="weapon" pname="weapons"/>
      </Base:Names>
      <Base:Adjectives>
        <Base:Adjective adjective="broad"/>
        <Base:Adjective adjective="huge"/>
        <Base:Adjective adjective="long"/>
        <Base:Adjective adjective="straight"/>
        <Base:Adjective adjective="two-hand"/>
        <Base:Adjective adjective="two-handed"/>
        <Base:Adjective adjective="two-hander"/>
      </Base:Adjectives>
      <Base:Descriptions>
        <Base:Description type="brief">
             huge two-handed sword
        </Base:Description>
        <Base:Description type="examine">
             This is a huge, straight-bladed two-handed sword, with a leather
wrapped grip, spherical pommel, and straight guard. It is about 59 inches long
overall. There is something inscribed on the rusty blade.
        </Base:Description>
        <Base:Description type="look">
             You look at the rusty two-handed sword.
        </Base:Description>
      </Base:Descriptions>
      <Base:Exit door="false"/>
    </Base:Detail>
    <Base:Detail id="blade" prime="false" def="false" abstract="false"
hush="0">
      <Base:Preposition close="true" against="true" under="false" on="true"
inside="false" near="true" over="false" behind="false" before="true"
beside="true"/>
      <Base:Names>
        <Base:Name sname="blade" pname="blades"/>
        <Base:Name sname="edge" pname="edges"/>
        <Base:Name sname="tip" pname="tips"/>
        <Base:Name sname="point" pname="points"/>
        <Base:Name sname="inscription" pname="inscriptions"/>
      </Base:Names>
      <Base:Adjectives>
        <Base:Adjective adjective="dented"/>
        <Base:Adjective adjective="dinged"/>
        <Base:Adjective adjective="huge"/>
        <Base:Adjective adjective="rust-covered"/>
        <Base:Adjective adjective="rusted"/>
        <Base:Adjective adjective="rusty"/>
        <Base:Adjective adjective="sharp"/>
        <Base:Adjective adjective="steel"/>
        <Base:Adjective adjective="straight"/>
        <Base:Adjective adjective="sword"/>
        <Base:Adjective adjective="tapered"/>
        <Base:Adjective adjective="tapering"/>
        <Base:Adjective adjective="two-hand"/>
        <Base:Adjective adjective="two-handed"/>
        <Base:Adjective adjective="two-hander"/>
        <Base:Adjective adjective="weapon"/>
      </Base:Adjectives>
      <Base:Descriptions>
        <Base:Description type="brief">
             two-hand sword blade
        </Base:Description>
        <Base:Description type="examine">
             The rusty, dinged, dented steel blade of this two-handed sword is
about 46 inches long; it has, however, been kept sharp on both edges. It has a
flat diamond cross section without taper, and comes rapidly to a point in the
final three inches or so. The word 'Solaris' is inscribed in archaic letters on
the blade.
        </Base:Description>
        <Base:Description type="look">
             You look at the long, rusty steel blade of the two-handed sword.
        </Base:Description>
        <Base:Description type="taste">
             The blade tastes rusty and sharp!
        </Base:Description>
      </Base:Descriptions>
      <Base:Exit door="false"/>
    </Base:Detail>
    <Base:Detail id="grip" prime="false" def="false" abstract="false" hush="0">
      <Base:Preposition close="true" against="true" under="false" on="true"
inside="false" near="true" over="false" behind="false" before="true"
beside="true"/>
      <Base:Names>
        <Base:Name sname="grip" pname="grips"/>
        <Base:Name sname="handle" pname="handles"/>
        <Base:Name sname="leather" pname="leathers"/>
        <Base:Name sname="wrapping" pname="wrappings"/>
      </Base:Names>
      <Base:Adjectives>
        <Base:Adjective adjective="huge"/>
        <Base:Adjective adjective="leather"/>
        <Base:Adjective adjective="leather-wrapped"/>
        <Base:Adjective adjective="stained"/>
        <Base:Adjective adjective="sword"/>
        <Base:Adjective adjective="tight"/>
        <Base:Adjective adjective="tightly-wrapped"/>
        <Base:Adjective adjective="two-handed"/>
        <Base:Adjective adjective="two-hander"/>
        <Base:Adjective adjective="weapon"/>
      </Base:Adjectives>
      <Base:Descriptions>
        <Base:Description type="brief">
             sword grip
        </Base:Description>
        <Base:Description type="examine">
             The grip of the two-handed sword (between the guard and the
pommel) is about ten inches long, and tightly wrapped with stained leather.
        </Base:Description>
        <Base:Description type="look">
             You look at the leather-wrapped grip of the two-handed sword.
        </Base:Description>
        <Base:Description type="taste">
             The grip tastes of sweat and leather.
        </Base:Description>
      </Base:Descriptions>
      <Base:Exit door="false"/>
    </Base:Detail>
    <Base:Detail id="guard" prime="false" def="false" abstract="false"
hush="0">
      <Base:Preposition close="false" against="false" under="false" on="false"
inside="false" near="false" over="false" behind="false" before="false"
beside="false"/>
      <Base:Names>
        <Base:Name sname="guard" pname="guards"/>
        <Base:Name sname="bar" pname="bars"/>
      </Base:Names>
      <Base:Adjectives>
        <Base:Adjective adjective="dented"/>
        <Base:Adjective adjective="dinged"/>
        <Base:Adjective adjective="huge"/>
        <Base:Adjective adjective="rusted"/>
        <Base:Adjective adjective="rusty"/>
        <Base:Adjective adjective="square"/>
        <Base:Adjective adjective="steel"/>
        <Base:Adjective adjective="straight"/>
        <Base:Adjective adjective="sword"/>
        <Base:Adjective adjective="two-handed"/>
        <Base:Adjective adjective="two-hander"/>
        <Base:Adjective adjective="weapon"/>
      </Base:Adjectives>
      <Base:Descriptions>
        <Base:Description type="brief">
             sword guard
        </Base:Description>
        <Base:Description type="examine">
             The guard of the sword is a rusty, dinged and dented square steel
bar about thirteen inches long, at right angles to and between the grip and the
blade itself.
        </Base:Description>
        <Base:Description type="look">
             You look at the straight steel guard of the two-handed sword.
        </Base:Description>
        <Base:Description type="taste">
             The guard tastes rusty.
        </Base:Description>
      </Base:Descriptions>
      <Base:Exit door="false"/>
    </Base:Detail>
    <Base:Detail id="hilt" prime="false" def="false" abstract="false" hush="0">
      <Base:Preposition close="true" against="true" under="false" on="true"
inside="false" near="true" over="false" behind="false" before="true"
beside="true"/>
      <Base:Names>
        <Base:Name sname="hilt" pname="hilts"/>
      </Base:Names>
      <Base:Adjectives>
        <Base:Adjective adjective="dented"/>
        <Base:Adjective adjective="dinged"/>
        <Base:Adjective adjective="huge"/>
        <Base:Adjective adjective="rusted"/>
        <Base:Adjective adjective="rusty"/>
        <Base:Adjective adjective="simple"/>
        <Base:Adjective adjective="sword"/>
        <Base:Adjective adjective="two-handed"/>
        <Base:Adjective adjective="two-hander"/>
        <Base:Adjective adjective="weapon"/>
      </Base:Adjectives>
      <Base:Descriptions>
        <Base:Description type="brief">
             two-handed sword hilt
        </Base:Description>
        <Base:Description type="examine">
             The hilt of this two-handed sword consists of a leather-wrapped
grip, a straight guard (between the grip and the blade) and a spherical pommel.
The leather is stained, the metal is rusty, dinged and dented.
        </Base:Description>
        <Base:Description type="look">
             You look at the simple hilt of the two-handed sword.
        </Base:Description>
        <Base:Description type="taste">
             The sword hilt tastes rusty and sweaty.
        </Base:Description>
      </Base:Descriptions>
      <Base:Exit door="false"/>
    </Base:Detail>
    <Base:Detail id="pommel" prime="false" def="false" abstract="false"
hush="0">
      <Base:Preposition close="true" against="true" under="false" on="true"
inside="false" near="true" over="false" behind="false" before="true"
beside="true"/>
      <Base:Names>
        <Base:Name sname="pommel" pname="pommels"/>
        <Base:Name sname="sphere" pname="spheres"/>
      </Base:Names>
      <Base:Adjectives>
        <Base:Adjective adjective="huge"/>
        <Base:Adjective adjective="plain"/>
        <Base:Adjective adjective="round"/>
        <Base:Adjective adjective="spherical"/>
        <Base:Adjective adjective="steel"/>
        <Base:Adjective adjective="sword"/>
        <Base:Adjective adjective="two-handed"/>
        <Base:Adjective adjective="two-hander"/>
        <Base:Adjective adjective="weapon"/>
      </Base:Adjectives>
      <Base:Descriptions>
        <Base:Description type="brief">
             two-handed sword pommel
        </Base:Description>
        <Base:Description type="examine">
             The pommel of this two-handed sword is a rusty, dented steel
sphere, about an inch across.
        </Base:Description>
        <Base:Description type="look">
             You look at the spherical steel pommel of the two-handed sword.
        </Base:Description>
        <Base:Description type="taste">
             The pommel tastes rusty.
        </Base:Description>
      </Base:Descriptions>
      <Base:Exit door="false"/>
    </Base:Detail>
  </Base:Details>
  <Base:Bulk>
    <Base:Mass value="2.3"/>
    <Base:Density value="7.8"/>
    <Base:Capacity value="0"/>
    <Base:LDim value="1.5"/>
    <Base:MaxWeight value="0"/>
    <Base:MaxFA value="0"/>
    <Base:MaxDepth value="0"/>
  </Base:Bulk>
  <Base:Combat>
    <Base:Strength value="1"/>
    <Base:MaxFatigue value="100"/>
  </Base:Combat>
  <Base:Clothing>
    <Base:Covered value="right-hand"/>
    <Base:SingleWear value="false"/>
  </Base:Clothing>
  <Base:Container>
    <Base:ContainerVerbSecond/>
    <Base:ContainerVerbThird/>
  </Base:Container>
  <Notes:Notes/>
  <Ur:UrChildren>
    <Ur:UrChild urchild="OBJ(/base/obj/thing#5371)"/>
  </Ur:UrChildren>
</Base:Thing>
</object>
your opinion...