Fractal Softworks Forum

Please login or register.

Login with username, password and session length

Author Topic: SSME; Starsector Mod Expander peer review request.  (Read 3527 times)

TJJ

  • Admiral
  • *****
  • Posts: 1905
    • View Profile
SSME; Starsector Mod Expander peer review request.
« on: May 14, 2015, 11:43:51 AM »

Very early version.
Take a look, have a play, break it as much as you can.

SSME intends to provide a semi-secure framework for run-time modification of Starsector's bytecode, thereby allowing far greater customization of the game's functionality.
Familiarity with Java bytecode, and run-time instrumentation libraries is strongly recommended.

Installation & Launching.

1) Extract both SSME (HERE), and the Example Mod (HERE), to your mods folder. (all sourcecode is included)
2) launch Starsector via your platform's SSME launch script located in the SSME mod folder.
Note. mac & *nix launch scripts are completely untested; if they don't work, pls let me know xxx)

(The launch scripts are just adaptations of Starsector's default scripts, with a few modifications:
- SSME added to the classpath
- libraries added to the classpath
- "java.system.class.loader" property added.
- now using -javaagent instead.
- Now using BOTH java.system.class.loader AND -javaagent. Compartmentalizing SSME code & Starsector code into separate class loaders prevents instrumentation malfunctions (transformers transforming their own code libraries)
- entry class changed from StarfarerLauncher to StarsectorModExpander (SSME's main class)

Quick overview:

  • Mods that require SSME functionality should include an "ssme.json" in the root of their mod folder.
  • "ssme.json" contains a list of jars to append to the classpath, and the name of a classTransformer contained within. (A class that implements the interface org.tjj.starsector.ssme.ClassTransformer, and will be instantiated by SSME.)
  • Prior to the execution of any unsafe code, the user is prompted to give authorization to each Mod that desires it.
  • SSME makes a few tweaks to the Starsector launcher, to add a UI for modifying previously granted/refused authorizations
  • Class transformation occurs in 2 stages.
  • Early transformation. ( ClassTransformer#doEarlyTransformations(ClassProvider) )
    This occurs before any of Starsector's core code is loaded. Each Mod's ClassTransformer is given the opportunity to apply bytecode modifications to any of the game's classes it can explicitly name.
  • Late transformation. ( ClassTransformer#doLateTransformation(String,byte[]) )
    This occurs immediately before a class is loaded. Each Mod's ClassTransformer is given a chance to modify the bytecode of the class being loaded. This is useful if you want to apply a transformation to every class in the game, or to classes for which you have no name. (either because of obfuscation, or because it's script code of other mods)
  • For convenience, SSME includes 3 bytecode instrumentation libraries. Javassist (which is what SSME itself uses), ASM (low level library), and Byte Buddy (not done much with this API, but it looks really good!)
  • SSME offers some (and will offer more) utility methods for aiding in bytecode manipulation.
  • The Example Mod is a demonstration of the simplicity of the process. It intercepts the loading of ship_data.csv & applies a modification to each JSONObject before passing it back to the game code. (inspired by this thread)

Guidance when designing your instrumentation:
  • Don't attempt to write instrumentation without having a debugger attached to the VM; you'll be wasting your time  ;)
  • Never rely upon obfuscated names; they will almost certainly change between releases. Identify methods via attributes other than their name (see Utils.findDeclaredMethods(CtClass, MethodPrototype)
  • Make your instrumentation code fail-fast! While many instrumentation mods will work flawlessly between Starsector patches, when they do fail, for your own sanity you want them to fail as early & as verbosely as possible.
  • Make sure you don't instrument your own instrumentation classes! (while redirecting Random.methods() to my own implementations, I instrumented the target class too, resulting in an infinite loop! ;D ). Improved the API so this is now impossible
  • Don't forget that the constructors for anonymous classes take hidden parameters (their containing class, plus any 'final' local variables that they access)
  • erm..... stuff that I'll discover while I write SSMF (Starsector Multifarer)  ;D

Known Issues:

When ASM is set to COMPUTE_MAXS | COMPUTE_FRAMES on classes that it touches, it generates an invalid class file for the obfuscated class

Code
sound/OooOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO

This is either a bug in ASM (making class file format assumptions it shouldn't be), or a bug in the obfuscator Alex is using (generating a class that is technically outside the class file format specification).
Either way, it should be fixable with a patch to ASM - but I won't bother until it becomes an blocking issue that needs to be solved.

Little diagram explaining where class loading responsibility lies, and what code SSME can touch:
Spoiler
[close]
« Last Edit: May 17, 2015, 01:26:23 PM by TJJ »
Logged

Sproginator

  • Admiral
  • *****
  • Posts: 3592
  • Forum Ancient
    • View Profile
Re: SSME; Starsector Mod Expander peer review request.
« Reply #1 on: May 14, 2015, 12:26:40 PM »

Am confused. What exactly does this allow people to customise?
Logged
A person who's never made a mistake, never tried anything new
- Albert Einstein

As long as we don't quit, we haven't failed
- Jamie Fristrom (Programmer for Spiderman2 & Lead Developer for Energy Hook)

Dark.Revenant

  • Admiral
  • *****
  • Posts: 2806
    • View Profile
    • Sc2Mafia
Re: SSME; Starsector Mod Expander peer review request.
« Reply #2 on: May 14, 2015, 12:29:59 PM »

What are the use cases for this?  Generally speaking, a modder can just get functionality added to the API, and most things that won't get added to the API are so complicated that the dev doesn't feel the need to add them, and he has the source code!

Also, the problem with multiplayer is that there is a huge difference between "working" and "polished and enjoyable".  There is a ton of UI work and design challenges in the way.
Logged

TJJ

  • Admiral
  • *****
  • Posts: 1905
    • View Profile
Re: SSME; Starsector Mod Expander peer review request.
« Reply #3 on: May 14, 2015, 12:40:01 PM »

Am confused. What exactly does this allow people to customise?

Almost everything.

What are the use cases for this?

Basically everything that I'll need for MP that is either impossible or impractical to expose through a public api.

I made an abridged list in the last thread that drifted onto the topic of MP.
« Last Edit: May 14, 2015, 12:43:21 PM by TJJ »
Logged

Sproginator

  • Admiral
  • *****
  • Posts: 3592
  • Forum Ancient
    • View Profile
Re: SSME; Starsector Mod Expander peer review request.
« Reply #4 on: May 15, 2015, 03:09:03 AM »

So, can I make new mount types? New weapon sizes? New mechanics?
Logged
A person who's never made a mistake, never tried anything new
- Albert Einstein

As long as we don't quit, we haven't failed
- Jamie Fristrom (Programmer for Spiderman2 & Lead Developer for Energy Hook)

TJJ

  • Admiral
  • *****
  • Posts: 1905
    • View Profile
Re: SSME; Starsector Mod Expander peer review request.
« Reply #5 on: May 15, 2015, 06:39:09 AM »

So, can I make new mount types? New weapon sizes? New mechanics?

Theoretically yes, though they would probably be very hard modifications to make because they're likely buried deep within obfuscated code.

The easiest modifications are those where the game interacts with unobfuscated APIs
Whether they're classes from the JRE, json, lwjgl, swing, or the game's own unobfuscated APIs.

It becomes more difficult the further away from unobfuscated code your instrumentation has to delve.

p.s.

I've updated SSME; for intercepting & applying the bytecode modifiations it's now using a javaagent rather than replacing the system class loader.
This both neatens, simplifies and secures the code, while also allowing instrumentation of mod scripts themselves. (important if you're writing a transformer that has to touch every class in the game; e.g. imposing strictfp)
« Last Edit: May 15, 2015, 10:25:30 AM by TJJ »
Logged

xenoargh

  • Admiral
  • *****
  • Posts: 5078
  • naively breaking things!
    • View Profile
Re: SSME; Starsector Mod Expander peer review request.
« Reply #6 on: May 15, 2015, 09:48:10 AM »

Hrmm.  Wouldn't it be better, in a lot of cases, to simply ask Alex if he'd be willing to un-obfuscate certain code areas, so that it's a bit more like making a mod for Minecraft, where we can largely see the engine code?

Most of the stuff I've wanted to do with serious modding has to do with core rendering stuff that is generally un-accessible and obfuscated atm, so I'd really like to be able to change methods, but I'm not sure I'd want to delve deep into the obfuscated code to figure it out, only to see it broken every build.  It was bad enough trying to maintain Vacuum through the other major changes that happened at the campaign level.

I like how you're approaching the deep stat-modification issue; that is pretty cool, and I may even use it to finally do the Hardpoint weapon changes I've talked about a few times and see how they actually work in practice, balance-wise, if it's possible to add to the method that handles that behavior.

Anyhow, I will try and find time to install this and play around with the example soonish.  Kind of busy until Sunday though :)
Logged
Please check out my SS projects :)
Xeno's Mod Pack

TJJ

  • Admiral
  • *****
  • Posts: 1905
    • View Profile
Re: SSME; Starsector Mod Expander peer review request.
« Reply #7 on: May 15, 2015, 10:24:06 AM »

As a stepping stone towards multiplayer, and a proof of concept for SSME, I'm going to be working on a battle recorder + playback mod next.

This should touch on how easy (or hard!) it is to:
- hook into the main menu (for presenting a list of recorded battles, and engaging playback mode); [we don't (yet) have a public API for doing this, right?]
- hook into lwjgl input methods, to record key/mouse events/states per frame.
- make the battle simulation completely deterministic
  • strictfp everything (done*, trivially easy)
  • redirecting random()/Random usage to implementations where I can control the seed
  • eliminating any framerate dependent logic. (to begin with, probably by forcing a constant frame delta)
  • investigate if there's any usage of default hashCode(), and eliminate it
  • addressing any non-determinism caused by multithreading
- other stuff I've yet to consider!

^ Notice how every one of these requirements is also needed for my multiplayer proposal ;D
« Last Edit: May 16, 2015, 06:10:29 AM by TJJ »
Logged

TJJ

  • Admiral
  • *****
  • Posts: 1905
    • View Profile
Re: SSME; Starsector Mod Expander peer review request.
« Reply #8 on: May 18, 2015, 06:25:34 AM »

Making progress  ;D
Spoiler
[close]

Admittedly all it is so far is the hooks necessary for adding main menu entries ;)
Logged

TJJ

  • Admiral
  • *****
  • Posts: 1905
    • View Profile
Re: SSME; Starsector Mod Expander peer review request.
« Reply #9 on: May 30, 2015, 07:23:02 AM »

Added a sanitisation step to ssme.
Essentially it is now deobfuscating all package, type, method, and field names to remove illegal identifiers. (Identifiers that are legal in the class file specification, but not the Java language specification)

Going forward this should remove any future incompatibility with javassist's compiler, and also make better reference material when designing/implementing instrumentations.

Now I can get back to implementing the battle recorder/replay mod!
Logged