Jump to content

Community driven documentation masterpost


stupid_chris

Recommended Posts

Given the ridiculous amount of sticky threads this forum is getting, we've decided to regroup the information into one place.

Below, you will be able to find the OP of the documentation oriented and informative threads to help in your various modding endeavours. A link to the full thread with the active discussion will also be provided.

Threads:

  • Stock Part Cost and Balance Spreadsheet for 0.24
  • Contract Modding Information for Mod Authors
  • Science and mods!

Edited by stupid_chris
Link to comment
Share on other sites

Originally posted by Tiberion

Stock Part Cost and Balance Spreadsheet for 0.24

Here is a Google Speadsheet with the stock parts broken down into categories. You can see their costs and some important stats to see how they stack up. It should help you figure out a base line for your own parts, should you want to balance them against stock numbers.

https://docs.google.com/spreadsheets/d/1nbUSmw0NpyEzEMRKvCoML1t3SVWDxAi6SH1utMiI-Yw/edit?usp=sharing

I was updating it through testing, but doing so by hand is a bit of work so there may be some typos or out of date things. I don't think so, but its possible, so feel free to look it over and check it out.

This isn't the place to argue about part balance by the way; making sweeping balance changes was not the focus, though the devs worked long and hard and were able to squeeze quite a few tweaks in, so be sure to thank them.

Anyone is free to grab a copy and make derivatives or whatever. Send me a PM if you have trouble using it. Feel free to post corrections here and I'll make them.

Edited by stupid_chris
Link to comment
Share on other sites

Originally posted by MrHappyFace

Contract Modding Information for Mod Authors

As you can see, there are now some contracts asking you to dock around Kerbin, of course, it needs some work (the insane rewards are insane), but it is basically the framework for a modded contract. It was also generated based on how far i had advanced (none at all, because it was a testing world, hence why it said Kerbin instead of Jool or something crazy like that)

Notes:

  • MOST Contract related stuff is found in the Contracts namespace
  • any class extending Contract (in the namespace Contracts) is automatically found and added

Creating a contract:

  1. Make a class that extends Contract, the game automatically finds all classes extending Contract and adds them in.
  2. override the following methods:
    • Generate()
    • CanBeCancelled()
    • CanBeDeclined()
    • GetHashString()
    • GetTitle()
    • GetDescription()
    • GetSynopsis()
    • MessageCompleted()
    • OnLoad()
    • OnSave()
    • MeetRequirements()

[*]In Generate(), you MUST call the following things:

  • base.SetExpiry()
  • base.SetScience(float reward, CelestialBody)
  • base.SetDeadlineYears(float numberOfYears, CelestialBody targetBody) OR base.SetDeadlineDays(float numberOfDays, CelestialBody targetBody)
  • base.SetReputation(float reward, float failiure, CelestialBody targetBody)
  • base.SetFunds(float advance, float reward, float failiure, targetBody)

[*]In Generate(), add some parameters using this.AddParameter(ContractParameter parameter, string id). I have no clue what id does, I just use null, which seems to work, Ill talk about ContractParameters later in this thread, but for now, just use new KerbalDeaths(), which will make you fail the contract if you kill any victims kerbals while the contract is active. The stock ContractParameters are in the namespace Contracts.Parameters, so try messing around with those.

[*]In MeetRequirements(), you can check if this contract should show up in mission control, and return false is it shouldn't and true if it should.

[*]the rest is customizable, but if you fill out the GetTitle(), GetDescription(), GetSynopsis(), and MessageCompleted(), it should show up in game. Mess around with the TextGen class (which, of course, is in the namespace Contracts)

ContractParameters:

  1. Make a class extending ContractParameter
  2. Override the following methods:
    • OnRegister()
    • OnUnregister()
    • OnLoad()
    • OnSave()
    • GetTitle()
    • GetHashString()

[*]In OnRegister(), put initialization code such as adding to a GameEvent, or instantiating a new MonoBehaviour

[*]In OnUnregister(), put code similar to what you would expect in OnDestroy(), such as removing a GameEvent added in OnRegister() or destroying a MonoBehaviour created in OnRegister()

[*]OnSave() and OnLoad() are where you handle persistence, keep in mind that in OnSave(), NEVER use node.SetValue(), ALWAYS usennode.AddValue()

[*]In GetTitle(), simply return the name of your parameter, like "Orbit " + targetBody.the name

[*]use base.SetComplete() to complete the contract.

Using ProgressTracking to select targets based on progress: such an imaginative title!

  • ​just mess around with the ProgressTracking class and the protected static methods in the Contract class, such as Contract.GetBodies_NextUnvisited(). Use these in Generate () in your contract class to select the targetBody parameter used in SetScience() and SetFunds() in your contract class. You should also pipe the targetBody parameter into the the ContractParameter you made.

Example Code:

Note: I dont care what you do with this code, its in the public domain

DockingContract.cs:


using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Contracts;
using Contracts.Parameters;
using KSP;
using KSPAchievements;
using ContractsPlus.Contracts.Parameters;

namespace ContractsPlus.Contracts
{
public class DockingContract : Contract
{
CelestialBody targetBody = null;

protected override bool Generate ()
{
targetBody = GetNextUnreachedTarget (1, true, false);
if (targetBody == null)
{
targetBody = Planetarium.fetch.Home;
Debug.LogWarning ("targetBody could not be computed, using Kerbin");
}

CelestialBodySubtree progress = null;
foreach (var node in ProgressTracking.Instance.celestialBodyNodes)
{
if (node.Body == targetBody)
progress = node;
}
if (progress == null)
{
Debug.LogError ("ProgressNode for targetBody " + targetBody.bodyName + " not found, terminating contract");
return false;
}

if (progress.docking.IsComplete)
{
Debug.Log ("Docking has already been completed for targetBody " + targetBody.bodyName + ", terminating contract");
return false;
}
bool manned = UnityEngine.Random.Range (0, 1) == 0;

this.AddParameter (new DockingParameter (targetBody, manned), null);
if (manned)
this.AddParameter (new KerbalDeaths(), null);

base.SetExpiry ();
base.SetScience (2.25f, targetBody);
base.SetDeadlineYears (1f, targetBody);
base.SetReputation (150f, 60f, targetBody);
base.SetFunds(15000f, 50000f, 35000f, targetBody);
return true;
}

public override bool CanBeCancelled ()
{
return true;
}
public override bool CanBeDeclined ()
{
return true;
}

protected override string GetHashString ()
{
return targetBody.bodyName;
}
protected override string GetTitle ()
{
return "Dock in orbit around " + targetBody.theName;
}
protected override string GetDescription ()
{
//those 3 strings appear to do nothing
return TextGen.GenerateBackStories (Agent.Name, Agent.GetMindsetString (), "docking", "dock", "kill all humans", new System.Random ().Next());
}
protected override string GetSynopsys ()
{
return "Dock two vessels in orbit around " + targetBody.theName;
}
protected override string MessageCompleted ()
{
return "You have succesfully docked around " + targetBody.theName;
}

protected override void OnLoad (ConfigNode node)
{
int bodyID = int.Parse(node.GetValue ("targetBody"));
foreach(var body in FlightGlobals.Bodies)
{
if (body.flightGlobalsIndex == bodyID)
targetBody = body;
}
}
protected override void OnSave (ConfigNode node)
{
int bodyID = targetBody.flightGlobalsIndex;
node.AddValue ("targetBody", bodyID);
}

//for testing purposes
public override bool MeetRequirements ()
{
return true;
}

protected static CelestialBody GetNextUnreachedTarget(int depth, bool removeSun, bool removeKerbin)
{
var bodies = Contract.GetBodies_NextUnreached (depth, null);
if (bodies != null)
{
if (removeSun)
bodies.Remove (Planetarium.fetch.Sun);
if (removeKerbin)
bodies.Remove (Planetarium.fetch.Home);

if (bodies.Count > 0)
return bodies [UnityEngine.Random.Range (0, bodies.Count - 1)];
}
return null;
}
}
}

DockingParameter.cs:


using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Contracts;
using KSP;
using KSPAchievements;

namespace ContractsPlus.Contracts.Parameters
{
public class DockingParameter : ContractParameter
{
public CelestialBody targetBody;
public bool manned = false;

public DockingParameter(CelestialBody target, bool manned)
{
this.targetBody = target;
this.manned = manned;
}

protected override string GetHashString ()
{
return targetBody.bodyName;
}
protected override string GetTitle ()
{
return "Dock two vessels in orbit around " + targetBody.theName;
}

protected override void OnRegister ()
{
GameEvents.onPartCouple.Add (OnDock);
}
protected override void OnUnregister ()
{
GameEvents.onPartCouple.Remove (OnDock);
}

protected override void OnSave (ConfigNode node)
{
int bodyID = int.Parse(node.GetValue ("targetBody"));
foreach(var body in FlightGlobals.Bodies)
{
if (body.flightGlobalsIndex == bodyID)
targetBody = body;
}
}
protected override void OnLoad (ConfigNode node)
{
int bodyID = targetBody.flightGlobalsIndex;
node.AddValue ("targetBody", bodyID);
}

private void OnDock(GameEvents.FromToAction<Part, Part> action)
{
if (manned)
{
if (action.from.vessel.GetVesselCrew ().Count > 0 && action.to.vessel.GetVesselCrew ().Count > 0)
{
if (action.from.vessel.mainBody == targetBody && action.to.vessel.mainBody)
{
base.SetComplete ();
}
}
}
else
{
if (action.from.vessel.mainBody == targetBody && action.to.vessel.mainBody)
{
base.SetComplete ();
}
}
}
}
}

:)

Feel free to contribute and/or correct me if im wrong.

Edited by stupid_chris
Link to comment
Share on other sites

Originally posted by DYJ

Science and mods!

Additions to PART {}

.22 adds two new parameters to PART, TechRequired and entryCost.

TechRequired is what research node unlocks your part.

entryCost is the cost of the part - in credits - when the node has been researched. Cost isn't actually implemented, the player has a bottomless wallet with the parts being automatically purchased upon researching a node.

New modules.

ModuleScienceExperiment

ModuleScienceExperiment is the new module for science stuff, it's fairly straight forward but references the ScienceDefs.cfg science definition file. For this to work just make sure the id matches in both .cfgs.

It automatically activates animations set up with the default ModuleAnimateGeneric module.

ModuleDataTransmitter

Antennae module. Same as ModuleScienceExperiment in regards to animations.

ModuleLandingLeg

New landing leg module, set up like so: http://i.imgur.com/kKMEbtk.png

ModuleScienceContainer

Allows the storage of science reports.

ScienceDefs.cfg

Located in GameData/Squad/Resources, works the same way as the resources definition. So you can make your own and package it with your mod just like the resources.cfg.

This file contains all flavour text and defines what can do science where, if you don't want to see spoilers don't read it.

SituationMask & biomeMask are bitmasks defining where the part can do science.

SituationMask determines in which of the following conditions science can be gathered:

SrfLanded = 1 SrfSplashed = 2, FlyingLow = 4, FlyingHigh = 8, InSpaceLow = 16, InSpaceHigh = 32

[TABLE]

[TR]

[TH][/TH]

[TH]InSpaceHigh = 32[/TH]

[TH]InSpaceLow = 16[/TH]

[TH] FlyingHigh = 8[/TH]

[TH]FlyingLow = 4[/TH]

[TH]SrfSplashed = 2[/TH]

[TH]SrfLanded = 1[/TH]

[TH]Binary[/TH]

[TH]Decimal[/TH]

[/TR]

[TR]

[TD]Option with everything selected:[/TD]

[TD]1[/TD]

[TD]1[/TD]

[TD]1[/TD]

[TD]1[/TD]

[TD]1[/TD]

[TD]1[/TD]

[TD]111111[/TD]

[TD]63[/TD]

[/TR]

[TR]

[TD]Option with only FlyingLow selected:[/TD]

[TD]0[/TD]

[TD]0[/TD]

[TD]0[/TD]

[TD]1[/TD]

[TD]0[/TD]

[TD]0[/TD]

[TD]000100[/TD]

[TD]4[/TD]

[/TR]

[/TABLE]

The number you need to input is a decimal conversion of binary yes/no selection.

So you grab the number you've gotten by filling out the options above and run it through a binary converter like this one: http://www.binaryhexconverter.com/binary-to-decimal-converter

BiomeMask works in a similar way but determines when biomes play a part in your science gathering.

Think of it as you are filling the list out again, 111111 or 63 is always. 000100 or 4 is only when flying low.

This allows your ground poking instrument to care about if you are in the desert or not while letting a deepspace radiowavesomethingorother not bother checking what it happens to be above.

Additional researchnodes.

A few extra empty nodes have been added to allow easy endgame tie-in by mods. As shown here: http://i.imgur.com/OkwRzka.png

Names are as follows:

experimentalRocketry

nanolathing

experimentalAerodynamics

aerospaceTech

experimentalElectrics

experimentalScience

automation

experimentalsMotors

If you have something that feels relevant please post it in this thread.

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
×
×
  • Create New...