13sep09 CmdrZin

ref1: ver. 05/29/09  

Making my first Managed Object for PDS

The goal is to devleop a Server managed object that will store Player information that changes based on Player and game server actions. Other reasons that the information is stored on the Server is to provide persistance to the information and that the Client is untrusted. The ManagedObject class is used to provide an information object that the Server can manage.

As alway, the first thing to do is to gather information on how to add ManagedObject to the Server. In ref1, pages 3, starts discussing Managed Objects and Managed References. Seems like a good place to start.

Managed Objects and Managed References

Managed Objects (MOs) are created and accessed using the Data Manager (see ref1: pag 1). They are manitained in a Object Store managed by the data base manager that is built into the Server.
All MOs must implement the ManagedObject and Serializable interfaces.

Example (ref1: pg 52)
    public class SwordWorldObject implements Serializable, ManagedObject

The Managed Reference (MR) for the MO is provided through the Data Manager. The MR is what is passed around, stored on inventory lists, and otherwise used to reference the object stored in the data base. Access to the MO is through the MR which is provided by the Data Manager getForUpdate and get methods. (see ref1: pg3) A String can also be associated to the MO to allow it to be access using the getBinding method of the Data Manager.
In general, use get if the MO is not going to be modified and use getForUpdate if it is. Makes sense.
One last point, the application has to manage the life cycle of the MO. Call removeObject, or removeBinding as needed, to delete a MO from the data base or the data base will fill up with garbage consisting of leftover MOs.


For the Zombies, Mutants, and Undead oh My game, the Player information in the MO will consist of four lists: Stats, Skills, Inventory, and Assignments. Each list will store String:Value pairs as entries. These entries will be used to reference an external data base (probably a MySQL server) to retreave more detailed information about the entry. This information remains static throughout the game and is common to all Players. The MO list Value elements are the primary things that change during the game other than adding or deleting an entry pair to or from the list.
The MO must also be associated to the Player Managed Object. This looks like a good time to go into the game code to see how it manages the Player MO.

Code Review

The game manages the Player as a MudUser object which extends MudCharacter which extend MudObject which implements the ManagedObject and Serializable interfaces. It seems the most powerful way to add the lists to the Mud User MO is to add them at the Mud Object level. This allows the list information to used in different ways depending on the game object being referenced. Here's the concept.

An Item's Lists

    Stats: These are the characteristics of the item such as weight, cost, attack damage, defense armor, brightness, etc.
    Skills: This list would contain skill boost values, require skill to use, and othe skill effects.
    Inventory: For a gun, this could be ammo left. For a battery, it could be minutes left of charge. etc.
    Assignments: This list could indicate what Assignments this item is used for or none at all.

A Door's Lists

    Stats: Toughness, security level, etc.
    Skills: Any special skill needed to open or disable the door.
    Inventory: May be a lock, broken of repaired that could bar the door or leave it open.
    Assignements: May not be applicable.

A Player's Lists (the most used)

    Stats: Specialty, Health, Strength, Intelligence, Agility, Attack, Damage, Defense, Weapon equipt, etc.
    Skills: Perception, Insight, Lock Pick, Chemistry, Electronics, Computers, etc.
    Inventory: 9mm Piston, Flak Vest, rope, flash light, helmet, etc.
    Assignements: Assignment Number (as a String) used as an ID.

Proposed code changes to based on current code
  private final Set<ManagedReference> inventory = new HashSet<ManagedReference>();
will be to add
  private final Set<ManagedReference> listStats = new HashSet<ManagedReference>();
  private final Set<ManagedReference> listSkills = new HashSet<ManagedReference>();
  private final Set<ManagedReference> listInventory = new HashSet<ManagedReference>();
  private final Set<ManagedReference> listAssignments = new HashSet<ManagedReference>();
These are all now HashMap<Integer, Integer> lists. A static DataBase class is used to retrieve the name String for the key (the first Integer) and the value (the second Integer) is used depending on the list. Most of the time it is the quantity or level of the key reference.
The DataBase can be filled in at boot up from an external data base, text files, or properties files. For now, it is loaded by code.

And similar to the way current inventory is handled, these methods will be added:
  public void addToList(ListType list, MudObject object)
  public void removeFromList(ListType list, MudObject object)
  public Set<MudObject> getInventory(ListType list)
  public Set<MudObject> getInventory(ListType list, boolean showInvisible)
  public boolean isInList(ListType list, MudObject object)
and an emun set to select which list to access {STATS, SKILLS, INVENTORY, ASSIGNMENTS} will also be needed.
This can all be added without disrupting the current game system.
NOTE: Since the Client code hase been broken out of the main server project to reduce the Web Start download time, in both projects has to be updated and kept in sync.

Since the items on the list are very simple and are not use anywhere else, a new class ListPair will be used instead of MudObject. (see new code)

ListPair class

This class has two atributes: String name and Interger value.
It has these methods:
  public ListPair(String n, Integer v) for a constructor
  public String getName()
  public Integer getValue()
  public void setValue()
others may be added later.
NOTE: May switch String to Enum and use external data base to define name strings.

Sending Information to the Client

To start, may use the same process as the Help command, but the Status update may be more useful. has some .send code. Will have to modify Client receiveMessage to use first byte of message as flag.

On the Server side, MudUser.receivedMessage() receives incoming mesaages. It calls parse() and on to MudUser.parseInnerCommand(). Since the information needed for the GUI is about the Player, the messgage can be serviced at this level. A look at the code shows that "help", "inv", "logout", and "yell" are handled at this level.

A New Command "info"

The plan will be to have the Server generate a message that sends the Player information lists back to the Client when an "info" message is sent by the Client. The INVENTORY command will be used a model.
        Add to catch "info" message.
      } else if (command.getCommand().equals("info")) {
    Add to enum CommandType list
    In the second half, add
    } else if ((command.getInvoker() == this) &&
               (command.getType() == CommandType.INFO)) {
Add a processInfoCommand() to (see code)


For this method, processInventoryCommand() was copied and used as a template. The main thing to do is to use command.addOutput() to build up a message that the Client could extract the lists from. So, for right now, this method only sends back the full lists. Later, parameters will be added to allow specific list information to be sent back such as a description of an inventory item or a skill.
The message will start with an @ character to act as a start token, a # character will be used to seperate the lists, and a | to seperate the pairs. Since the contents are all String, Integer pairs (comma delimited), parsing the message should be no problem.
(see code for implementation)
This process can now be tested by typing "info" into the Client command line. The Server should return a test string for now and the lists after more code is added.
Test string:
    "@Health,100|Strength,23#Lock Pick,2"
    "@00Health,100|Strength,23#Lock Pick,2"
A two digit message type has been added to provide more flexibility in sending information back to the Client.

Project Notes
New project is ZMUohMyNB.jar
New boot file is ZMUohMyNB.boot is still used for the game.
The new launch command it then
    java -jar bin/sgs-boot.jar tutorial/conf/ZMUohMyNB.boot

Debug runs, Client running in localhost mode, command returns "You can't do that."
Other commands seem to work...tweak inventory response to make sure this code is running.
Ah..didn't update for new project name...
hmm...ListPair class causing problems on start up...may be it has to be at least Serializable..
didn't complain..try Client..WOO HOO..test string came back after using "info"..on the the Client
Checking in code ....ZMUohMyNB Rev 144 9/16/2009 9:16:02 PM


Since the ZMUohMyClient project is only used to build a lite-weight WebStart client, the plan will be to just copy any files change in the ZMUohMyNB server project into the it. A one-way process only. All development is to be done in the server project since it can launch the Client through NetBeans.

ZMUohMyNB (Client relative code changes)

So far: (changed) (added) (changed)

The MudClient.receivedMessage() method needs to be changed so that the INFO message (indentified by the @ character) can be intercepted and used to update the info lists rather then being sent to the general display area.
Currently, all messages are flagged as OUTPUT and sent through appendOutput() to the display.
        Add test for an @ as the first character in the message, if so route to ClientInfo.parse() for processing.
        (see code for details)
The boxRight is the ClientInfo object being used by the MudClient, so boxRight.parse() is what is called.
Code changes continue in and and discussion in NewClientForZMUohMy.html.

MudMain.loggedIn has an additional message (info) sent after welcome message now. has a buildAndSendInfoMessage() method that will build the info message from the Lists and send it to the Client.