Config & Translation

Creating a Config & Translation with Synapse3

Config

Creating a Config with Neuron is really easy. First you have to create a new Type which will be your Config that inherits from Syml.IDocumentSection and give it the the Attribute Syml.DocumentSectionAttribute as well as Automatic

using Neuron.Core.Meta;
using Syml;

namespace DocsExample;

[Automatic]
[DocumentSection("MyConfig")] //The Name here will be the Section Header of your Config
public class MyConfig : IDocumentSection { }

Now can you add various Properties (or fields) to your Type

using Neuron.Core.Meta;
using Syml;

namespace DocsExample;

[Automatic]
[DocumentSection("")]
public class MyConfig : IDocumentSection
{
    public int AmountOfX { get; set; } = 5;

    public ushort Port { get; set; } = 7777;

    public bool EnableY { get; set; } = false;
}

Neuron will now detect your config and will on start of your Plugin serialize this class with the default values (for AmountOfX in this case 5) and add it inside the plugins.syml (modules.syml if you are creating a Module) file or deserialize the values of the config if the section of your config was found.

The now loaded Config will be binded then to the kernel to ensure that every time you request the Config the proper instances will be returned. Synapse.Get<MyConfig>()

Configs will be also updated every time they are loaded so if you update your plugin all new Configs will be added with the default values while the original config values are not touched and configs that were removed will be removed from the Configs as well.

What is about reloading Configs?

The Reload Event is not a direct feature of Neuron but one of Synapse, so Synapse will call the reload method of the Neuron Config Module upon raising of the Event.

This will unbind the old config and start the process again so that a new reloaded instances of the Config will be binded to the kernel.

This however means if you want to store your Configs somewhere and not use Synapse.Get<> every time you have to reload this field every time the Reload Event is fired. How you can automate this can you see here

Be careful not to use any special symbols when choosing a Name for your Config Section.

Try to use only default letters since otherwise SYML could deny the reading of the configs and throws an Error

Translation

In order to create a Translation you have to create a new Type that inherits from Translations<TYourOwnType> and add the Automatic Attribute to it

using Neuron.Core.Meta;
using Neuron.Modules.Configs.Localization;

namespace DocsExample;

[Automatic]
public class MyTranslation : Translations<MyTranslation> { }

Now can you add various Properties (or fields) to your Type

using Neuron.Core.Meta;
using Neuron.Modules.Configs.Localization;

namespace DocsExample;

[Automatic]
public class MyTranslation : Translations<MyTranslation>
{
    public string CommandResult { get; set; } = "CommandExecuted successfully";

    public string BroadcastMessage { get; set; } = "Hello World";
    public int BroadcastTime { get; set; } = 5;
}

If you don't use English as default Language, you have to override Default Language

using Neuron.Core.Meta;
using Neuron.Modules.Configs.Localization;

namespace DocsExample;

[Automatic]
public class MyTranslation : Translations<MyTranslation>
{
    public override string DefaultLanguage { get; set; } = "Deutsch"; //German

    public string CommandResult { get; set; } = "Command ausgeführt";
    
    public string BroadcastMessage { get; set; } = "Hallo Welt";
    public int BroadcastTime { get; set; } = 5;
}

As you can see you are not only limited to using strings but every object that can be serialized inside your configs which can be used for example to set up different broadcast times for different languages

The Translation will be binded and reloaded automatic by Neuron/Synapse so you can just use Synapse.Get<MyTranslation> in order to get the current Translation, however this will just return the default Translation so in order to get the proper Translation have you to use the Extension method Get() this would look like this

Synapse.Get<MyTranslation>().Get();

This will always return the current Translation (so you don't have to worry about reloading your instance like the config) defined inside the Synapse.syml config.

If you want to get the proper translation for a Player can you just use the Get method with the Player as argument

Synapse.Get<MyTranslation>().Get(player);

How to add Properties/Fields that should not be serialized?

Syml uses in the background Yaml so you can just place YamlIgnore on top of the field/property and it will be ignored

using Neuron.Core.Meta;
using Neuron.Modules.Configs.Localization;
using YamlDotNet.Serialization;

namespace DocsExample;

[Automatic]
public class MyTranslation : Translations<MyTranslation>
{
    public override string DefaultLanguage { get; set; } = "Deutsch";

    public string CommandResult { get; set; } = "Command ausgeführt";
    
    public string BroadcastMessage { get; set; } = "Hallo Welt";
    public int BroadcastTime { get; set; } = 5;

    [YamlIgnore]
    public string NotAConfig { get; set; } = "This is not used by the config";
}

What can I use as Config?

Syml supports every basic c# type (like string, int, float, double, array (list)) as well as types that are simple enough to be serialized, so you can create sub configs within your config

using System.Collections.Generic;
using Neuron.Core.Meta;
using Neuron.Modules.Configs.Localization;
using YamlDotNet.Serialization;

namespace DocsExample;

[Automatic]
public class MyTranslation : Translations<MyTranslation>
{
    public override string DefaultLanguage { get; set; } = "Deutsch";

    public string CommandResult { get; set; } = "Command ausgeführt";
    
    public string BroadcastMessage { get; set; } = "Hallo Welt";
    public int BroadcastTime { get; set; } = 5;

    public List<uint> ItemIds { get; set; } = new() { 0, 1, 2 };

    public ConfigObject FirstObject { get; set; } = new ConfigObject() { Name = "1", Id = 1 };
    public ConfigObject SecondObject { get; set; } = new ConfigObject() { Name = "2", Id = 2 };

    [YamlIgnore]
    public string NotAConfig { get; set; } = "This is used by the Plugin";
}

public class ConfigObject
{
    public string Name { get; set; }
    
    public uint Id { get; set; }
}

SerializedObjects

Since it is very tedious to create a new Type every time you want to store a Position Rotation or something else exist there a couple of predefined Types that can be casted to the proper Type that you actually want to store these are

NameDescription

SerializedItem

Config object with just the basic information for spawning an Item

SerializedPlayerItem

Config object with all Information from SerializedItem as well as Spawn Chance and a bool to provide the item with the preferred setup of the Player

SerializedAmmo

A Serialized object that stores the Ammo a Player can hold

SerializedPlayerInventory

A combination of SerializedAmmo and a List of SerializedPlayerItem

SerializedVector3

A Serialized Vector3 as well as Quaternion so Rotations can be stored as well

SerializedVector2

A Serialized Vector2

SerializedColor

Serialized Color for Color and Color32

SerializedEffect

Serialized PlayerEffect Intensity and duration

SerializedPlayerState

Config object with almost every important information about the state of the player

RoomPoint

A Position relative to a Room

using Neuron.Core.Events;
using Neuron.Core.Meta;
using Syml;
using Synapse3.SynapseModule;
using Synapse3.SynapseModule.Config;
using Synapse3.SynapseModule.Events;
using Synapse3.SynapseModule.Map.Rooms;
using UnityEngine;

namespace DocsExample;

[Automatic]
[DocumentSection("")]
public class MyConfig : IDocumentSection
{
    public int AmountOfX { get; set; } = 5;

    public ushort Port { get; set; } = 7777;

    public bool EnableY { get; set; } = false;
    
    public RoomPoint SpawnPoint { get; set; } = new ("Shelter", new Vector3(0f, 2f, 0f), Vector3.zero);

    public SerializedVector3 StaticPoint { get; set; } = new (0f, 0f, 0f);
}

[Automatic]
public class EventHandler : Listener
{
    [EventHandler]
    public void OnSetClass(SetClassEvent ev)
    {
        if (ev.Role == RoleType.Scientist)
        {
            ev.Position = Synapse.Get<MyConfig>().SpawnPoint.GetMapPosition();
        }
        else
        {
            //SerializedVector3 can be directly be casted to a Vector3 like this
            ev.Position = Synapse.Get<MyConfig>().StaticPoint;
        }
    }
}

Last updated