#Switcharo (Part Switcher API & Mod)

1 messages · Page 1 of 1 (latest)

forest pelican
#

Mod will have a simple fuel switcher. API is for modders

jovial remnant
#

fuel switcher>

#

?

forest pelican
#

yeah, like interstellar fuel switch

jovial remnant
#

what

forest pelican
#

all other API functionality will be added by the modders

#

Switch any tank to any fuel u desire

jovial remnant
#

oh

#

256t xenon tank gonna be lit

forest pelican
#

well u cant make it have more fuel than original

#

unless i add rescale to this too but idk

#

not rlly in the scope

jovial remnant
#

I meant you replace the biggest XL tank from methalox to xenon

forest pelican
#

Oh lmao yeah, then an 5m ion engine would make sense

jovial remnant
#

also maybe disable EC for this "fuel" switcher? As it is counted as a fuel for so reason

#

some*

novel granite
#

Is this meant to be strictly for fuel switches or will it provide a general part switching API?

forest pelican
#

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

forest pelican
#

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

forest pelican
#

im a bit against reflection since a lot of public fields are not suposed to be edited on the datas

novel granite
#

hm

#

I guess you could go with reflection along with a list of whitelisted/blacklisted properties?

#

but that's just adding even more complexity

forest pelican
#

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

forest pelican
novel granite
#

yeah

#

and having a cache should solve any issues with performance

#

especially as more and more mods start to use this

forest pelican
#

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

novel granite
#

hm, is there need for another custom format?

#

I mean it's fine for the part switch I guess

forest pelican
#

if i do json, i'll need to have all the fields on the json to be able to parse it back

novel granite
#

but we already have MM syntax, and there's JSON Patch standard

forest pelican
#

tbh i can copy MM syntax

novel granite
forest pelican
#

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

novel granite
#

tbh it's pretty low level

forest pelican
#

yeah it is, but lacks readability imo

#

at least from the examples

novel granite
#

at least for end users

forest pelican
#

let me check the MM whole syntax

novel granite
#

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

forest pelican
#

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

forest pelican
#

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

novel granite
#

alright, then I guess since you already have the name and idea, it's best to just keep it as the part switching mod?

forest pelican
#

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

novel granite
#

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

forest pelican
#

he seems to be using part of the MM parsing

#

which is making the code wayy too extensive

novel granite
#

yeah

forest pelican
#

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

novel granite
#

I mostly just know how B9 works from the user end (by user I mean a mod dev using it)

forest pelican
#

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

novel granite
#

in most cases you'd just specify the transforms in your model that you want to switch on/off based on the selected variant

forest pelican
#

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

forest pelican
# novel granite

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

novel granite
#

whichever way you do it, I'm sure it will work out great 😄

forest pelican
#

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!

novel granite
#

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

forest pelican
#

hmm thats true, but we dont have an MM yet :s

novel granite
#

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

forest pelican
#

I'll try to get the API done first, and share it on the JsonManager topic

novel granite
#

instead of each mod having to run its patching code each time the game is run

forest pelican
#

maybe that'll spark ideas for how to do it there

forest pelican
#

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

forest pelican
#

lmao @novel granite

#

ok so this is freaky

novel granite
#

nice

forest pelican
#

i tried to launch the craft

#

and im in space

#

and my craft is literally bending itself

novel granite
#

lmao

forest pelican
#

also none of the mods seems to be on the app bar lmao

novel granite
#

jesus that is cursed

forest pelican
#

also apoapsis of 109m?

#

-410m below ground?

#

This is so cursed

#

i might have changed kerbins orbit for all i know lmao

novel granite
#

by the way, how do you set the variant that you want to use?

forest pelican
#

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

novel granite
#

gotcha

vivid wind
#

Also this means that the floatingpointorigin script or whatever its called got a error

forest pelican
#

when i launched, the craft exploded cuz it was being pulled by the gravity way too much

#

(100.000t craft so its expected)

novel granite
#

the density of that thing must have been crazy husK

forest pelican
#

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

forest pelican
#

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

novel granite
#

yeah, that sounds cool

upper solstice
#

Can't wait for this to come out!

forest pelican
#

ITS WORKING

#

THE SWIVEL HAS 2000kn of THRUST NOW

#

ALL W/O CREATING A NEW PART

#

LETS FUCKING GOOOOOOOOOOOO

#

Ok so this is big

novel granite
#

Awesome job

forest pelican
#

cursed

#

even more cursed that it lift off

#

literally starhopper

jovial remnant
forest pelican
#

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 
novel granite
#

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

forest pelican
#

yeah makes sense

#

tho it will be kind of wierd to write it like that

novel granite
#

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

forest pelican
#

the thing with typeof is that they can do typeof(PartData).AssemblyQualifiedName

#

removing the need fo rthe assembly param

novel granite
#

I mean you can make two overloads of the method

forest pelican
#

yeah exactly

novel granite
#

one without an assembly parameter that will just call the other with Assembly-CSharp as the parameter value

forest pelican
#
        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

forest pelican
#

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

novel granite
#

looks interesting

#

I'm still unsure how to best handle all this stuff but this seems pretty good for this mod's purposes

forest pelican
#

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

novel granite
#

yeah, looks ok to me

forest pelican
#

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

forest pelican
#

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