Fractal Softworks Forum

Please login or register.

Login with username, password and session length
Advanced search  

News:

Starsector 0.97a is out! (02/02/24); New blog post: Simulator Enhancements (03/13/24)

Pages: [1] 2

Author Topic: Custom Trail Script (IMPORTANT INFO UPDATE)  (Read 7339 times)

Nicke535

  • Commander
  • ***
  • Posts: 240
  • Degenerate Core
    • View Profile
Custom Trail Script (IMPORTANT INFO UPDATE)
« on: June 23, 2018, 09:26:52 AM »

The Custom Trail Script is no longer available, in preparation for 0.9 re-release. All the Custom Trail functionalities will be baked into MagicLib; the "loose" script is as of Starsector 0.9 declared deprecated. Up until the release of Starsector 0.9, the script is still available to use (but not available from this thread as I want to reduce the spreading of the loose script in the 0.9 modding scene as much as possible).

There are multiple reasons for migrating the script in this manner, but here are the three primary ones:
  • Performance improvements for the end-user
  • I can now add new content to the script more often than "each major Starsector update"
  • I can now bug-fix the script, should need arise, without forcing other modders to re-write their implementations

Anyone who wants to spawn these custom trails will have to use MagicLib from this point onward. I apologize for the inconvenience this may cause, but am convinced that it will overall improve this script as it can now receive ongoing support and improvement.
« Last Edit: November 16, 2018, 07:17:33 AM by Nicke535 »
Logged

Nicke535

  • Commander
  • ***
  • Posts: 240
  • Degenerate Core
    • View Profile
Re: Custom Trail Script (Nicke's Toybox)
« Reply #1 on: June 23, 2018, 09:39:32 AM »

--REMOVED BY AUTHOR--
« Last Edit: November 16, 2018, 07:16:25 AM by Nicke535 »
Logged

Originem

  • Purple Principle
  • Captain
  • ****
  • Posts: 430
  • Dancing like a boss.
    • View Profile
Re: Custom Trail Script (Nicke's Toybox)
« Reply #2 on: June 23, 2018, 09:45:15 AM »

 ;D ;D ;D
Logged
My mods


Alex

  • Administrator
  • Admiral
  • *****
  • Posts: 23947
    • View Profile
Re: Custom Trail Script (Nicke's Toybox)
« Reply #3 on: June 23, 2018, 10:00:28 AM »

Very cool! This looks great.
Logged

MShadowy

  • Admiral
  • *****
  • Posts: 911
    • View Profile
Re: Custom Trail Script (Nicke's Toybox)
« Reply #4 on: June 23, 2018, 10:48:06 AM »

Definitely gonna be making use of this, thanks for the script! =)
Logged

PyroFuzz

  • Commander
  • ***
  • Posts: 110
    • View Profile
Re: Custom Trail Script (Nicke's Toybox)
« Reply #5 on: June 23, 2018, 10:58:35 AM »

Oh man! That looks nice! Initiate rainbow destroyer weaponry.
Logged
Hello!

Cycerin

  • Admiral
  • *****
  • Posts: 1665
  • beyond the infinite void
    • View Profile
Re: Custom Trail Script (Nicke's Toybox)
« Reply #6 on: June 23, 2018, 01:40:04 PM »

Really cool and exciting. Going to be playing around with it for sure. Great work!
Logged

Nicke535

  • Commander
  • ***
  • Posts: 240
  • Degenerate Core
    • View Profile
Re: Custom Trail Script (Nicke's Toybox)
« Reply #8 on: June 24, 2018, 03:59:24 AM »

Thanks for all the positive feedback, it means a lot!

Discussed some things with some other modders for a while, and determined that an example usage script would be in order. So here it is: this one works out-of-the-box if you simply
   A: add it to settings.json
   B: call AutoTrackNewTrail on each projectile you spawn which should have a trail (do this only once per projectile, the script handles the rest)
It also comes with an option to auto-cut trails if the projectile travels too far in a single frame, which can be useful in some cases.

This one is free to modify, BTW: it won't cause any issues at all, and is intended as an example even if it works by itself.

--REMOVED BY AUTHOR: SEE FIRST POST FOR INFO--
« Last Edit: November 16, 2018, 07:16:54 AM by Nicke535 »
Logged

Alex

  • Administrator
  • Admiral
  • *****
  • Posts: 23947
    • View Profile
Re: Custom Trail Script (Nicke's Toybox)
« Reply #9 on: June 24, 2018, 09:29:43 AM »

Maybe missing something obvious, but: why "private static" instead of just "private" plus putting the plugin instance into engine.getCustomData(), from init()? Any time I see "static" in plugin code it makes my memory leak alarms go off - it's not impossible to do it safely, but it's always possible - and pretty easy - to miss something.

E.G. in this case projectiles, ships, etc will stick around after you exit out of combat. I forget if ShipAPI has a reference to a FleetMemberAPI, but if it did (or if it started to at some point, perhaps indirectly), then exiting out of combat and then loading a new game could lead to the old game still remaining in memory.

This wouldn't be the worst sort of leak since it's a maximum of one copy of the engine leaking (since you clear the maps in init()), but it still potentially doubles memory use, and if just "private" would also do the job...
« Last Edit: June 24, 2018, 09:31:23 AM by Alex »
Logged

Nicke535

  • Commander
  • ***
  • Posts: 240
  • Degenerate Core
    • View Profile
Re: Custom Trail Script (Nicke's Toybox)
« Reply #10 on: June 24, 2018, 11:01:25 AM »

-snip- but: why "private static" instead of just "private" -snip-
Essentially, because it's easier to access from outside the script: since the functions have to be static to be accessed easily (calling NicToyCustomTrailPlugin.function instead of calling Global.getCombatEngine.getPlugins and going from there) the variables those functions access must be static, as well. The non-static plugin itself doesn't store information, it only uses it: the static maps keeps the information with the help of an ID as key, which is just a Float (one map, however, stores with CombatEntityAPI as key).

Your point on game engine, however... I'm sort of wondering here: if I leave a Map with a CombatEntityAPI as a key, would that thus by extension save the entire combat data, even when the engine that had the entity in question stops being instantiated? If this is the case, I've made an oversight I did not expect: I thought once the combat engine was killed off, any entities inside it would cease to exist and my references to those entities would now return Null, since I've only referenced their data as keys.

I must honestly say I don't know if this causes issues with memory: I have not done detailed memory mapping, especially not in the campaign. I simply know a bit too little about how the game handles long-term memory storage and how it "cleans up" after killing off the combat engine.


EDIT: I somehow managed to miss your comment on storing it in engine.getCustomData()… that solution is significantly safer, so I'll try to move everything over to that before people start using this plugin to too big a degree. It would as far as I see not cause any issues, and would be just as easy for the end-user.
« Last Edit: June 24, 2018, 11:16:40 AM by Nicke535 »
Logged

Nicke535

  • Commander
  • ***
  • Posts: 240
  • Degenerate Core
    • View Profile
Re: Custom Trail Script (Nicke's Toybox)
« Reply #11 on: June 24, 2018, 11:41:24 AM »

IMPORTANT:

While I am not 100% sure that the previous script had severe leaking issues, they had some potential leaks, and if Alex prediction is correct could have massive memory leaks. Thus, the Plugin portion of this script has been updated: anyone who has downloaded the old version need to download this new version to replace it.

I know I said I wouldn't make changes, but this was too big to not be fixed and I would prefer to fix it as fast as possible, so that the old script doesn't have time to spread too far. I hope you all understand. The actual usage of the functions remain unchanged: there are no differences for the end user other than potentially stopping memory leaks.

Alex

  • Administrator
  • Admiral
  • *****
  • Posts: 23947
    • View Profile
Re: Custom Trail Script (Nicke's Toybox)
« Reply #12 on: June 24, 2018, 12:18:14 PM »

Essentially, because it's easier to access from outside the script: since the functions have to be static to be accessed easily (calling NicToyCustomTrailPlugin.function instead of calling Global.getCombatEngine.getPlugins and going from there) the variables those functions access must be static, as well. The non-static plugin itself doesn't store information, it only uses it: the static maps keeps the information with the help of an ID as key, which is just a Float (one map, however, stores with CombatEntityAPI as key).

...

EDIT: I somehow managed to miss your comment on storing it in engine.getCustomData()… that solution is significantly safer, so I'll try to move everything over to that before people start using this plugin to too big a degree. It would as far as I see not cause any issues, and would be just as easy for the end-user.

Right, yeah. Accessing customData every time is kind of a pain, so what I generally do is have a static method, sort of like so:

class NicToyTrailProjectileTrackerPlugin {
...

public static final String KEY = "NicToyTrailProjectileTrackerPlugin_key";
public static NicToyTrailProjectileTrackerPlugin get() {
   return Global.getCombatEngine().getCustomData().get(KEY);
}

...
}

And then have the init() method put the plugin into the customData. Then when you're using it, it's just

NicToyTrailProjectileTrackerPlugin.get().SPRITE_CATEGORIES

Which isn't really that much more awkward to write.


Your point on game engine, however... I'm sort of wondering here: if I leave a Map with a CombatEntityAPI as a key, would that thus by extension save the entire combat data, even when the engine that had the entity in question stops being instantiated? If this is the case, I've made an oversight I did not expect: I thought once the combat engine was killed off, any entities inside it would cease to exist and my references to those entities would now return Null, since I've only referenced their data as keys.

I must honestly say I don't know if this causes issues with memory: I have not done detailed memory mapping, especially not in the campaign. I simply know a bit too little about how the game handles long-term memory storage and how it "cleans up" after killing off the combat engine.

All objects in java are handled through references. If you have a reference to something, it will not be garbage collected (unless it's from somewhere that could itself be garbage collected due to not having any outside references pointing to it). So for example if you have a reference to a CombatEntityAPI (as a key or value in a map, or whatever), that will prevent that entity from being freed up, because you could access it through that reference. It would never automatically become null, that can't happen.

Anything that entity references, in turn, would not be garbage collected either. If somewhere along the line the entity or something the entity references points to the combat engine itself, then the engine wouldn't be collected either.

Or if it was pointing to the campaign engine (say, a ShipAPI has a FleetMemberAPI data member, which has a FleetDataAPI data member, which has a CampaignFleetAPI data member, which has a containingLocation data member, which is a StarSystemAPI, which in turn has its hyperspace anchor, which in turn points to hyperspace, which in turn has every single star system, then none of that stuff can get garbage collected all because of the static map holding on to a ShipAPI or a DamagingProjectileAPI or whatever.

So, what gets pointed to depends on the implementation of the combat entity (or whatever you're holding on to), and could change without warning. It's best to just assume that holding on to any combat entity or anything similar will result in the entire combat and campaign engine not being collected, because it would be the case for some of these objects, and because it could become the case due to otherwise invisible implementation changes I might make. But if you have these references in a non-static data member in the plugin, you're safe, since that reference is from inside the combat engine, and will not prevent it from getting garbage-collected once it no longer has outside references pointing to it.

I hope that makes sense! Let me know if I can clarify anything here.
Logged

Nicke535

  • Commander
  • ***
  • Posts: 240
  • Degenerate Core
    • View Profile
Re: Custom Trail Script (Nicke's Toybox)
« Reply #13 on: June 24, 2018, 12:27:33 PM »

-large amount of detailed feedback, see previous post-
Yeah, that clarified quite a lot of things: these things are just the kind of stuff you miss when self-teaching a programming language, even more so when relating that knowledge to someone else's code.

The fix I now implemented simply made it find the plugin itself at the beginning of any static function: sure, costed me 8 rows of code or something, but I found it the simplest solution. It also fixed another issue I had not even considered: what would happen if this plugin was called without an CombatEntityAPI existing? It would store a lot of data needlessly. Now, it only actually adds stuff to the plugin in question, so if no plugin exists when the function is called, it simply returns null and continues on its merry way.

Thanks again for the feedback and attention: it means a lot and is very helpful.


...oh, and by the way: I'm working on porting this script to work on the campaign layer, as well. I'll keep you people updated once I start making any significant progress.

EDIT: I have now also adjusted the example script provided, to fix the same issue as outlined in the posts above.
« Last Edit: June 24, 2018, 01:23:08 PM by Nicke535 »
Logged

Alex

  • Administrator
  • Admiral
  • *****
  • Posts: 23947
    • View Profile
Re: Custom Trail Script (Nicke's Toybox)
« Reply #14 on: June 24, 2018, 12:35:57 PM »

Cool, glad that made sense and helped! And, yeah, totally hear you on this being an easy thing to miss. It's pretty behind-the-scenes and there's not much occasion to run into it over the course of just doing normal things.
Logged
Pages: [1] 2