Fractal Softworks Forum

Please login or register.

Login with username, password and session length
Advanced search  
Pages: [1] 2

Author Topic: [0.95a] DroneLib v1.1.0 - Evolved Combat Systems (New Tutorial!)  (Read 22923 times)

tomatopaste

  • Commander
  • ***
  • Posts: 154
  • Gentle Mann of Leisure
    • View Profile



DroneLib is a collection of utilities, base classes and example code to give mod creators more options for creating engaging and unique ship combat mechanics to play with. It is a dependency like other libraries such as LazyWizard's LazyLib, which must be also be installed.

Note: to play around with two example subsystems, check DroneLib/data/config/settings.json for "dl_UseHammerheadForShowcase" and set it to true.

Current Features

Multimode Drone Launcher Shipsystem Framework
This mod provides the framework for a modder to create a drone shipsystem that can order its drones to assume multiple unique formations to fulfill different purposes. These formations can be cycled through with the normal activation key. The possibilities are effectively endless, one example of a system could be five small PD Laser equipped drones in a defensive circle, while a second formation could direct all five drones to cluster forwards. Tested drone ideas include clamping vector thruster drones, shield drones, anti-fighter sniper drones, ECCM boosting drones etc. etc.
The library handles the underlying framework of the drone system, specifically simulating a 'drone forge', where the system has a maximum capacity of stored drones, and a rate at which they can be replenished in combat. It also handles drone creation and assignment. It is up to the modder to configure shipsystem data such as reserve capacity, number of modes etc., and the other major task is to program the drone AI. The library provides a base ai class that handles common tasks, while the modder focuses on the per-mode behaviour of the drone, such as position, facing angle and visual effects. The library provides static utility methods in dl_DroneAIUtils, which implement moving, rotation and target selection.

ECCM Drone Shipsystem featuring in the upcoming Pearson Exotronics v1.0.0

"Subsystems" - Simulated Auxiliary Shipsystems
Subsystems are entirely custom effect scripts modelled closely on vanilla's shipsystem format. It makes use of a slick combat GUI that is modular and allows modders to create subsystems that are unlimited in simplicity or complexity. The GUI scales to any weapon configuration and group size, and also fits on the screen at the lowest screen resolution. They can be assigned to any particular hotkey for activation, and an unlimited number of subsystems can be active on a ship at once. Subsystems can be baked into a ship hull by simply associating a subsystem id with a hull id, or alternatively, they can also be applied to a single ShipAPI instance. This means that a hullmod can add a subsystem modularly (a phase cloak hullmod was successfully tested). Subsystems are straightforward for modders to implement, taking fewer individual steps than vanilla shipsystems. They require a csv data entry, similar to shipsystems.csv, and a single master script that includes apply/unapply and AI. Unfortunately vanilla's system AIs such as WEAPON_BOOST aren't available because they are naturally hardcoded, but it can be surprisingly easy to make a decent subsystem AI using ship AI flags.

Tutorial subsystem cycle in action

Compact GUI mode

Info GUI mode

Drone Launcher Subsystems
Putting it together - this ports the shipsystem framework to be useable by subsystems. This has the advantage of freeing up the ship system slot for something more central to the ship's design, and also makes drone systems hullmod-portable.

Hammerhead with tutorial drone subsystem


Tutorials/Documentation for modders
Read through the src folder, it contains a working example for each feature. Theses are indicated by a few"example" packages, such as "mymod_EpicBurnDriveSubsystem". A lot of methods have documentation descriptions attached, especially utility methods. I will get around to detailed tutorials at some point, but modders can contact me at any time for help. To figure out how subsystems work, you'll need to look at the mod plugin, dl_SubsystemUtils and the example/mymod_XXXXSubsystem folder in src.

Hullmod-added Subsystem Walkthrough
This tutorial describes how to add a subsystem to a ship through a hullmod. It is assumed that the mod creator is using an IDE such as IntelliJ, and they have defined DroneLib.jar as a library. A subsystem consists of four data entries – a subsystems.csv entry, a .java file for the subsystem ai and effects script, a hull_mods.csv entry and a .java file for the hullmod that applies it. We are going to walk through how to create a Manoeuvring Jets imitation subsystem.

Entry in subsystems.csv
The subsystems.csv entry provides DroneLib with the information needed to operate the subsystem. Any fields left blank will use default values. If the hotkey field is left blank, the library will use the default hotkey bindings H,J,K,L etc. This is generally a better idea unless you prefer your subsystem to use a particular hotkey. Empty fields for numbers e.g. inTime, fluxPerSecondFlat will default to 0.0, and isToggle defaults to FALSE.
Raw csv line:
Manoeuvring Jets,manoeuvring_jets,,0.5,4,0.3,4,,3,


Subsystem Script
DroneLib requires a subsystem to have a stats script to apply effects using vanilla’s MutableShipStatsAPI, which allows us to make modifications to various ship stats such as max speed, acceleration and turn rate. The apply() and unapply() methods are copied from vanilla’s ManeuveringJetsStats.java script with a couple of simplifications that do not modify the system behaviour. This script uses a simple AI that will attempt to activate the subsystem when the ship’s AI wants to move around the battlefield in particular situations.

Subsystem source code
package data.scripts.subsystems;

import com.fs.starfarer.api.Global;
import com.fs.starfarer.api.combat.MutableShipStatsAPI;
import com.fs.starfarer.api.combat.ShipAPI;
import com.fs.starfarer.api.combat.ShipEngineControllerAPI;
import com.fs.starfarer.api.combat.ShipwideAIFlags;

public class mymod_ManoeuvringJetsSubsystem extends dl_BaseSubsystem {
    public static final String SUBSYSTEM_ID = "manoeuvring_jets"; //this should match the id in the csv
   
    public mymod_ManoeuvringJetsSubsystem() {
        super(SUBSYSTEM_ID);
}

    @Override
    public void apply(MutableShipStatsAPI stats, String id, SubsystemState state, float effectLevel) {
        if (state == SubsystemState.OUT) {
            stats.getMaxSpeed().unmodify(id); // to slow down ship to its regular top speed while powering drive down
            stats.getMaxTurnRate().unmodify(id);
        } else {
            stats.getMaxSpeed().modifyFlat(id, 50f);
            stats.getAcceleration().modifyPercent(id, 200f * effectLevel);
            stats.getDeceleration().modifyPercent(id, 200f * effectLevel);
            stats.getTurnAcceleration().modifyFlat(id, 30f * effectLevel);
            stats.getTurnAcceleration().modifyPercent(id, 200f * effectLevel);
            stats.getMaxTurnRate().modifyFlat(id, 15f);
            stats.getMaxTurnRate().modifyPercent(id, 100f);
        }

        stats.getEntity();
        ShipAPI ship = (ShipAPI) stats.getEntity();
        String key = ship.getId() + "_" + id;
        Object test = Global.getCombatEngine().getCustomData().get(key);
        if (state == SubsystemState.IN) {
            if (test == null && effectLevel > 0.2f) {
                Global.getCombatEngine().getCustomData().put(key, new Object());
                ship.getEngineController().getExtendLengthFraction().advance(1f);
                for (ShipEngineControllerAPI.ShipEngineAPI engine : ship.getEngineController().getShipEngines()) {
                    if (engine.isSystemActivated()) {
                        ship.getEngineController().setFlameLevel(engine.getEngineSlot(), 1f);
                    }
                }
            }
        } else {
            Global.getCombatEngine().getCustomData().remove(key);
        }
    }

    @Override
    public void unapply(MutableShipStatsAPI stats, String id) {
        stats.getMaxSpeed().unmodify(id);
        stats.getMaxTurnRate().unmodify(id);
        stats.getTurnAcceleration().unmodify(id);
        stats.getAcceleration().unmodify(id);
        stats.getDeceleration().unmodify(id);
    }

    @Override
    public String getStatusString() {
        return null; //use default text
    }

    @Override
    public String getInfoString() {
        if (isActive()) return "IMPROVED MANOEUVRABILITY";
        if (isCooldown()) return "COOLING INJECTOR";
        return "INJECTOR PRIMED";
    }

    @Override
    public String getFlavourString() {
        return "+50 MAX SPEED AND ACCELERATION BOOST";
    }

    @Override
    public int getNumGuiBars() { //number of slots the subsystem uses in combat GUI
        return 1;
    }

    @Override
    public void aiInit() {
        //do nothing
    }

    @Override
    public void aiUpdate(float v) {
        if (ship == null || ship.isAlive()) return;
        ShipwideAIFlags flags = ship.getAIFlags();
        if (
                flags.hasFlag(ShipwideAIFlags.AIFlags.MANEUVER_TARGET)
                || flags.hasFlag(ShipwideAIFlags.AIFlags.TURN_QUICKLY)
                || flags.hasFlag(ShipwideAIFlags.AIFlags.RUN_QUICKLY)
        ) {
            activate();
        }
    }
}
[close]

Hullmod Setup
This hullmod is basically identical to any other hullmod implementation. We firstly need a hull_mods.csv entry, nothing fancy.

Raw csv line:
Manoeuvring Jets Subsystem,manjets_subsys,1,,,,Engines,2000,TRUE,,,4,8,20,40,data.scripts.hullmods.mymod_ManoeuvringJetsSubsystemHullmod,Installs a modular manoeuvring jets subsystem with a longer cooldown.,Adds maneuvering jets subsystem.,graphics/hullmods/augmented_engines.png




Finally, we need a hullmod .java file that will be used to add the hullmod to our ship. It uses the method dl_SubsystemUtils.queueSubsystemForShip(ShipAPI ship, Class<? extends dl_BaseSubsystem> subsystemClass) to tell DroneLib that we want to apply an instance of this subsystem class when the ship enters combat.

Hullmod source code
package data.scripts.hullmods;

import com.fs.starfarer.api.combat.BaseHullMod;
import com.fs.starfarer.api.combat.ShipAPI;
import data.scripts.subsystems.mymod_ManoeuvringJetsSubsystem;
import data.scripts.util.dl_SubsystemUtils;

public class mymod_ManoeuvringJetsSubsystemHullmod extends BaseHullMod {
    @Override
    public void applyEffectsAfterShipCreation(ShipAPI ship, String id) {
        dl_SubsystemUtils.queueSubsystemForShip(ship, mymod_ManoeuvringJetsSubsystem.class);
    }
}
[close]
Result
We have created a simple hullmod that will create a manoeuvring jets subsystem on any ship it is installed on. It also works on AI ships making simple use of vanilla's ShipAIFlags functionality.



[close]
« Last Edit: July 27, 2021, 08:35:08 AM by tomatopaste »
Logged

Klokinator

  • Ensign
  • *
  • Posts: 34
    • View Profile
Re: [0.95a] DroneLib - Evolved Combat Systems (Mod Utility Library)
« Reply #2 on: July 12, 2021, 09:01:34 AM »

Please modders, make use of this, and hopefully a lot of use. This sounds too cool to ignore. I'd love to see hullmods that instate specific drone behavior, just as one example.
Logged

tomatopaste

  • Commander
  • ***
  • Posts: 154
  • Gentle Mann of Leisure
    • View Profile
Re: [0.95a] DroneLib - Evolved Combat Systems (Mod Utility Library)
« Reply #3 on: July 12, 2021, 09:05:37 AM »

Oooh subsystems!
So how do they work with ship systems?
Are they completely independent?
Yep, 100% independent. Transferable across all ships.
Logged

Sutopia

  • Admiral
  • *****
  • Posts: 903
    • View Profile
Re: [0.95a] DroneLib - Evolved Combat Systems (Mod Utility Library)
« Reply #4 on: July 12, 2021, 10:20:01 AM »

Are drones affected by any skills?
Can I use this library to make custom wing AI instead of drone AI?
Are subsystems affected by system expertise?

Morrokain

  • Admiral
  • *****
  • Posts: 1977
  • Megalith Dreadnought - Archean Order
    • View Profile
Re: [0.95a] DroneLib - Evolved Combat Systems (Mod Utility Library)
« Reply #5 on: July 12, 2021, 01:16:17 PM »

Well now, this looks very interesting!

Do you have an idea of how easy/difficult the framework will be to maintain in future Starsector updates? My one hesitation would be to rig a bunch of stuff to use the framework and then an update would render all of it inoperable for an indeterminable amount of time.

Still, this is very cool and I love how its even separate from ship systems so you could conceivably synergize the dual mechanics for a pretty unique ship.
Logged

DecoyGrenadeOut

  • Ensign
  • *
  • Posts: 13
    • View Profile
Re: [0.95a] DroneLib - Evolved Combat Systems (Mod Utility Library)
« Reply #6 on: July 12, 2021, 04:15:09 PM »

This looks REALLY cool! I can't wait to see what other modders are going to do with it!

Speaking of GUI modifications, is there any way to modify the weapon GUI so that it notifies you when all weapons in a given weapon group is able to fire (an OK/READY right beside the weapon group in combat HUD)? Because I have quite some trouble timing cooldowns for weapon with high delays like AM Blaster.
Logged

tomatopaste

  • Commander
  • ***
  • Posts: 154
  • Gentle Mann of Leisure
    • View Profile
Re: [0.95a] DroneLib - Evolved Combat Systems (Mod Utility Library)
« Reply #7 on: July 12, 2021, 07:41:06 PM »

Are drones affected by any skills?
Can I use this library to make custom wing AI instead of drone AI?
Are subsystems affected by system expertise?

Player skills are not currently taken into account, I will add them once the initial proof of concept is rock steady.
Custom wing AI is currently outside the scope of this library, that would be a whole different can of worms to modularise and there would have to be sufficient motivation to do so, unless somebody else wanted to work on it.
Well now, this looks very interesting!

Do you have an idea of how easy/difficult the framework will be to maintain in future Starsector updates? My one hesitation would be to rig a bunch of stuff to use the framework and then an update would render all of it inoperable for an indeterminable amount of time.

Still, this is very cool and I love how its even separate from ship systems so you could conceivably synergize the dual mechanics for a pretty unique ship.

This framework could have existed in a number of previous updates since it is uses combat api functions that have been around for a while, so unless alex decides to revamp the entire combat engine and GUI I don't see future updates breaking it.
Logged

6chad.noirlee9

  • Captain
  • ****
  • Posts: 332
    • View Profile
Re: [0.95a] DroneLib - Evolved Combat Systems (Mod Utility Library)
« Reply #8 on: July 12, 2021, 09:48:46 PM »

STOKED IS AN UNDERSTATEMENT: thanks for doing this
Logged
edit: edit: maybe were just falling with style LOL.  make a bubble, make the space in front of it smaller and just fall forward

Morrokain

  • Admiral
  • *****
  • Posts: 1977
  • Megalith Dreadnought - Archean Order
    • View Profile
Re: [0.95a] DroneLib - Evolved Combat Systems (Mod Utility Library)
« Reply #9 on: July 13, 2021, 04:42:39 PM »

This framework could have existed in a number of previous updates since it is uses combat api functions that have been around for a while, so unless alex decides to revamp the entire combat engine and GUI I don't see future updates breaking it.

Ah nice good to know! Yeah never say never but I feel that its pretty unlikely that this would be reworked at this point.
Logged

Thaago

  • Global Moderator
  • Admiral
  • *****
  • Posts: 5861
  • Harpoon Affectionado
    • View Profile
    • Email
Re: [0.95a] DroneLib - Evolved Combat Systems (Mod Utility Library)
« Reply #10 on: July 17, 2021, 06:31:18 PM »

This looks awesome! I've always liked drones, and the ability to have multiple systems on a ship (applying to individual weapon groups even!!) is great.
Logged

Cirind

  • Ensign
  • *
  • Posts: 4
    • View Profile
    • Email
Re: [0.95a] DroneLib - Evolved Combat Systems (Mod Utility Library)
« Reply #11 on: July 18, 2021, 03:36:27 PM »

Just wanted to say that this is probably one of best things on this forum.
Logged

tomatopaste

  • Commander
  • ***
  • Posts: 154
  • Gentle Mann of Leisure
    • View Profile
Re: [0.95a] DroneLib - Evolved Combat Systems (Mod Utility Library)
« Reply #12 on: July 19, 2021, 10:30:01 AM »

DroneLib v1.0.1
Download v1.0.1
Fixed major problem with mod csv merging. A reminder that subsystem instances applied in combat via applySubsystemToShip(ShipAPI Ship, dl_Subsystem subsystem) will need to have .init(ShipAPI ship) and .aiInit() called externally.

v1.0.1
-fixed CSV merging between mods
-updated method documentation
Logged

tomatopaste

  • Commander
  • ***
  • Posts: 154
  • Gentle Mann of Leisure
    • View Profile

Quick showcase of some shenanigans implementing subsystems with RogueSynth hullmods, which I am working on updating to 0.95a.




Logged

tomatopaste

  • Commander
  • ***
  • Posts: 154
  • Gentle Mann of Leisure
    • View Profile

DroneLib v1.1.0
Download v1.1.0
Important update with refinements and fixes.

v1.1.0
-added centralised subsystem hullmod queuing function to dl_SubsystemUtils
    -queueSubsystemFromHullmodForShip(ShipAPI ship, Class<? extends dl_BaseSubsystem> subsystemClass)
    -Queues a subsystem for a ShipAPI instance so it will be applied upon entering combat. Allows subsystems to be
     cleanly added via hullmod
-fixed subsystem ai scripts running while player control active
-fixed subsystem gui showing with no subsystems installed on player ship
-added useful getter and setter methods to dl_BaseSubsystem
    -methods such as setCooldown(float cooldown) apply changes only to the subsystem instance, it does not globally
     change the subsystem spec data
-added default hotkey manager, if the 'hotkey' field in the csv is left blank it will use a unique default
    -custom hotkeys can be defined for subsystem slots 1-6, 6th slot will be copied with more subsystems
-added static getSubsystemsOnShip(ShipAPI ship) method to dl_SubsystemCombatManager
-added overridable methods in dl_BaseSubsystem to prevent subsystem being used while venting and/or overloaded
-changed a couple of method names for clarity - unfortunately will cause crashes with any mods using old method names
    -queueSubsystemFromHullmodForShip -> queueSubsystemForShip
        -method does not require a hullmod
    -getSystemId -> getSubsystemId
        -clear up any confusion with regular shipsystems
    -may have missed one or two, but nothing has been removed so the successor name should be obvious
-updated/added javadoc comments to several methods
Logged
Pages: [1] 2