#Fancy Fuel Tanks DEVBLOG

1 messages · Page 5 of 1

lunar peak
#

Yeah. That's the torroidal tank with stage interconnects.

surreal loom
#

ah

#

no idea that was the technical term

lunar peak
#

In the shot above you added another cylindrical part that's not part of this tank

surreal loom
#

i was using "smushed sphere"

#

i stacked four on top of each other

#

then for comparison i added the stock giant ball of hydrogen ontop of it

#

i wanted to see how four of these looked stacked together. looks kinda cool

#

not too goofy but still kerbally

lunar peak
#

Technically, a toroid is a doughnut like shape. I'm assuming there's a toroidal tank inside some sort of faring here.

surreal loom
#

definitely would be

lunar peak
#

That would be structurally stonger than just making a smushed sphere

surreal loom
#

because when you look into how they store the liquid hydrogen and edvverything that goes into a NTP its pretty wild

lunar peak
#

There might be plumbing or cryogenics or whatnot in the spaces not used up by the toroid

surreal loom
#

also adding a 45 degree angle part and structural parts to the mod later on

#

but thats the main inspiration of the design

lunar peak
#

I wonder why they have those tanks canted at an angle?

surreal loom
#

concept art so no idea why

#

i think it looks cool

#

so im using this as the third update

#

im reworking the hydrogen tanks and friday ill release the new update

#

then the next update is adding more structural parts so you can do cool stuff like that picture

#

so inside of that toroid there would be a lot of tanks

#

i think this falls into Hydrogen Heated by Fission Reactor

#

since the engine is basically a small nuclear fission reactor

#

I think it does make it look better and not so bland

lunar peak
#

Nice! I like it this way.

surreal loom
#

adding them on the inside as well

#

that's it. that finishes that, might need to tweak metallic levels

surreal loom
#

not too shabby

lunar peak
#

I love it! That looks freaking awesome!

surreal loom
#

few minor things to adjust. its inbetween medium and large. but i really like how the medium docking port attaches

#

so i dont think ill change that, all im gonna do is add a srfAttach so you can attach things to it radialy

surreal loom
#

few more touchups and the hydrogen tanks are good to go

surreal loom
#

@dreamy escarp how would I set it up to switch between the two texture sets? 🤔

surreal loom
#

@dreamy escarp

using UnityEngine;

namespace FFT
{
    public class FuelTankSelector : MonoBehaviour
    {
        [SerializeField]
        private GameObject SR812;

        [SerializeField]
        private GameObject Sr812_v2;

        private bool isModel1Active = true;

        public void ToggleModels()
        {
            isModel1Active = !isModel1Active;
            SR812.SetActive(isModel1Active);
            Sr812_v2.SetActive(!isModel1Active);
        }
    }
}```
#

this is what ive got so far, but the UI part i'm not sure how to do.

surreal loom
surreal loom
#
-Update OAB pictures
-Clean up textures
-Add descriptions to new tanks
-Release 0.1.4

-Develop Fuel Tank Selector
-Get VFX fully functional```
surreal loom
surreal loom
surreal loom
lunar peak
surreal loom
# lunar peak Nice video!

Thank you! I Def will be picking your brain on UITK! I'm adding a UI element to be able to swap between different models/textures. Not sure what would be easier to do

lunar peak
# surreal loom Thank you! I Def will be picking your brain on UITK! I'm adding a UI element to ...

If there are just two options, then a button works fine and you can have it toggle between one label and the other - so clicking the button would have the effect of changing the texture and the label on the button. If you've got more than two possible textures, and especially if the list of textures is variable, then a drop down menu is a good option for picking these thing. You can find examples of both approaches in FP where there's a button that toggles between Celestial and Vessel for target selection, and then a target selection dropdown that's populated with a list of vessels or celestials depending on the state of the button.

surreal loom
#

It's learning how to use UITK and how to make it select a material

#

Also UITK is weird. Feels easier to just code it lol

lunar peak
#

Yeah, I'm still getting the hang of some things. I get messed up on applying styles, but otherwise it's pretty easy once you've done it a bit.

surreal loom
gray fable
#

But I guess it might be a bit much for someone who doesn't have experience with that

surreal loom
#

so itll be a new learning curve but i do think it will be easier to understand versus how i made toggle notifications

#

then ill be able to decide which route i want to take for other mods

#

because the coding part of toggle notifications was really fun

dreamy escarp
#

what i meant by changing textures was the B9 PArt Switch way (variants) nto actually toggling the game objects, but that works too

surreal loom
dreamy escarp
#

1

#

A)

#

but its not ready yet AsukaDead

#

i'm gonna work on it rn tho

surreal loom
#

no worries. its on my to do list after i get 0.1.4 released. im just finishing up textures and some finer details that i missed then ill release 0.1.4.

ive got two things to get fully functional that i havent quite got working:

  1. dynamic vent vfx (combine both modules to one module)
  2. add the UI to swap between different models

i can hold off on putting time into making a UI thing if you're making something that does the same thing though

surreal loom
hybrid fable
#

if you want to keep it stockalike idk if the radiation hazard sticker is a good choice because none of the normal hydrogen tanks have them

#

additionally, H_2 by itself isn't radioactive iirc, just the NTR

#

they do liike very good though, huge props

surreal loom
#

Not really going for a stock look.

The radiation symbol looks cool on it imo is all. The labeling for LH2 is on the top and bottom. I could switch out the radiation label and use an LH2 label. Reason for the radiation is it indicates its fuel for the nuclear engines which makes people understand its purpose easier.

Hydrogen has a radioactive isotope called Tritium. Tritium is used in controlled Nuclear Fusion.

The deuterium-tritium Fusion is the easiest nuclear reaction at the lowest energy.

Deuterium is H2. "Heavy Hydrogen" it's one of two stable isotopes of Hydrogen.
Tritium is H3. Half life of 12 years

surreal loom
#

To do:
-Update OAB pictures
`-Clean up textures
-Add descriptions to new tanks
-Release 0.1.4

-Develop Fuel Tank Selector
-Get VFX fully functional`

#

@quartz dagger fixed the issue where the mesh collider was making these angle when radially attached

#

To do:
-Update OAB pictures
-Clean up textures -Add descriptions to new tanks -SR-815 fix the srfAttach -CV-411 fix the srfAttach -Fix CoolingVFX errors Verify VentValveVFX function -Limit VFX to 90% instead of 80% fuel
No VFX for M/L for now`
-Release 0.1.4

-Develop Fuel Tank Selector
-Get VFX fully functional`

#

sad. didnt get the angle right

fierce sundial
surreal loom
#

@upper summit not sure what happened or why im getting this. 99% sure its something i did:

System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at <695d1cc93cca45069c528c15c9fdd749>:0)
Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at <695d1cc93cca45069c528c15c9fdd749>:0)
System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) (at <695d1cc93cca45069c528c15c9fdd749>:0)
PartEditor.OnInspectorGUI () (at Assets/KSP2UnityTools/Editor/PartEditor.cs:101)
UnityEditor.UIElements.InspectorElement+<>c__DisplayClass59_0.<CreateIMGUIInspectorFromEditor>b__0 () (at Library/PackageCache/[email protected]/Editor/Inspector/InspectorElement.cs:638)
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr, Boolean&)
#

this is the erorr I get when I try to "Save Part Json"

upper summit
#

hmm, do you have the space warp dll in your project?

surreal loom
#

this is what the editoor asemdef looks like

upper summit
#

Hmm, I don't think I wrote any spacewarp specific code in there, but you might like have something on your part that depends on spacewarp to be serialized

surreal loom
surreal loom
#

Found why. How do I update the SpaceWarp 1.1.1 in my visual studio project?

@upper summit

upper summit
surreal loom
upper summit
#

Wait ... your using the feed from nuget.org
Do you know how to add another source?

surreal loom
#

I probably need to switch to spacewarp.template then?

upper summit
surreal loom
#

oh

upper summit
#

https://nuget.spacewarp.org/api/v3will be the precise link

#

but your sources should be under the nuget options

surreal loom
upper summit
#

No
Press the plus at the top

surreal loom
#

it now created a new package source

#

is this correct?

upper summit
#

Then press update

surreal loom
#

i did that

upper summit
#

Now you should be able to grab a newer version

surreal loom
#

Package restore failed. rolling back package changes for FFT

upper summit
surreal loom
#

no it does this when i hit update:

upper summit
#

It resets the field? That doesn't make any sense

surreal loom
#

thats what i have in my packages right now

upper summit
#

Re add space warp

surreal loom
upper summit
#

I am utterly confused
@gray fable you are more knowledgeable than me on this stuff ... could you help here?

gray fable
#

I have never messed around with the NuGet settings in Visual Studio

#

the template just adds this property to the csproj file:

<RestoreAdditionalProjectSources>
    https://nuget.spacewarp.org/v3/index.json
</RestoreAdditionalProjectSources>
surreal loom
#

wilco

upper summit
#

I don't either normally ... I've always used rider, I thought you knew a bit more apologies

surreal loom
#

its got that in there

gray fable
#

StackOverflow says to just clear the cache

#

is your target framework netstandard2.0?

surreal loom
#

yes framework is netstandard2.0

#

this may be a problem. it cant find mypluginfo.cs

gray fable
#

That should get automatically created by the package BepInEx.PluginInfoProps

surreal loom
#

well it went from like 15 errors to now 550 errors

gray fable
#

Hm, yeah, because now no packages are cached and the NuGet restore is still failing

#

So no references are working

#

But why

surreal loom
#

what are common reasons why?

gray fable
#

I've never seen this happen before

#

Honestly you could try to keep debugging this for possibly hours, or you could just make a new project with the latest template and drag your code and bundles over to it in like 5 minutes

#

I would suggest just trying that

surreal loom
#

true

gray fable
#

And if that doesn't work either, then something went wrong with your whole NuGet/Visual Studio/.NET installation

#

But hopefully that's not the case

surreal loom
#

i have a feelin gits because toggle notifications i used 472 instead of netstandard2.0

#

and i used the togglenotifications template to make this which is probably why its messing up now

gray fable
#

It should be almost fully interchangeable for our purposes

#

SpaceWarp was netstandard2.0 first, then it was changed to net472, and then back to netstandard2.0

#

So idk if it can be that

surreal loom
#

when i create a new project i get the same errors:

#

im so confused now

#

i shut down visual studio and restarted and now no errors

#

BUT i still have the old spacewarp 1.1.1

#

these are the updates available:

#

now its a matter of updating spacewarp from 1.1.1 to 1.4.0

#

its using net472

#

@gray fable i did some wizardry and now i just need to get spacewarp to update to 1.4.0 but thi sis the error i get

gray fable
#

where is Mono.TextTemplating even coming from

surreal loom
#

what i did:

  1. made sure i had netstandard2.0
  2. uninstalled spacewarp 1.1.1
    reinstalled spacewarp 1.1.1
#

dotnet

gray fable
surreal loom
#

Examine the project's dependencies in Visual Studio to be sure you're using the correct package identifier and version number. Check your NuGet.Config for the PackageSourceMapping configuration. The package in question may be available on a source that is not configured.

gray fable
#

if you have the RestoreAdditionalProjectSources property as I showed you, you should just be able to go and change SpaceWarp to <PackageReference Include="SpaceWarp" Version="1.4.0" />

surreal loom
#

ah

#

thats cool. k doing that now

#

holy crap that was ez

#

thank you munix and cheese

gray fable
#

yeah, my advice is, don't use the UI, just change it directly in the XML in your .csproj file

surreal loom
#

i didnt realize i needed to make sure my visual studio updates when new versions of spacewarp drop

gray fable
#

Visual Studio is dumb and messes stuff up

surreal loom
#

i thought it auto did it for me

#

I'm cosmo, I break things.

surreal loom
#

yeah no idea. its completely broken @gray fable

gray fable
#

Can you show me the window with the package sources?

surreal loom
#

brand new project

#

now ill update spacewarp

gray fable
surreal loom
gray fable
surreal loom
#

so like that instead?

gray fable
#

And no need to delete the Offline packages thing

surreal loom
#

good to know

#

YOU LEGEND!

gray fable
#

Basically nothing in there needs to ever be touched

gray fable
#

So it didn't fix it?

surreal loom
#

not yet

#

i thought it did

gray fable
#

The last error is easily fixed, you just need to reference UnityEngine.Modules 2020.3.33.1

surreal loom
#

it cant find bepinex.analyzers

gray fable
#

Just try to delete the .packages folder that it talks about manually

#

I mean

#

.nuget/packages

#

And I don't think the package manager UI works with RestoreAdditionalPackageSources, you can go and add nuget.spacewarp.org as a new source instead of overwriting the old one, if you really want to use the UI

surreal loom
#

think that its working

#

hm

#

last warning is the 2020.3.33.1

#

no warnings/errors on the packages anymore:

just gotta figure out how to fix the NU1605 error

gray fable
#

It needs to be 2020.3.33.1

surreal loom
#

i hate being dyslexic

#

thank you for the help munix. simple things but i did learn a lot so thats cool

gray fable
#

glad it works now!

surreal loom
#

`To do:

-add check for OAB. If in OAB no animation plays -Update OAB pictures -Clean up textures -Develop Fuel Tank Selector -Migrate to one module -Limit what is being updated during OnModuleFixedUpdate -Set more conditions for animations -Find ways to improve performance

surreal loom
#

@south girder

anything I can do to improve this?

var fuelPercentage = RefreshVesselData.fuelPercentage.fuelPercentage;
            if (fuelPercentage < 0)
            { FFTPlugin.Logger.LogError("fuelPercentage is less than 0"); }
            FL = DataVentValve.VFXOpacityCurve.Evaluate((float)fuelPercentage);
            Animator.SetFloat("FL", FL);
            FFTPlugin.Logger.LogInfo("fuelPercentage is: " + fuelPercentage);

            var isInAtmosphere = RefreshVesselData.isInAtmosphere.isInAtmosphere;
            InAtmo = isInAtmosphere;
            Animator.SetBool("InAtmo", InAtmo);
            if (isInAtmosphere is false)
            {
                FFTPlugin.Logger.LogError("isInAtmosphere is false");
            }
            FFTPlugin.Logger.LogInfo("isInAtmosphere is: " + isInAtmosphere);```

also, is fuelPercentage going to give me the fuelpercentage of the entire vessel? trying to get the fuel level a different way
south girder
#

fuelPercentage is for the entire vessel, yes. You likely want StageFuelPercentage which is for the current stage

#

or ideally fuel for the tank you want to annimate, no?

surreal loom
#

first i was attempign to get the fuelpercentage functional then i was going to copy paste and add the stagefuelpercentage

south girder
#

you can have multiple tanks on a single stage too, no?

surreal loom
#

at lesat thats how i would make it function, just not sure how it actually functions

south girder
#

looking at StageFuelPercentage is good enough IMO. Otherwise I guess you'd have to manually look into fuel for each part. Doable, but complicates things.

surreal loom
#

hm makes sense

#

there's other things ill use to make sure hydrogen tanks dont constantly animate LOL

#

cause right now the hydrogen tanks have the vfx going until the fuel is below 80%

#

figured out why it wasnt working LUL

#

wrong data...

var fuelPercentage = RefreshVesselData.fuelPercentage.fuelPercentage;
            FL = DataVentValve.VFXOpacityCurve.Evaluate((float)fuelPercentage);
            Animator.SetFloat("FL", FL);```

needs to be
```cs
var fuelPercentage = RefreshVesselData.fuelPercentage.fuelPercentage;
            FL = DataFuelTanks.VFXOpacityCurve.Evaluate((float)fuelPercentage);
            Animator.SetFloat("FL", FL);```
surreal loom
#

`FFT v0.1.4.1 To Do:

`add check for OAB. If in OAB no animation plays
-Update OAB pictures
-Clean up textures
-Develop Fuel Tank Selector
-Find ways to improve performance
Migrate to one module
Limit what is being updated during OnModuleFixedUpdate

Improvements:
-Module now checks multiple VFX effects and sets conditions based on a variety of factors.
ASL, AGL, Fuel Level, and InAtmo are the base conditions that must be met for the
VFX to play. Module uses two VFX effects. `

surreal loom
surreal loom
#

`FFT v0.1.4.1 To Do:

`add check for OAB. If in OAB no animation plays
-Update OAB pictures
-Clean up textures
-Develop Fuel Tank Selector
-Find ways to improve performance
Migrate to one module
Limit what is being updated during OnModuleFixedUpdate
Create new VFXConditions

Improvements:
-Module now checks multiple VFX effects and sets conditions based on a variety of factors.
ASL, AGL, Fuel Level, and InAtmo are the base conditions that must be met for the
VFX to play. Module uses two VFX effects. `

surreal loom
#

mm flight data:

surreal loom
#

a bit of python. got distracted and decided to look into data lol

surreal loom
surreal loom
#

`FFT v0.1.4.1 To Do:

`add check for OAB. If in OAB no animation plays
-Update OAB pictures
-Clean up textures
-Develop Fuel Tank Selector
-Find ways to improve performance
Migrate to one module
Limit what is being updated during OnModuleFixedUpdate
Create new VFXConditions

Improvements:
-Module now checks multiple VFX effects and sets conditions based on a variety of factors.
ASL, AGL, Fuel Level, and InAtmo are the base conditions that must be met for the
VFX to play. Module uses two VFX effects. `

sick dagger
surreal loom
#

any questions just ping me!

sick dagger
#

Ok

#

Lol the terminal is so confusing with its keys and such but they have an entire modern UI for settings

surreal loom
#

lol its pretty cool. i like being able to finally customize terminals in windows with ease. im a big fan of garuda linux but too lazy and impatient to make garuda my daily

sick dagger
#

Yeah

surreal loom
#

getting drivers setup for my 4090, and everything is a headache. once its working, it runs amazing

sick dagger
#

I like your mats backgrounds

surreal loom
#

but any update etc is a headache

#

thanks its just a picture of mars (well render of mars)

sick dagger
surreal loom
sick dagger
#

Yeah I never really liked or enjoyed Linux. Windows for me is just so much better cause it’s easier to get built in compilers for c++ and it’s just better for compatibility. I hate Microsoft but I like windows

surreal loom
#

I like Garuda it's just a headache to do it all on your own. Which, if you just want a stable OS that you don't update, yeah linux is awesome. but if you want to keep your drivers etc updated and you use propriertary software, windows is just easier

#

especially for gaming. i dont feel like 4-8 hours of updating a game so it works on linux

#

cause when games get updated it really sucks

#

lol

#

still i think linux works better that windows for performance. but that performance is neglible now imo

sick dagger
#

Yeah. I just like having an Os that works out of the box doesn’t need to days to get it how you want it (it’s took me that long for my old Linux install) and is just friendly to a retard like me

surreal loom
#

its also VERY easy to ruin your linux install by making one change to the kernal or running an update without reading the readme's and knowing what the update is changing

#

which is what is great about linux, its fully customizable

#

i just dont have the time or patience to want to go that deep into my os

sick dagger
surreal loom
#

true. windows destroys ram lol (me who uses google chrome still because i like it for convenience)

#

yup. i know google chrome is a ram hog, but it works really well LUL

#

solution? moar ram. 64 GB of it (i really want 128 though i have absolutely NO reason to have that much)

sick dagger
surreal loom
#

LUL

#

they're so toxic haha. always hating on windows and annoying. like i really enjoy arch linux, its great. but its not the only way to run a pc.

surreal loom
#

yeah cause thats so easy lol

sick dagger
upper summit
#

I ... want to use arch again but its not really tenable for me atm

surreal loom
#

i didnt know that about google chrome. i just like the convenience with my google accounts etc

#

i never realized it is very easy to turn something ON with programming, but man is it a challenge to figure out how to turn it OFF

#

im trying to learn/teach myself how to improve performance for my plugin by not making it run all the time

#

so down the rabbit hole i go today

sick dagger
#

It’s kinda fun nerding the Shit out

surreal loom
#

oh hell yeah it is

#

i learn more ways to NOT do things, and i learn how i did them. sometimes, sometimes i still dont understand why it worked

#

for example, MicroEngineer has some amazing scripting to it with how it runs in the background

sick dagger
#

I learn how to not do things by doing those not good things and then debugging it for 3 days.

surreal loom
#

LUL

#

the debugging is real

#

half my code will be a debuglog sometimes lol

surreal loom
#

me: sees how well micro engineer functions
inner me: don't rewrite everything
me: rewrites everything
@south girder

south girder
#

happy to be of influence! ❤️

lunar peak
#

So it looks like you’re on the hook now for some sort of antiparticle engine or other such ultra tech… best get cranking!

surreal loom
sick dagger
surreal loom
# sick dagger

That's epic. I do have a big mod I'm working on. It's gonna take a while til it's ready. I need colonies and science mode

lunar peak
#

Dude! You done made a name for yourself! You’re on the map! Now look what you’ve done? Ppl are gonna be expecting great things! I have a hunch you’re not gonna disappoint!

surreal loom
#

decided to flair up my scripts a bit:

//|=====================Summary========================|0|
//|  refreshes the game manager and checks game state  |1|
//|by cvusmo===========================================|4|
//|====================================================|1|```
#

so at the top of each script it says what it does and on the right it has the version number. why? cause it looks cool.

First two rules of Modding:

  1. Always look cool.
  2. Never let your coffee cup go empty.
glacial thicket
#

Idk why but this mod makes my game go extremely laggy

#

which is sad bcz the parts are very nice :(

surreal loom
#

The problem with 0.1.4.0 is once the game loads the plugin runs. Once you get into a game and attach a part from the mod, the module never stops running. It'll stop the animation but the script itself is running every frame.

surreal loom
surreal loom
#
## MessageManager
- **Responsibility**: Listens for specific messages/events.
- **Actions**: 
  - On receiving specific messages, forwards them to the ConditionsManager.

## ConditionsManager
- **Responsibility**: Validates whether incoming messages meet specific conditions.
- **Actions**: 
  - If conditions are met, sends instructions to the Manager.

## Manager
- **Responsibility**: Acts as an intermediary layer.
- **Actions**: 
  - Receives instructions from the ConditionsManager and delegates the task to LoadModule.

## LoadModule
- **Responsibility**: Ensures that the correct module gets loaded.
- **Actions**: 
  - On receiving instructions, confirms which module needs to be loaded.
  - Delegates the task to StartModule.

## StartModule
- **Responsibility**: Initiates the module start process.
- **Actions**: 
  - Tells the specified module to start.
  - Informs ResetModule to reset the ConditionsManager.

## ResetModule
- **Responsibility**: Resets the ConditionsManager to its default state.
- **Actions**: 
  - Resets the ConditionsManager values.
  - Verifies if the reset has taken it back to its default state for reuse.
#

just an example of how im going to boot, preload, and load modules based on messages being listened to by the MessageManager.

surreal loom
#

It is now ready for testing and debugging!

surreal loom
#

it's beautiful @south girder

#

@fierce sundial went to test it because im excited. didnt set up the module_generator and/or module_engine correctly hm

#

@glacial thicket to address performance issues and to help improve player experience I'm adding a way to turn on/off the vfx with the next update. thank you for letting me know you were having performance issues. Hopefully 0.1.4.1 fixes them, otherwise you will be able to turn the vfx off so you don't have performance issues.

fierce sundial
surreal loom
#

not sure how it works tbh. there's a lot of info with engines lol

fierce sundial
#

pretty sure you need a flameout vfx manager

surreal loom
#

ah

#

good to know

fierce sundial
#

and reference it in the module

surreal loom
#

ill get working on that tomorrow. time for me to unwind and chill. im so excited to see how this thing looks in game lol

surreal loom
#

@south girder @lunar peak I've got a simple issue I think. It's very new to me but I feel like for either of you its a very easy fix.

Currently, the ONLY things that get logged is from my ConditionsManager class. None of my other custom loggers for different classes are logging anything.

When you get a chance, could you take a look at the FFTPlugin and ConditionsManager. I'm not sure why the logging isn't working.

south girder
surreal loom
surreal loom
#

thats the logoutput so you can see what was logged

#

lines up super clean! @fierce sundial

fierce sundial
#

nice

#

does it look good painted?

surreal loom
#

just data points to mess with and learn the in's and out of module_engine

#

it looks amazing painted, one sec

#

definitely a lot im going to learn from this model! thanks for sharing it. it gives me a better idea of how to model complex things, as well as texturing things a bit better

fierce sundial
#

Nice

surreal loom
# fierce sundial Nice

also decided to use assetstudio to look at engine settings so i understand how to use it in unity.

south girder
surreal loom
#

OMG

#

my life just got instantly better

#

i had no idea i could do that

south girder
#

it's extremely valuable to see what's happening when you do something and maybe even more important, to browse KSP2 inner working while the game is running, to explore classes, methods, everything

#

yep!

surreal loom
#

k first i get this engine module set up, then before testing i do what you just showed me

#

thank you!

south girder
#

no problem, happy to help!

surreal loom
#

so basically i can use that to debug while the game is running and look at my code to see what i need to change?

#

or whats not working/being called etc

south girder
#

exactly, set your breakpoints where needed, see the status of all variables and step through the code line by line to see how it's changing

surreal loom
south girder
#

oh yeah, I was blown away also when I saw that the game can be debugged like this 😄

surreal loom
#

wait i already have the editor

#

lol

#

so im basically making my own dev build of the game

surreal loom
#
hdr-display-enabled=0
gc-max-time-slice=3
player-connection-debug=1

is that correct?

south girder
#

yep

surreal loom
#

lol

surreal loom
#

@south girder where do i get that?

south girder
surreal loom
#

okay i thought i did something wrong loll

south girder
#

or, well, you can if you want to from here: https://github.com/Falki-git/HUMANS. Debug is activated with ctrl+H and normal window with alt+H, but it's heavily WIP at the moment

surreal loom
#

no worries ill wait til you release it!

#

Never used this before, if I highlight these, does that mean it will debug and tell me something?

#

also, what value is setting 1 atm in module_engine? is it the atmo curve?

south girder
#

those are breakpoints. You place them where you want code execution to pause so you can examine stuff. There's more to breakpoints, like setting them to pause only at specific values, but that's rarely needed.

south girder
surreal loom
#

today is a more learning day than fixing day

#

i do need to debug this, but im not rushing as 0.1.4.0 is coming out in 5 days

south girder
#

part modules is something I'd like to learn more as time goes on

surreal loom
#

so that will change things and i wanna get it at least functional before 0.1.4 is relleased

#

theyre simple really

#

and with your knowledge of programming, once you understand how it works youll write some epic modules

#

whats taking me long is im new to all of this. which is fine, everyone starts somewhere

#

but dev time in mods will get faster as i learn more for me

#

like i was able to rewrite the entire program in a day and a half, but toggle notifications took me a month to write

south girder
#

oh definitely, it's a very steep learning curve to learn modding

surreal loom
#

used the micro engineer as template, and then made it specific to my mod

#

because i need to learn hbow to optimize and improve performance, structure things better, and not waste memory/cpu/gpu usage

#

i can turn a module on, it is really weird trying to turn it off or put it in a sleep state lol

#

but ive got the core wrote, so now its just checking, debugging, and fixing mistakes in logic

#

when i turn on assetloader:

LUL

south girder
#

don't even have that much 😆

#

but you can get by with a lot less. I've done some modding on steam deck which is 16 GB, and it's certainly doable. Majority of assets are celestialbodies, so if don't need them you can exclude them from loading

#

I was able to load everything with 16 GB by removing celestialbodies and KSC assets.

surreal loom
#

thats insane

#

i cannot imagine doing this without my current rig

#

(4090, i9-13900k, 64gb ddr5 @ 5200)...

#

it also feels easier to just look at the code instead of mess around with unity unless its a module i made

#

the modules in the game are awesome, but undersatnding what it does is just easier to look at the .json and then update your new .json to use similar values

fierce sundial
#

beast pc

#

that ram tho, 64gb ddr5 at 5200!

surreal loom
surreal loom
#

It's the Kraken slayer. Finally got my dream setup and I love it

fierce sundial
#

ive got a machine with a 3060 12gb, ryzen 3 3100 (gonna upgrade soon) and 32 gb of ddr4 @3200mhz

surreal loom
#

nice!

#

solid pc

fierce sundial
#

yeah its pretty good

surreal loom
#

my stream pc (old gaming rig) has an i9-9900k, rtx 2070, 32gb ddr4 @ 3200mhz

#

and my server runs on an i5-9600k with 16gb of ram, no gpu

#

i skip about 2 generations before upgrading. first time ever buying a top end GPU.

#

i didnt get a 2080Ti when they came out, i was happy with the 2070. 3000 series came out and i thought of a 3090 but decided to wait til 4000 series

#

only reason i want to upgrade to 128 gb of ram is so i can run more programs lol

#

this is the .json ive setup for your engine to test it. still not sure if i have it correct

#

so this helps. but how do i get the debug logs to show up in the IDE?

#

thats all that showed up in the output?

#

this is the bepinex log thats logging things

#

ah so player.log is what is logging all the errors not logoutput.log or ksp2.log

learning that these all log different things

#

BUT at least the data is correct:

#

so i sort of understand how module_engine works, its also way easier to edit the .json than to use the module inside of unity

south girder
#

player.log is what I use mostly, I open it in notepad++. Though you can open spacewarp's console in-game with alt+c. It's quite handy as you can filter what will be display, like filtering only what your mod outputs

surreal loom
#

any website i can use to learn about VS 2022 debug stuff? this is an entirely new thing to me. ive zero idea how it works and how to use it. its super cool but i need to learn how this thing works

south girder
#

hmm, don't know about guides, but the basics are really simple.
You add breakpoints where you want the code execution to stop so you can look at stuff.
When the code stops you can do several things, you can hover over the code to quickly see what values variables have, but for more details you use the Watch or Locals window. Locals will tell you the status of all localy available variables, and in Watch window you can input whatever you want. In my short video you saw I started typing out GameManager.Instance.Game... then you see what's inside 'Game' and then drill through other properties

surreal loom
#

ah

#

starting to make more sense

south girder
#

so basic concept is to look at the player.log and see on what line an exception was thrown, usually a null reference exception (something was null). So log tells you the line number, and then you go to VS, find the line number in your .cs file and place a breakpoint there. Then load the game, attach unity debugger with 'Debug -> Attach unity Debugger' and do the stuff in-game which will trigger that breakpoint. Then go to VS and examine what's wrong

surreal loom
#

OHHH that makes way more sense

#

so intead of me seeing the null, i go "oh hey, i see it, now lets go to the debugger, and sort things out

#

well isntead of me doing it manually and rewriting things to see if i fixed it or not, i can use the debugger to debug it there

#

i see how its supposed to be used and its purpose now

#

thanks for explaining that lol

south girder
#

exactly 👍

surreal loom
#

basically ive not initialized things properly so im combing through it all and making sure everything is initialized properly

south girder
#

that's the usual culprit, yeah 🙂

surreal loom
#

im all about brute force and ignorance. i learn from hard lessons and by repitition.

south girder
#

oh and when your breakpoint is hit, you can step through the code line by line and see what's changing. Click on Debug and there you'll see keyboard shortcuts F10 and F11, those are most important. F10 steps over a line of code, meaning goes from the current to the next one and F11 steps into the method to go further down

surreal loom
#

thats pretty rad!

surreal loom
#

@south girder do you ever map out the flow of your code before writing it?

For example:

Plugin - responsibilities "x, y and z"
Manager - " does this and that"
MessageManager - "does this"
Controller1 - "sets this and uses this"

south girder
#

In my head when swimming/running/showering, yes, but it's a good idea to write it down, sure!

surreal loom
#
//|=====================Summary========================|0|
//| Resets the ConditionsManager to its default states |1|
//|by cvusmo===========================================|4|
//|====================================================|1|
#

ive added this into my scripts so I know what it does but also

#
## MessageManager
- **Responsibility**: Listens for specific messages/events.
- **Actions**: 
  - On receiving specific messages, forwards them to the ConditionsManager.

## ConditionsManager
- **Responsibility**: Validates whether incoming messages meet specific conditions.
- **Actions**: 
  - If conditions are met, sends instructions to the Manager.

## Manager
- **Responsibility**: Acts as an intermediary layer.
- **Actions**: 
  - Receives instructions from the ConditionsManager and delegates the task to LoadModule.

## LoadModule
- **Responsibility**: Ensures that the correct module gets loaded.
- **Actions**: 
  - On receiving instructions, confirms which module needs to be loaded.
  - Delegates the task to StartModule.

## StartModule
- **Responsibility**: Initiates the module start process.
- **Actions**: 
  - Tells the specified module to start.
  - Informs ResetModule to reset the ConditionsManager.

## ResetModule
- **Responsibility**: Resets the ConditionsManager to its default state.
- **Actions**: 
  - Resets the ConditionsManager values.
  - Verifies if the reset has taken it back to its default state for reuse.
#

Made that so I know what things are supposed to be doing

south girder
#

That's a really good thing to have, especially to document things so others can have an easier time understand your code, and mandatory for mods with API imho. Though it's never a priority for developers sadly 🙂
If I have many things to remember to do I'd usually create tasks for myself on github or just write //TODO comments in code if they're smaller things.

surreal loom
#

its a way I know what Im doing and how it works lol otherwise i spend too much time remmebering how it works lol

#

also super easy to write up a rough draft, then tell chatGPT to format it, make the wording sound better, and generate a markdown for you

surreal loom
south girder
#

That's great!

surreal loom
surreal loom
surreal loom
#

@upper summit How did I break it?

@south girder

upper summit
#

How the fuck

surreal loom
#

Figured it out lol

#

Here's what happened...

#

In my plugin, I attempted to call Utilities.Utility.Initialize();

private void Initialize()
{
    _logger.LogInfo("Initializing FFTPlugin...");

    Utilities.Utility.Initialize();

    MessageManager.SubscribeToMessages();
    _logger.LogInfo("Subscribed to messages.");
}```

The problem is that cannot be run until the game has actually loaded:

```cs
public static void Initialize()
{
    RefreshGameManager();
    RefreshActiveVesselAndCurrentManeuver();
}
public static void RefreshActiveVesselAndCurrentManeuver()
{
    ActiveVessel = GameManager.Instance?.Game?.ViewController?.GetActiveVehicle(true)?.GetSimVessel(true);
    CurrentManeuver = ActiveVessel != null ? GameManager.Instance?.Game?.SpaceSimulation.Maneuvers.GetNodesForVessel(ActiveVessel.GlobalId).FirstOrDefault() : null;
}
public static void RefreshGameManager()
{
    var state = GameManager.Instance?.Game?.GlobalGameState?.GetGameState();
    MessageCenter = GameManager.Instance?.Game?.Messages;
}```
#

so I've moved Utilities.Utility.Initialize(); to be ran in Manager.Update(); which gets called

private void UpdateManager()
{
    Manager.Update();
    _logger.LogInfo("Manager.Update() is called");
}```

in FFTPlugin.cs
#

I think that'll fix it.

sick dagger
surreal loom
sick dagger
#

idk

#

thought

#

s

surreal loom
#

easy to read notes on notepad

sick dagger
#

I know

#

Nvm

surreal loom
sick dagger
#

nice

surreal loom
#

now the module isnt being seen by unity. hm

surreal loom
#

Fixed it.

#

sighs I didn't FIX it. I just found another way to break the game.

#
NullReferenceException: Object reference not set to an instance of an object
  at SpaceWarp.SpaceWarpManager.GetSingleSpaceWarpPlugin (System.Collections.Generic.ICollection`1[T] ignoredGUIDs, System.Collections.Generic.ICollection`1[T] spaceWarpInfos, System.Collections.Generic.ICollection`1[T] errorDescriptions, SpaceWarp.API.Mods.BaseSpaceWarpPlugin plugin) [0x00006] in <a3efa574dafd43679814e645b3b9dcb6>:0 
  at SpaceWarp.SpaceWarpManager.GetCodeBasedSpaceWarpPlugins (System.Collections.Generic.List`1[T] spaceWarpPlugins, System.Collections.Generic.ICollection`1[T] ignoredGUIDs, System.Collections.Generic.ICollection`1[T] spaceWarpInfos, System.Collections.Generic.ICollection`1[T] errorDescriptions) [0x0000f] in <a3efa574dafd43679814e645b3b9dcb6>:0 
  at SpaceWarp.SpaceWarpManager.GetAllPlugins () [0x00014] in <a3efa574dafd43679814e645b3b9dcb6>:0 
  at SpaceWarp.Patching.BootstrapPatch.GetSpaceWarpMods () [0x00000] in <a3efa574dafd43679814e645b3b9dcb6>:0 
  at (wrapper dynamic-method) KSP.Game.GameManager.DMD<KSP.Game.GameManager::Awake>(KSP.Game.GameManager)```
wary vessel
#

Hi

surreal loom
wary vessel
#

Good hbu?

surreal loom
#

not too shabby. just deep into programming right now

wary vessel
#

lol just found one of your vids on shorts

surreal loom
#

Nice!

#

I try to make 1 video a week and get a few shorts out. With modding it's taking more time so balancing things out. Glad you're here

wary vessel
#

ok i got a mod idea

#

i think its pretty cool but i dont think anyone will code it

surreal loom
#

#1079080073409347604 definitely leave it there

#

but tell me your mod idea

wary vessel
#

Inflatable habitat modules that are compact and easy to use

surreal loom
wary vessel
#

Oh ty

#

i couldnt think of anything for 2 hours so i used clyde lol

surreal loom
#

i plan to make an inflateable mod that has habitats, bouncing parachutes like Curiosity had when it landed on mars etc

#

its a solid idea and im excited to work on it

wary vessel
#

oh

#

yea

surreal loom
#

ive gotta get FFT performance better and VFX better looking so thats what im focused on developing right now

wary vessel
#

i named my mod in mod ideas Kerbal Exploration and Development Agency

#

(K.E.D.A) (clyde is helpful for part concepts lol)

#

brb

#

back

surreal loom
#

dope

wary vessel
#

clyde giving detailed information about 10 parts lol

surreal loom
#

lol nice

#

theres lots that can be done it just takes time is all

#

some of it can be made now for the game, and others will need science mode and colony added

#

i focus on resources and science, so thats what my mods focus on

wary vessel
#

earlier

#

but beside that

wary vessel
surreal loom
#

short term is FFT, and the next mod i havent even considered yet lol. i made toggle notifications and that was a fun project

wary vessel
#

https://www.youtube.com/watch?v=Od_E2O-YHN8 i looked at this and its how i thought of inflatable habitats as a mod lol

Why Inflatable Habitats Are The Key To A Mars Colony!

Last Video: Major NEW NASA & SpaceX Moon Landing Update!
https://youtu.be/B6tZqWnaQdU

► Join Our Discord Server: https://discord.gg/zfMNSnuRQN
► Patreon: https://www.patreon.com/theteslaspace
► Subscribe to our other channel, The Space Race: https://www.youtube.com/c/TheTeslaSpace
Mars Colo...

▶ Play video
#

its just when i use clyde

#

clyde never does the thing i want him to do

surreal loom
#

who is clyde btw?

wary vessel
#

so

#

AI

#

go to add convo

#

and then do that

#

hes kinda helpful

#

but if you need like someone who can give some extra advice ask someone else

#

i didnt even realise i had ksp2 open for 5 hours

surreal loom
#

ah nice

#

AI is cool

wary vessel
#

yea

#

i asked him for a name he gave me K.E.D.A

#

i couldnt get a better one lol

surreal loom
#

lol

wary vessel
#

just go to mod ideas and ill add some more things thatll be in it

#

its the newest one

#

How far are you into the science mod thing?

surreal loom
#

pretty far with the modelling and animations

wary vessel
#

ok

surreal loom
#

obvious no work has been done with science since it's not in the game

wary vessel
#

ok

#

wait

#

what if in ksp2

#

some certain parts would be secretive and the kerbals had to like study some planets to realise what could make their rockets better or things that are really efficient and fuel conservent but you need something from another planet

#

that would be a cool concept

surreal loom
#

its on my to do list

#

but i need a tech tree so i can add the a whoel new branch to it

#

i wanna make three branches
Biology
Quantum Field
Mining

wary vessel
#

ooh that sounds cool

#

Do you think that these are possible to code a mod for in ksp2? (only some)

surreal loom
#

Anything is possible to code. It could take a while. If the modules aren't in the game, you have to program everything yourself. For example...

#

this is all im working on right now to make Fancy Fuel Tanks work

#

thats for a "simple" fuel tank mod with vfx added to it

#

the more complicated things get, and the less you can use already pre-made modules, the more you're going to spend developing your own modules etc

wary vessel
#

idk how to code so thats why i put mine in #1079080073409347604

surreal loom
#

all good

#

i dont know how to either, this is my fourth month modding

wary vessel
#

like ive never coded lol

surreal loom
#

i never coded before this, other than making a basic script for arma 3

#

everyone here is super helpful if you want to learn

#

also a fun place to hang out

wary vessel
#

I just hope someone makes my mod idea a reality. I think its pretty cool tbh if someone could make an animation to make it look realistic for the inflation of the habitats

surreal loom
#

itll come, it just takes time

#

its taken me 3 days to rewrite all of FFT's programming and its still not functional yet

wary vessel
#

wow i dont unterstand that but it looks complicated

surreal loom
#

@south girder seeing red a lot. LUL

Also I wrote the code as DI and it didnt work so I reverted back to Singleton.

south girder
#

ok. Works now?

surreal loom
# south girder ok. Works now?

singleton is working. so now im finally debugging it. so far just a bunch of little things like not initializing stuff

#
public override void OnInitialized()
{
    base.OnInitialized();
    _logger.LogInfo("Initializing FFTPlugin...");

    _messageManager.SubscribeToMessages();
    _manager.Update();
    _logger.LogInfo("Subscribed to messages.");
}```

probably a bad idea to try to subscribe to messages when the plugin is initalizing?
#

cause theres nothing really to subscribe to yet

#
  at (wrapper managed-to-native) System.Object.__icall_wrapper_ves_icall_object_new_specific(intptr)
  at FFT.Utilities.RefreshVesselData..ctor () [0x00014] in E:\Modding\repos\FFT\FFTProject\Utilities\RefreshVesselData.cs:21 
  at FFT.Managers.MessageManager..ctor (BepInEx.Logging.ManualLogSource logger) [0x0006f] in E:\Modding\repos\FFT\FFTProject\Managers\MessageManager.cs:47 
  at FFT.Managers.MessageManager.get_Instance () [0x00017] in E:\Modding\repos\FFT\FFTProject\Managers\MessageManager.cs:31 
  at FFT.Managers.ConditionsManager.get_Instance () [0x00010] in E:\Modding\repos\FFT\FFTProject\Managers\ConditionsManager.cs:26 
  at FFT.Managers.MessageManager..ctor (BepInEx.Logging.ManualLogSource logger) [0x000a6] in E:\Modding\repos\FFT\FFTProject\Managers\MessageManager.cs:54 
  at FFT.Managers.MessageManager.get_Instance () [0x00017] in E:\Modding\repos\FFT\FFTProject\Managers\MessageManager.cs:31 ```
south girder
#

is your code up to date on the git repo?

surreal loom
#

lemme double check

#

thats the branch im working on

#

i have a stable dev branch so i made two others to test on

south girder
#

I don't know what's happening just by looking at this. But if you think it's due to things not being initialized yet, you can try subscribing to messages when you reach main menu. Although it works for Micro Engineer to subscribe during mod initialization

surreal loom
#

hm

#

its probably something i messed up and did wrong

#

but i need some sleep

#

appreciate the pointers!

#

My brain is mush lol. I thought using dependency injection would be better for performance than singleton. It looked awesome I just couldn't figure it out

south girder
#

I see you're doing subscribe in 2 different places.

public override void OnInitialized()
        {
            base.OnInitialized();
            _logger.LogInfo("Initializing FFTPlugin...");

            _messageManager.SubscribeToMessages();
            _manager.Update();
            _logger.LogInfo("Subscribed to messages.");
        }
private void Initialize()
        {
            _logger.LogInfo("Initializing FFTPlugin...");
            _messageManager.SubscribeToMessages();
            _logger.LogInfo("Subscribed to messages.");
        }

that probably isn't right 🙂

surreal loom
#

Nope. Definitely need sleep if I'm making mistakes like that haga

south girder
#

and you call initialization during the class constructor:

private FFTPlugin()
        {
            try
            {
                InitializeDependencies();
                InitializeConfig();
                Initialize();
            }
            catch (Exception ex)
            {
                HandleException(ex, "Initialization");
            }
        }
#

best to do everything in
public override void OnInitialized()

#

ok, go and rest, best to do this with a clear head 🙂

surreal loom
#

@south girder

public override void OnInitialized()
{
    base.OnInitialized();
    _logger.LogInfo("Initializing FFTPlugin...");

    try
    {
        InitializeDependencies();
    }
    catch (Exception ex)
    {
        HandleException(ex, "Initialization");
    }

    Config.Bind(
        "Fancy Fuel Tanks Settings",
        "Enable VFX",
        true,
        "Fancy Fuel Tanks adds Dynamic Environmental Effects to fuel tanks"
    );

    _messageManager.SubscribeToMessages();
    _manager.Update();
    _logger.LogInfo("Subscribed to messages.");
}
public void SetLoadModule(ILoadModule loadModule)
{
    _loadModule = (LoadModule)loadModule;
}
private void InitializeDependencies()
{
    _messageManager = MessageManager.Instance;
    _moduleController = ModuleController.Instance;
    _conditionsManager = new ConditionsManager(_messageManager, _logger);
    _loadModule = LoadModule.Instance;
    _startModule = new StartModule(_messageManager, _logger);
    _resetModule = ResetModule.Instance;
    _manager = Manager.Instance;

    _moduleVentValve = Module_VentValve.Instance;
}```
south girder
#

ok, try it

surreal loom
#

first log shows specifics to FFT and second log is the full log

#

somehow i have a recursive loop

#

so messagemanager is trying to access itself and conditionsmanager

#

first time seeing a StackOverflowException as well

south girder
#

yeah, it's hard to see stack overflow in c# 🙂

south girder
#

can I see the whole FFTPlugin.cs file?

surreal loom
#

I'm doing a lazy method to load things

#

I think thatll solve the issues with the stackoverflow thats in messagemanager and conditionsmanager

#

I think that'll solve the issue

#

Could be 100% wrong

south girder
#

conditionsManager is a singleton, so this is wrong probably _conditionsManager = new ConditionsManager(_messageManager, _logger);

#

startmodule as well

surreal loom
#

hm

#

ah

#

I don thave an instance of either in their classes made

#

and im using singleton, this makes sense

#
  private void InitializeDependencies()
  {
      _messageManager = MessageManager.Instance;
      _moduleController = ModuleController.Instance;
      _conditionsManager = ConditionsManager.Instance;
      _loadModule = LoadModule.Instance;
      _startModule = StartModule.Instance;
      _resetModule = ResetModule.Instance;
      _manager = Manager.Instance;
      _moduleVentValve = Module_VentValve.Instance;
  }```

fixed it
south girder
#

you're subscribing to messages in MessageManager constructor, so this is redundant: _messageManager.SubscribeToMessages();

surreal loom
#

I thought I had to call it in oninitialized so it actually ran?

south girder
#

so as soon as you call MessageManager.Instance; of a singleton, its instance is instantiated and everything inside the constructor (private MessageManager(ManualLogSource logger)) is executed

surreal loom
#

i had no idea that constructors were called when an instance is instantiated

#

lol

#

oh wow

#

okay, so when I make an instance:

_messageManager = MessageManager.Instance;

it then calls that constructor and anything in:

{
    ModuleListeners = new Dictionary<ModuleType, Action>
    {
        { ModuleType.ModuleVentValve, () => _logger.LogDebug("Listening to ModuleVentValve.") }
    };

    ModuleReadyToLoad = delegate { };
    SubscribeToMessages();
}```

gets called?
#

how do I make sure I instantiate things at the right time? For example, how I'm undersatnding it is that when the game is loading and in the main menu, i should have the plugin everything witht he plugin instantiated.

Then when it gets into game and meets conditions, it should run various modules i create?

#

thats how i think it works but again, i could have this very wrong. my big concern was making sure everything is loaded properly so the mod works and has everything it needs

#
public override void OnInitialized()
{
    base.OnInitialized();
    _logger.LogInfo("Initializing FFTPlugin...");

    try
    {
        InitializeDependencies();
    }
    catch (Exception ex)
    {
        HandleException(ex, "Initialization");
    }

    Config.Bind(
        "Fancy Fuel Tanks Settings",
        "Enable VFX",
        true,
        "Fancy Fuel Tanks adds Dynamic Environmental Effects to fuel tanks"
    );

    //_messageManager.SubscribeToMessages();
    //_manager.Update();
    _logger.LogInfo("Subscribed to messages.");
}```

FFTPlugin calls InitalizeDependencies which instantiates everything causing all the contructors to run.

```cs
private Manager()
{
    Logger = BepInEx.Logging.Logger.CreateLogSource("FFT.Manager: ");
    Update();
    _messageManager.ModuleReadyToLoad += HandleModuleReadyToLoad;

}
public void Update()
{
    Utility.RefreshGameManager();
    _messageManager.Update();
    Logger.LogDebug("MessageManager.Update called");
}```

Manager's constructor runs and runs it's update and makes the handle ModuleReadyToLoad
#
private MessageManager(ManualLogSource logger)
{
    ModuleListeners = new Dictionary<ModuleType, Action>
    {
        { ModuleType.ModuleVentValve, () => _logger.LogDebug("Listening to ModuleVentValve.") }
    };

    ModuleReadyToLoad = delegate { };
    SubscribeToMessages();
}
public void SubscribeToMessages()
{
    _logger.LogDebug($"Subscribing To Messages... ");
    Utility.RefreshGameManager();
    Utility.MessageCenter.Subscribe<GameStateEnteredMessage>(msg => conditionsmanager.GameStateEnteredHandler((GameStateEnteredMessage)msg));
    Utility.MessageCenter.Subscribe<GameStateLeftMessage>(msg => conditionsmanager.GameStateLeftHandler((GameStateLeftMessage)msg));
    Utility.MessageCenter.Subscribe<VesselSituationChangedMessage>(msg => conditionsmanager.HandleVesselSituationChanged((VesselSituationChangedMessage)msg));
    _logger.LogDebug($"Subscribed to: {nameof(GameStateEnteredMessage)}, {nameof(GameStateLeftMessage)}, {nameof(VesselSituationChangedMessage)}");

    ModuleReadyToLoad += HandleModuleReadyToLoad;
    _logger.LogDebug("Subscribed to ModuleReadyToLoad event.");
}```

Message managers constructor is called and it runs all of its stuff and subscribes to messages.
#

That's how I think it's working.

south girder
#

so, one step back cause I'm not sure if we understand each other correctly.

this is called a singleton pattern:

private static MessageManager _instance;
public static MessageManager Instance
{
    get
    {
        lock (_lock)
        {
            if (_instance == null)
            {
                _instance = new MessageManager(_logger);
            }
            return _instance;
        }
    }
}

private MessageManager(ManualLogSource logger)
{
    ModuleListeners = new Dictionary<ModuleType, Action>
    {
        { ModuleType.ModuleVentValve, () => _logger.LogDebug("Listening to ModuleVentValve.") }
    };

    conditionsmanager = ConditionsManager.Instance;
    ModuleReadyToLoad = delegate { };
    SubscribeToMessages();
}

It's use it to assure that one and only one instance of that class can be instantiated.
As soon as you type MessageManager.Instance it goes to public static MessageManager Instance and retrieves _instance. Since _instance is null, it instantiates the instance with new MessageManager(_logger). When you instantiate an instance a constructor is called, whatever constructor you defined.
You defined private MessageManager(ManualLogSource logger) (the private part is important so this class cannot be instantiated from outside. It can be only instantiated from inside the class, from get Instance

surreal loom
#

well

#

i ran it

#

things are being called before the game is loaded so it crashes

south girder
#

second, for plugins it's best to initialize things in OnInitialized when you can. But you can't initialize stuff that isn't ready when the game is loading

surreal loom
#

so i need to be sure that I call things at the right time

south girder
#

so if you know some stuff is ready later, then initialize when that later parts gets done

south girder
#

for the messages, they're safe to subscribe on OnInitialized cause they're already done then

surreal loom
#

hm

#

where is player.log stored?

south girder
#

for other stuff you're trying to do I'm not sure if they're ready on OnInitialized, I'm not that versed

#

"C:\Users<yourusername>\AppData\LocalLow\Intercept Games\Kerbal Space Program 2\Player.log"

surreal loom
#

[Debug :FFT.MessageManager] Subscribing To Messages...
[Debug :FFT.MessageManager] Subscribed to: GameStateEnteredMessage, GameStateLeftMessage, VesselSituationChangedMessage
[Debug :FFT.MessageManager] Subscribed to ModuleReadyToLoad event.

#

then right after that, it crashes

#

so basically i need to sort out when to initialize other things so things work properly

#

which subscribing works fine

south girder
#

after [Debug :FFT.MessageManager] Subscribed to ModuleReadyToLoad event. there's _conditionsManager = new ConditionsManager(_messageManager, _logger); right? Did you sort it out that you're not doing new ConditionsManager ?

#

or, ModuleController

surreal loom
#
public static ConditionsManager Instance
{
    get
    {
        lock (_lock)
        {
            return _instance ??= new ConditionsManager(MessageManager.Instance, Logger.CreateLogSource("FFT.ConditionsManager"));
        }
    }
}```
#
{
    InitializeModuleStates();
}
private void InitializeModuleStates()
{
    foreach (ModuleType moduleType in Enum.GetValues(typeof(ModuleType)))
    {
        moduleStates[moduleType] = false;
    }
}```
#
{
    _messageManager = messageManager ?? throw new ArgumentNullException(nameof(messageManager));
    _logger = logger ?? throw new ArgumentNullException(nameof(logger));

    _messageManager.GameStateEntered += GameStateEnteredHandler;
    _messageManager.GameStateLeft += GameStateLeftHandler;
    _messageManager.VesselSituationChanged += HandleVesselSituationChanged;
}```
#

so looking at this module controller should run later

south girder
#
private void InitializeDependencies()
{
    _messageManager = MessageManager.Instance;
    _moduleController = ModuleController.Instance;
    _conditionsManager = new ConditionsManager(_messageManager, _logger);
    _loadModule = LoadModule.Instance;
    _startModule = new StartModule(_messageManager, _logger);
    _resetModule = ResetModule.Instance;
    _manager = Manager.Instance;

    _moduleVentValve = Module_VentValve.Instance;
}

ModuleController gets instantiated first

surreal loom
#

Would this separate when things get instantiated?

private void InitializeDependencies()
{
    _moduleController = ModuleController.Instance;
    _manager = Manager.Instance;
    _messageManager = MessageManager.Instance;
    _conditionsManager = ConditionsManager.Instance;              
}
public override void OnPostInitialized()
{
    base.OnPostInitialized();
    _moduleVentValve = Module_VentValve.Instance;
    _loadModule = LoadModule.Instance;
    _startModule = StartModule.Instance;
    _resetModule = ResetModule.Instance;
    _logger.LogInfo("FFTPlugin OnPostInitialized called.");
}```
south girder
#

it's instantiated in a way you're writing the code 🙂
but yes, OnPostInitialized is called after OnInitialized

surreal loom
#

when exactly is onpostinitialized called? after everything has ran its oninitialized?

south girder
#

yes

surreal loom
#

ah thats cool

south girder
#

I think that all mods go through OnInitialized, then all go through OnPostInitialized

surreal loom
#

so i just need to make sure the core things i need instantiate in OnInitialize, then things I need but won't be available until everything has loaded, needs to be in OnPostInitialized?

south girder
#

... if you're sure they'll be loaded when OnPostInitialized is called, then yes

surreal loom
#

sure is rather subjective

#

lol im not sure at all

#

but i think it makes sense and i just need to verify how the constructors are working to be sure that theyre in the correct order

south girder
#

everything you're doing is being done linearly, nothing is async. So whatever you write before the other, it will be executed first

surreal loom
#

is that a good way to do it?

south girder
#

when you write _moduleController = ModuleController.Instance; ModileController gets instantiated and everything you wrote in the constructor of ModuleController will be executed

south girder
surreal loom
#

okay

#

thast good lol

#

now ive gotta check my constructors

#

and make sure what theyre calling is appropriate otherwise instanitate them later

south girder
#

yes

surreal loom
#

this makes sense

#

could i use try and catch to initialize things better. im doing it in oninitialize but could i use it to say "hey try this, but if this happens, catch this and wait to do this again"

south girder
#

so if inside the contructor you're calling SomeOtherClass.Instance, then it will go and instantiated that other class... which is a bit messy, I would avoid that

surreal loom
#

lol

#

This will throw a null exception if these are null, correct?
_messageManager = messageManager ?? throw new ArgumentNullException(nameof(messageManager));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));

south girder
surreal loom
#

which simplifies things a bit for me

#

but i also am not sure what i need to have intiialized so my plugin to be working once the game has loaded

south girder
#

for microengineer, I tend to do stuff when gamestate is in flight view, map view or OAB, so I have subscriptions for gamestateentered and gamestateleft

south girder
# surreal loom This will throw a null exception if these are null, correct? _messageManager = m...

chatGPT to the rescue:

The ?? operator checks if the value on the left side (_messageManager) is null. If it's not null, the operator returns the value of _messageManager and the assignment ends. If it is null, the operator returns the value on the right side (messageManager).
If the value on the right side (messageManager) is also null, then the throw statement is executed.
The throw statement throws an exception, specifically an instance of ArgumentNullException. The nameof(messageManager) part provides the name of the argument (parameter) that is causing the exception. This helps in providing meaningful error messages and debugging information.
#

I would suggest you place a breakpoint at the beginning of OnInitialized and then step into the code (F11) line by line so you can see for yourself how the flow goes, when instances are instantiated, when constructors are called, etc. You'll learn a lot from it

surreal loom
#

chadGPT

#

uhh how do I do a breakpoint?

#

sorry im so new at all of this

#

thank you for taking the time to help me learn this as well

south girder
#

click here

surreal loom
#

I've done that, do I set the breakpoint to keep running the code?

#

well how do I select it with the IO thing?

south girder
#

once you've placed the breakpoint (red dot and the line's background is red) then code will pause executing on that line. But you need to attach to unity's instance when you start the game

#

don't worry about the IO thing 😄

surreal loom
#

do i need it to be running with the debugger to select it?

#

this lets me red dot

south girder
#

so, 1. place a breakpoint, 2. start the game, 3. Immediately when the game starts attach unity debugger with Debug -> Attach Unity Debugger

surreal loom
#

Stream time after that I'll be diving back into this

#

appreciate the demo!

wary vessel
#

nobody cares about my idea 😦

surreal loom
wary vessel
#

ok

surreal loom
#

@south girder

Well, I learned why all my constructors were messing up. They were recursively calling creating a stackoverflow.

public static Manager Instance
{
    get
    {
        lock (_lock)
        {
            if (_instance == null)
            {
                _instance = Manager.Instance; <<<<
            }
            return _instance;
        }
    }
}```

If I do this:

```cs
public static Manager Instance
{
   get
   {
       lock (_lock)
       {
           if (_instance == null)
           {
               _instance = new Manager(); 
           }
           return _instance;
       }
   }
}```

It should work as intended
south girder
#

lol yeah, I missed that 🙂

surreal loom
#

I have scrubbed through this an dim really hoping it works

#

inbetween debugging, im doing a 4K stream test. uhh yeah i can stream 4k that sinsane.

surreal loom
#

@south girder what does this mean?

#
[Debug  : FFTPlugin] Attempting to initialize ConditionsManager...
[Debug  : FFTPlugin] ConditionsManager initialized successfully.
[Debug  : FFTPlugin] Attempting to initialize ModuleController...
[Debug  : FFTPlugin] ModuleController initialized successfully.
[Debug  : FFTPlugin] Attempting to initialize StartModule...
[Debug  : FFTPlugin] StartModule initialized successfully.
[Debug  : FFTPlugin] Attempting to initialize ResetModule...```

getting closer!
#

things are starting to load and its starting to make sense

south girder
# surreal loom <@378898832559439876> what does this mean?

that usually means that the breakpoint is not reachable, either by VS getting confused with something, or more often that you made changes to the code after copying .dll and .pdb files to the game folder (.pdb file is the one that holds information about debugging).
Solution? Build the solution again, copy files, start the game and don't make changes to your code. If you still get those yellow triangles VS might be confused by something - restart it, rebuild again...

#

oh and you probably don't need that many breakpoint. Set one before the stuff you want to examine and then F10 and F11 through the code to get to the part you're interested in

surreal loom
#

but im close, ive just gotta tidy up startmodule, resetmodule, and loadmodule

#

then it should load correctly

#

im havin ga lot of recursive calls on themselves creating stackoverflows. and a lot of redundant code because it was bread in me to be redundant with PLCs and automation

#

but im gonna call it a night, rest some and finish it up tomorrow

#

ive uplaoded it all to https://github.com/cvusmo/FFT/tree/dev gonna make one more push right now to have it updated to what it is right now.

I just need to make sure my constructors in my controller folder are corret and figure out when they need to initialize and then make sure they initialize at the right time. which will be after post-initialize. I want them to initialize when the game state changes to KSC or something like that. when the game is actually loaded and the player is actively in their game

GitHub

Fancy Fuel Tanks "FFT". Contribute to cvusmo/FFT development by creating an account on GitHub.

south girder
#

it'll work out, you're doing excellent progress!

surreal loom
#
[Info   : FFTPlugin] Subscribing to messages.... 
[Debug  :FFT.MessageManager] Subscribing To Messages...
[Debug  :FFT.MessageManager] Subscribed to: GameStateEnteredMessage, GameStateLeftMessage, VesselSituationChangedMessage
[Debug  : FFTPlugin] Initialized FFTPlugin.```
surreal loom
#
[Debug  : FFTPlugin] Calling OnPostInitialized...
[Debug  : FFTPlugin] Attempting to initialize ConditionsManager...
[Debug  : FFTPlugin] ConditionsManager initialized successfully.
[Debug  : FFTPlugin] Attempting to initialize ModuleController...
[Debug  : FFTPlugin] ModuleController initialized successfully.
[Debug  : FFTPlugin] Attempting to initialize StartModule...
[Debug  : FFTPlugin] StartModule initialized successfully.
[Debug  : FFTPlugin] Attempting to initialize ResetModule...
Uploading Crash Report
StackOverflowException: The requested operation caused a stack overflow.
  at (wrapper managed-to-native) System.Object.__icall_wrapper_ves_icall_object_new_specific(intptr)
  at BepInEx.Logging.Logger.CreateLogSource (System.String sourceName) [0x00000] in <fe49c90fe8e24102b42489c11910c71c>:0 
  at FFT.Managers.Manager..ctor () [0x00011] in E:\Modding\repos\FFT\FFTProject\Managers\Manager.cs:43 
  at FFT.Managers.Manager.get_Instance () [0x00010] in E:\Modding\repos\FFT\FFTProject\Managers\Manager.cs:37 
  at FFT.Controllers.LoadModule.Initialize () [0x00007] in E:\Modding\repos\FFT\FFTProject\Controllers\LoadModule.cs:68 
  at FFT.Controllers.LoadModule.get_Instance () [0x00017] in E:\Modding\repos\FFT\FFTProject\Controllers\LoadModule.cs:30 
  at FFT.Managers.Manager..ctor () [0x00089] in E:\Modding\repos\FFT\FFTProject\Managers\Manager.cs:48 ```
surreal loom
#
[Debug  : FFTPlugin] Initializing FFTPlugin...
[Info   : FFTPlugin] Subscribing to messages.... 
[Debug  :FFT.MessageManager] Subscribing To Messages...
[Debug  :FFT.MessageManager] Subscribed to: GameStateEnteredMessage, GameStateLeftMessage, VesselSituationChangedMessage
[Debug  : FFTPlugin] Initialized FFTPlugin.
[System] Initialization for plugin Fancy Fuel Tanks completed in 0.0078s.```
#

slowly fixing the bugs

sick dagger
#

bro you have about the same messages as the lux devlog

surreal loom
#

lol

#

its a lot of debugging

#

im having stack overflows and some other issues with the code, but slowly fixing the bugs

surreal loom
#
[Debug  : FFTPlugin] Set FFTPlugin.Path to: 
[Debug  : FFTPlugin] Set FFTPlugin.Path to: E:\Modding\Kerbal Space Program 2\BepInEx\plugins\FFT
[Debug  : FFTPlugin] Set FFTPlugin.Path to: 
[Debug  : FFTPlugin] Accessed FFTPlugin.Path: 
[Debug  : FFTPlugin] PluginFolderPath: 
[Debug  : FFTPlugin] FFTPlugin OnPreInitialized called.
[System] Pre-initialization for plugin Fancy Fuel Tanks completed in 0.0122s.```
surreal loom
#

Fixed pathing error. Now I have a config that I can swap to change the pathing for the dev build. Release build won't have it but for dev build it's nice.

[Debug  : FFTPlugin] Set FFTPlugin.Path to: E:\Modding\Kerbal Space Program 2\BepInEx\plugins\FFT
[Debug  : FFTPlugin] Set FFTPlugin.Path to: 
[Debug  : FFTPlugin] Accessed FFTPlugin.Path: 
[Debug  : FFTPlugin] PluginFolderPath: 
[Debug  : FFTPlugin] FFTPlugin OnPreInitialized called.
[System] Pre-initialization for plugin Fancy Fuel Tanks completed in 0.0122s.
[Debug  : FFTPlugin] Calling OnPostInitialized...
[Debug  : FFTPlugin] Attempting to initialize ConditionsManager...
[Debug  : FFTPlugin] ConditionsManager initialized successfully.
[Debug  : FFTPlugin] Attempting to initialize ModuleController...
[Debug  : FFTPlugin] ModuleController initialized successfully.
[Debug  : FFTPlugin] Attempting to initialize StartModule...
[Debug  : FFTPlugin] StartModule initialized successfully.
[Debug  : FFTPlugin] Attempting to initialize ResetModule...
[Error  : FFTPlugin] Error during OnPostInitialized: ValueFactory attempted to access the Value property of this instance.
[System] Post-initialization for plugin Fancy Fuel Tanks completed in 0.0103s.
[Debug  :FFT.ConditionsManager] Left Previous GameState: UNKNOWN GAMESTATE.
[Debug  :FFT.ConditionsManager] Entered New GameState: MainMenu.```

[Debug : FFTPlugin] Set FFTPlugin.Path to:
[Debug : FFTPlugin] Set FFTPlugin.Path to: E:\Modding\Kerbal Space Program 2\BepInEx\plugins\FFT
[Debug : FFTPlugin] PluginFolderPath: E:\Modding\Kerbal Space Program 2\BepInEx\plugins\FFT
[Debug : FFTPlugin] FFTPlugin OnPreInitialized called.
[System] Pre-initialization for plugin Fancy Fuel Tanks completed in 0.0028s.```

#
Unable to open archive file: FFT.FFTPlugin.Path/addressables/StandaloneWindows64/defaultlocalgroup_assets_all_bbe62f479f9cbb13928eca7e471dd38c.bundle
Failed to read data for the AssetBundle 'FFT.FFTPlugin.Path\addressables\StandaloneWindows64\defaultlocalgroup_unitybuiltinshaders_237e3d59f44efca5bd52e9de65795925.bundle'.
[System] Exception passed from Unity.Addressables! [RemoteProviderException : Invalid path in AssetBundleProvider: 'FFT.FFTPlugin.Path\addressables\StandaloneWindows64\defaultlocalgroup_unitybuiltinshaders_237e3d59f44efca5bd52e9de65795925.bundle'.
]```
surreal loom
surreal loom
#

LETS GOOO

#

and immediately sad.

surreal loom
#

LETS FREAKING GO!

surreal loom
#

@south girder thank you! slowly but surely learning how to debug

south girder
#

lol, it's an emotional rollercoaster reading your thread 😄
excelent!

surreal loom
#

LUL

internal void InitializeData()
{

  if (_fuelTankDefinitions == null || _ventValveDefinitions == null)
    {
        throw new Exception("Definitions are not initialized.");
    }

    _dataFuelTanks = new Data_FuelTanks();
    _dataValveParts = new Data_ValveParts();
    _dataVentValve = new Data_VentValve();
    _fuelTankDefinitions = new FuelTankDefinitions();
    _ventValveDefinitions = new VentValveDefinitions();   

    FuelTankDefinitions.PopulateFuelTanks(_dataFuelTanks);
    VentValveDefinitions.PopulateVentValve(_dataValveParts);
}```
#

figured out why it ws coming back null

#

huh.. @south girder what does this mean? never had anything show up in autos before

#

OMG is this telling me the values of things in my code currently??

south girder
#

Autos is just one of the debugging windows, like Locals and Watch.

surreal loom
south girder
surreal loom
#

so now i can see why this part isn't working

#

thats freaking sweet

#

no idea how to fix it, but its cool. soon.tm ill have it fixed

#

getting closer to being able to test the vfx

south girder
#

in the Watch window you can type in anything you want to se current values

surreal loom
#

this is a big problem. when i select the CV401, it should use that data to be like "yup found CV401!" but instead everything is returning null.

#

so later today i have more debugging to do. but a lot has been accomplished!

south girder
#

I often just set a breakpoint in OnGui or Update just to get the game to pause, and then I type stuff and explore GameManager properties

surreal loom
#

so what I did is set a breakpoint here on InitializeData to see what the values are. now if i continue, it should change those values correct?

south girder
#

yep

surreal loom
#

HHOLY SHIT

#

i just did the F11 thing

south girder
#

press F11 to step into InitializeData()

surreal loom
#

thats freakin sickkk

#

oh lawd my game hates me

south girder
#

F11 steps into the method, F10 skips over it

surreal loom
#

its like "WTF ARE YOU DOING BRO. STOP"

#

alright so now ive gotta make sure the definitions are initialized

#

this is starting to make sense in how breakpoints work and how i can use them to debug

#

its super super super super useful

#

oh

#

they're not singletons. might need to change the definiltions to be singletons

#

not too shabby

surreal loom
#

SUCCESS! (maybe)

#

well now ive just gotta debug and make the animation work and make sure conditions are being set.

surreal loom
#
-Update OAB pictures [WIP]
-Clean up textures [WIP]
-Improve VFX quality [WIP]
-Improve Texture quality on Hydrogen Tanks (medium) [WIP]
-Improve performance of VFX [WIP]
-Create custom logger[WIP]

Next Update: [0.1.4.3]
-Develop Fuel Tank Selector [Coming in 0.1.4.3]```
surreal loom
#
[Error  : FFTPlugin] Failed to find FuelTankDefinitions.
[Error  : FFTPlugin] Failed to find VentValveDefinitions.
[Debug  : FFTPlugin] InitializeData success.
[Debug  : FFTPlugin] InitializeVFX called.
[Debug  : FFTPlugin] InitializeVFX success.
[Debug  : FFTPlugin] Animator called: CV401.prefab_7fedfb1a-8429-4ac9-a1fc-653e1e897e10 (UnityEngine.Animator)
[Debug  : FFTPlugin] Animator success: CV401.prefab_7fedfb1a-8429-4ac9-a1fc-653e1e897e10 (UnityEngine.Animator)
[General] Execution Priority marked Dirty
[Debug] [engine_1v_methalox_swivel.Module_Engine] TryGetRendererMaterialsByName was unable to find engine_1v_methalox_swivel
[System] Property [isVisible] already found in context!
[System] Property [isVisible] already found in context!
[General] Execution Priority marked Dirty
[System] Starting... completed in 0.0000s.
[Debug  : FFTPlugin] Emission disabled.
[Debug  : FFTPlugin] StopVFX Called```
surreal loom
#

@south girder any pointers on getting a the DataFuelTanks, DataVentValve, DataValveParts, FuelTankDefinitions and VentValveDefinitions to properly intialize?

#
using KSP.Sim.Definitions;
using UnityEngine;

namespace FFT.Modules
{
    [Serializable]
    public class Data_FuelTanks : ModuleData
    {
        public override Type ModuleType => typeof(Module_VentValve);
        public Dictionary<string, GameObject> fuelTankDict;

        public void Awake()
        {
            fuelTankDict = new Dictionary<string, GameObject>();

            fuelTankDict.Add("CV401", CV401);
            fuelTankDict.Add("CV411", CV411);
            fuelTankDict.Add("CV421", CV421);
            fuelTankDict.Add("SP701", SP701);
            fuelTankDict.Add("SR812", SR812);
            fuelTankDict.Add("SR812A", SR812A);
            fuelTankDict.Add("SR813", SR813);
        }

        [SerializeField]
        public GameObject CV401;
        [SerializeField]
        public GameObject CV411;
        [SerializeField]
        public GameObject CV421;
        [SerializeField]
        public GameObject SP701;
        [SerializeField]
        public GameObject SR812;
        [SerializeField]
        public GameObject SR812A;
        [SerializeField]
        public GameObject SR813;

    }
}```
#
using KSP.Sim;
using KSP.Sim.Definitions;
using System.Collections.Generic;
using UnityEngine;

namespace FFT.Modules
{
    public class Data_ValveParts : MonoBehaviour
    {
        public Dictionary<string, GameObject> ventValveDict;  
        public void Awake()
        {
            ventValveDict = new Dictionary<string, GameObject>();

            ventValveDict.Add("RF1", RF1);
            ventValveDict.Add("RF2", RF2);
        }

        [SerializeField]
        public GameObject RF1;
        [SerializeField]
        public GameObject RF2;      
    }
}
#
using FFT.Modules;
using System.Collections.Generic;
using KSP.Sim;
using KSP.Sim.Definitions;
using System;
using UnityEngine;

namespace FFT.Modules
{
    [Serializable]
    public class Data_VentValve : ModuleData
    {
        public override Type ModuleType => typeof(Module_VentValve);

        [KSPState]
        public AnimationCurve VFXASLCurve = new AnimationCurve(new Keyframe(0, 0), new Keyframe(1000, 1));
        [KSPState]
        public AnimationCurve VFXAGLCurve = new AnimationCurve(new Keyframe(0, 0), new Keyframe(1000, 1));
        [KSPState]
        public AnimationCurve VFXVerticalVelocity = new AnimationCurve(new Keyframe(0, 0), new Keyframe(200, 1));
        [KSPState]
        public AnimationCurve VFXHorizontalVelocity = new AnimationCurve(new Keyframe(0, 0), new Keyframe(200, 1));
        [KSPState]
        public AnimationCurve VFXDynamicPressure = new AnimationCurve(new Keyframe(101.325f, 0), new Keyframe(0.100f, 1));
        [KSPState]
        public AnimationCurve VFXStaticPressure = new AnimationCurve(new Keyframe(99.65f, 0), new Keyframe(0, 1));
        [KSPState]
        public AnimationCurve VFXAtmosphericTemperature = new AnimationCurve(new Keyframe(287.24f, 0), new Keyframe(0, 1));
        [KSPState]
        public AnimationCurve VFXExternalTemperature = new AnimationCurve(new Keyframe(287.24f, 0), new Keyframe(0, 1));
        [KSPState]
        public AnimationCurve VFXOpacityCurve = new AnimationCurve(new Keyframe(1, 1), new Keyframe(0.95f, 0));
    }
}```
#
using System.Collections.Generic;
using UnityEngine;

namespace FFT.Modules
{
    public class FuelTankDefinitions : MonoBehaviour
    {
        [SerializeField]
        public List<GameObject> fuelTankDefinitions;
        [SerializeField]
        public Data_VentValve _dataVentvalve;
        [SerializeField]
        public Data_FuelTanks _dataFuelTanks;
        public Dictionary<string, GameObject> fuelTanksDict = new Dictionary<string, GameObject>();
        public bool isInitialized;

        public void PopulateFuelTanks(Data_FuelTanks data)
        {
            if (this.isInitialized)
                return;
            this.fuelTanksDict["CV401"] = data.CV401;
            this.fuelTanksDict["CV411"] = data.CV411;
            this.fuelTanksDict["CV421"] = data.CV421;
            this.fuelTanksDict["SP701"] = data.SP701;
            this.fuelTanksDict["SR812"] = data.SR812;
            this.fuelTanksDict["SR812A"] = data.SR812A;
            this.fuelTanksDict["SR813"] = data.SR813;
            this.isInitialized = true;
        }

        public GameObject GetFuelTank(string tankName)
        {
            GameObject gameObject;
            return this.fuelTanksDict.TryGetValue(tankName, out gameObject) ? gameObject : (GameObject)null;
        }

        public Module_VentValve GetmoduleVentValve(string tankName)
        {
            GameObject gameObject;
            return this.fuelTanksDict.TryGetValue(tankName, out gameObject) ? gameObject.GetComponent<Module_VentValve>() : (Module_VentValve)null;
        }
    }
}```
#
using System.Collections.Generic;
using UnityEngine;

namespace FFT.Modules
{
    public class VentValveDefinitions : MonoBehaviour
    {
        [SerializeField]
        public List<GameObject> ventValveDefinitions;
        [SerializeField]
        public Data_VentValve DataVentValve;
        [SerializeField]
        public Data_ValveParts _dataValveParts;
        public Dictionary<string, GameObject> ventValveDict = new Dictionary<string, GameObject>();
        public bool isInitialized;

        public void PopulateVentValve(Data_ValveParts data)
        {
            if (this.isInitialized)
                return;
            this.ventValveDict["RF1"] = data.RF1;
            this.ventValveDict["RF2"] = data.RF2;
            this.isInitialized = true;
        }

        public GameObject GetVentValve(string valveName)
        {
            GameObject gameObject;
            return this.ventValveDict.TryGetValue(valveName, out gameObject) ? gameObject : (GameObject)null;
        }

        public Module_VentValve GetVentValveModule(string valveName)
        {
            GameObject gameObject;
            return this.ventValveDict.TryGetValue(valveName, out gameObject) ? gameObject.GetComponent<Module_VentValve>() : (Module_VentValve)null;
        }
    }
}```
#

I think I figured it out.

 public VentValveDefinitions _ventValveDefinitions { get; private set; }
 public FuelTankDefinitions _fuelTankDefinitions { get; private set; }```

I need these to be getters not just 

public Definition _def;
#

so now they're properties

south girder
#

does it work now?

surreal loom
#

no idea yet

#

im sorting through the initialization process

#

trying to figure out which gets called first, second third etc

#
public override void OnInitialize()
{
    base.OnInitialize();
    InitializeData();
    if (PartBackingMode == PartBackingModes.Flight)
    {
        InitializeVFX();
    }
}
public void Awake()
{
    PSVentValveVFX = VentValveVFX.GetComponentInChildren<ParticleSystem>();
    PSCoolingVFX = PSCoolingVFX.GetComponentInChildren<ParticleSystem>();
    DataValveParts = new Data_ValveParts();
    DataVentValve = new Data_VentValve();

    RefreshVesselData = new RefreshVesselData();
    Animator = this.GetComponentInParent<Animator>();
    DynamicGravityCooling = GetComponentInParent<DynamicGravityForVFX>();
    DynamicGravityVent = GetComponentInParent<DynamicGravityForVFX>();
}
public override void AddDataModules()
{
    base.AddDataModules();
    if (this._dataVentValve == null)
        this._dataVentValve = new Data_VentValve();
    this.DataModules.TryAddUnique<Data_VentValve>(this._dataVentValve, out this._dataVentValve);
}
internal void InitializeData()
{```
#

im wondering if oninitialize gets called or awake gets called first

south girder
#

I don't have much experience with monobehaviours, so don't know how much I can help

#

awake is always first

#

just a sec, I'll link you something

surreal loom
#

appreciate it

south girder
south girder
#

I've read a few times that you should almost never put things in Awake(). You should use Start() for initializing things. But this is more @dreamy escarp territory, he'll know a lot more 🙂

surreal loom
#

I'm learning the hard way of how things should intialize lol

#

the order really does matter

#

I see why start is called once

#

i mean i see why start is useful. its called once for the script

#

but now it goes into im using Awake and OnDestroy. I'm destroying the module after it finishes and if it meets conditions again im making it wake up so it a nice loop. start means its called once and its running and if i destroy it or disable it i have to intentionally enable it again

south girder
#

that sounds good, but I don't know much to be sure 🙂

surreal loom
#

no worries. i appreciate the help and that link is clutch!

surreal loom
#

LETS GOOO!

@south girder

#

damn that feels good

#

(still no vfx showing but thats okay, slowly getting there)

#

The module is coming together:

south girder
#

nice!

surreal loom
#

and now having issues building the addressable hm

#

but progress is progress!

#
Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at <695d1cc93cca45069c528c15c9fdd749>:0)
System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) (at <695d1cc93cca45069c528c15c9fdd749>:0)
PartEditor.OnInspectorGUI () (at Assets/KSP2UnityTools/Editor/PartEditor.cs:76)
UnityEditor.UIElements.InspectorElement+<>c__DisplayClass59_0.<CreateIMGUIInspectorFromEditor>b__0 () (at Library/PackageCache/[email protected]/Editor/Inspector/InspectorElement.cs:638)
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr, Boolean&)
#

well time for a nap. got a lot done and theres proably a simple fix to this

#
System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at <695d1cc93cca45069c528c15c9fdd749>:0)
Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at <695d1cc93cca45069c528c15c9fdd749>:0)
System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) (at <695d1cc93cca45069c528c15c9fdd749>:0)
PartEditor.OnInspectorGUI () (at Assets/KSP2UnityTools/Editor/PartEditor.cs:76)
UnityEditor.UIElements.InspectorElement+<>c__DisplayClass59_0.<CreateIMGUIInspectorFromEditor>b__0 () (at Library/PackageCache/[email protected]/Editor/Inspector/InspectorElement.cs:638)
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr, Boolean&)

@upper summit or @gray fable not sure why im getting this in unity when i attempt to save my json. When you get a chance please take a look and let me know what you think. I'm off to bed

gray fable
#

you have a reference to SpaceWarp somewhere in your Unity project?

surreal loom
gray fable
#

And that doesn't have a reference to SpaceWarp?

#

References are recursive, so if you add a DLL that references SpaceWarp, you also have to add SpaceWarp, and all the DLLs that SpaceWarp references, and all the ones that SpaceWarp's references reference, etc

#

So if that's the case, the best thing to do would be to separate the DLL with stuff you need inside Unity out from your main plugin DLL, and just load it dynamically from your plugin at runtime

#

Or, do something like UITK for KSP 2, which has part of its source code inside a Unity project (UitkForKsp2.Controls), and the Unity project is a subfolder of the main C# project, and then you just set up your .csproj to compile the Unity code as well when you're compiling the main plugin, making it usable inside the Unity Editor, as well as inside the game

surreal loom
#

thank you @gray fable ill dig into all of that today!

surreal loom
#
 public override void AddDataModules()
 {
     FFTPlugin.Instance._logger.LogDebug("AddDataModules called...");
     base.AddDataModules();

     _dataVentValve ??= new Data_VentValve();
     DataModules.TryAddUnique(_dataVentValve, out _dataVentValve);

     _ventValveDefinitions ??= new VentValveDefinitions();
     DataModules.TryAddUnique(_ventValveDefinitions, out _ventValveDefinitions);

     _dataFuelTanks ??= new Data_FuelTanks();
     DataModules.TryAddUnique(_dataFuelTanks, out _dataFuelTanks);

     _fuelTankDefinitions ??= new FuelTankDefinitions();
     DataModules.TryAddUnique(_fuelTankDefinitions, out _fuelTankDefinitions);

     _dataValveParts ??= new Data_ValveParts();
     DataModules.TryAddUnique(_dataValveParts, out _dataValveParts);

     FFTPlugin.Instance._logger.LogDebug("Added Data Modules.");
 }```

@gray fable this is what started making unity tell me i had to have bepinex and spacewarp .dll's referenced
gray fable
#

yeah, you're referencing your plugin's logger, and you plugin is based on SpaceWarp

#

you could just switch that log for Unity's built-in Debug.Log(...)

surreal loom
#

thats an easy fix

#

i appreciate that. i was trying to avoid using bepinex.logging in the modules

#

worked. ez fix. i knew it was something simple but i was way too tired to deal with it last night lol

#

thank you munix!

gray fable
#

awesome, glad that helped!

surreal loom
#

now to learn how to make better vfx but still use the calculations in the game to impact how the vfx work. which is a lot more complicated than i thought it would be

#

particlesystem is great, but it relies heavily on the cpu which reduces performance as every physics frame its calculating things to update the particlesystem

#

its okay for a 3 second animation particle vfx. but for what im trying to do it is not optimal whatsoever

surreal loom
#

the satisfaction of organization:

surreal loom
#

@quartz dagger you were asking how the vfx was going:

quartz dagger
#

Looks nice!

surreal loom
#

To Do [0.1.4.2]:

  • 🛠 VFX Overhaul:
    • Develop a Custom Shader
    • Refinement
      • Develop strategies for further performance optimization.
  • Update OAB pictures [WIP]
  • Improve Texture quality on Hydrogen Tanks (medium) [WIP]
  • Improve performance of VFX [WIP]

Next Update [0.1.4.3]:

  • Develop Fuel Tank Selector [Coming in 0.1.4.3]
surreal loom
#

@dreamy escarp can I add

        [Header(Distortion)]
        _DistortionStrength ("Strength", Float) = 1.0
        _DistortionBlend ("Blend", Range(0, 1)) = 0.5```

into my custom shader and will it be used by the game?
surreal loom
#

also here's what it looks like in unity.

surreal loom
#

@gray fable TTR LUL

#

i didnt mean for the smoke to be all phallic shaped but it is. lol

gray fable
surreal loom
#

i think unity is telling me i need to get either more coffee or to go to bed

#

To Do [0.1.4.2]:

  • 🛠️ VFX Overhaul:
  • Develop a Custom Shader [Made but will need adjustments and Lux's wisdom]
  • Python to create spritesheet [COMPELTE]
  • Create Sprite Renderer [WIP]
  • Update OAB pictures [WIP]
  • Improve Texture quality on Hydrogen Tanks (medium) [WIP]
  • Improve performance of VFX [WIP]

Next Update [0.1.4.3]:

  • Develop Fuel Tank Selector [Coming in 0.1.4.3]
surreal loom
surreal loom
#

@dreamy escarp can you look over this shader and give me feedback on how I can improve

dreamy escarp
#

what u trynna do?

#

justa distortion shader?

surreal loom
#

give me a sec to type out what im tryhing to do with it

#

I'm going to use a 2D spritesheet to use to create the rocket vent plume smoke effect. I'll be packing textures so I can get the most out of them using the maps that the game uses.

normal
diffuse
metallic
ambient occlusion
paintmap(probably wont use that)
emission

ill bake specificed maps to add the distortion, opacity, height, and other maps into those maps to add more to the texture. ive also added a simple light calculation but im not sure if the game uses _WorldSpaceLightPos0.xyz or what

                float3 lightDir = normalize(_WorldSpaceLightPos0.xyz); // directional light
                float3 normal = normalize(tex2D(_NormalMap, i.uv).xyz * 2.0 - 1.0); 
                float diff = max(dot(normal, lightDir), 0.0);
                col.rgb *= diff;```
dreamy escarp
#

well light data wont really work

#

since ksp2 uses a somewhat custom light library

#

as for everything else, seems fine

#

shaders are pretty forgiving cuz they usually are very performant

surreal loom
#

hm

#

it seems the best way to make a good vfx is to create a custom shader. interesting about the light bit though. i can remove that.

I looked at the additive shader and it gave me an idea.

I want to use the Unity Animator component's floats and improve performance by using shader properties directly. So instead of my mod using the Module_VentValve to use Unity's Particlesystem to update the VFX and get all the values, I want to make the shader use that information. In my module it'd look something like this i think:

 Material vfxMaterial = VentValveVFX.GetComponent<Renderer>().material; 
float ASLValue = GetCurveValue(_dataVentValve.VFXASLCurve, (float)vesselData.AltitudeAsl); vfxMaterial.SetFloat("_ASL", ASLValue);```
surreal loom
#

getting closer

surreal loom
surreal loom
#

float2 distortion = tex2D(_NormalMap, i.uv).rg * 2.0 - 1.0;

This is cool @dreamy escarp I can pick the channels that its using. mind blown

surreal loom
#

most work the 4090 has seen in a bit

dreamy escarp
#

Yeah shaders have an abusive relationship with gpus

surreal loom
#

I think I may have taken the texture thing a bit too literal. I used every channel for 5 maps. But my textures look like solid colors. Any guides on setting up textures better?

Ie trying to use curvature, height, and Displacement in a normal map?

surreal loom
#

well moving from a spritesheet animation to a volumetric shader

surreal loom
surreal loom
#

512x512 volumetric slicing:

surreal loom
surreal loom
#

I'm making my own tools in unity to automate things:

surreal loom
#

Progress:

Now to figure out how to get the 3Dtextures to work.

surreal loom
#

@dreamy escarp basic volume shader. need to add more to it, but it works (i think). also using 3D textures for it

surreal loom
#

automating the slicing.

surreal loom
surreal loom
#

@dreamy escarp should I be using HDRP or is that not supported by KSP2? 🤔

dreamy escarp
#

tbf im not sure

#

i think they use the builtin

surreal loom
#

def a question i wanna ask the dev's just to find out.

also, i forgot to uh... make nodes for my texture sooo... yeah.

surreal loom
#

Today I'm making all the 3D Textures.

surreal loom
tame briar
surreal loom
surreal loom
# tame briar AssetStudio?

nope. openvdb for unity that i converted and did black magic on so i can just use vdb's to create 3D textures and materials

#

once im done, i can pull it out of the project and ram usage will go down

#

it was 5 year old plugin i found on github, and got working in unity last night

surreal loom
#

or for some reason i had 5 unity hubs running with the unity project running 3 separate times but it didnt show it like that?

surreal loom
#

much better

surreal loom
lunar peak
#

@surreal loom, how hard is it to add a new fuel type to the game? I've begun introducing magnetoplasmadynamic thrusters in SPARK (I've just got one so far), and realistically those should be using Lithium as their fuel, or more precisely LithiumEC (assuming it needs to work similarly to XenonEC). Real-world MPD thrusters can and have been designed and built to use other fuels like Argon, but I'm not sure any have been built to use Xenon - and if they were I'd expect poorer performance.

#

So, I may need to either add some fuel tanks to SPARK (which is what NFP does) or see if some other friendly modder would be willing to make some Lithium variant tanks. Or maybe it's something I can do with Patch Manager?

gray fable
#

You can just add them to #1147327464486477874

#

As for adding fuel tanks for it, yeah, Patch Manager is probably the best bet

#

Though I'm not sure if we have part copying working yet

lunar peak
#

That makes sense for the place to add it as a resource. The bigger question (for me) is how. I'll poke around in the source looking at XenonEC to see if I can figure it out.