Description of protocol between server and client: take two

  • More about protocol
  • Keywords
  • Delimiters
  • Movement
  • Location
  • Current Cyphesis events
  • Basic events
  • Extended events
  • Cyphesis specific events
  • Obsolete or maybe bugs (next snapshot will remove this)
  • More about protocol

    This is 'naturally' biased to what Cyphesis currently uses, raise your voice and say how things should be!

    Keywords

    I think that messages should have keywords like this:
    what='foo', location=(1,2,4), target='bar', etc...

    Instead of this:
    'foo',(1,2,4),NULL,'bar'
    (= what='foo', location=(1,2,4), source=NULL target='bar')

    Why? You don't need to worry about order and you can later add new keywords and you can leave keywords out. In short its more robust against changes.

    Exception: type (=command) of event: this will always be first and always exist.
    (event('move',source=..,target=..,..))

    Binary protocol is different beast of course.

    Delimiters

    Why something like 'event(....)' ? You can embed events inside other events: event('sight',event('move',...))

    Why something like "[event(...),event(...)]" ? Now you can send several events at same time.

    Other suggestions or counterarguments against these features?

    Maybe HTML/XML style:

    
           amount="0.3"
    
    

    To compare Python style:

    event('sight',
          what=event('move',what='_Characterid_234',loc=(12,4,5)),
          amount=0.3)
    

    Movement

    What I'm suggesting here is different from what Cyphesis currently does.

    In server use absolute coordinates. To client send relative (to player) coordinates. Player sends back relative coordinates that server then translates to absolute coordinates. This allows for things like player being lost etc...

    Or maybe client should not send 'move' -events/commands. It should probably send 'force' -commands.
    (maybe event('force',what=dir(0,1.2),target='_ground_10',amount=15.0) )
    Then it will get back event('sight',event('move',...))

    Location

    Maybe: location(place='containerid',xyz=(x,y,z))
    Examples:
    location(place='_world_0', xyz=(100,200,50))
    location(place='_house_123', xyz=(3,2,0))

    Now if house is removed (assuming first was for house), then later translates to:
    location(place='_world_0',xyz=(103,202,50))

    Or in client case relative:
    location(place='_world_0', rel_xyz=(1,10,0))
    (map editor can choose absolute coordinates if it wants to, (N)PC can't)

    Current Cyphesis events

    I let Cyphesis run few hundred cycles and collected different event types, here are results:

    (':' beginning of line is visual formatting)

    event type:
    
    :     example event
    
    When client sends, then 'source' attribute in event is optional.
    event attributes: "command", "source", "target", "desc", "what", "what_desc", 
                      "loc", "loc_desc", "amount", "time"
       command: event type: is always first, other attributes have keyword
       source, target, time: event source, target and time
       what: what thing this event talks about?
       loc: location of event
       amount: depends about 'what' -attribute
       
    ething: attribute list for thing
    esay: what has been said
    

    Does event has too many attributes? Should something dropped or combined with antoher?

    How would you implement these or something equivalent?

    Basic events

    These or something equivalent should be in protocol.

    MAKE:
    event('make',source:id,what:ething(..),time:time) :
    
    :        event('make',source='_Observer_2',
    :              what=ething('Bjorn',sex='male',type='smith',
    :              desc='only smith in village (_Observer_2_7)',
    :              age=1728000.0,name='Bjorn',place='home',xyz=(70, 0, 300)), 
    :              time=(612, 1, 5, 12, 0, 0, 0, 0, 0)) 
    
    event('make',source:id,what:id,time:time) :
    
    :        event('make',source='_house_7',what='_fire_16',
    :              time=(612, 1, 5, 12, 0, 0, 0, 0, 0)) 
    
    
    event('make',source:id,desc:string,what:ething(..),time:time) :
    
    :        event('make',source='_Miyora_6',desc='birth',
    :              what=ething('Miyora4',sex='female',name='Miyora4',
    :              type='farmer',copy='_Miyora_6'),
    :              time=(612, 1, 5, 12, 0, 0, 0, 0, 0)) 
    
    
    CHANGE:
    event('change',source:id,target:id,what:id,amount:number,time:time) :
    
    :        event('change',source='_house_7',target='_house_7',what='_house_7',
    :              amount=-0.03,time=(612, 1, 5, 12, 0, 0, 0, 0, 0)) 
    
    
    DESTROY:
    event('destroy',source:id,what:id,time:time)
    
    :        event('destroy',source='_fire_16',what='_fire_16',
    :              time=(612, 1, 5, 12, 0, 0, 0, 0, 0)) 
    
    event('destroy',source:id,desc:string,what:id,time:time) :
    
    :        event('destroy',source='_Bjorn_9',desc='death',what='_Bjorn_9',
    :              time=(612, 1, 5, 12, 0, 0, 0, 0, 0)) 
    
    
    MOVE:
    See above sections about movement and location!
    
    event('move',source:id,target:id,what:id,loc:xyz,time:time) :
    
    :        event('move',source='_Nisuf_5',target='_Nisuf_5',what='_Nisuf_5',
    :             loc=(20, 50, 300),time=(612, 1, 5, 12, 0, 0, 0, 0, 0)) 
    
    
    event('move',source:id,target:id,what:id,loc:id,time:time)
    
    :        event('move',source='_Nisuf_5',target='_Nisuf_5',what='_Nisuf_5',
    :              loc='_house_7',time=(612, 1, 5, 12, 0, 0, 0, 0, 0)) 
    
    Not really different type, but:
    :        event('move',source='_Bjorn_9',target='_Axe_7',what='_Axe_7,
    :              loc='_Nisuf_5',time=(612, 1, 5, 12, 0, 0, 0, 0, 0)) 
    
    Hmm... something where source, target, what and loc all are different
    (imaginary thing, wont be implemented for long time):
    :      event('move',source='_Bjorn_9',target='_Nisuf_5',what='right hand',
    :            location(rel_xyz=(0,0,0.2),time=(612, 1, 5, 12, 0, 0, 0, 0, 0))
    
    
    SAY:
    event('say',source:id,target:id,what:esay(..),time:time) :
    
    :       event('say',source='_Observer_2',target='_Bjorn_9',
    :             what=esay('learn',subject='create axes',
    :             object="make_amount('axe',10,'ordinary axe','smithy')"),
    :             time=(612, 1, 5, 12, 0, 0, 0, 0, 0)) 
    
    Or less Cyphesis NPC scripting specific example (next snapshot):
    
    :       event('say',source='_Nisuf_5',target='_Bjorn_9',
    :             what=esay('buy',subject='axe'"),
    :             time=(612, 1, 5, 12, 0, 0, 0, 0, 0)) 
    
    SOUND?:
    Missing event, should be:
    event('sound',what=event(...))
    
    SIGHT:
    event('sight',source:id,what:event('change',source:id,target:id,what:id,
                                       amount:number,time:time),time:time) :
    :       event('sight',source='_house_7',what=event('change',
    :             source='_house_7',target='_house_7',what='_house_7',
    :             amount=-0.06,time=(612, 1, 5, 12, 0, 0, 0, 0, 0)),
    :             time=(612, 1, 5, 12, 0, 0, 0, 0, 0)) 
    
    event('sight',what:event('make',what:ething(..),time:time)) :
    
    :        event('sight',what=event('make',what=ething('_Observer_2',
    :              desc='external mind',type='thing.vbody.god_body',
    :              xyz=(-100, -100, -100),name='Observer',place='home',
    :              status=1.0),time=(612, 1, 5, 12, 0, 0, 0, 0, 0))) 
    
    event('sight',source:id,what:event('move',source:id,target:id,what:id,
          loc:xyz,time:time),time:time) :
    
    :        event('sight',source='_Nisuf_5',what=event('move',
    :              source='_Nisuf_5',target='_Nisuf_5',what='_Nisuf_5',
    :              loc=(20, 50, 300),time=(612, 1, 5, 12, 0, 0, 0, 0, 0)),
    :              time=(612, 1, 5, 12, 0, 0, 0, 0, 0)) 
    
    event('sight',source:id,what:event('move',source:id,target:id,what:id,
          loc:id,time:time),time:time) :
    
    :        event('sight',source='_Nisuf_5',what=event('move',
    :              source='_Nisuf_5',target='_Nisuf_5',what='_Nisuf_5',
    :              loc='_house_7',time=(612, 1, 5, 12, 0, 0, 0, 0, 0)),
    :              time=(612, 1, 5, 12, 0, 0, 0, 0, 0)) 
    

    Extended events

    Not part of first iteration of protocol definition, IMHO. Handle these and similar things later (of course we should discuss these in the sense that whether the protocol syntax allow all needed things)

    event('fire',source:id,target:id,what:id,loc:id,amount:number,time:time) :
    :       event('fire',source='_fire_16',target='_house_7',what='_fire_16',
    :             loc='_house_7',amount=0.15,time=(612, 1, 5, 12, 0, 0, 0, 0, 0)) 
    
    
    event('sight',source:id,what:event('fire',source:id,target:id,what:id,loc:id,
          amount:number,time:time),time:time) :
    :       event('sight',source='_fire_16',what=event('fire',source='_fire_16',
    :             target='_house_7',what='_fire_16',loc='_house_7',amount=0.15,
    :             time=(612, 1, 5, 12, 0, 0, 0, 0, 0)),
    :             time=(612, 1, 5, 12, 0, 0, 0, 0, 0)) 
    
    Maybe something more generan than just extinguish?
    event('extinguish',source:id,target:id,what:id,time:time) :
    
    :        event('extinguish',source='_Nisuf_5',target='_fire_16',
    :              what='_fire_16',time=(612, 1, 5, 12, 0, 0, 0, 0, 0)) 
    

    Cyphesis specific events

    Genereal NYI (Not Yet Implemented) 'event' ;-)
    event('imaginary',source:id,desc:string,time:time) :
    
    :        event('imaginary',source='_Nisuf_5',desc='have a breakfast',
    :              time=(612, 1, 5, 12, 0, 0, 0, 0, 0)) 
    
    event('debug',what:string,time:time) :
    
    :        event('debug',what='on',time=(612, 1, 5, 12, 0, 0, 0, 0, 0)) 
    
    For debugging (NPC mind reading)
    event('goal',source:id,what:list,what_desc:string,time:time) :
    
    :        event('goal',source='_Nisuf_5',
    :              what=[event('imaginary',desc='have a breakfast')],
    :              what_desc="imaginary('have a breakfast').imaginary()",
    :              time=(612, 1, 5, 12, 0, 0, 0, 0, 0)) 
    

    Obsolete or maybe bugs (soon to be removed)

    event('say',source:id,what:string,time:time) :
    
    :        event('say',source='_Nisuf_5',what='I want to buy axe',
    :              time=(612, 1, 5, 12, 0, 0, 0, 0, 0)) 
    
    
    (source='_world_0' missing)
    event('make',what:id,time:time) :
    
    :        event('make',what='_illegal_1',time=(612, 1, 5, 12, 0, 0, 0, 0, 0)) 
    
    (source='_observer_2' missing)
    event('make',what:ething(..),time:time) :
    
    :       event('make',what=ething('Observer',desc='external mind',
    :             name='Observer',type='god_body',xyz=(-100, -100, -100)),
    :             time=(612, 1, 5, 12, 0, 0, 0, 0, 0)) 
    

    Aloril