Shop OBEX P1 Docs P2 Docs Learn Events
Distributed Synchronization Between Multiple Propellers — Parallax Forums

Distributed Synchronization Between Multiple Propellers

Brett WeirBrett Weir Posts: 288
edited 2014-05-04 07:26 in Propeller 1
Hello everyone,

I have something I'm working on, and I need some feedback as to whether you think my approach is a good idea.

I have two LameStation units connected to each other via serial cable (or wifi; interface is the same), so that people can play against each other.

What I ultimately hope to create is a generic distributed networking scheme between multiple nodes, that allows units' game states to stay in sync with each other without requiring any one LameStation to act as the main server, provided that they all have the same game running. I would also like to abstract the synchronization code into its own library so that this task is managed outside of game code.

Now, at present, my code contains a lot of stuff that looks like this; manual synchronization of key values and expecting the same from the transceiver.
PUB HandleNetworking

    if tankoldx <> tankx[yourtank]
       pst.Char(UPDATETANKX)
       pst.Char(tankx[yourtank])

    if tankoldy <> tanky[yourtank]
       pst.Char(UPDATETANKY)
       pst.Char(tanky[yourtank])

    if tankolddir <> tankdir[yourtank]
       pst.Char(UPDATETANKDIR)
       pst.Char(tankdir[yourtank])

    if bulletspawned == 1
       pst.Char(UPDATEBULLETSPAWN)
       bulletspawned := 0

    if tankspawned == 1
       pst.Char(UPDATETANKSPAWN)
       pst.Char(respawnindex)
       tankspawned := 0

    if oldscore <> score[yourtank]
       pst.Char(UPDATESCORE)
       pst.Char(score[yourtank])

    repeat while pst.RxCount > 0
          receivebyte := pst.CharIn

          if receivebyte == UPDATETANKX
             tankx[theirtank] := pst.CharIn

          elseif receivebyte == UPDATETANKY
             tanky[theirtank] := pst.CharIn

          elseif receivebyte == UPDATETANKDIR
             tankdir[theirtank] := pst.CharIn

          elseif receivebyte == UPDATEBULLETSPAWN
             SpawnBullet(theirtank)

          elseif receivebyte == UPDATETANKSPAWN
             receivebyte := pst.CharIn
             SpawnTank(theirtank,receivebyte,0)

          elseif receivebyte == UPDATESCORE
             score[theirtank] := pst.CharIn

          elseif receivebyte == UPDATETANKDIED
             receivebyte := pst.CharIn
             tankon[receivebyte] := 0

You can see pretty quickly that this doesn't scale well, and is not very maintainable. The problem though is that Spin doesn't appear to support callback functions, or so sayeth this page: http://propeller.wikispaces.com/Method+Calls.

Do you guys have any ideas about how to go about this? Am I correct that Spin does not support callback functions, and if so, are there any good strategies for doing this kind of synchronization?

Thanks in advance; any advice is much appreciated.

Comments

  • dnalordnalor Posts: 222
    edited 2014-05-04 07:26
    No there are no callbacks. But would that help?

    First I would spend a changed-flag-byte for each entry in the Information tables if it is room for that.
    If you change a information form your game code than you increment this byte.

    Then how many Cogs can you use for that?
    Best would be one Cog for sending and one Cog for receiving.
    In the sendig Cog you can stay in the loop for sending:
    repeat
      if scorechanged[yourtank]
         ...sendinformationcode...
         scorechanged[yourtank]--
      
       if.....
    
    So because you only increment or decrement your flag, you can not unintended forget to send an information.
    Edit: I am not sure if this statement is really correct. You maybe need locks.
    And for debugging you may can see, how good your transmition speed is.
    In the receiving Cog you can also stay in your receiving loop.

    Of course you can do this in one Cog. Then I would interleave the sending and receiving.
    sendidx := STARTIDX_S
    recidx := STARTIDX_R
    
    repeat
       sendinformation(sendidx)
       sendidx++
       if sendidx == ENDIDX_S
             sendidx := STARTIDX_S
    
       if tryToReceive(recidx)
           recidx++
           if recidx == ENDIDX_R
                recidx := STARTIDX_R
    
    

    Sorry, I am not good in Spin. So there are maybe errors.
    And this was my first idea, but maybe it helps.
Sign In or Register to comment.