RolePlayingDesign: Difference between revisions

From Arianne
Jump to navigation Jump to search
Content deleted Content added
No edit summary
Added new
Line 17: Line 17:
* IRPRuleProcessor is the interface that you need to implement in order to personalize the actions to execute.
* IRPRuleProcessor is the interface that you need to implement in order to personalize the actions to execute.
* RPWorld that is the class that you need to extend to implement the onInit and onFinish in order to personalize what happens when you init the server and what happens when you close the server.
* RPWorld that is the class that you need to extend to implement the onInit and onFinish in order to personalize what happens when you init the server and what happens when you close the server.
* IRPZone is a interface that you ''could'' implement to achive the highest personalization possible of the engine, I would instead use MarauroaRPZone that implements our great feature Delta^2.
* IRPZone is a interface that you ''could'' implement to achive the highest personalization possible of the engine, I would instead use MarauroaRPZone that implements our great feature Delta<sup>2</sup>.




Line 27: Line 27:
* control AI
* control AI


As you see this is a HUGE class that is complex. So the idea is to split this behavior into smaller subclasses.
As you see this is a HUGE taks that is complex. So the idea is to split this behavior into smaller subclasses.


RPManager provides a simple interface to the GameManager for using it:
RPManager provides a simple interface to the GameManager for using it:
* addRPAction
* addRPAction
* getRPObject
* addRPObject
* onInit Player
* removeRPObject
* onExit Player
* hasRPObject
* transferContent


addRPAction simply queues an action for that player to be executed on the next turn.
addRPAction simply queues an action for that player to be executed on the next turn.


addRPObject, removeRPObject and hasRPObject is a interface to manage RPWorld.
getRPObject is a interface to manage RPWorld to ease the adquisition of the RPObject when exiting the game.

onInit and onExit are callback functions that are used by GameManager to notify that a player has entered the game or that a player has exit the game.

transferContent is a callback function too that is called by RPRuleProcessor to stream content to players.


The main outline of RPManager could be:
The main outline of RPManager could be:
Line 44: Line 49:
{
{
Procced through every action in this turn
Procced through every action in this turn

Build Perception
Build Perception
Remove timed out players
Remove timed out players

Revision as of 09:50, 8 February 2005

It is perhaps the most complex part of all the middleware that compromises Arianne.
Role Playing Design determines how easy is to create a new game for Arianne. We had to choose easing the creation of turn time limited based games, so Arianne will work better with that kind of games, also known as realtime games.

Role Playing Desing anyway tries to keep generic and game agnostic. The very basic idea behind RPManager is:

  forever
    {
    Execute Actions
    Send Perceptions
    Wait for next turn
    }

To achieve this we use several classes:

  • RPManager that is coded in the Marauroa and don't need to be modified.
  • IRPRuleProcessor is the interface that you need to implement in order to personalize the actions to execute.
  • RPWorld that is the class that you need to extend to implement the onInit and onFinish in order to personalize what happens when you init the server and what happens when you close the server.
  • IRPZone is a interface that you could implement to achive the highest personalization possible of the engine, I would instead use MarauroaRPZone that implements our great feature Delta2.


RPManager

The goal of RP Manager is to handle the whole RP game. This means mainly:

  • run RPActions from clients
  • manage RPWorld
  • control triggers for events
  • control AI

As you see this is a HUGE taks that is complex. So the idea is to split this behavior into smaller subclasses.

RPManager provides a simple interface to the GameManager for using it:

  • addRPAction
  • getRPObject
  • onInit Player
  • onExit Player
  • transferContent

addRPAction simply queues an action for that player to be executed on the next turn.

getRPObject is a interface to manage RPWorld to ease the adquisition of the RPObject when exiting the game.

onInit and onExit are callback functions that are used by GameManager to notify that a player has entered the game or that a player has exit the game.

transferContent is a callback function too that is called by RPRuleProcessor to stream content to players.

The main outline of RPManager could be:

forever
  {
  Procced through every action in this turn

  Build Perception
  Remove timed out players

  Wait for Turn completion.
  Go to Next Turn
  }

RPScheduler is the class that handles actions to be queued for each player. All the complexity of Action management should be handled here.

RuleProcessor is a wrapper class for hide actions code. All the actions code MUST be here, this class also acts as a Action code loader, as some actions are not part of Marauroa, but scripts.


Actions and Objects

The whole Marauroa system is managed by two main entities, RPAction and RPObject

Actions

To express the willing of a client to do something it must send the server a MessageC2SAction message.

An action is composed of several attributes, an attributed is similar to a variable that has a name and contains a value.

There are optional and mandatory attributes. If a mandatory attribute is not found, the message is skipped by the RPServerManager.

Mandatory Actions Attributes are action_id and type.

The action_id is used to identify the action when a resulting response comes in a perception

Optional Actions Attributes: (Read "Actions Explained" for more details.)

Objects

The containers of information of the whole Marauroa server are RPObjects. An object is composed of several attributes, an attribute is similar to a variable that has a name and contains a value and also it is composed of Slots. A Slot is a container or array of containers that the object has to host other objects inside it.

Mandatory Object Attributes: id, type and zoneid

id is an unique identification for the Object and zoneid is the identification for the zone where the object resides and type is the type of the object aka class, so that you can share attributes for all the instances of the class.

An id is only unique inside the zone which contains that object.

Also engine give special treatment to two types of attributes: - Attributes that begin with ! are completely hidden for all the users but the owner of the object. - Attributes that begin with # are completely hidden for all the users.

Classes of Objects Explained

Classes of Objects are the basic way of structuring Marauroa data structures.

A class defines types of the attributes and its visibility and gives it an internal code that is used to speed up searchs and save bandwidth. You can base a class on another, this feature is known as inheritance.

The data types available are:

  • Strings
  • Short strings ( up to 255 bytes )
  • Integers ( 4 bytes )
  • Shorts ( 2 bytes )
  • Byte ( 1 byte )
  • Flag ( it is a binary attribute )

Attributes can also be visible if clients see them when they change, or invisible if clients can't see them.

Slots

As you know Objects can contain inside another object much like you have the keys inside your pocket. The goal of Slots is to provide a richer game play while reducing the number of object in the zone.

To have these objects inside, we need our hoster object to have slots to place them. One slot can only handle one single object.

For example a avatar can have: - left hand - right hand - backpack - left pocket - right pocket

and we can store objects on these slots.

Once the object is stored inside the avatar or another object, the only way of accessing it is through the object that contains our stored object.


How Perceptions and Actions work

Actions are sent from client to server in order to make their character to do an action. In order for the client to know the result of the action Server need to send it to client. How?

On a first try, we used to send client back an action that was the result, but make code really hard because we had to update to different things, perceptions and actions, so the idea appeared intuitively: Why not join action reply and perceptions.

So the action reply is stored inside each object (that executed the action ) with a set of attributes that determine the action return status and the attributes. This way of working make a bit harder to RPManager but it simplify a lot the creation of new clients.

See Actions reply in Objects document to know exactly what is returned, but keep in mind that it depends of each particular game.

Delta perception Algorithm

The main idea behind the DPA is not to send ALL the objects to client, but only those that has been modified.

Imagine that we have 1000 objects, and only O1 and O505 are active objects that are modified each turn. Ok?

Traditional method:

- Get objects that our player should see ( 1000 objects )
- Send them to player ( 1000 objects )
- Next turn
- Get objects that our player should see ( 1000 objects )
- Send them to player
- Next turn
...

I hope you see the problem..., we are sending again objects that never changed.

The delta perception algorithm:

- Get objects that our player should see ( 1000 objects )
- Reduce the list to the modified ones ( 1000 objects )
- Store also the objects that are not longer visible ( 0 objects )
- Send them to player ( 1000 objects )
- Next turn
- Get objects that our player should see ( 1000 objects )
- Reduce the list to the modified ones ( 2 objects )
- Store also the objects that are not longer visible ( 0 objects )
- Send them to player ( 2 objects )
- Next turn
...

The next step on delta perception algorithm is pretty clear: delta^2 The idea is to send only what changes of the objects that changed. That why you save even more bandwidth, making perceptions around 20% of the delta perception size.

The delta^2 algorithm is based on four containers:

  • List of added objects
  • List of modified added attributes of objects
  • List of modified deleted attributes of objects
  • List of deleted objects

An area really related to DPA is RPZone

Well, as you should know, MPEG adds a full frame each X number of frames, so it can be used as synchronization in case the file get corrupted. The idea is that if you fail to continue decompressing data, you can always omit things until the next full frame and then when you synced. The idea here is similar, if we fail to synchronize with server we send him a Out of Sync Message so that server will send a sync perception so that clients can synchronize, as UDP is not a secure transport.

To make perception works it is important to call the modify method on RPZone so this way objects modified are stored in the modified list.


Zones and Worlds

Objects must be stored somewhere, and we use Zones now to store them. A zone is just a container of Objects.

In order to improve the modifiability of the Marauroa platform we have made RPZone to be an interface so that if you want you can implement it as you think it is more efficient.

The actual Marauroa RP Zone consists of several data structures:

  • a HashMap of RPObject.ID to RPObject
  • a List of RPObject
  • a Perception

The idea is to have already computed in the Zone the perception so saving LOTS of time that would be needed to generate it. All the data structures contain the same objects, but the hashmap is used to fast search of objects using its RPObject.ID, this is the most usual way for locating the object. List is used to improve the time required to build a total perception. And well, we used perception to pre-calculate the delta perception.

Actually the perception is the same for all the players on the Zone.

In order to make perceptions work, you have to manually call modify method so that you notify the zone about changes in a character.