[Progress - 5th March] Modding API

  • 4 Replies
  • 475 Views
*

Mark

  • Wired Games
  • Administrator
  • Commander
  • *****
  • 276
    • View Profile
[Progress - 5th March] Modding API
« on: March 05, 2017, 01:06:14 AM »
Hey all,


This is a technical post, but it's a milestone for UoN and I wanted to share. :)

One of the most difficult to implement features of a complex game is a modding API, the ability to inject custom code into the game. The reason it is difficult is because the game has to be structured to suit code injection, the ability to use code that was not written as part of the game. Luckily I planned for a modding API from the start, but I still had a lot of work to do to actually implement it.

I added the ability to use custom assets (textures, models, UIs), and config files (for entities in the game, spaceships, equipment) into the game last year, but put off the modding API until recently. Thankfully that work is now complete, UoN now has a full modding API where all of the systems in the game are accessible to, and can use, custom code.

Here is an example of code from the base mod (UNION uses a base mod for all of the game's content). This is the main spaceship process, which manages Heat and Instability. This file is saved as a .CS file in the mod folder.
Code: [Select]
using System;
using UON.Common;
using UON.ModdingAPI;

namespace UON.BaseMod
{
    public class StandardSpaceshipExtension : ISpaceshipExtension
    {
        private float m_nextUpdatePassiveHeatTime;

        private ISpaceshipComponent m_spaceshipComponent;
        private IEquipmentComponent m_equipmentComponent;

        public void OnServerEntityUpdate(float deltaTime, IKotarEntity entity)
        {
            m_spaceshipComponent = entity.GetComponent<SpaceshipComponent>(ComponentIds.Spaceship);
            m_equipmentComponent = entity.GetComponent<EquipmentComponent>(ComponentIds.Equipment);
           
            for (byte systemIndex = 0; systemIndex < m_spaceshipComponent.Template.Systems.Count; systemIndex++)
            {
                float actualPassiveHeatLevel = 0.0f;
                if (m_equipmentComponent[systemIndex].OperatingPowerLevel >= m_equipmentComponent[systemIndex].Template.Class.MinOperatingPower)
                {
                    actualPassiveHeatLevel = m_equipmentComponent[systemIndex].OperatingPowerLevel * m_equipmentComponent[systemIndex].Template.PassiveHeatCoefficient;
                }

                if (actualPassiveHeatLevel == 0.0f)
                {
                    m_equipmentComponent[systemIndex].PassiveOperatingHeat = actualPassiveHeatLevel;
                }
                else if (UONGame.Instance.PlayTime.TotalTime.TotalSeconds > m_nextUpdatePassiveHeatTime)
                {
                    m_equipmentComponent[systemIndex].PassiveOperatingHeat = actualPassiveHeatLevel + (((float)UONGame.Instance.Random.NextDouble() * 20.0f) - 10.0f);
                }

                if (m_equipmentComponent[systemIndex].Heat > m_equipmentComponent[systemIndex].PassiveOperatingHeat)
                {
                    float excessHeat = m_equipmentComponent[systemIndex].Heat - m_equipmentComponent[systemIndex].Template.HeatsinkCapacity;
                    if (excessHeat > 0.0f)
                    {
                        m_equipmentComponent[systemIndex].Instability += (excessHeat * m_equipmentComponent[systemIndex].Template.OverheatToInstabilityRate);
                        m_equipmentComponent[systemIndex].Heat -= excessHeat;
                    }

                    m_equipmentComponent[systemIndex].Heat -= ((m_equipmentComponent[systemIndex].Template.HeatDissipationAmountPerSecond * 0.5f) + (m_equipmentComponent[systemIndex].Template.HeatDissipationAmountPerSecond * 0.5f * (m_equipmentComponent[systemIndex].PercentageIntegrity / 100))) * deltaTime;
                }

                if (m_equipmentComponent[systemIndex].Heat < m_equipmentComponent[systemIndex].PassiveOperatingHeat)
                {
                    m_equipmentComponent[systemIndex].Heat = Math.Min(m_equipmentComponent[systemIndex].Heat + (4.0f * deltaTime), m_equipmentComponent[systemIndex].PassiveOperatingHeat); // Add heat up to the current PassiveOperatingHeat, 4.0f is just a sample number
                }

                if (UONGame.Instance.PlayTime.TotalTime.TotalSeconds > m_nextUpdatePassiveHeatTime)
                {
                    m_nextUpdatePassiveHeatTime = (float)UONGame.Instance.PlayTime.TotalTime.TotalSeconds + 0.75f + ((float)UONGame.Instance.Random.NextDouble() * 0.75f);
                }
            }
        }
    }
}

To use this code, all that is required is setting the class name StandardSpaceshipExtension in the SpaceshipExtensionCodePath entry on the spaceship config file:
Code: [Select]
/* UNION Spaceship Template v0.01a */
{
"Key": "Albatross",
"IsEnabled": true,
"Data": {
"TypeKey": "Spaceship",
"FactionKey": "UNION",
"IsPlayerSelectable": true,
"ClassType": "Frigate",
"EntityPath": "UNIONBase/Entity/Albatross",
"SpaceshipExtensionCodePath": "UNIONBase/Code/StandardSpaceshipExtension"
        }
}

Now that the modding API has been completed I will, over time, be moving a lot of code out of the compiled game and into the base mod. Anyone can then modify the code and put it into their own mods.


Thanks for reading!

Mark

*

Dusk

  • Ensign
  • *
  • 5
    • View Profile
Re: [Progress - 5th March] Modding API
« Reply #1 on: March 05, 2017, 02:17:01 AM »
Nice! I actually wasn't expecting this to be showing up for a while. Can't wait to start messing around with the UI lol. Quick question about that actually, is there any idea of just how moddable the UI will be? For instance, will it be primarily visual or will the option exist to add new functionalities to the different stations? It would be cool to see what people come up with!

*

Mark

  • Wired Games
  • Administrator
  • Commander
  • *****
  • 276
    • View Profile
Re: [Progress - 5th March] Modding API
« Reply #2 on: March 05, 2017, 02:22:18 AM »
Adding modding to a game gets exponentially harder as development progresses. This is why I knew I had to tackle it sooner rather than later. Modding has always been an important part of my vision for UoN.

The UIs are fully moddable, and extra functionality can be added. The modding API allows for custom logic and data to be added to spaceships (and other entities), and this logic and data can be accessed from UIs.
« Last Edit: March 05, 2017, 04:36:15 AM by Mark »

*

Blaze

  • Lt. Commander
  • ***
  • 133
    • View Profile
Re: [Progress - 5th March] Modding API
« Reply #3 on: March 05, 2017, 10:07:03 AM »
Awesome news!

I really think the modding aspect is something you should include in the marketing of the game, since it's a phenomenal feature and it might attract additional people who maybe wouldn't play the game otherwise.

*

Mark

  • Wired Games
  • Administrator
  • Commander
  • *****
  • 276
    • View Profile
Re: [Progress - 5th March] Modding API
« Reply #4 on: March 05, 2017, 02:41:19 PM »
Absolutely! 😊 I will definitely incorporate modding as a element of the marketing.