bbosen - 2020-06-02

Some missions benefit from "synchronization" of mobile objects like battleships, aircraft carriers, or naval destroyers. In those cases, it is helpful to designate one of the 10 possible players as the "commander" of this synchronization process.

Under ordinary circumstances, that "MissionCommander" is the only player to TRANSMIT the name of "MissionChronoMilestones". The MissionCommander does this periodically as time passes. A typical mission might advance through a new MissionChronoMilestone" state once every two or three minutes. At each of those points, the MissionCommander transmits the name of the corresponding MissionChronoMilestone. It's as if the MissionCommander were to say:

"ATTENTION ALL PLAYERS: The mission has now advanced to MissionChronoMilestone 5. Many of you already knew that and all of your ships and other moving objects are already in the proper positions, but if you are new to this mission (or if some unforseen event has caused your mobile objects to drift out of position), you should immediately reposition all of your moving objects according to the corresponding, hard-coded positions and orientations according to our mission plan."

At that point, all players adjust the position of aircraft carriers, battleships, naval destroyers, and anything else that moves around. The new positions are taken from the source code of the mission, so everybody goes to the same place. Usually, the mission's arrival at a new MissionChronoMilestone comes as no surprise to participating players, since everybody is processing the same mission details at the same rate. Generally this results in small position adjustments that may be so tiny as to be inperceptible. However, as a new player enters an ongoing mission, he might make a much bigger adjustment.

For example, suppose five players have been active in a mission for 20 minutes when a sixth player joins. The original five players might have advanced through MissionChronoMilestone #8, so their aircraft carriers will be well into the mission geography. That new player will not know any of this until the MissionCommander reaches MissionChronoMilestone #9 and transmits the corresponding message. At that point, the first five players may make tiny little adjustments to remain synchronized, but the newcomer will need to make a BIG adjustment, leaping more than 20 minutes forward into the mission plan.

Ordinarily, players that are NOT the MissionCommander are only expected to RECEIVE MissionChronoMilestone names as the mission progresses, using them as indexes into pre-written, hard-coded tables of that position information, so that mobile mission objects seen by all players can simultaneously "leap" to the appropriate locations when the MissionCommander commands everybody to match his situation at a specified MissionChronoMilestone according to the mission's hard-coded design.

As time progresses between MissionChronoMilestones, each player moves all of his mobile mission objects according to the mission plan, so once positions are synchronized, they tend to remain synchronized to a reasonable degree. However, due to different processing speeds and other technical factors, it is commonplace for some players to advance these objects slightly faster than others. Accordingly, upon receipt of a new MissionChronomilestone, it is commonplace to see slight adjustments in order to maintain the best synchronization.

I have expanded LAC's global mission infrastructure with some new tools and variables to make it easy to determine who is the current MissionCommander. You should know that every Sentient, human player participating in any of our online, multi-player, server-based missions is always assigned a number between "1" and "10" to identify him within the mission. For each player, that value has long been known as "MyNetworkId".

All of our sample missions already have a block of code resembling this:

    if (MissionTenSecondTimer > 10000)
       { //@ Get here once every 10 seconds
       MissionTenSecondTimer = 0; //@ Will expire again in 10 more seconds
       HighestRecentMyNetworkId = 0; //@ Reset records of recent player numbers
       if (MissionCommanderCandidate > MyNetworkId)
          { //@ If any Inpacket of prior 10 seconds came from a player with higher ID than me
          MissionCommander = MissionCommanderCandidate; //@ Then THAT player is MissionCommander
          }
       else
          { //@ Otherwise, I am the MissionCommander
          MissionCommander = MyNetworkId;
          }
       sprintf (SystemMessageBufferA, "MISSIONCOMMANDER = %d", MissionCommander);
       NewSystemMessageNeedsScrolling = true;
       MissionCommanderCandidate = 0; //@ Erase stale values from prior 10 seconds
       }

That block has code, contained within a block that gets executed once every ten seconds, that updates a new, global, unsigned integer variable named "MissionCommander" with the appropriate value according to all network InPackets received during the prior 10-second period. It works with other global variables (like "MissionCommanderCandidate") and functions, beyond the scope of mission code, to do so. To assist development and debugging, the end of that sample code block includes these two special lines that can be deleted once everything is working reliably:

   sprintf (SystemMessageBufferA, "MISSIONCOMMANDER = %d", MissionCommander);
   NewSystemMessageNeedsScrolling = true;

Those two lines cause the scrolling, three-line "SystemMessagePanel" instrument on LAC's cockpit to display messages like "MISSIONCOMMANDER = 4", updating them every ten seconds.

If you write a new mission that moves ships or other objects around, you can use that block of code to determine which currently active Sentient network player has the highest network ID number (between "1" and "10") and accordingly, which player ought to initiate synchronization activities as "MissionCommander". All of the sample mission source-code files within recently published versions of LAC include code like this for your reference.

A little block of code like this could subsequently determine if the current player is the MissionCommander:

if (MissionCommander == MyNetworkId)
   { // Get here if the current player is the MissionCommander
   // 
   // Insert code here to transmit the current position and
   // status of mobile or changing objects to other players.
   //
   // The "Morse Code Radio" could use the "CCCCCCCC"
   // or "ChronoMilestone" command to do this, as
   // documented elsewhere.
   //

   }

In all of our sample missions that synchronize the positions of ships or other mobile objects, code like that is already present in logic associated with important mission "states" that get activated when timers advance the mission into each of as many as ten important, comprehensively pre-defined "MissionChronoMilestones".

 

Last edit: bbosen 2020-07-13