#Switcharo (Part Switcher API & Mod)
1 messages · Page 1 of 1 (latest)
yeah, like interstellar fuel switch
what
all other API functionality will be added by the modders
Switch any tank to any fuel u desire
well u cant make it have more fuel than original
unless i add rescale to this too but idk
not rlly in the scope
I meant you replace the biggest XL tank from methalox to xenon
Oh lmao yeah, then an 5m ion engine would make sense
also maybe disable EC for this "fuel" switcher? As it is counted as a fuel for so reason
some*
Is this meant to be strictly for fuel switches or will it provide a general part switching API?
it will be kinda like Spitfire where u have a mod with functionalities
but it is optional
and then u also have the API with no functionality
the mod will have the IFS, the API will have every functionality to change parts in the OAB
and the mod will need the API obviously
im thorn between using reflection to get all the fields or setting them up by hand...
i feel like by hand i'll have more control over them, and i'll be able to make a better .cfg
also serialization would require me to go through all the Modules, one by one, to find what module has x field
im a bit against reflection since a lot of public fields are not suposed to be edited on the datas
hm
I guess you could go with reflection along with a list of whitelisted/blacklisted properties?
but that's just adding even more complexity
yeah thats what im doing rn, before i was doing a Type-FieldName list and listing all the fields, but thats a bit dumb, blacklist with only the fieldnames is better
this is a complex thing so 
yeah
and having a cache should solve any issues with performance
especially as more and more mods start to use this
true, hope that SpaceWarps mod list comes soon, that way i can use IF:ModID and just search for the modID on spacewarp
i'll leave that feature oout for now
basically this would be a .cfg
base = partName
ID = someUniqueString
OVERRIDES
cost = 1234
maximumDrag = 1000.0 (any field value pair outside a IF means its for PartCoreData)
IFMODULE:Data_Drag (meaning if the prefab has this data)
weight = .5 (any field value pair inside a IF means its for that data)
ENDIF
IFMODULE:Data_Engine
thrust = 350
ENDIF
IFMOD:sorry (meaning if spacewarp has this module)
ADDMODULE:Module_DeployableControlSurface
DeployAngle = 15(Set the data on the added module)
ENDADD
REMOVEMODULE:Module_ControlSurface
ENDIF
maybe add something before the IF and ADD
like
@IF
@ENDIF
or
#ADDMODULE
#ENDADD
any value not set will be left as the parts default
hm, is there need for another custom format?
I mean it's fine for the part switch I guess
if i do json, i'll need to have all the fields on the json to be able to parse it back
but we already have MM syntax, and there's JSON Patch standard
tbh i can copy MM syntax
let me check, but yeah theres no need for a custom one if i can do the same on others
hmm json patch will leave the .cfg cluttered i think
tbh it's pretty low level
yeah I meant that as a bad thing, really
at least for end users
let me check the MM whole syntax
but if you're thinking of making this into basically what the JsonManager was supposed to be, I think it would be wise to discuss this with the community and decide on a standard together
well, this can deffinetly be adapted to be the JsonManager
the only difference is that this creates a variant, and jsonManager modifies the original
but a patch on the parts loading could replace the Original part with the modified one
let me get a working version and then i'll go into the JsonManager
ok so @novel granite variants and changing the original part its quite different, for variants you can just change the values on GameManager.Instance.Game.Parts before the save game load and you're good
now for variants, aka parts switcher
to avoid creating a new part on the OAB
you have to apply the changes on runtime when the player changes the variant
and then apply them again when the player launches the vehicle
so i dont think that this can reliably be a JsonManager
better yet, this can be either one or another
tho im sure that JsonManager could use my methods/classes to modify the original parts
alright, then I guess since you already have the name and idea, it's best to just keep it as the part switching mod?
I'll make it easy for JsonManager to use this
but yeah i'll keep the part switching mod
because i need it for the non gimbaling engines, and the non deployable gridfins
also i'll use it for the starship engine shroud and a couple more things
https://github.com/blowfishpro/B9PartSwitch jesus I just tried looking into how B9 Part Switch does it in KSP 1
since it still has to deal with a part database and modules and all that
but that's way too much code for me to just quickly skim through lmao
he seems to be using part of the MM parsing
which is making the code wayy too extensive
yeah
because MM has a lot of features, but for variants you only need like 1/3 of them
that was the main reason for me to do the custom syntax
MM is very complete but for variants its not really needed
I mostly just know how B9 works from the user end (by user I mean a mod dev using it)
but basically what json managers will have to do
Create a new Variant, add Overrides to it, and then just retrieve the rawJson from it and apply to the right key value pair in GameManager.Instance.Game.Parts
in most cases you'd just specify the transforms in your model that you want to switch on/off based on the selected variant
Overrides are basically a class with a target (fieldName) and a Value, when someone tries to acess either PartCore or rawJson in the Variant class, those will be applied and the modified PartCore and rawJson will be outputed
yeah i might do that too, but i'm looking for a solution that doesnt leave 10 different variants instantiated in game
maybe, delete them once the craft goes into flight mode? idk i'll look into it
i dont want to do that mostly cuz there are a lot of classes that are not tied to MonoBehaviours
whichever way you do it, I'm sure it will work out great 😄
and a disabled gameobject only affects MonoBehaviours, so if the game tries to access data that are not in the MonoBehaviour loop there might be problems
i hope so!
I think the main advantage for doing it the way that B9PS does is that it utilizes the MM configuration files so it automatically gets cached along with all the patches and new .cfg definitions by MM
hmm thats true, but we dont have an MM yet :s
we really need to get on JsonManager sooner or later, yeah
so that we have a standardized way of dealing with this sort of stuff
I'll try to get the API done first, and share it on the JsonManager topic
instead of each mod having to run its patching code each time the game is run
maybe that'll spark ideas for how to do it there
1st test, set the cost to 1000 and the mass to 10000.5
of the swivel
lets see if it works 🤞
if it does i should have TWR of 0.001 lmao
nice
i tried to launch the craft
and im in space
and my craft is literally bending itself
lmao
jesus that is cursed
also apoapsis of 109m?
-410m below ground?
This is so cursed
i might have changed kerbins orbit for all i know lmao
by the way, how do you set the variant that you want to use?
still havent done that, i plan to do maybe a forward-back button on the PartsManager
like
< {VariantName} >
or a slider maybe? idk
for now i just set this as the default variant to test if it was working
gotcha
I love unities floating point error when it comes to rendering
Also this means that the floatingpointorigin script or whatever its called got a error
this was during a Revert to Launch
when i launched, the craft exploded cuz it was being pulled by the gravity way too much
(100.000t craft so its expected)
the density of that thing must have been crazy 
switching from setting everything on Initialize to adding the variant to the partslist and filtering it out on the OAB
probably will make everything way easier
and will also allow for different gameObjects with different meshes and different modules
changing to Module_Variant
this will also help for JSONManager to change it later
ie: RSS can create a Variant thats a totally new engine, and they can configure via JSONManager for the default variant to be x
@novel granite sounds good?
Module_Variant only stores de variantID
and on Init for OAB Part or for simObjectPart it applies the changes
this way, lets say someone updates the variant overrides, ie he adds a new module, all the instances of that part will be updated
the old way, only new instances of that part would be updated
yeah, that sounds cool
Can't wait for this to come out!
ITS WORKING
THE SWIVEL HAS 2000kn of THRUST NOW
ALL W/O CREATING A NEW PART
LETS FUCKING GOOOOOOOOOOOO
Ok so this is big
Awesome job

syntax for modifying parts
var varBuilder = VariantBuilder.Create("engine_1v_methalox_swivel", "engine_1v_methalox_swivel_variant")
.Modify<double>("Assembly-CSharp", "KSP.Sim.Definitions.PartData", "mass")
.Modify<float>("Assembly-CSharp", "KSP.Modules.Data_Engine", "maxThrust")
.Finish();
PPMPart variant = VariantBuilder.Create(string partName, string variantName/*Must be unique*/)
.Modify<TypeModified>(string AssemblyName, string FullClassName, string fieldName)
.Finish();//Finish() returns a PPMPart, Finish(Action<PPMPart> callback) calls the callback once finished
actually, might not be a bad idea to make the assembly name the last parameter and make it optional, with the default being Assembly-CSharp
since most people will need just the game assembly
and in that case they'd be able to do just
var variant = VariableBuilder.Create("part_name", "variant_name")
.Modify<double>(typeof(PartData), nameof(PartData.mass))
.Finish();
since they can be sure the game's types will exist
the thing with typeof is that they can do typeof(PartData).AssemblyQualifiedName
removing the need fo rthe assembly param
I mean you can make two overloads of the method
yeah exactly
one without an assembly parameter that will just call the other with Assembly-CSharp as the parameter value
var Variant = VariantBuilder.Create("engine_1v_methalox_swivel", "engine_1v_methalox_swivel_variant")
.Modify<double>("Assembly-CSharp", "KSP.Sim.Definitions.PartData", "mass").Set(10.5)
.Modify<float>("KSP.Modules.Data_Engine, Assembly-CSharp", "maxThrust").Set(1500f)
.Modify<bool>(typeof(Data_Engine), "UseEmissive").Set(false)
.Finish();
this will be how it will work
ok so
i might change a bit of the backend to this
im thinking of changing to a Instruction based system
something like Vector3Instruction
with a abstractMethod called Apply(Prefab)
inside each instruction's Apply, there would be the manipulation that that instruction would do to it
something like
class AddModuleInstruction
{
string target = "partName";
string targetGameObject = "lorem ipsum";
string fullyQualifiedModuleName = "SORRY.Modules.Module_ProceduralEngineCover, SORRY"
void Apply(GameObject prefab)
{
Module_ProceduralEngineCover newModule = new(); //This would have to be a reflection to get a new instance
prefab.FindGameObject(targetGameObject).AddComponent(newModule);
}
}
then the modder, to make the configs would simply create a json with the data corresponding to the Instruction that he wants
ie
{
"InstructionType" = "Switcharo.Instructions.AddModuleInstruction",
"conditional" = "@IF(SORRY)" //or empty string if no conditional should be met
"target" = "Reiptor-12",
"targetGameObject" = "CoreGameObject",
"fullyQualifiedModuleName" = "SORRY.Modules.Module_ProceduralEngineCover, SORRY"
}
each instruction type would have fields to all the values that can be changed via switcharo
@novel granite htoughts?
i could also add fields on the json for things like "If x mod is installed"
just like ModlueManager
looks interesting
I'm still unsure how to best handle all this stuff but this seems pretty good for this mod's purposes
Should look something like this
{
"Name": "swivel_no_gimbal", //Variant Name
"OriginalPartName": "engine_1v_methalox_swivel" //Original partName from which to copy and modify
"instructions": [
{
"$type": "Patchouli.Instructions.ModifyPartData, com.github.luxstice.patchoulispartmanager", //this would not exist with a custom deserializer, would be changed for something like "type": "PartData"
"Changes": {
"mass": 10.0
}
},
{
"$type": "Patchouli.Instructions.ModifyModule, com.github.luxstice.patchoulispartmanager", //this would not exist
"FullyQualifiedModuleType": "KSP.Modules.Module_Gimbal, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
"Changes": {
"gimbalRange": 0.0
}
}
],
}
instructions are already working btw
{
"Name": "swivel_no_gimbal",
"OriginalPartName": "engine_1v_methalox_swivel",
"instructions": [
{
"FullyQualifiedModuleType": "KSP.Sim.Definitions.PartData, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
"Changes": {
"mass": 10.0
}
},
{
"FullyQualifiedModuleType": "KSP.Modules.Module_Gimbal, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
"Changes": {
"gimbalRange": 0.0
}
}
],
}
cleaned
@novel granite sounds good? this would be ie, change swivel's mass to 10 tons and remove gimbaling
so now we have no gimbal (and more thrust) raptors for the outer rings
yeah, looks ok to me
reinforcing the "toggle the meshes" thing that you said @novel granite
idk how it was on KSP1, but most KSP2VFX that are driven by some module now use unity's editor to be assigned, this can be assigned via code but for a toggle on demand thing its not ideal since its not that performance friendly
ie
this only has 2 because i made my custom VFX handler with LFO
but stock plumes use 3-7 game objects each
and they auto toggle on once the engine starts running
i was taking a deeper look into B9 parts switch to see how they implemented various configurations (Subtypes)
and yeah i dont think its doable, at least not in a simple, abstractable way
my idea is to, in the instructions, have a way for you to say "Replace x gameObject with y"
or, RemoveAllGameObjectUnder x and Instantiate y
and in those instructions there will be extra fields for when ur dealing with an engine, where u can specify which go where
And we have part switch
better now
i do need a custom JsonDeserializer tho
to allow for prettier config files
**{
"instructions": [
{
"$type": "Patchouli.Instructions.ModifyPartData, com.github.luxstice.patchoulispartmanager",
"TargetType": "KSP.Sim.Definitions.PartData, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
"Changes": {
"System.Double mass": 2.0
}
},
{
"$type": "Patchouli.Instructions.ModifyEngine, com.github.luxstice.patchoulispartmanager",
"TargetType": "KSP.Modules.Data_Engine, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
"Changes": {
"System.Single maxThrust": 500.0
}
}
],
"Name": "swivel_doubleMass_1.5xThrust"
}**
as of now it looks like this
which isnt bad
but you know, aint great either