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.

ModAPI Changes 12-8

Discussion in 'Modding' started by rexxar, Dec 8, 2016.

  1. rexxar Developer

    Joined:
    Dec 11, 2014
    Messages:
    1,414
    Trophy Points:
    207
    This week we've got some very exciting modding changes! It's something you've all been asking for :D

    But first, some less exciting details. :(

    The private text component of text panels has been removed. The API calls are still in place, but they will be removed eventually. Since the LCD can no longer be set to show private text, and users cannot edit private text, you shouldn't have any reason to use these things in your mods and scripts.

    I know a lot of you use private text as a way to get user input to configure your scripts, but we have a very nice replacement. All terminal blocks now have a CustomData field. Players will now see a button in the terminal menu that opens a text editor. Custom Data is synced and has a character limit of 64k. You can access it in your scripts and mods with IMyTerminalBlock.CustomData.

    Please note that the custom data field is meant for user input or simple script configuration, like the LCD private text. Don't use this to store large mod configuration, because it is synced to all players. If you need to store custom data in entities, use the new storage component.

    Now for the exciting bit, you can now add a storage component to entities, where you can store any data you like. Your custom data will be saved to the entity itself, no more having to set up crazy saving schemes where you serialize everything and stick it in the world file. This guide was written by the always amazing @Phoenix84

    A new storage component has been added for entities; Sandbox.Game.EntityComponents.MyModStorageComponent

    This component can be added to any entity, and provides a Dictionary<Guid, string> for saving whatever data your mod needs to save.

    To use this, check for an existing one, and if it doesn't exist, create one:
    Code:
    if (Entity.Storage == null)
        Entity.Storage = new MyModStorageComponent();
    
    After you have an instance, you can access it like a dictionary:
    Code:
    var mymodguid = new Guid("2111B766-07C8-4E59-869A-DD3244F3AC67");
    Entity.Storage[mymodguid] = "Some data for me to save";
    
    You will want to use a unique Guid for each data item you want to save. This will be unique to your mod.
    You can generate GUIDs in Visual Studio, or here: https://www.guidgenerator.com/online-guid-generator.aspx

    This component will be shared by other mods, so play nice. Don't replace a storage component if one already exists, use the existing one.

    You don't need to remove the component if it's empty, the game will not save anything if it's empty. It will be as if it didn't exist. This keeps your save files from growing large for empty classes.

    Your mod specific data will be automatically removed from the world when the mod is removed from the world, however due to that, you must tell the game which GUIDs you are using.

    To do this, create an EntityComponents.sbc file in your mod Data directory, following this style:
    Code:
      <EntityComponents>
        <EntityComponent xsi:type="MyObjectBuilder_ModStorageComponentDefinition">
          <Id>
            <TypeId>ModStorageComponent</TypeId>
            <SubtypeId>ModName</SubtypeId>
          </Id>
          <RegisteredStorageGuids>
            <guid>00000000-0000-0000-0000-000000000000</guid>
            <guid>2111B766-07C8-4E59-869A-DD3244F3AC67</guid>
          </RegisteredStorageGuids>
        </EntityComponent>
      </EntityComponents>
    This also keeps your saved data around in case your script breaks. Otherwise your data would be removed if your scripts failed.

    This class is not synced. You will still need to do that yourself.
     
    Last edited: Jan 3, 2017
    • Like Like x 3
    • Informative Informative x 1
  2. Duckroll

    Joined:
    May 24, 2016
    Messages:
    65
    Trophy Points:
    32
    Is this now in stable?
     
  3. rexxar Developer

    Joined:
    Dec 11, 2014
    Messages:
    1,414
    Trophy Points:
    207
    yes
     
  4. Draygo

    Joined:
    Jan 14, 2014
    Messages:
    1,296
    Trophy Points:
    132
    New example, this must now be wrapped in a definitions tag because keen.
    Code:
    <Definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <EntityComponents>
        <EntityComponent xsi:type="MyObjectBuilder_ModStorageComponentDefinition">
          <Id>
            <TypeId>ModStorageComponent</TypeId>
            <SubtypeId>Holo</SubtypeId>
          </Id>
          <RegisteredStorageGuids>
            <guid>00000000-0000-0000-0000-000000000000</guid>
            <guid>2111B766-07C8-4E59-869A-DD3244F3AC67</guid>
          </RegisteredStorageGuids>
        </EntityComponent>
      </EntityComponents>
    </Definitions>