Jump to content

Module is not found


marce

Recommended Posts

Hi!

I have the following problem: I add a Module to a Part. The module is added to the Part:


PART
{
part = trussPiece1x_4294755220
partName = Part
pos = -7.737654E-08,6.068702,-0.8850844
rot = -3.090862E-08,0.7071068,-0.7071068,-3.090862E-08
attRot = 0,0,0,1
mir = 1,1,1
istg = 0
dstg = 0
sidx = -1
sqor = -1
attm = 1
srfN = srfAttach,trussPiece3x_4294755240
EVENTS
{
}
ACTIONS
{
}
MODULE
{
name = ModuleActiveStrutFreeAttachTarget
isEnabled = True
Id = bd975dc5-056a-460c-b89f-0bc6a1ccc1b1
EVENTS
{
}
ACTIONS
{
}
}
}

But the following code returns an empty list:


FlightGlobals.ActiveVessel.Parts.Where(p => p.Modules.Contains("ModuleActiveStrutFreeAttachTarget"))
.Select(p => p.Modules["ModuleActiveStrutFreeAttachTarget"] as ModuleActiveStrutFreeAttachTarget)
.ToList();

I'm doing exactly the same (with different module name) with another module where it works without any problems. I also checked the spelling twice.

The only thing that's different: in the workign case the module is in the part's cfg file while in the not workign case I add the module at runtime using part.AddModule.

For any help I would be very grateful since this is currently a showstopper...

Link to comment
Share on other sites

might be (but I have no clue what I'm talking about) that the current API-function AddModule does not interact correctly with linq right now.

I've read something similiar somewhere completely else once..

Did you try to loop through the PartModules the standard way just to make sure?

Let me know if that worked please..

Within the next few days, I planned to implement the same thing for KSPI modules in my Impulse-Drive DLL - so your experience will be appreciated than..

Link to comment
Share on other sites

I did try to enumerate the PartList manually, yes.

My current suspicion is that AddModule works only temporarily. A scene change will only add those modules defined in the part's cfg to the PartList.

I originally didn't want to add my target module to every part because it won't be used or needed 99% of the time but only add it to those parts which really need it.

This doesn't seem to be possible, so I have no other choice as to add it to every part in the whole game with a manually created opt-out list...

This is REALLY a pitty wasting memory! If you find any solution please tell me so that I can fix this!

Link to comment
Share on other sites

Oh I see lol

So you can Add the module by code, but it does not stay persistent..

Actually I never expected it to stay..

AddModule is from my understanding a virtual thing..

So I suggest the following without having it tested..

loop through the parts, find the part that should have the mod, add it - do that in onStart or if that is not enough in FixedUpdate.

But onStart should be enough in my understanding..

I don't know your requirements to select the part - but I hope you got the point..

If you want some additional script complications, you can indeed add stuff to the VESSEL section of the persitent file - just make sure it does not get overwritten by the game itselfe on scene end - so the timing is crucial there..

But if you manage that part, the modules should be loaded on scene change as if it where in cfg at beginning..

A third option (iirc there is something like this) - did you experiment with the "IsPersistent" thingy that is around in partModule?

That might do the above part for you - but I never used it..

btw - if you are from austria, we live close and could talk german aswelll..

Link to comment
Share on other sites

I'd suggest we stay with English for the good of the greater audience (you know, there may come others with this problem), if you'd like to express something in German simply send me a PM :)

on topic:

Actually I only need to identify a single part reliably. Currently I add a module which contains a GUID. However, each part gets assigned a what seems to be unique ID (maybe Ticks?) anyway (e.g. part = DockingStrutTargeter_4294787888). If this doesn't ever change (through scene changes, reloads, docking, etc) and I can access it I won't need my module at all.

@IsPersistent: haven't seen that in a PartModule but only at Fields?

I'd like to avoid adding stuff to the vessel itself, also having decoupling/docking in mind...

Link to comment
Share on other sites

You should be using ProtoVessel and ProtoPartSnapshot.

Thanks for the hint, I googled a bit but didn't find good information what those are and escpecially how to use them corectly.

Do you know any resources describing or mods using them I can look at?

Link to comment
Share on other sites

Thanks for the hint, I googled a bit but didn't find good information what those are and especially how to use them correctly.

Do you know any resources describing or mods using them I can look at?

ProtoVessel Returns active information of all unloaded craft.

reading your situation again think your looking for current active vessel? In which case flightglobals might be throwing an exception. So I overcame this in an active flight with this.

but if its other vessels your searching for then ProtoVessel is what you want to use. Best to foreach each step to get to what you want. Since its a pretty big list.


private Vessel activeVessel
{
get
{
// We need this try-catch-block, because FlightGlobals.ActiveVessel might throw
// an exception
try
{
if (HighLogic.LoadedSceneIsFlight && FlightGlobals.ActiveVessel != null)
{
return FlightGlobals.ActiveVessel;
}
else
{
return null;
}
}
catch
{
return null;
}
}
}

Now you can refrence acitvevessel and won't get any exceptions in case the code is null at time of check. Not so important during editor or out of flight, but becomes much more of a problem in flight.

Feel free to check out Mission controller code on my github page. It has lots and lots of examples of loading Parts, and Active parts, and even finding modules. Most important parts would be. This. and this.

Many more examples spread through the code, to many to find and list though.

Edited by malkuth
Link to comment
Share on other sites

@IsPersistent: haven't seen that in a PartModule but only at Fields?

just for reference..

It's in part

Part.isPersistent

I thought it might save the added modules with it..

but never tried..

Malkuth is a better source right now..

Link to comment
Share on other sites

I have some tiny OnStart code to create an ID if none is present and to register for some controller functions when in editor, but no Awake. And I do handle editor or inflight differently, so no NullRefs (mostly :wink:), I'm adding to the correct part.

I think I have to elaborate a bit: I add the module to a part which does NOT have it in its cfg file in the editor (or inflight, both should work) using AddModule. The module is now present until I change scene (like launch from VAB). Now the module is saved in the craft file just fine but won't be present on the launchpad.

Maybe the protopart can make the module persistent, but I have to look through the MissonController code for longer to understand what that is and how it works.

Except someone can come up with exactly the code I need to use instead of AddModule for me? :wink:

Link to comment
Share on other sites

I have some tiny OnStart code to create an ID if none is present and to register for some controller functions when in editor, but no Awake. And I do handle editor or inflight differently, so no NullRefs (mostly :wink:), I'm adding to the correct part.

I think I have to elaborate a bit: I add the module to a part which does NOT have it in its cfg file in the editor (or inflight, both should work) using AddModule. The module is now present until I change scene (like launch from VAB). Now the module is saved in the craft file just fine but won't be present on the launchpad.

Maybe the protopart can make the module persistent, but I have to look through the MissonController code for longer to understand what that is and how it works.

Except someone can come up with exactly the code I need to use instead of AddModule for me? :wink:

Have you tried to replace the module name in your code to see if its actually a code problem or maybe a module problem.. Something simple like ModuleEngineFX or ModuleEngine. Because it seems EvilReaper checked you code and it worked for him.

Edited by malkuth
Link to comment
Share on other sites

No pretty sure protopart only takes a snapshot of the peristant file and whats available for craft.

Was afraid of that :(

I'm not sure what you mean about not having a Module Listed in .cfg file? Does that actually work? Oh are you using ModuleManger yea that should work.

It is added purely programmatically and is then present, but only temporarily, that's the reason why I now use a MM config to add it to the cfg of all parts ensuring that it will be present. However, that's not very performance oriented...

Link to comment
Share on other sites

Was afraid of that :(

It is added purely programmatically and is then present, but only temporarily, that's the reason why I now use a MM config to add it to the cfg of all parts ensuring that it will be present. However, that's not very performance oriented...

Hmmm, so your trying to take away a module that is already loaded on a craft? Pretty sure that any craft launched keeps whatever module it has for it lifetime, and can't be taken away, unless you Delete the module reference from the persistent file, for that ship.

One of the big reasons that part makers try hardest to keep all name references the same, to keep Player Save Game files safe from Deleting Ships that don't match any know parts or modules.

Edited by malkuth
Link to comment
Share on other sites

I see, interesting.

So, could it be possible that your check is happening before the module is added? Hence why your getting a Blank return? But if your using MM then that should not be the case. MM adds modules and load.

Like I said I would eliminate module problems and check to see if the code works with a known working module.. If it does then your looking at the wrong problem ;)

Link to comment
Share on other sites

So, could it be possible that your check is happening before the module is added? Hence why your getting a Blank return?
No I request the modules of all parts (to be on the safe side) continously again and again.

But if your using MM then that should not be the case. MM adds modules and load.
Yes, adding it to all parts with MM works, it's just inefficient.
Like I said I would eliminate module problems and check to see if the code works with a known working module.. If it does then your looking at the wrong problem ;)
The problem is the same for stock modules too, I tried.
Link to comment
Share on other sites

The module is now present until I change scene (like launch from VAB). Now the module is saved in the craft file just fine but won't be present on the launchpad.

It's persistent, but not how you think. If you added the part inflight, changing scenes is no problem. The problem you're encountering is that KSP treats "persistent" and "regular" data differently. Your module is added to the .craft file but is ignored if that file isn't loaded as a persistent save, which it isn't when moving from editor to flight. So it's deleted, KSP writes a warning about not being able to load a module for any affected parts and things proceed.

Is there a reason you're adding the PartModules in the editor as opposed to when flight begins? A description of what you're trying to do would be helpful.

Link to comment
Share on other sites

Understand!

What I'm trying to do: I'm near to the release of a mod that combines the features of DockingStruts & QuantumStruts + adds a few more. It is possible to activate an "aiming" mode and select any part of the vessel as long as it's not out of range or the angle is too big etc.

The last step was to add editor support as in: connecting targeters with targets or any part can be done in editor too instead on in flight only.

To reconnect this "free" attached strut I need a unique and unchanging reference to the selected part. So my first intention was to add a Module which contains only a GUID when the user selects the target part. The I save this ID in the targeter part and can reconnect whenever required. Since this module is volatile (as xEvilRepperx explained) I now switched over to adding the module with the GUID preemptive to all parts so that it is always there.

Of course a module containing a single field is not terrible regarding performance but I'd like to avoid it if possible.

EDIT: I made a quick video showing the two link modes. This thread relates to the second mode (attach anywhere)

Edited by marce
added video link
Link to comment
Share on other sites

intresting project - good luck..

once more I don't know if there is a better way..

but I'd try the part module approach..

I guess you have same issues like DavonTC - each engine there can be assigned to groups - he wasn't able to make those settings available in editor either..

I guess there too it lost the settings on flight..

however - complicated work arounds are allways possible..

for a "formation mode" to allow vessels to fly together, I had to write an independent manager last week, that was created as a singleton and called by each vessel's partModule

So each vessel announced it's presence and the manager remebered all settings per vessel GUID to pass along to the other vessels if needed..

I could imagine creating a strut-manager, that remembers those settings by assigning an id based on partinfo and position to the data set..

Later you could read that out and parse it with the active vessel..

I hope you got the point - it's complicated stuff to explain..

Link to comment
Share on other sites

The problem of safely identifying a specific part remains. Once I have the unique ID I can store it in the targeting module as well without the need of an additional manager.

Well, I'll continue with my current approach for the moment since more complex solutions also create more complex bugs and the gains isn't really worth the effort...

Link to comment
Share on other sites

I hesitate to suggest this since it's quite hacky and will prevent your mod from working with any other mod that happens to also use it, but one thing you could do is stuff your data into Part.customPartData and redo your editor associations on ship launch. I can't think of any other way to uniquely identify any given part from the editor to flight than either that or doing what you're doing and adding a new PartModule with a single field to all existing parts

Edit: Also I didn't try this out, but another possibility (that I haven't explored and so may not work as imagined):

  1. When the player enters the editor, add your identifying PartModule to ALL part prefabs
  2. If the player leaves the editor and it's not to launch the ship, remove the PartModule from all part prefabs again
  3. If the player leaves the editor and it's to launch the ship, leave the PartModules attached until the ship is loaded, then strip all PartModules from all part prefabs, do your logic with whatever uses them to identify parts, and then strip all unused identifier PartModules from the ship

The idea is to get around the issue of the .craft loading a PartModule that it doesn't recognize. If it's attached temporarily, you could use it to smuggle your GUID data out of the editor and into the flight vessel.

The main attraction of this method is that you wouldn't clobber any other mod functionality doing it, although it could be argued that it's even uglier than the first method

Edited by xEvilReeperx
Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...