Jump to content

Recommended Posts


  • Unity Engine has been upgraded to 5.4.0p4 - This is a patch version. Go to the Unity site and "get Unity" then go to the patch releases page.

  • KSPUtil.dll has been merged into Assembly-CSharp.dll - change references in your Project.

  • A LOT of redudant classes that were not being used any more have been removed.

  • KSP now uses 9.80665 and 6.67408e-11 instead of 9.81 and 6.674e-11 for gravity equations.

  • KSPedia and asset bundles generation still has to be built in Unity 5.2.4 editor.





  • Now contains a HostedFromToAction. The Host is the Source part the transfer is initiating from.



  •    Fires on a crew transfer when User selects a FullPart as the destination part BEFORE the ScreenMessage is posted.

  •    Allows mod to customise the CrewTransfer.fullMessage.


  • Fires when the user clicks the Transfer Crew button. You can then set the CrewHatchController.overrideTransfer to false and the stock transfer will stop there. Allowing a mod to completely control their own crew transfer.


  • Fires when the user clicks the EVA button. You can then set the FlightEVA.overrideEVA to false and the EVAr will stop there. Allowing a mod to completely control or block EVAs.


  • Fires when a PartItemTransfer is commenced. (see info on this class below).


  • Fires any time a part is added or removed, the moment it happens, unlike onVesselModified.


  • Collects various vessel events and fires them off with a single one.

  •    Specifically - onPartAttach,onPartRemove,onPartCouple,onPartDie,onPartUndock,onVesselWasModified,onVesselPartCountChanged


  • Fires whenever a parts priority (staging, etc) are changed.


  • Fires whenever a parts crossfeed state changes.


  • Fires whenever fuelline states change.


  • Fires when the screen resolution is modified.


  • Fires whenever a custom waypoint is created/saved.


  • Fires whenever a custom waypoint is loaded.


  • Fires whenever events cause the undo logic to save in the editor.


  • Fires after a Pod is actually added to the vessel in the Editor.


  • Fires when the user dismisses the “do you want to save this new ship” dialog in the Editor.


  • Called when the CommNet is Initialised at startup.


  • Fired when the node network initializes - can take a few frames


  • Called when KerbNet vessel changes


  • When the Gforces on vessel exceed a parts gTolerance this event will fire. (per part).


  • Fired when a kerbal grabs a ladder attached to a part


  • Fired when a kerbal leaves a ladder attached to a part


  • Fires right before a vessel's VesselPrecalculate component is added so something else can add a different one


  • Fires when the VesselPrecalculate component engages physics easing.


  • Fires when the VesselPrecalculate component ends physics easing.


  • Fires when an orbital survey is completed.


  • Fires when a Kerbal is levelled up.


  • Fires when Resource Converter Efficiency changes.


  • When the Pressure on vessel exceed a parts maxPressure this event will fire. (per part).


  • Fires when a kerbals active/inactive state changes. (Unconscious)


Game Parameters:

New Game Parameters

  • Highlogic.CurrentGame.Parameters.CustomParams<GameParameters.DifficultyParams>().EnableCommNet - True/False Commnet can be turned Off or On.

  • Highlogic.CurrentGame.Parameters.CustomParams<GameParameters.DifficultyParams>().RespawnTimer - This is the Kerbal Respawn period. Is initially set to GameSettings.DEFAULT_KERBAL_RESPAWN_TIMER but user can change it for each save game. Mods should look to use this parameter for kerbal respawn.

  • Highlogic.CurrentGame.Parameters.CustomParams<GameParameters.AdvancedParams>().EnableKerbalExperience - If this is off all kerbals start with maximum experience. If on then kerbals gain experience over time and gain that experience on recovery or immediately depending on the value of ImmediateLevelUp.

  • Highlogic.CurrentGame.Parameters..CustomParams<GameParameters.AdvancedParams>().ImmediateLevelUp - Applies experience immediately and kerbals level up immediately instead of when they are recovered.

  • Highlogic.CurrentGame.Parameters..CustomParams<GameParameters.AdvancedParams>().AllowNegativeFunds - If on Career games can go into negative funds.

  • Highlogic.CurrentGame.Parameters..CustomParams<GameParameters.AdvancedParams>().AllowNegativeScience - If on science and career games can go into negative science.

  • Highlogic.CurrentGame.Parameters.CustomParams<GameParameters.AdvancedParams>().BuildingImpactDamageMult - A multiplier applied to and building damage.

  • Highlogic.CurrentGame.Parameters.CustomParams<GameParameters.AdvancedParams>().IResourceTransferObeyCrossfeed - If enabled prevents manual resource transfers across parts where crossfeed has been disabled.

  • HighLogic.CurrentGame.Parameters.CustomParams<CommNetParams>().DSNModifier - Multiplier applied to the size of the DSN. (default = 1).

  • HighLogic.CurrentGame.Parameters.CustomParams<CommNetParams>().occlusionMultiplier - Multiplier applied to the effective size of objects that can occlude antennas. (default 0.9f).

  • HighLogic.CurrentGame.Parameters.CustomParams<CommNetParams>().rangeModifier - Modifier added to the effective range of antenna. (Default = 1).

  • HighLogic.CurrentGame.Parameters.CustomParams<CommNetParams>().requireSignalForControl - If true ModuleCommand requires a connection (or crew) to have control or partial control of the vessel. (Used by all ModuleCommand parts).

  • HighLogic.CurrentGame.Parameters.CustomParams<GameParameters.AdvancedParams>().PartUpgradesInSandbox - If true allows Part upgrades in Sandbox mode.



Other notes:

  • Do not call FlightGlobals.SetActiveVessel from inside OnGUI code against an unloaded vessel or it will cause Unity to crash to desktop. If you need logic in OnGUI for this, store the switch/vessel in a static and call SetActiveVessel in next Update cycle.

  • KSPAddon now supports the following:
  • KSPAddon.Startup.AllGameScenes, KSPAddon.Startup.FlightAndEditor, KSPAddon.Startup.FlightAndKSC

  • Having a const field defined on a PartModule is now supported.

  • Support for custom Mod TechTree Icons and loading of TechTree added. In the TechTree.cfg just specify a GameData relative path to the Icon you want.

  • Mods can now use the Stock Game Difficulty Settings Menus through extensions for New Games and the In-Game Settings Menus. For more details see the “Mod Integration into Stock Settings section below”.

  • Vessel now has a Vessel.resourcePartSet which uses the PartSet class. For more Details see the “PartSet Class” section below.

  • There is now a FlightGlobals.VesselsLoaded and FlightGlobals.VesselsUnloaded which lets us iterate over a specific portion of Vessels without checking the entire list.

  • Added many accessors/setters. 

  • Vessel control level can be clamped to a field in Vessel (so can be restricted to Partial even if otherwise would be Full).  There is a public get accessor:- Vessel.CurrentControlLevel which will return one of Vessel.ControlLevel's values.

  • GetModuleMass/Cost methods can now be passed the situation.

  • Fix where kerbal mass (if set to nonzero) was not applied in the editor.

  • Added two new dictionary-related classes (DictionaryValueList and ListDictionary).

    • DictionaryValueList<TKey, TValue> can be used to store TKey, TValue dictionary also supplies an updated TValue List.

    • ListDictionary : ICollection, IDictionary, IEnumerable. An IDictionary using a singly linked list. Recommended for collections that typically contain 10 items or less.

  • Celestial bodies now cache all of their PQS Cities. PQSCity[] CelestialBody.pqsCities.

  • GetAtmoThermalStats, GetAtmoSolarStats, GetFullTemperature(pos) and GetFullTemperature(alt, atmoTempOffset) have been moved from FlightIntegrator to CelestialBody.

  • All game root nodes now generate a random persistent seed, which is different from game to game. HighLogic.CurrentGame.Seed. Is used by stock for chances to see anomolies in KerbNet, but mods can use it for other random number seed generation.

  • All forces on valid parts except wheel forces are now done via Part.AddForce/Torque/AddForceAtPosition. Note that the forcemode used is Force; to use a different forcemode, convert the force to the correct amount. It is the job of the Flight Integrator to then apply all these forces to actual rigidbodies (rather than all the disparate modules' job). You must convert from rb.addforce!!

  • Inverse rot thresh is clamped to be >= atmo depth.

  • The CBs bodyPosition is passed on to PQS as 'precisePosition'.  
    All PQSSurfaceObjects are tracked (PQSCity derives from that now) - that array is set in Start.

  • The CBs recip of the rotation period is cached.

  • There are more and faster lat/long/alt methods.

  • Use mass-weighted average angular velocity of parts for vessel angular velocity.

  • ITorqueProvider now reports two Vector3s, positive torque (that produced by control

actuation 1,1,1) and negative torque (that produced by -1,-1,-1).

  • Node definitions can take an extra digit after size, either 0 or 1: that sets whether the node can crossfeed. Defaults to 1 (yes).

  • ModuleEngines now supports `clampPropReceived = True`. This will clamp the ratio of propellant requested based on prior results. So if IntakeAir is listed first and less than the full requirement is returned, it will only request that ratio of further propellants. In this case the "Prop Req Met" display will show the minimum requirement-met ratio rather than the average. Engines that use IntakeAir (or other cases like that) need to have `clampPropReceived = True` in each of their MODULEs that do that, and need to have that PROPELLANT first and the other PROPELLANTs later. See stock jet cfgs for examples.

  • ModuleEngines now supports Real Fuels-style throttling and rates.

  • ModuleEngines now supports throttle-Isp interactions.

    • Turn on with useThrottleIspCurve = True and set the throttleIspCurve and throttleIspCurveAtmStrength curves.

    • throttleMin is set by minThrust/maxThrust

    • 0 throttle = 0 thrust, else it lerps between minThrust and maxThrust

    • throttlingBaseDivisor should be set to 1 for RF engines, 0.2 is for the 5x-as-heavy stock ones.

    • Final Isp = input Isp * Lerp(1, throttleIspCurve.Eval(throttle state), throttleIspCurveAtmStrength.Eval(atms of pressure)).

  • Allow kerbals to have/save/load arbitrary experience points. ProtoCrewMember.ExtraExperience can be used to record Additional arbitrary experience points for a kerbal (automatically added to the kerbals experience and Level).

  • Replaced all checks for experience traits (Pilot, Scientist, Engineer) with individual experience effects.

  • ModuleExperienceManagement partmodule added - Is configured to the MPL (Science Lab) but can be added to any part. Allows recording of experience/flight logs without having to return crew to Kerbin.

  • ResearchAndDevelopment.GetTechnologyTitle(string id) will convert a tech ID to a tech title.

  • Support max pressure (dynamic + static), `maxPressure`, and max G, `gTolerance`, for parts.  

  • Added CelestialBody.hasSolidSurface so mods that add a PQSController to gas giant don't cause silly things such as "Plant a flag on Jool" contracts.

  • Added CelestialBody.minOrbitalDistance - this is set in CB Setup to be the minimum safe orbital radius.

  • Added CelestialBody.scaledEllipsoid - can use this horizon culling for occlusion.

  • Added CelestialBody.scaledElipRadMult - the ellipsoid axes.

  • Added CelestialBody.scaledRadiusHorizonMultiplier - mult to radius. I.e. Kerbin has 0.72 or so due to bouncing off atmosphere

  • Added KSPAssemblyDependencyEqualMajor as an attribute. Use instead of KSPAssemblyDependency if you want to force requiring the stated major version, not >= the major version, from your dependency.

  • AssemblyDependancy has been fixed and new KSPAssemblyDependencyEqualMajor added.

  • If you are setting a vessel's position and/or changing its orbit, call Vessel.IgnoreGForces(framecount) on the vessel for the number of frames that g forces should be ignored (try 1, then 2 if that doesn't work, etc).

  • ModuleDeployablePart (covers antennas, solars, radiators) also has a gResistance (for Gs) as well as windResistance (for Q).    NOTE: (This is old but still true): Vessel.obt_velocity and .srf_velocity and the spd versions are not valid in FixedUpdate unless on rails. This is because they are based off what the orbit is estimated to be after PhysX integration runs (i.e. after all FixedUpdates run).    

  • Crew transfer now derives from a generic abstract PartItemTransfer class. Classes can derive from it to implement any kind of (crew transfer-style) part-part transfer. Also an event is fired right before a crew transfer is created so mods can just kill it and easily create their own CrewTransfer-derived class and have that be called on that event (see also new GameEvents).

  • KerbalRoster.ExperienceConfig is now GameDatabase.Instance.ExperienceConfigs

  • There is a new PartItemTransfer abstract class that is applied to CrewTransfer (previous point), and ExperimentTransfer (ModuleScienceExperiment and ModuleScienceContainer). For more information see the PartItemTransfer Class section below.

  • Extended ModuleScienceContainer to send and, from (from ModuleScienceExperiment) receive, experiment data.

  • ModuleDeployableSolarPanel.panelStates has moved to ModuleDeployablePart.DeployState. ModuleDeployableSolarPanel now inherits ModuleDeployablePart.

  • You can now delete Editor Custom Part Filters. KSP.UI.Screens.PartCategorizer.DeleteCategory() and DeleteSubcategory() are now public.

  • You can now access the SelectedVessel and SetVessel method in the TrackingStation. KSP.UI.Screens.SpaceTracking.SelectedVessel and KSP.UI.Screens.SpaceTracking.SetVessel.

  • New PartModule ModuleColorChanger - effectively split off from ModuleAblator. Allows you to animate a shader on a part eg: emissive, lights, ablator, whatever you can think of. For more details see the “Module ColorChange” section below.

  • PartModules now support upgrades. (see the ”Partmodule Upgrades” section below).

  • New module ModuleRCSFX is available

  • inverseStageCarryover - new field added to part config files (true by default). Governs whether a parts inverseStage should carry over to child parts. Disabled on all fairings.

  • vessel.EVALadderVessel -  returns the vessel of the part of the ladder the kerbal is on, or just vessel (if non kerbal, no ladder, non ladder-on-part-on-vessel). That's beyond kerbalEVA.LadderPart, which returns the part of the ladder the kerbal is on, or null. It can be used when say, you want the correct situation (i.e. if a kerbal is on a ladder, use the ladder vessel's SITUATION, otherwise use the actual vessel's).

  • All Methods and properties in ModuleDataTransmitter have been made virtual.

  • All Methods in VesselPrecalculate have been made virtual.

  • InputLockManager now has IsAllLocked() and IsAnyUnlocked()

  • VesselModule now has a public reference to the actual Vessel

  • KerbalEVA, Kerbal, and KerbalExpressionSystem are now all virtuals and PCM.Spawn is now a static delegate (and so can be replaced)

  • FlightEVA pulls from the PartLoader's part list so EVA kerbals can be replaced

  • AssemblyLoader now ignores abstract classes.

  • Added 'requiresFullControl' as an option to UI_Controls, actions, and events. Apply it to the thrust limiter on engines so it cannot be changed when only in partial control.
  • GLimits can now be applied to crew and they can go inactive for periods of time. See ProtoCrewMember.outDueToG/setInactive. When Inactive they affect vessel control and are excluded from EVA and Crew Transfer processing.

  • Add missing add and remove methods to PartResourceList, add event which fires when the list changes.

  • VesselType enum now includes Plane and Relay as a valid vessel type.

  • Public interface IJointLockState. Mods that allow free joint between parts (IR mostly) should implement it on their module so the autostruts don't lock the joint with struts. If you want to check the result there is a "Visualize Autostruts" options in the Physics tab of the console.

  • You can add new display mode to the KerbNet by creating subclass of KerbNetMode and they will be automatically loaded.

  • IContractObjectiveModule interface added to Contracts.

  • Part.highlighter changes. See Part.Highlight/HighlightRecursive/SetHighlight/SetHighlightColor/SetHighlightDefault/SetHighlightType. See also Highlighter and HighLightingSystem classes.

  • VesselType enum now has new values for Plane and Relay

  • ExperimentResultDialogPage has changed and ScienceData.

    •    ScienceData.transmitValue is now ScienceData.baseTransmitValue

    •    ScienceData.labBoost is now derived from ScienceData.transmitBonus which is also used for CommNet transmit boost/bonus.

    •    ExperimentResultDialogPage is now based on the above two values.

  • PartLoader's behaviour has changed. Do not use PartLoader.parts, use Partloader.LoadedPartsList.

  • The three pre-built Part Modules are now available to be modified (FlagSite, KerbalEVA, kerbalEVAfemale). The are located in \GameData\Squad\Parts\Prebuilt.

  • So you can modify using Module Manager config files instead of via code (as was the only way to do this in previous versions).

  • ProtoPartResourceSnapshot.resourceValues is now protected. If you want to read/write packed resources for a ProtoPart use ProtoPartResourceSnapshot.amount which is no a public get/set.

  • Resource handler is now part of the base PartModule.

  • Vessel contains a number of new accessors and counters around Crew.

  • Vessel.crewableParts is the count of parts that can contain crew.

  • Vessel.crewedParts is the count of parts that actually do contain crew.

  • Vessel.GetCrewCount() is the count of crew onboard the vessel.

  • Vessel.getVesselCrew() returns a list of crew onboard the vessel.

  • Vessel.CrewListSetDirty() will set the cached crew list as dirty forcing it to be rebuilt.

  • Vessel.CrewWasModified(vessel) will force the crewlist to be rebuild and fire GameEvents.onVesselCrewWasModified.

  • Vessel.CrewWasModified(vessel, vessel) will do the same as previous but for two vessels passed in.

  • The vesselCrew and crewedParts, crewableParts counts are also stored in the protoVessel when a vessel is unloaded.

  • Staging fields are now part of the base PartModule class. You can set them as part of the PartModule node in the part config file.

    •    bool stagingEnabled - indicates if staging is enabled for a part.

    •    stagingEnableText is a text string you can set that will appear in the PAW (Part Action Window).

    •    bool stagingToggleEnabledEditor if true allows the user to toggle staging for a part in the editor.

    •    bool stagingToggleEnabledFlight if true allows the user to toggle staging for a part in flight.

PartModule Upgrades:

  • PartModules now support upgrades. Upgrades are unlocked via the Tech Tree in career mode and Use the entryCost field.

  • PartModule PartStatsUpgradeModule is used to upgrade PART node stats.

  • PartModule.showUpgradesInModuleInfo is a new KSPField bool. If true Upgrade information will be compiled into the PartInfo and shown where applicable.

  • An UPGRADES node can be added to a PartModule Node to upgrade stats within a PartModule. Multiple UPGRADE nodes are specified within the UPGRADES node to upgrade stats.

  • A PARTUPGRADE node is added which is us

    ed for displaying the Icons and tooltips in the TechTree.

  • The PartUpgradeManager ScenarioModule handles the Upgrading. Mods can Interface to this to modify the stock upgrade behaviour and extend.


    UPGRADE nodes can now have ExclusiveWith__ = [some string]

  • This means you can chain upgrades. Only the last found upgrade of the given string is applied.

  • PartStatsUpgradeModule can now specify mass = [amount] and/or cost = [amount] for an UPGRADE node to specify specific mass or cost to an upgrade.

  • You can also alternatively specify massAdd = [amount] and/or costAdd = [amount] for an UPGRADE node to additively add mass or cost to the previous values.

An Example is easier, this MM file will update the LVT45 maxThrust on the ModuleEngines and maxTemp on the part at GeneralRocketry and AdvRocketry.
Note the "IsAdditiveUpgrade__" field. This field tells the PartModule Load to add the UPGRADE nodes additive. If it is false the nodes will overwrite each other this is only applicable to the PartStatsUpgradeModule.



		showUpgradesInModuleInfo = true
				name__ = LVT45-GenRocketry-Thrust
				techRequired__ = generalRocketry							
				maxThrust = 400
				name__ = LVT45-AdvRocketry-Thrust
				techRequired__ = advRocketry 				
				maxThrust = 900
        name = PartStatsUpgradeModule
        showUpgradesInModuleInfo = true
                name__ = LVT45-GenRocketry-Thrust
                techRequired__ = generalRocketry
				IsAdditiveUpgrade__ = True	
					maxTemp = 2500
                name__ = LVT45-AdvRocketry-Thrust
                techRequired__ = advRocketry
				IsAdditiveUpgrade__ = True	
					maxTemp = 2900

	name = LVT45-GenRocketry-Thrust
	partIcon = liquidEngine2
	techRequired = generalRocketry
	entryCost = 10000
	title = LV-T45 Thrust Upgrade
	description = The LV-T45 engine now generates 400 kN of thrust and has a max temp of 2500.
	name = LVT45-AdvRocketry-Thrust
	partIcon = liquidEngine2
	techRequired = advRocketry
	entryCost = 50000
	title = LV-T45 Thrust Upgrade
	description = The LV-T45 engine now generates 900 kN of thrust and has a max temp of 2900.

PartSet Class:

Vessels now have a Vessel.resourcePartSet which uses the PartSet class.
PartResource is no longer derived from MonoBehaviour, PartResources are built as part of the PartSet for a vessel.

  • Public static in _id is the current counter for the number of Partsets.

  • Public static int NextID - will return the next _id.

  • Public int setId - is the globally valid ID for this set.


  • public virtual void GetConnectedResourceTotals(int id, out double amount, out double maxAmount, bool pulling)

  • public virtual void GetConnectedResourceTotals(int id, out double amount, out double maxAmount, double threshold, bool pulling)

    • The above two methods will return the amount and maxamount of the passed in resource(id) in the partset.

    • Set pulling true if you want to get how much of the resource is actually stored,

    • set pulling false if you want to know how much capacity is available

    • (push) - amount and maxamount will return the amounts of free capacity there is, not how much of the resource is actually stored).

The second method obeys threshold amount.

  • public virtual void GetConnectedResourceTotals(int id, out double amount, out double maxAmount, bool pulling)

  • public virtual void GetConnectedResourceTotals(int id, out double amount, out double maxAmount, double threshold, bool pulling)

    • This method replaces the old RequestResource mechanic, and is called by Part.RequestResource.

  • public virtual double RequestResource(Part part, int id, double demand, bool usePri)
  • usePri - if true, will request resource with respect to the priority set, If false will request resource from all parts regardless of priority.


  • public bool ContainsPart(Part p) - returns true if partset contains a part.

  • public HashSet<Part> GetParts() - returns the set of parts or a new one if set contains none.

  • public bool SetsEqual(HashSet<Part> set) - will do a compare on the passed in set with this set and return true if they contain the same parts or false if they do not.


  • public PartSet(HashSet<Part> parts) - Creates a PartSet that is passed in. (not vessel wide) that will be hooked into GameEvents.onPartResourceFlowStateChange &  GameEvents.onPartResourceFlowModeChange. So when these events fire the PartSet will automatically be updated.

  • public PartSet(Vessel v) - same as the previous, but this is a Vessel wide PartSet.

  • public PartSet(PartSet set) - Makes a copy of a PartSet.

  • public virtual void RebuildVessel(Vessel newVessel) - will recreate PartSet vessel wide.

  • public virtual void RebuildParts(HashSet<Part> newParts) - Rebuilds a PartSet as a crossfeed set.

  • public static void BuildPartSets(List<Part> parts, Vessel v) - Builds the PartSet for a list of parts (say in the editor) or for the entire Vessel if v is not null.

  • public static void AddPartToSet(HashSet<Part> set, Part p, Vessel v) - Recursively add a part to a set, if not in the editor it will also check the vessel for p matches v. Also obeys fuel crossfeed rules.

PartItemTransfer Class:

PartItemTransfer is a  new Abstract class attached to CrewTransfer and ExperimentTransfer.

  • CrewTransfer is tied to the CrewHatchController

  • ExperimentTransfer is tied to the ModuleScienceExperiment and ModuleScienceContainer TransferDataEvent's.

You can now hook into CrewTransfer and override the following:

  • bool IsValidPart(Part p)

  • bool IsSemiValidPart(Part p)

  • HookAdditionalEvents()

  • UnhookAdditionalEvents()

  • AfterPartsFound()

  • OnPartSelect(Part p)

You can now hook into ExperimentTransfer and override the following:

  • bool IsValidPart(Part p)

  • bool IsSemiValidPart(Part p)

  • OnSrcPartSelect(Part p)

  • OnPartSelect(Part p)


Mod integration into Stock Settings:

From V1.2 there is an ability to integrate your mod into the Stock New Game and In-Game Settings Menus.

The class is: GameParameters.CustomParameterNode

You can add a class to your mod derived from this type. It will automatically appear in the new game and in-game settings menus based on parameters you set.

Data is automatically persisted for you into a ConfigNode under the PARAMETERS config node in the save file.

The fields in this class of interest are, you must define public get accessors for these:

  • string Title - The title that will appear at the top of your settings section.

  • string Section - This defines the Tab Name/Section your settings will appear in (name of the table).

  • int SectionOrder - This defines the Order within the Tab for this CustomParameterNode (order within the tab, if you have multiple columns).

  • GameParameters.GameMode GameMode - The gamemodes your settings will appear for.

  • HasPresets - If you have preset values for the difficulty settings (more below)


There are Four Virtual Methods:

  • void SetDifficultyPreset(GameParameters.Preset preset) - Can be overridden to set the various parameters based on the Difficulty button the user presses at the top of the settings window.

  • bool Interactible(MemberInfo member, GameParameters parameters) - Can be overridden to set the various fields to be Interactible or not based on whatever conditions you want to set. Interactible means the field can be set/changed by the user or not.

  • bool Enabled(MemberInfo member, GameParameters parameters) - Can be overridden to set the various fields to be Enabled or not based on whatever conditions you want to set. Enabled means the field will be Visible in the UI or not.

  • IList ValidValues(MemberInfo member)

UI Fields

The following Class Types can be assigned to Variables in the CustomParameterNode:-

  • CustomFloatParameterUI - Define a type Float UI parameter.

  • CustomIntParameterUI  - Define a type Int UI parameter.

  • CustomStringParameterUI - Define a type String UI parameter. - This is NOT an input parameter but a String that you can define that will be displayed in the UI. It has  a special Field public int lines = 1; which you can set to the number of Lines you want the string to be in the UI. Note: any string you assign to this field will NOT auto-wrap but you can insert "\n" returns into the string.

They all inherit Type CustomParameterUI (more below) and have the following public fields:-

  • public float minValue - Set the minimum value for the Input field.

  • public float maxValue = 1f - Set the maximum value for the Input field.

  • public float stepSize = 1f - Set the Step size for the UI slider for the field. (Except for CustomFloatParameterUI)

  • Public int stepCount = 11; - The Step count for the slider. (CustomFloatParameterUI only)

  • Public float logBase; - Log base value for calculating the slider step.(CustomFloatParameterUI only)

  • public string displayFormat = "N0" - Set the Display format for the field in the UI.

  • public bool asPercentage - If true field is displayed/calculated as a percentage.

CustomParameterNode is inherited by the above UI paramater types and also can handle two other types:-

Enum and IList (more to follow below).

It contains the following public fields that you can set on any of the UI parameters:-

  • public string title; - This is the Title String that can override/appear in the UI above the field input. this field is Truncated based on the UI size. This is a limitation that cannot be changed.

  • public string toolTip; - Set this to a string and a tooltip will automatically be provided for your field.

  • public GameParameters.GameMode gameMode = GameParameters.GameMode.ANY; - Set this to the gamemodes you want this field to appear for.

  • public bool newGameOnly; - If set to true only appears in the new game settings menu and won't appear in the in-game settings menu. If false it will appear in both.

  • public bool autoPersistance = true; - Set to false if you don't want this field persisted in the PARAMETERS config node in the save file.

Enum type field

You can define Enum types to a CustomParameterUI. First define an Enum somewhere and use it's type for a CustomParameterUI. (See MyEnum in the example below).


ILIST type field

You can define a List to a CustomParameterUI. (See the Example below)

How to access your settings fields

You can access your fields by doing :-


(or whatever field)

Depending on how your mod operates you may also want to register for the GameEvents:-






An Example:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using UnityEngine;

namespace TestCustomSettings
    public class TestCustomParams : GameParameters.CustomParameterNode
       public enum SomeEnum

       public override string Title { get { return "My Cool Mod's Options"; } }
       public override GameParameters.GameMode GameMode { get { return GameParameters.GameMode.ANY; } }
       public override string Section { get { return "MyCoolMod"; } }
       public override int SectionOrder { get { return 1; } }
       public override bool HasPresets { get { return true; } }
       [GameParameters.CustomParameterUI("My Boolean - Mod Enabled?", toolTip = "test bool tooltip")]
       public bool MyBool = true;
       [GameParameters.CustomStringParameterUI("Test String UI", autoPersistance = true, lines = 2, title = "This is what should show Test string#1", toolTip = "test string tooltip")]
       public string UIstring = "";
       [GameParameters.CustomFloatParameterUI("My Float", minValue = 0.0f, maxValue = 50.0f)]
       public double MyFloat = 1.0f;
       [GameParameters.CustomIntParameterUI("My Integer", maxValue = 10)]
       public int MyInt = 1;
       [GameParameters.CustomIntParameterUI("My Non-Sandbox Integer", gameMode = GameParameters.GameMode.CAREER | GameParameters.GameMode.SCIENCE)]
       public int MyCareerInt = 1;
       [GameParameters.CustomIntParameterUI("My New Game Integer", newGameOnly = true)]
       public int MyNewGameInt = 1;
       [GameParameters.CustomFloatParameterUI("My Percentage", asPercentage = true)]
       public double MyPercentage = 0.5f;
       [GameParameters.CustomIntParameterUI("My Stepped Integer", maxValue = 500000, stepSize = 1000)]
       public int MySteppedInt = 1000;
       [GameParameters.CustomParameterUI("My Enum")]
       public SomeEnum MyEnum = SomeEnum.MEDIUM;
       [GameParameters.CustomIntParameterUI("My Int Property", minValue = 100, maxValue = 500)]
       public int MyProperty { get { return myPropertyBackingField; } set { myPropertyBackingField = value; } }
       private int myPropertyBackingField = 100;
       [GameParameters.CustomParameterUI("My IList Field", toolTip = "ILIST field values")]
       public string MyIlist = "";
       public override void SetDifficultyPreset(GameParameters.Preset preset)
           Debug.Log("Setting difficulty preset");
           switch (preset)
               case GameParameters.Preset.Easy:
                   MyInt = 1;

               case GameParameters.Preset.Normal:
                   MyInt = 2;

               case GameParameters.Preset.Moderate:
                   MyInt = 3;

               case GameParameters.Preset.Hard:
                   MyInt = 4;

       public override bool Enabled(MemberInfo member, GameParameters parameters)
           if (member.Name == "MyBool") //This Field must always be enabled.
               return true;
           if (MyBool == false) //Otherwise it depends on the value of MyBool if it's false return false
               if (member.Name == "UIstring" || member.Name == "MyFloat") // Example these fields are Enabled (visible) all the time.
                   return true;
               return false;

           return true; //otherwise return true

       public override bool Interactible(MemberInfo member, GameParameters parameters)
           if (member.Name == "MyBool") //This Field must always be Interactible.
               return true;
           if (MyBool == false)  //Otherwise it depends on the value of MyBool if it's false return false
               return false;
           return true; //otherwise return true

       public override IList ValidValues(MemberInfo member)
           if (member.Name == "MyIlist")
               List<string> myList = new List<string>();
               foreach (CelestialBody cb in FlightGlobals.Bodies)
               IList myIlist = myList;
               return myIlist;
               return null;


New Game Settings:



ModuleColorChanger & ModuleAnimationSetter:
ModuleColorChanger is  an IScalarModule, and also has an animation version of it, ModuleAnimationSetter


  • public string moduleID = "colorChanger"

  • public string shaderProperty = ""

  • public int shaderPropertyInt

  • public FloatCurve redCurve; - Define a Red floatcurve.

  • public FloatCurve greenCurve; - Define a Green floatcurve.

  • public FloatCurve blueCurve; - Define a Blue floatcurve.

  • public FloatCurve alphaCurve; - Define the alpha floatcurve.

  • public float animRate = 1f; - The speed at which the floatcurve is applied to the colors. Is multiplied by the flixeddeltatime.

  • public bool animState = false; - false = 0 (normalized value) applied to the colors. True = 1.

  • public bool useRate = true; - True will automatically apply the color floatcurve

  • public bool toggleInEditor = true; - Action button to toggle the animation available in the editor

  • public bool toggleInFlight = true; - Action button to toggle the animation available in flight

  • public bool toggleUnfocused = false; - GUI action is available when unfocused

  • public bool toggleAction = false; - Action is set to active or not.

  • public float unfocusedRange = 5f; - The unfocused range.

  • public string toggleName = "Toggle Color"; - Will appear on the Action Button

  • public string eventOnName - Will appear on the Action Button

  • public string eventOffName - Will appear on the Action Button


  • public void SetState(bool val) - Set the rgba values to normalized value 0 (if you pass in false) or 1 (if you pass in true).

  • public void SetState(float val) - Will set the rgba to the normalized value along the floatcurves based on the value passed in.

  • public void SetState(Color val) - Pass in a Color and the rgba values will be set to the passed in color.


Link to post
Share on other sites
This topic is now closed to further replies.
  • Create New...