Welcome to Keen Software House Forums! Log in or Sign up to interact with the KSH community.
  1. You are currently browsing our forum as a guest. Create your own forum account to access all forum functionality.

Programmable Block Inter-Grid Communication Guide

Discussion in 'Programming (In-game)' started by rexxar, Jan 19, 2017.

Thread Status:
This last post in this thread was made more than 31 days old.
  1. rexxar Senior Engineer

    Messages:
    1,530
    Oh yes, that's right. The single most requested feature for PB is now happening. Programmable blocks can now utilize the antenna system to send data to other grids. We said it was never gonna happen, but we have to keep you on your toes now, don't we? ;-)

    While you pick your collective jaws up from the floor, let's show some love for @Malware who helped design this system, and @Jimmacle for providing so much feedback that I ended up rewriting everything <3

    In the terminal for both types of antenna, you will find a drop-down box that contains all the programmable blocks on the grid. Simply select the PB you want to attach to the antenna, and when the antenna receives a message, it will run the selected PB with the message as the argument.

    Laser antenna are simpler, so I'll address them first. Of course, laser antenna can only be connected to one other antenna at a time, so communications through laser antenna is completely secure and undetectable.

    Here's the (truncated) laser antenna interface:
    Code:
    public interface IMyLaserAntenna : IMyFunctionalBlock
    {
      /// <summary>
      /// Sends a message to the programmable block associated with this antenna's partner
      /// </summary>
      /// <param name="message"></param>
      bool TransmitMessage(string message);
    }
    
    In your transmitting PB, simply find the laser antenna you want to send from, then call antenna.TransmitMessage(message); The method will return true if it was able to successfully send the message.

    Antenna are a bit more complex, as they broadcast to anyone who will listen. There are two options for restricting communication. The transmitting antenna can choose who to broadcast to with the TransmitTarget enum:
    Code:
    [Flags]
    public enum MyTransmitTarget
    {
      None = 0,
      Owner = 1 << 0,
      Ally = 1 << 1,
      Neutral = 1 << 2,
      Enemy = 1 << 3,
      Everyone = Owner | Ally | Neutral | Enemy,
      Default = Owner | Ally,
    }
    
    This is a Flag enum, which means you can combine elements. If you want to send to only neutral and allied antenna, you just OR them together: var target = MyTransmitTarget.Ally | MyTransmitTarget.Neutral.

    On the recieving end, you can choose to ignore messages from allies, or messages from neutral and enemy grids. There are two checkboxes in the terminal that let you configure this, as well as new entries in the antenna interface:

    Code:
    public interface IMyRadioAntenna : IMyFunctionalBlock
    {
      /// <summary>
      /// Broadcasts a message to all PB attached to the antenna system.
      /// Returns false if broadcasting failed for any reason.
      /// </summary>
      /// <param name="message"></param>
      /// <param name="target"></param>
      bool TransmitMessage( string message, MyTransmitTarget target = MyTransmitTarget.Default );
    
      /// <summary>
      /// Ignores broadcasts sent by friendly antenna that do not belong to you
      /// </summary>
      bool IgnoreAlliedBroadcast { get; set; }
    
      /// <summary>
      /// Ignores broadcasts sent by neutral and enemy antenna
      /// </summary>
      bool IgnoreOtherBroadcast { get; set; }
    }
    
    For both antenna types, when you call TransmitMessage, your transmission is queued for the beginning of the next tick. This means that each antenna can only transmit once per tick. If you try to transmit again in the same tick, the TransmitMessage method will return false. This was a necessary restriction to prevent PB running too many times in a tick, and it also makes it much easier to have bi-directional communication.

    Do note that you could possibly receive malicious, malformed, or just unknown data. Your script needs to be able to handle anything at all in the argument, so make sure to use safe design patterns like try/catch and TryParse instead of straight Parse.

    Example reciever script:
    Code:
    string password = "A702A9E2-4C2A-436B-B9C4-8F8D9221D72F";
    
    void Main(string argument)
    {
      if (argument == password)
      {
         List<IMyWarhead> warheads = new List<IMyWarhead>();
         GridTerminalSystem.GetBlocksOfType(warheads);
         foreach (var warhead in warheads)
         {
            warhead.SetValue("Safety", true);
            warhead.SetValue("DetonationTime", 3f);
            warhead.ApplyAction("StartCountdown");
         }
    
         List<IMyRadioAntenna> antennas = new List<IMyRadioAntenna>();
         GridTerminalSystem.GetBlocksOfType(antennas);
         foreach (var antenna in antennas)
         {
            antenna.CustomName = "WARNING! SELF DESTRUCT IN 3 SECONDS";
            antenna.SetValue("IsBroadcasting", true);
            antenna.SetValue("Radius", 50000f);
            return;
         }
      }
    
      if (argument == "OpenHangar1")
      {
         var hangarGroup = GridTerminalSystem.GetBlockGroupWithName("Hangar 1");
         List<IMyAirtightHangarDoor> doors = new List<IMyAirtightHangarDoor>();
         hangarGroup.GetBlocksOfType(doors);
    
         foreach (var door in doors)
         {
            door.SetValue("Open", true);
         }
      }
      if (argument == "CloseHangar1")
      {
         var hangarGroup = GridTerminalSystem.GetBlockGroupWithName("Hangar 1");
         List<IMyAirtightHangarDoor> doors = new List<IMyAirtightHangarDoor>();
         hangarGroup.GetBlocksOfType(doors);
    
         foreach (var door in doors)
         {
            door.SetValue("Open", false);
         }
      }
    }
    
    Example transmitter:
    Code:
    void Main(string argument)
    {
       var ant = GridTerminalSystem.GetBlockWithName("Antenna") as IMyRadioAntenna;
       ant.TransmitMessage(argument, MyTransmitTarget.Everyone);
    }
    
     
    • Like Like x 24
    • Informative Informative x 3
  2. iN5URG3NT Senior Engineer

    Messages:
    1,132
    Awesome!

    Quick question, will this new system break the old "cross grid" system? For instance, how missiles could be guided by a ship orientation as long as they were originally connected to that grid.
     
  3. Malware Master Engineer

    Messages:
    9,085
    @iN5URG3NT There never was an old cross grid system. There is a cross-grid exploit. While this particular update will not break that, you're better off keeping that in mind.
     
    • Agree Agree x 4
    • Informative Informative x 2
  4. iN5URG3NT Senior Engineer

    Messages:
    1,132
    Thanks for the info man!

    Oh yea, I know it was an exploit and was going to be fixed eventually, I was just curious if there was going to be a "grace period" where we could swap over to the new, better system without all our missiles breaking. I'm not expecting special treatment though! The show must go on! This system is obviously better.

    I waited six weeks for timers to be fixed so I could upload a ship with a new missile system, it's been on the WS for three days. A couple of weeks for the scripters to get things together would be nice. But it's cool, we fleet builders know our place, we are the peasantry of the content creation hierarchy. :)
     
    • Agree Agree x 3
  5. Cheetah97 Trainee Engineer

    Messages:
    31
    Ple-ease, could you also allow for queue-style message handling?
    For example, add a "UseQueueSystem" boolean to the interface, and a Queue<string> for messages. If UseQueueSystem is true, then instead of invoking the PB the antenna will simply store the message in the queue. To prevent abuse and overload, the Queue will only hold up to 20 messages, and if the queue overflows, the oldest message will be removed in order to place the new one.

    Of course "you can always implement this by yourself in your script", but it will be very nice if we really were given options on how we want to handle the messaging. In certain circumstances, this may be beneficial for performance. Imagine you have a central control station, which controls 10 drones. These drones report their positions and their integrity, so their status can be displayed on an LCD. So, with the Queue option, instead of running the PB on central station 10 times and handling one message at a time (and redraw the LCD 10 times, etc...), the PB could be run only once with a timer, and process 10 messages in single run. This may greatly decrease performance impact if, for example, you are doing an inventory lister script for several stations, which displays a combined readout of ingots, components, etc across your facilities.
     
    Last edited: Jan 19, 2017
    • Agree Agree x 1
  6. Malware Master Engineer

    Messages:
    9,085
    @Cheetah97 We were able to get this because we made it so simple so it didn't take too much time to do. Don't forget we scripters aren't exactly of the highest priority. You're gonna have to deal with the system yourself. Besides, people are going to want very different ways to handle messages.
     
    • Agree Agree x 2
  7. Cheetah97 Trainee Engineer

    Messages:
    31
    @Malware Uh, ok. Could you at least allow to register a handler or expose an event in ModAPI which will fire when antenna receives a message?
    E.g. either a general message system handler somewhere from the depths of messaging system, or a plain ModAPI.(IMyRadioAntenna/IMyLaserAntenna).OnMessageReceived(string Message) fired just before a message is supplied to a PB?
     
    • Agree Agree x 2
  8. Malware Master Engineer

    Messages:
    9,085
    I was just a helper on this one, @rexxar did the coding. You're gonna have to ask him
     
  9. Gwindalmir Senior Engineer

    Messages:
    1,000
    So, if you pin the PB Run action to the toolbar, you can now execute remote actions! Something promised to us since antennas first came out!

    I had asked for this myself, but due to time it wasn't done. I'm hopeful it'll get added later.
    If I added it, I might make it a Func<IMyProgrammableBlock,string,bool> so mods can veto the message.
     
    Last edited: Jan 19, 2017
    • Informative Informative x 1
  10. Rdav Apprentice Engineer

    Messages:
    117
    Rexxar, I've been dreaming of this day for a long time, all childish squealing aside I shall simply just instead say
    Thank you.
     
    • Like Like x 2
    • Agree Agree x 2
  11. Textor Junior Engineer

    Messages:
    775
    What's this? Something has stirred me from my slumber...
     
    • Like Like x 3
  12. MisterSwift Apprentice Engineer

    Messages:
    367
    Wow, I've been wanting this since I first learned how to use PBs! I'm going to enjoy the hell out of this when I get back to SE. Keep up the good work guys :tu:
     
  13. Whiplash141 Junior Engineer

    Messages:
    957
    What is the char length limit of the argument?
     
    • Like Like x 3
  14. sepen_ Trainee Engineer

    Messages:
    45
    Thanks a lot! The effort is really appreciated.

    (And you all knew it was the right thing to do.. ;) )
     
  15. ManIkWeet Trainee Engineer

    Messages:
    26
    So is this going to be in the next update? I can't wait to build an elevator with it :D

    Edit: yes it is, yay!
     
    Last edited: Jan 19, 2017
  16. ColonelCabbage Trainee Engineer

    Messages:
    20
    ayyy. This is awesome, great work!
     
  17. Velenka Trainee Engineer

    Messages:
    25
    Oh man, I'm so excited. I can't wait to get started working on some interesting projects!
     
  18. Me 10 Jin Apprentice Engineer

    Messages:
    463
    Someone get me 6 bags of cheetos and a case of mountain dew STAT !
     
  19. Dax23333 Junior Engineer

    Messages:
    625
    This is such a game changer, and just as i'm starting to try out programmable blocks!

    Intuitive and secure, this is going to be spectacular! Even for noob projects like mine this is brilliant. Only tuesday I was wondering how cool it'd be to be able to press a button to make all my autominers come home. Now I'll have to rebuild the fancy new design and make a new one..
     
  20. thekingmen Trainee Engineer

    Messages:
    17
    wouhou!
    Just when I was thinking if I should use these unnoficial mod to add an inter-grid communication or not.

    As for the queue functionnality, it may be better handled by other scripters/libraries on top of this base functionnality. Like EasyAPI, someone could implement a mid layer and add features like message classification and queue, retries and stuff. by doing this in a mid layer outside of the official game, those people that want something very specific can just make it themself exactly like they want and stop whinning. If this become a standard it's a good thing to improve functionnality and simplify usage, except for newbies who will not think to look at such libraries in the workshop/forum.
     
  21. Anonymous Blackness Trainee Engineer

    Messages:
    7
    Weird. I've been working on a long range network communications mod somewhat like this...
     
  22. Concave Trainee Engineer

    Messages:
    90
    Great! Looking forward to experimenting.
     
  23. Ronin1973 Master Engineer

    Messages:
    4,477

    The problem with creating a Queue system is that griefers will create a spam system that overloads it as a counter-measure against another player's network.
     
  24. Loues S. Cat Apprentice Engineer

    Messages:
    138
    Hmmm.... so any way to get EntityId of the grid an antenna is on without having to use raycast from a camera or check a sensor? ^.^;
    I need a way to tag messages with the oragin.
     
  25. gothosan Junior Engineer

    Messages:
    718
    If I get it right we can also send messages for enemies?
    In MP its logical I guess for two factions at war to communicate with each other, maybe one send a truce or surrender message to the other, but how will that work in SP
    with AI? Some messages to make AI ignore us / AI will send messages to the player?
    I'm excited about this! Amazing work :)
     
  26. Loues S. Cat Apprentice Engineer

    Messages:
    138
    Hmmm.. So I built my message processing and output queuing and I tried capping my message send rate.
    I tried crazy low values like 0.005 first, but quickly changed to 0.02 and then 0.025 which worked much beter but still saw a fair bit of failure.
    same for 0.03 o.035, 0.04, and 0.045 each being slightly better than the last in terms of reducing failure rate
    0.05 works /almost/ flawlessly, but I still get a failure onve in a blue moon. ( about 1 in 4000-5000 send efforts )
    But it is probably worth asking.... how long is the minimul interval between broadcasts exactly?
    I mean the way I am doing it messages will never be sent at exactly 0.05 seconds appart. There will always be a delay as the script only runs so fast so obvously the wiggle room in there is causing my issues.
    What is the minimum time to guarantee a new tick (I kind of assume it is tick based, but then I would have assumed the programable block can only be run once a tick and that is clearly wrong >.>) will have started when a script goes to send a message through an antenna?
     
  27. Badger Trainee Engineer

    Messages:
    11
    This is awesome!
    Do we know when it is likely to make it into the stable release?
     
  28. Dwarf-Lord Pangolin Senior Engineer

    Messages:
    2,597
    TL;DR: missiles using spooky action at a distance will no longer work. No more entangled-pair guided missiles. Very glad I've been building mine with antennae! :D

    Edit: thinking back, I really need to make a list, with links to relevant update & blog posts, of every time Keen has implemented a feature they weren't planning to because it was requested by the players. I suspect it'll be longer than for any other company I've heard of.
     
    Last edited: Jan 20, 2017
    • Like Like x 1
    • Agree Agree x 1
  29. Malware Master Engineer

    Messages:
    9,085
    Stable updates around once a month
    --- Automerge ---
    Entity IDs are available on the grid interface
     
  30. Dax23333 Junior Engineer

    Messages:
    625
    Will a signal from this be relayed across multiple antennas to cover more distance? Or will only other antennas within range of the first one be able to pick it up the message and act on it?
     
Thread Status:
This last post in this thread was made more than 31 days old.