World Instantiation

Reiv3r
edited April 2011 in Photon Server
I don't understand why MmoWorld in the Photon MmoDemo is instantiated. Or why it's called what it is.

Is there any specific reason why MmoWorld is just a group of subscriptions and properties and instantiated per peer? Wouldn't MmoWorldSettings be a better descriptor?

Also why is the IWorld Interface never instantiated?

Is there any reason why one wouldn't want to just create a 'World' and then 'Region' classes on server startup and use MmoWorldSettings to track where they are? Then add a struct to the Actor class containing information like "Region". Then when an actor is created they're added to a stack in the singleton IWorld class that's running. Need to get a set of actors really quick? Run through the stack.

Comments

  • MmoWorld is a GridWorld subclass; GridWorld implements IWorld; GridWorld is a collection of Regions.
    MmoWorld is NOT instantiated per peer, why do you think that?
    You can create the world at server startup. The demo just doesn't do it to make client development and testing more flexible.
    The main reason why regions don't have a list of actors is that a developer might think that accessing other actors is thread safe which is not the case. Actors run in the peer's fiber, in order to get any information from them you do either have go through their fiber or use locks or other thread safe mechanisms. The demo uses the fiber enqueue approach (publishing messages in a region does this).
  • That's amusing, I could have sworn I saw MmoPeer instantiating MmoWorld. So part of the Actor class actually contains the IWorld that actor presides in?

    Also why isn't accessing Actors thread safe?

    Right now I have some untested code where I /did/ extend IWorld and instantiate it at server setup. (Singleton pattern), would it be unsafe to make a reference to every MmoPeer in an AssetCache (Implementation of ItemCache) and access them to get their WorldStats (A class of properties containing their Rotation, Position, UID, Username, Etc)?
  • Yes, that would not be thread safe.
    Every peer runs in its own "thread", and so does the peer's actor and all of his items.
    This allows actors/items to move at the very same time.
    You cannot iterate over a list of peers and expect them to provide thread safe data if they change it at the very same time.
    So you would either have to use a different model where peers don't change positions at the same time (e.g. by using one giant loop that updates all positions in an interval) or work with snap shots instead of the current position - or use locks around position reads/writes where you run into danger of causing deadlocks. The mmo demo uses snap shots when exchanging position data, so you could use those to maintain a "world state".
  • I see. Silly non-parallel programming.

    So the model of looping through peers isn't a bad one, it's just that the data needs to not be changed while it's being read or written to. So in an ideal situation I should actually include a method that accesses the data on the assets without breaking thread safety.

    So, like you suggested, instead of looping through these threads, a better method would be to maintain a 'world state' of snapshots of the data from these threads? Maybe by implementing a subscription to the threads themselves so that they will actually save new data to the world state on events triggered by the IWorld implementation (The singleton pattern class I mentioned).

    I'm trying to accomplish a 'cache' of data and centralize some things in the MmoCore because of the way I want to access data, essentially. (Rather than running things from the MmoPeers and threads themselves, I'd like a lot of code to be runnable out of the threads).

    Edit:

    In addition, I'm not used to concurrent state programming so reading through this code is incredibly difficult for me. So that's pretty much why I want to keep operations and events threaded, but not world states. The world state has its own thread through the singleton class. The actor also isn't threaded (if it ever was. I wrote a new class for actors), and item data is now just data loaded and saved into an SQL database. (SQL code is threaded).
  • that sounds good. you could use an interest area for this (with interest in the whole world).
    override OnItemSubscribed: subscribe to the item position channel and maintain your list there.
    override OnItemUnsubscribed: delete item from list
  • I'll look into those classes in the help file. Thanks, Boris!