Jump to content

KSPAddon instantiated twice


Recommended Posts

Hello, I'm making a partless plugin derived from ScenarioModule.

I want it to start at every scene "in game", as in only those that are accessible when a save file is loaded.

So I set the KSPAddon attribute like this:


[KSPAddon(KSPAddon.Startup.EveryScene, false)]
public class CrewFiles : ScenarioModule
{
...
}

and then filter out the scenes I don't want by running my logic only when HighLogic says I'm in a scene I'm ok with.

However, looking at the log my addon gets instantiated TWICE for each scene. If I set KSPAddon.Startup.SpaceCentre, then it's fine and only one instance is created.

What am I doing wrong? Oo

Link to comment
Share on other sites

The doubling thing might be caused by having two copies of the .dll somewhere, though that might not be the case if it only happens some of the time.

The best option is to ditch the standard KSPAddon and use this one: http://forum.kerbalspaceprogram.com/threads/79889-Expanded-KSPAddon-modes?p=1157014&viewfull=1#post1157014

It lets you specify multiple scenes for your addon to start in. I've used it in several mods and it works great.

Link to comment
Share on other sites

Well, no, I'm sure there is only one dll. Also, I only get 2 instances when I set it to startup in every scene, but only 1 when I startup in the KSC.

Anyway, I'll take your suggestion and use the improved version :)

Thank you!

Link to comment
Share on other sites

You've got a bit of a mistake in there. ScenarioModules are handled differently. The game's persistence file contains a list of them and which scenes to load them in and the game uses that information to load them, rather than the KSPAddon attribute.

What you need is a special KSPAddon that checks to see if your ScenarioModule was added to the game or not. I seem to recall a cleaner method of going about this but I couldn't find it, so in the meantime I'll give you my version:

//note the lack of any attributes on this one
public class YourScenarioModule : ScenarioModule { }

[KSPAddon(KSPAddon.Startup.SpaceCentre, false)]
public class ScenarioCreator : MonoBehaviour
{
public void Start()
{
bool scenarioExists = !HighLogic.CurrentGame.scenarios.All(scenario =>
scenario.moduleName != typeof(YourScenarioModule).Name
);


if (!scenarioExists)
{
try
{
Debug.Log("Adding YourScenarioModule to game '" + HighLogic.CurrentGame.Title + "'");
HighLogic.CurrentGame.AddProtoScenarioModule(typeof(YourScenarioModule), new GameScenes[1] { GameScenes.FLIGHT });
// the game will add this scenario to the appropriate persistent file on save from now on
}
catch (ArgumentException ae)
{
Debug.LogException(ae);
}
catch
{
Debug.Log("Unknown failure while adding scenario.");
}
}
Destroy(this);
}
}

Modify the GameScenes array passed into AddProtoScenarioModule to include any scenes in which your ScenarioModule should be loaded. Once you've run this code once, look into the persistence file (or a quicksave) and confirm that a section that looks like this is in there:

SCENARIO
{
name = YourScenarioModule
scene = 7
}

Link to comment
Share on other sites

Uh, ok... I'm not quite sure how this kind of things are handled, sorry :)

Basically, I just want to have my plugin to start execution when the game is loaded and stop when the player exits a save and goes back to the main menu.

With your solution my scenario module will be re-instantiated at every scene, is that correct?

Link to comment
Share on other sites

Uh, ok... I'm not quite sure how this kind of things are handled, sorry :)

Basically, I just want to have my plugin to start execution when the game is loaded and stop when the player exits a save and goes back to the main menu.

With your solution my scenario module will be re-instantiated at every scene, is that correct?

The ScenarioModule will only be loaded in the GameScenes you specified during the initial setup (the AddProtoScenarioModule step), this is when it runs the OnLoad/OnSave methods that allow you to store data in the persistent file. You might also have to delete the existing ScenarioModule from your persistent.sfs file while you're still developing and making changes. If the ScenarioModule already exists you might not be able to change which GameScenes it will start in.

The second class, the one you're instantiating the ScenarioModule from, will start whenever you want it to using KSPAddon, or KSPAddonImproved.

The more common way of using ScenarioModules, at least that I've seen (SCANsat here, Kethane here), is to put all of the instantiating code inside the ScenarioModule, and run an instance of it from your secondary class. Then you can do stuff with whatever you stored in the ScenarioModule with your secondary class.

Link to comment
Share on other sites

So if I'm not mistaken, this (from scansat) does basically the same that you told me, except it's only in one class.

It tries to get the controller from the loaded modules, and creates one if it can't find it.


[B]public[/B] [B]static[/B] SCANcontroller controller {
[B]get[/B] {
Game g = HighLogic.CurrentGame;
[B]if[/B](g == [B]null[/B]) [B]return[/B] [B]null[/B];
[B]foreach[/B](ProtoScenarioModule mod [B]in[/B] g.scenarios) {
[B]if[/B](mod.moduleName == [B]typeof[/B](SCANcontroller).Name) {
[B]return[/B] (SCANcontroller)mod.moduleRef;
}
}
[B]return[/B] (SCANcontroller)g.AddProtoScenarioModule([B]typeof[/B](SCANcontroller), GameScenes.FLIGHT).moduleRef;
}
[B]private[/B] [B]set[/B] { }
}

Link to comment
Share on other sites

The doubling thing might be caused by having two copies of the .dll somewhere, though that might not be the case if it only happens some of the time.

The best option is to ditch the standard KSPAddon and use this one: http://forum.kerbalspaceprogram.com/threads/79889-Expanded-KSPAddon-modes?p=1157014&viewfull=1#post1157014

It lets you specify multiple scenes for your addon to start in. I've used it in several mods and it works great.

Ok, I am using KSPAddonImproved: it does precisely what I need and it's super-easy to use :)

I just tested it and I'm super happy with it :D

Link to comment
Share on other sites

So if I'm not mistaken, this (from scansat) does basically the same that you told me, except it's only in one class.

It tries to get the controller from the loaded modules, and creates one if it can't find it.

By itself yes, it's all in one class. But data from the ScenarioModule is used by other classes by calling SCANcontroller.controller.something.

Ok, I am using KSPAddonImproved: it does precisely what I need and it's super-easy to use :)

I just tested it and I'm super happy with it :D

If you don't need to store stuff in the persistent file then you should be fine with that. There are obviously other ways to store info, it's just that ScenarioModules provide a simple way of globally storing data for the entire save file.

Link to comment
Share on other sites

If you don't need to store stuff in the persistent file then you should be fine with that. There are obviously other ways to store info, it's just that ScenarioModules provide a simple way of globally storing data for the entire save file.

Absolutely. Actually I don't need any persistence for the module itself: it maintains a copy of the hired and applicant kerbals in a separate cfg file so that you can have a persistence file for each kerbal :D

Ill release it soon, probably tomorrow: I want to write a short documentation before I upload it, but it's midnight here so I'm going to sleep before :)

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...