For Modders - Rjoande/RealBattery GitHub Wiki

This guide explains how to customize a part with a specific set of battery types and how to create new battery types from scratch. A full library of subtypes and B9TankTypes is available for reference, making it easy to copy all the necessary parameters into your own compatibility patches. Several Module Manager filters are also provided to help you target specific part types when writing patches.

RealBattery Module

RealBattery uses a custom module to manage the conversion between StoredCharge and ElectricCharge, and to interact with the vessel’s power system. In the original version of RealBattery, most parameters were hardcoded into the module logic. With RealBattery Recharged, the majority of these values can now be defined directly in part config files, dramatically expanding the potential for modders to customize and fine-tune battery behavior.

Below is an overview of the configurable parameters handled by the RealBattery module in .cfg files.

Field Type Description
BatteryTypeDisplayName string Localized display name for the battery subtype shown in the UI (e.g., "Lead-acid", "NiCd").
HighEClevel float Threshold ratio (0–1) above which the battery begins to charge from the vessel's EC pool. Values >1 disable charging, effectively making the battery primary (non-rechargeable).
LowEClevel float Threshold ratio (0–1) below which the battery begins to discharge into the vessel's EC pool.
Crating float Defines the maximum continuous charge/discharge rate as a multiple of the battery’s total capacity. For example, 1.0 means the battery can be fully charged or discharged in one hour, 2.0 in half an hour, and so on.
SelfDischargeRate float Percentage of SOC (State of Charge) lost per day due to passive self-discharge. Expected range: 0–1.
CycleDurability int Number of full charge/discharge cycles after which battery performance degrades below 80% of nominal capacity.
ThermalLoss float Fraction of EC per second (during charge or discharge) converted into heat. Expected range: 0–1.
ChargeEfficiencyCurve FloatCurve Defines the battery’s charging efficiency based on its current state of charge (SOC). Input: SOC (0–1), Output: charge rate multiplier (0–1). Setting all output values to 0 disables charging, simulating a primary (non-rechargeable) battery.

Note: SelfDischargeRate, CycleDurability and ThermalLoss are not yet functional in the current version of the mod. They are already included in the configuration files and descriptions in preparation for future updates, but they do not yet influence in-game behavior.

Examples of ChargeEfficiencyCurve

Efficiency increases up to 70% at 50% charge, then gradually decreases to 50% at full capacity.

ChargeEfficiencyCurve
{
   key = 0.0 0.55
   key = 0.3 0.65
   key = 0.5 0.70
   key = 0.8 0.60
   key = 1.0 0.50
}

Curve for a primary (non-rechargeable) battery: efficiency is zero at all charge levels, effectively disabling recharging - best combined with something like HighEClevel = 2.

ChargeEfficiencyCurve
{
   key = 0.0 0.00
   key = 1.0 0.00
}

Adding default Battery Types to a part

All stock parts, and many from popular mods, are already configured with a set of battery chemistries that match their intended use in the real world. In addition, an automatic fallback patch assigns a plausible battery configuration to any part that hasn't been explicitly defined, based on its role (e.g., standalone battery, crew module, probe core).

Preparation

As explained in the Gameplay Guide, different battery types offer varying energy and power densities. However, there's another important factor to consider: volumetric energy density (Wh/L). This value is used when writing ModuleManager patches, particularly when using B9PartSwitch to switch between battery types.

The idea is to work backward from a part’s original Electric Charge capacity to estimate its physical volume. Based on in-game data, stock batteries have an average energy density of approximately 2.83 EC/L. From this, we can derive a "base volume" by multiplying the Electric Charge amount by 0.3 (the precise conversion would be 0.353, but 0.3 is a cleaner approximation for patching purposes).

RBbaseVolume = #$/RESOURCE[ElectricCharge]/maxAmount$
@RBbaseVolume *= 0.3

You can compute this manually, but using the RBbaseVolume variable is especially helpful when writing patches for multiple parts.

Each part that uses RealBattery must include the following:

  • The ElectricCharge resource
  • The StoredCharge resource
  • The RealBattery module

These are automatically handled in most patches, but should be included manually in custom configurations.

Adding a single Battery Type

If the part (or set of parts) is intended to support only one battery chemistry, you’ll need to define the correct resource amounts and manually configure all relevant parameters in the RealBattery module.

Set resource amounts

To determine the correct amount of resources, multiply RBbaseVolume by the unitsPerVolume value specified in the corresponding B9_TANK_TYPE. Let’s take a lithium-ion battery as an example:

B9_TANK_TYPE
{
    name = Li_ion
    tankMass = 0.004
    tankCost = 12
    RESOURCE
    {
        name = ElectricCharge
        unitsPerVolume = 0.8
    }
    RESOURCE
    {
        name = StoredCharge
        unitsPerVolume = 0.2
    }
}

In your patch, you would write:

@RESOURCE[ElectricCharge]
{
    @maxAmount = #$../RBbaseVolume$
    @maxAmount *= 0.8
    @amount = #$../RBbaseVolume$
    @amount *= 0.8
}
%RESOURCE
{
    %name = StoredCharge
    %maxAmount = #$../RBbaseVolume$
    @maxAmount *= 0.2
    %amount = #$../RBbaseVolume$
    @amount *= 0.2
}

Adjust mass and cost (standalone batteries only)

If the part is a standalone battery (not, for example, a probe or crew module), you should also update the part’s mass and cost using the tankMass and tankCost values from the tankType:

@mass = #$/RBbaseVolume$
@mass *= 0.004

@cost = #$/mass$
@cost *= 12

Configure the RealBattery Module

Finally — and most importantly — you must add the RealBattery module itself. Most values can be copied directly from the corresponding DATA section used in the battery SUBTYPE definition.

MODULE
{
    name = RealBattery
    BatteryTypeDisplayName = #LOC_RB_short_Li_ion
    HighEClevel = 0.95
    LowEClevel = 0.90
    Crate = 1
    SelfDischargeRate = 0.01
    CycleDurability = 1000
    ThermalLoss = 0.15
    ChargeEfficiencyCurve
    {
        key = 0.0 0.80
        key = 0.3 0.85
        key = 0.6 0.90
        key = 0.85 0.85
        key = 1.0 0.80
    }
}

Note: Most battery subtypes do not explicitly include HighEClevel and LowEClevel values, unless they are non-rechargeable batteries (in which case HighEClevel = 2). These values can be omitted; the module will fall back to default thresholds if not provided.

Adding multiple Battery Types

To add multiple battery variants to a part using B9PartSwitch, the process is very similar to adding a single type. As before, you’ll need to calculate the RBbaseVolume, and add both the StoredCharge resource and the RealBattery module.

These latter elements may use placeholder or default values since they will be overridden by each subtype at runtime. However, for visual consistency in the editor, it's recommended to copy the key values from the **first subtype **— especially BatteryTypeDisplayName, Crate, and optionally HighEClevel and LowEClevel. Other parameters (like durability, efficiency, thermal loss) do not show in the editor and can be omitted at this stage.

So the first part of your patch will look very similar to the single-chemistry example:

RBbaseVolume = #$/RESOURCE[ElectricCharge]/maxAmount$
@RBbaseVolume *= 0.3

@mass = #$/RBbaseVolume$
@mass *= 0.004

@cost = #$/mass$
@cost *= 12

@RESOURCE[ElectricCharge]
{
    @maxAmount = #$../RBbaseVolume$
    @maxAmount *= 0.8
    @amount = #$../RBbaseVolume$
    @amount *= 0.8
}
%RESOURCE
{
    %name = StoredCharge
    %maxAmount = #$../RBbaseVolume$
    @maxAmount *= 0.2
    %amount = #$../RBbaseVolume$
    @amount *= 0.2
}
MODULE
{
    name = RealBattery
    BatteryTypeDisplayName = #LOC_RB_short_Li_ion
    Crate = 1
    HighEClevel = 0.95
    LowEClevel = 0.90
}

B9PartSwitch Configuration

You’ll now need to add the main switch module, which can be used as-is across parts:

MODULE
{
    name = ModuleB9PartSwitch
    moduleID = batterySwitch
    switcherDescription = #LOC_RB_batterySwitcherDescription
    switcherDescriptionPlural = #LOC_RB_batterySwitcherDescriptionPlural
    baseVolume = #$../RBbaseVolume$
}

Adding Subtypes

Each subtype must then be defined inside ModuleB9PartSwitch. You can copy them directly from the default library of subtypes. The only required change is to remove or comment out the upgradeRequired field from the first subtype, otherwise no batteries may show up in the editor if the required tech node is not yet unlocked.

In the following example, we define two subtypes: Li-ion (default in this part, no tech requirement) and Solid State:

SUBTYPE
{
    name = Li_ion
    title = #LOC_RB_title_Li_ion
    descriptionSummary = #LOC_RB_descSum_Li_ion
    descriptionDetail = #LOC_RB_descDet_Li_ion
    tankType = Li_ion
    // upgradeRequired = RB_UpgradeLiIon
    defaultSubtypePriority = 6
    MODULE
    {
        IDENTIFIER
        {
            name = RealBattery
        }
        DATA
        {
            BatteryTypeDisplayName = #LOC_RB_short_Li_ion
            Crate = 1
            SelfDischargeRate = 0.01
            CycleDurability = 1000
            ThermalLoss = 0.15
            ChargeEfficiencyCurve
            {
                key = 0.0 0.80
                key = 0.3 0.85
                key = 0.6 0.90
                key = 0.85 0.85
                key = 1.0 0.80
            }
        }
    }
}
SUBTYPE
{
    name = SSB
    title = #LOC_RB_title_SSB
    descriptionSummary = #LOC_RB_descSum_SSB
    descriptionDetail = #LOC_RB_descDet_SSB
    tankType = SSB
    upgradeRequired = RB_UpgradeSSB
    defaultSubtypePriority = 9
    MODULE
    {
        IDENTIFIER
        {
            name = RealBattery
        }
        DATA
        {
            BatteryTypeDisplayName = #LOC_RB_short_SSB
            Crate = 2
            SelfDischargeRate = 0.003
            CycleDurability = 10000
            ThermalLoss = 0.05
            ChargeEfficiencyCurve
            {
                key = 0.0 0.90
                key = 0.2 0.95
                key = 0.8 0.95
                key = 1.0 0.90
            }
        }
    }
}

Creating a new Battery Type

RealBattery includes many battery chemistries actually used in the aerospace industry, as well as some speculative or futuristic ones. However, if you'd like to create your own custom battery type, this section explains how to do it.

Define the Battery specs

Start by choosing the specifications of your battery. The key parameters are:

  • Energy density by mass (Wh/kg)
  • Energy density by volume (Wh/L)
  • Power density by mass (W/kg)
  • Cost ($/kWh)
  • Charge efficiency (%)
  • Self-discharge rate (%/month)
  • Cycle durability (number of cycles)

⚠️ The last two values (self-discharge and durability) are not yet functional in the current release, but it's a good idea to include them anyway, for compatibility with future updates.

You can find real-world data for most battery chemistries online; consider that energy density and power density are sometimes also called specific energy and specific power. Alternatively, you’re free to invent your own specs for fictional, exotic, or intentionally overpowered ("cheaty") battery types.

All of these parameters will need to be converted into in-game values for the config files. To make this easier, we provide a spreadsheet that does the math for you (also included in the mod release):

📎 Battery Balancing Calculator (Google Sheet)

⚠️ For balance reasons, all default RealBattery chemistries are nerfed to approximately one-third of their real-world energy and power values. The spreadsheet returns both realistic and KSP-balanced values.

Write the Config

Once you’ve defined and calculated all parameters, you can write the corresponding config blocks using the examples in the previous sections.

If you plan to use your custom battery as a B9PartSwitch subtype, you must also define a matching B9_TANK_TYPE. Here’s a template you can copy and fill in:

B9_TANK_TYPE
{
    name =                 // Unique internal ID
    primaryColor =         // HEX color for UI
    secondaryColor =       // HEX color for UI

    tankMass =             // Mass per unit volume (tons)
    tankCost =             // Cost per unit mass (funds/t)

    RESOURCE
    {
        name = ElectricCharge
        unitsPerVolume =   // Power capacity per unit volume (kW/L)
    }
    RESOURCE
    {
        name = StoredCharge
        unitsPerVolume =   // Energy capacity per unit volume (kWh/L)
    }
}

For more details on how B9_TANK_TYPE works, refer to the official B9PartSwitch documentation.