#Fancy Fuel Tanks DEVBLOG
1 messages · Page 5 of 1
In the shot above you added another cylindrical part that's not part of this tank
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
Technically, a toroid is a doughnut like shape. I'm assuming there's a toroidal tank inside some sort of faring here.
definitely would be
That would be structurally stonger than just making a smushed sphere
because when you look into how they store the liquid hydrogen and edvverything that goes into a NTP its pretty wild
There might be plumbing or cryogenics or whatnot in the spaces not used up by the toroid
also adding a 45 degree angle part and structural parts to the mod later on
but thats the main inspiration of the design
I wonder why they have those tanks canted at an angle?
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
This is what ive been using as reference points
I think it does make it look better and not so bland
Nice! I like it this way.
adding them on the inside as well
that's it. that finishes that, might need to tweak metallic levels
I love it! That looks freaking awesome!
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
few more touchups and the hydrogen tanks are good to go
@dreamy escarp how would I set it up to switch between the two texture sets? 🤔
@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.
-Update OAB pictures
-Clean up textures
-Add descriptions to new tanks
-Release 0.1.4
-Develop Fuel Tank Selector
-Get VFX fully functional```
Welcome! I'm cvusmo (cosmo) and this is the third devblog for mods I'm developing for KSP2! I really enjoy KSP (both 1 and 2). The sequel has a lot of potential and I'm hoping to be part of helping make KSP 2 awesome. I wasn't able to do much during KSP 1's lifespan as I was in the military at the time.
Now I'm able to do what I always wanted ...
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
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.
I did learn how to toggle things 
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
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.
thats what it seems like. dont know what a .uss or .xmls thing is but overall it is nice to have a visual aid when designing it
It's extremely easy to get started with it for web designers, it's basically dumbed down HTML + CSS
But I guess it might be a bit much for someone who doesn't have experience with that
interesting. it looks fairly simple tbh but for me with zero experience im completely unfamiliar with it which is fine, i want to learn new things
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
what i meant by changing textures was the B9 PArt Switch way (variants) nto actually toggling the game objects, but that works too
what would be the best for performance:
A. Selection is between two different model variants
B. Selection is between two different textures
?
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:
- dynamic vent vfx (combine both modules to one module)
- 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
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
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
icons for 0.1.4
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
fyi ksp2 icons are rendered using an orthographic camera not perspective camera
good to know!
@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"
hmm, do you have the space warp dll in your project?
no. i can add it but its never been in the project
this is what the editoor asemdef looks like
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
just wanted to double check that it was on me and nothing in the unity tools. thank you!
Found why. How do I update the SpaceWarp 1.1.1 in my visual studio project?
@upper summit
use the nuget window, it should have an option fto select another version
I probably need to switch to spacewarp.template then?
No
I was meaning, you need to add nuget.spacewarp.org to your sources
oh
https://nuget.spacewarp.org/api/v3will be the precise link
but your sources should be under the nuget options
No
Press the plus at the top
Alright change the source to this actually
https://nuget.spacewarp.org/v3/index.json
Then press update
i did that
Now you should be able to grab a newer version
no it does this when i hit update:
It resets the field? That doesn't make any sense
thats what i have in my packages right now
Re add space warp
I am utterly confused
@gray fable you are more knowledgeable than me on this stuff ... could you help here?
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>
wilco
I don't either normally ... I've always used rider, I thought you knew a bit more apologies
When I am trying to install any nuget package in VS2017 for asp.net core. it is constantly showing "Package restore failed. Rolling back package changes" for each package.
StackOverflow says to just clear the cache
is your target framework netstandard2.0?
yes framework is netstandard2.0
this may be a problem. it cant find mypluginfo.cs
That should get automatically created by the package BepInEx.PluginInfoProps
well it went from like 15 errors to now 550 errors
Hm, yeah, because now no packages are cached and the NuGet restore is still failing
So no references are working
But why
what are common reasons why?
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
true
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
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
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
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
where is Mono.TextTemplating even coming from
what i did:
- made sure i had netstandard2.0
- uninstalled spacewarp 1.1.1
reinstalled spacewarp 1.1.1
dotnet
SpaceWarp 1.1 used net472, that's why you're seeing that message, it's normal
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.
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" />
ah
thats cool. k doing that now
holy crap that was ez
thank you munix and cheese
yeah, my advice is, don't use the UI, just change it directly in the XML in your .csproj file
i didnt realize i needed to make sure my visual studio updates when new versions of spacewarp drop
Visual Studio is dumb and messes stuff up
Can you show me the window with the package sources?
I see the issue
You removed the original nuget.org source (or rather replaced it with nuget.spacewarp.org)
So it can't find any NuGet packages outside of the few that are on nuget.spacewarp.org
so like that instead?
Basically nothing in there needs to ever be touched
So it didn't fix it?
The last error is easily fixed, you just need to reference UnityEngine.Modules 2020.3.33.1
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
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

i hate being dyslexic
fixed
thank you for the help munix. simple things but i did learn a lot so thats cool
glad it works now!
`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
@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
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?
I was wanting to get both to work, and set two floats. 1 for the entire vessel fuel percentage and 1 for the stage because you could have multiple fuel tanks that are in different stages ie hydrogen tanks
first i was attempign to get the fuelpercentage functional then i was going to copy paste and add the stagefuelpercentage
you can have multiple tanks on a single stage too, no?
this is true. i figured stagefuelpercentage counted all the tanks in the stage
at lesat thats how i would make it function, just not sure how it actually functions
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.
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);```
`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. `
Adding more dynamic VFX to Fancy Fuel Tanks mod.
`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. `
a bit of python. got distracted and decided to look into data lol
`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. `
How do you change background terminal
give me one sec and ill show you
@sick dagger
any questions just ping me!
Ok
Lol the terminal is so confusing with its keys and such but they have an entire modern UI for settings
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
Yeah
getting drivers setup for my 4090, and everything is a headache. once its working, it runs amazing
I like your mats backgrounds
but any update etc is a headache
thanks its just a picture of mars (well render of mars)
Nvidia drivers for Linux in general are a pain in the ass.
yup. for a while i had garuda as my daily, about a year? then i just got fed up with updates and such so went to back to windows for daily
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
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
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
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
Yeah primarily cause it doesn’t eat the shit out of your ram. I think windows still eats ram but it’s better about ceilings and dishing it out.
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)
Yeah. I also hate the Linux community. They just shit on everybody that doesn’t like Linux. Also I saw a person say. Dude it’s not hard to install Linux if you don’t like the Linux distros make your own like bro💀
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.
make your own distro LUL
yeah cause thats so easy lol
I hade opera for a while but it just got tiring about the opera ads then I saw the twitter account. Also chrome does hog ram but they were the first to not combine all the tabs so if one tab doesn’t work the rest work fine
I ... want to use arch again but its not really tenable for me atm
i love arch i just am too lazy to use it as a daily. i have it for fun though. i play POE 2 on garuda. runs great
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
It’s kinda fun nerding the Shit out
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
I learn how to not do things by doing those not good things and then debugging it for 3 days.
me: sees how well micro engineer functions
inner me: don't rewrite everything
me: rewrites everything
@south girder
happy to be of influence! ❤️
So it looks like you’re on the hook now for some sort of antiparticle engine or other such ultra tech… best get cranking!
It's so well structured. Really enjoy how you and scholsrat make your mods with programming. The structure is awesome
Ah shiz
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
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!
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:
- Always look cool.
- Never let your coffee cup go empty.
Idk why but this mod makes my game go extremely laggy
which is sad bcz the parts are very nice :(
It had to do with how the vfx are being rendered. 0.1.4.1 is going to fix the performance issues. 0.1.4.0 is going to create a lot of lag with adding lots of parts. 0.1.4.1 I'm working on now and will come out Friday or next Friday
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.
thats why ive rewritten everything so that it performs better and the modules aren't running every frame.
## 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.
It is now ready for testing and debugging!
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.
what does the module engine look like
hm
not sure how it works tbh. there's a lot of info with engines lol
pretty sure you need a flameout vfx manager
and reference it in the module
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
@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.
Everything appears to be ok in these 2 classes you sent. Are you saying that the methods where logging takes place are executed, but the log itself isn't created? Did you set up a debugging environment like we talked about earlier?
I'm not sure if the logging is actually executed. Which is weird because the plugin should be executing because the other class is logging.
I'll have to look back at our previous conversation to see if I setup a debugging environment correctly. Most likely I didnt.
thats the logoutput so you can see what was logged
lines up super clean! @fierce sundial
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
Nice
also decided to use assetstudio to look at engine settings so i understand how to use it in unity.
I'm gonna show you what you're missing out by not setting the debugging environment yet 😉
You follow the guide from here https://gist.github.com/gotmachine/d973adcb9ae413386291170fa346d043 (and adjust slightly cause we're using KSP2 and the guide is written for KSP1, but it's almost the same), and afterwards you'll be able to do something like this:
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!
k first i get this engine module set up, then before testing i do what you just showed me
thank you!
no problem, happy to help!
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
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
so much faster than how i was debugging lol. i was saving, hoping debug log would log errors, remaking my addresable in unity, launching game, see what broke, and repeat
oh yeah, I was blown away also when I saw that the game can be debugged like this 😄
this is the editor ill need?
wait i already have the editor
lol
so im basically making my own dev build of the game
hdr-display-enabled=0
gc-max-time-slice=3
player-connection-debug=1
is that correct?
yep
You can't yet. It's from HUMANS I'm currently working on: https://discord.com/channels/1078696971088433153/1138780280719683766
ohhh
okay i thought i did something wrong loll
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
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?
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.
good to know
that I don't know. I'm also learning stuff as I go along
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
part modules is something I'd like to learn more as time goes on
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
oh definitely, it's a very steep learning curve to learn modding
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
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.
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
danggg
beast pc
that ram tho, 64gb ddr5 at 5200!
Some say it should be 6000 mhz. But it was recommended by Intel to be 5200
It's the Kraken slayer. Finally got my dream setup and I love it
ive got a machine with a 3060 12gb, ryzen 3 3100 (gonna upgrade soon) and 32 gb of ddr4 @3200mhz
yeah its pretty good
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
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
i use the spacewarp console as it gives me live updates which is super nice. but yeah, now i see where logs are going. i was only looking at ksp2.log and output.log
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
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
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
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
exactly 👍
basically ive not initialized things properly so im combing through it all and making sure everything is initialized properly
that's the usual culprit, yeah 🙂
good to know lol
im all about brute force and ignorance. i learn from hard lessons and by repitition.
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
thats pretty rad!
@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"
In my head when swimming/running/showering, yes, but it's a good idea to write it down, sure!
//|=====================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
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.
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
@south girder how im going to be doing my patch notes/readme.md's from now on
That's great!
I've been updating it daily as I make changes. I never realized how much I get done in a patch lol
@upper summit How did I break it?
@south girder
How the fuck
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.
wonder how that will work with notepad
what do you mean?
easy to read notes on notepad
a friend of mine just told me about obsidian. This is how to take notes. holy crap its cool
10/10 recommend this thing;
nice
now the module isnt being seen by unity. hm
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)```
Hi
welcome, how are you?
Good hbu?
not too shabby. just deep into programming right now
lol just found one of your vids on shorts
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
Inflatable habitat modules that are compact and easy to use
its on my to-do list!
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
ive gotta get FFT performance better and VFX better looking so thats what im focused on developing right now
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
dope
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
i thought i saw a wip science mod
earlier
but beside that
Didnt see ur message lol anyways that would be cool
my longterm mod that im developing is KERN, it adds particle physics to ksp 2
short term is FFT, and the next mod i havent even considered yet lol. i made toggle notifications and that was a fun project
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...
its just when i use clyde
clyde never does the thing i want him to do
who is clyde btw?
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
lol
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?
pretty far with the modelling and animations
ok
obvious no work has been done with science since it's not in the game
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
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
ooh that sounds cool
Do you think that these are possible to code a mod for in ksp2? (only some)
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
idk how to code so thats why i put mine in #1079080073409347604
like ive never coded lol
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
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
itll come, it just takes time
its taken me 3 days to rewrite all of FFT's programming and its still not functional yet
wow i dont unterstand that but it looks complicated
@south girder seeing red a lot. LUL
Also I wrote the code as DI and it didnt work so I reverted back to Singleton.
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 ```
well tomorrow i can sort this out
is your code up to date on the git repo?
lemme double check
thats the branch im working on
i have a stable dev branch so i made two others to test on
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
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
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 🙂
Nope. Definitely need sleep if I'm making mistakes like that haga
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 🙂
@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;
}```
ok, try it
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
yeah, it's hard to see stack overflow in c# 🙂
can I see the whole FFTPlugin.cs file?
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
conditionsManager is a singleton, so this is wrong probably _conditionsManager = new ConditionsManager(_messageManager, _logger);
startmodule as well
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
you're subscribing to messages in MessageManager constructor, so this is redundant: _messageManager.SubscribeToMessages();
I thought I had to call it in oninitialized so it actually ran?
you already have it in the constructor: https://github.com/cvusmo/FFT/blob/singletonBuild/FFTProject/Managers/MessageManager.cs#L56
constructors are called when an instance is instantiated
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
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.
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
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
so i need to be sure that I call things at the right time
so if you know some stuff is ready later, then initialize when that later parts gets done
literally just learned this the hard way lol
for the messages, they're safe to subscribe on OnInitialized cause they're already done then
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"
[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
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
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
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
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.");
}```
it's instantiated in a way you're writing the code 🙂
but yes, OnPostInitialized is called after OnInitialized
when exactly is onpostinitialized called? after everything has ran its oninitialized?
yes
ah thats cool
I think that all mods go through OnInitialized, then all go through OnPostInitialized
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?
... if you're sure they'll be loaded when OnPostInitialized is called, then yes
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
everything you're doing is being done linearly, nothing is async. So whatever you write before the other, it will be executed first
is that a good way to do it?
when you write _moduleController = ModuleController.Instance; ModileController gets instantiated and everything you wrote in the constructor of ModuleController will be executed
yes it is
okay
thast good lol
now ive gotta check my constructors
and make sure what theyre calling is appropriate otherwise instanitate them later
yes
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"
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
yeah this is making a lot more sense now
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));
well yes, if you're initializing something that you're waiting for from the game and you don't know when the game will have it ready. But if you're initializing your own classes you should always know when you will have it ready
true. i know majority of my classes don't need to be initialized until after the game has loaded
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
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
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
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
click here
I've done that, do I set the breakpoint to keep running the code?
well how do I select it with the IO thing?
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 😄
do i need it to be running with the debugger to select it?
'
this lets me red dot
so, 1. place a breakpoint, 2. start the game, 3. Immediately when the game starts attach unity debugger with Debug -> Attach Unity Debugger
quick demonstration
nobody cares about my idea 😦
its a great idea. its just going to take time for myself or someone else to start working on it
ok
@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
lol yeah, I missed that 🙂
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.
@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
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
i used the wrong dll
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
it'll work out, you're doing excellent progress!
[Info : FFTPlugin] Subscribing to messages....
[Debug :FFT.MessageManager] Subscribing To Messages...
[Debug :FFT.MessageManager] Subscribed to: GameStateEnteredMessage, GameStateLeftMessage, VesselSituationChangedMessage
[Debug : FFTPlugin] Initialized FFTPlugin.```
[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 ```
[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
bro you have about the same messages as the lux devlog
lol
its a lot of debugging
im having stack overflows and some other issues with the code, but slowly fixing the bugs
[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.```
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'.
]```
LETS FREAKING GO!
lol, it's an emotional rollercoaster reading your thread 😄
excelent!
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??
Autos is just one of the debugging windows, like Locals and Watch.
Yes, that's very useful!
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
in the Watch window you can type in anything you want to se current values
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!
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
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?
yep
press F11 to step into InitializeData()
F11 steps into the method, F10 skips over it
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
SUCCESS! (maybe)
well now ive just gotta debug and make the animation work and make sure conditions are being set.
-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]```
[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```
@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
does it work now?
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
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
appreciate it
this might help: https://docs.unity3d.com/Manual/ExecutionOrder.html
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 🙂
interesting
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
that sounds good, but I don't know much to be sure 🙂
no worries. i appreciate the help and that link is clutch!
LETS GOOO!
@south girder
damn that feels good
(still no vfx showing but thats okay, slowly getting there)
The module is coming together:
nice!
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
you have a reference to SpaceWarp somewhere in your Unity project?
I shouldn't have one. I've only got a reference to my .dll
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
thank you @gray fable ill dig into all of that today!
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
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(...)
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!
awesome, glad that helped!
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
the satisfaction of organization:
@quartz dagger you were asking how the vfx was going:
Looks nice!
cries internally ha.. im so happy it looks nice. goes back to rendering
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]
@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?
@gray fable TTR LUL
i didnt mean for the smoke to be all phallic shaped but it is. lol

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]
@dreamy escarp can you look over this shader and give me feedback on how I can improve
here's the updated one.
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;```
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
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);```
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
most work the 4090 has seen in a bit
Yeah shaders have an abusive relationship with gpus
I accidently made a smoke thunder cloud. It's like a strobe almost 🤣
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?
well moving from a spritesheet animation to a volumetric shader
512x512 volumetric slicing:
Progress:
Now to figure out how to get the 3Dtextures to work.
@dreamy escarp basic volume shader. need to add more to it, but it works (i think). also using 3D textures for it
automating the slicing.
@dreamy escarp should I be using HDRP or is that not supported by KSP2? 🤔
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.
Today I'm making all the 3D Textures.
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
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?
much better
@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?
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
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.
