Do you like statistics?
Would you like to know exactly how many enemy fleets you've personally blown up in your entire playthrough?
Or how many of your ships fell in glorious battle against the accursed <DORITOS>?
If so, this mod may be for you! Please enjoy it:
Download (https://github.com/briansd9/starsector-fleethistory/releases/latest/download/fleethistory.zip)
Fleet Action History v1.0.10 - 2023-05-10
Safe to add to existing savegames, and easily removable too
Individual battle histories for each of your ships and officers
(https://i.imgur.com/f6UFrio.png)
Officer level ups and new skills are tracked too
(https://i.imgur.com/foK3yhY.png)
(https://i.imgur.com/5CW4SlY.png)
(https://i.imgur.com/27ossug.png)
Detailed logs for every battle you fight
(https://i.imgur.com/kEKunne.png)
(https://i.imgur.com/sbfKn8H.png)
(https://i.imgur.com/1t3Wj5t.png)
(https://i.imgur.com/txNWjtG.png)
Tested with unreasonably huge battle sizes and every faction mod I could find - no crashes or slowdown
I pray for the souls of all the poor crewmen who were incinerated for my testing
(https://i.imgur.com/NczaNyc.png)
(https://i.imgur.com/32cTLGS.png)
In-game configuration, no fiddling with settings.json ever! Also includes built-in "clear data" function for safe removal from savefiles
(https://i.imgur.com/T1JW8sE.png)
For fellow modders
Integration ideas are welcome. If you'd like to experiment, add fleethistory.jar as a library in your IDE and try out these methods:
U.getOfficerLogFor(PersonAPI.getId())
U.getShipLogFor(FleetMemberAPI.getId())
Known issues and limitations
- Only battles you fight personally are tracked - autoresolve not handled
- Kills of fighters, dorito crumbs, and any other ships dynamically spawned on the field can't be recorded
- If you transfer command during battle, only the stats of the last ship commanded are credited to you
- Battlestation kills sometimes behave oddly (more than one ship gets the kill; fleet point value assigned is greater than actual value)
Future plans
- Battle recap / timeline
- Log of post-battle loot?
- Suggestions welcome
Thanks to...
- The adepts of #advanced_scripting_sanctum on Discord, every one of you is a gentleman and a scholar
- Nick XR, whose Detailed Combat Results (https://fractalsoftworks.com/forum/index.php?topic=11551.0) was an inspiration for this mod
- Alex for this beautiful game - playing since 2012
- And you for trying this out! Let me know how it goes
Change log
v1.0.10 (2023-05-10)
- fixed: crash when switching kill count display mode to "table"
v1.0.9 (2023-05-06)
- Compatibility update for Starsector 0.96 release
v1.0.8 (2022-04-29)
- Minor fix to prevent a crash of unknown cause (https://fractalsoftworks.com/forum/index.php?topic=5061.msg361695#msg361695)
v1.0.7 (2021-11-14)
- Minor fix to prevent occasional crash when playing with Vayra's Sector unofficial update (https://fractalsoftworks.com/forum/index.php?topic=5061.8115)
v1.0.6 (2021-06-29)
- Fixed savefile-corrupting bug (instructions for repairing affected saves can be found here: https://fractalsoftworks.com/forum/index.php?topic=21929.msg334039#msg334039 )
v1.0.5 (2021-06-28)
- Fixed some minor text bugs (thanks to saya39)
v1.0.4 (2021-06-27)
- Will no longer add story points when mousing over lost player ships in battle report. ????
- Added translation support for fossic friends
v1.0.0 - v1.0.3 (2021-06-08)
- Various post-release crash fixes
Hmm, this mod doesn't use settings.json at all, the settings are stored in the savefile (campaign.xml) instead.
Okay. I misunderstood where the settings were.
Would a general framework for this kind of configuration be of interest? I suppose it's theoretically possible... but any changes made would be limited to that savefile, so you'd have to input them all over again for every new game. (Also, programming UI elements in Starsector is rather tough)
I still believe that modders would find uses for this! Its like having a new tool on a toolbench. The tool is designed for a purpose but creativity allows alternative uses that could surprise you.
Spoiler
(https://external-content.duckduckgo.com/iu/?u=http%3A%2F%2Fmedia.boingboing.net%2Fwp-content%2Fuploads%2F2016%2F02%2Fwpn9AX.gif&f=1&nofb=1)
Would a general framework for this kind of configuration be of interest? I suppose it's theoretically possible... but any changes made would be limited to that savefile, so you'd have to input them all over again for every new game. (Also, programming UI elements in Starsector is rather tough)
There's actually a way, check out:
Global.getSettings().writeTextFileToCommon();
Global.getSettings().readTextFileFromCommon();
I think there's an IO limit of 1MB, but if you limit to read on startup and write on save and you don't write much, you should be fine.
But this is cool, especially the configuration. You should ask one of the maintainers of a lib if the configuration stuff could go in there.
I'm getting a crash with this
449766 [Thread-3] ERROR com.fs.starfarer.combat.CombatMain - java.lang.NullPointerException
java.lang.NullPointerException
at fleethistory.BattleLogger.getParent(BattleLogger.java:87)
at fleethistory.BattleLogger.advance(BattleLogger.java:59)
at com.fs.starfarer.title.Object.L$Oo.super(Unknown Source)
at com.fs.starfarer.combat.oOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO.B.super(Unknown Source)
at com.fs.starfarer.combat.CombatEngine.advanceInner(Unknown Source)
at com.fs.starfarer.combat.CombatEngine.advance(Unknown Source)
at com.fs.starfarer.combat.CombatState.traverse(Unknown Source)
at com.fs.state.AppDriver.begin(Unknown Source)
at com.fs.starfarer.combat.CombatMain.main(Unknown Source)
at com.fs.starfarer.StarfarerLauncher.o00000(Unknown Source)
at com.fs.starfarer.StarfarerLauncher$1.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Image
(https://i.ibb.co/GMD9sP8/Code-h2p-UW5-Mps8.png)
notepad++
(https://i.ibb.co/KsRdgBg/notepad-p-T6-WNMu4-SG.png)
[attachment deleted by admin]
Sorry about that - should be fixed in v1.0.2 (https://github.com/briansd9/starsector-fleethistory/releases/download/1.0.2/fleethistory.zip)
Can you take a look to this crash? (modversion 1.02)
After I join the battle and click to auto resolve (second in command) the game crashed. I had a save before the battle and try to repeat the same procedure but suddenly... no crash :D strange...
Spoiler
1612505 [Thread-3] ERROR com.fs.starfarer.combat.CombatMain - java.lang.NullPointerException
java.lang.NullPointerException
at fleethistory.types.BattleRecord.setCaptains(BattleRecord.java:154)
at fleethistory.types.BattleRecord.setPlayerFleetStrength(BattleRecord.java:141)
at fleethistory.listeners.BattleListener.logPlayerFleetOutcome(BattleListener.java:130)
at fleethistory.listeners.BattleListener.logCombatResults(BattleListener.java:61)
at fleethistory.listeners.BattleListener.reportPlayerEngagement(BattleListener.java:52)
at com.fs.starfarer.campaign.CampaignEngine.reportPlayerEngagement(Unknown Source)
at com.fs.starfarer.api.impl.campaign.FleetEncounterContext.processEngagementResul ts(FleetEncounterContext.java:247)
at com.fs.starfarer.api.impl.campaign.FleetInteractionDialogPluginImpl.backFromEng agement(FleetInteractionDialogPluginImpl.java:590)
at exerelin.campaign.battle.NexFleetInteractionDialogPluginImpl.backFromEngagement(NexFleetInteractionDialogPluginImpl.java:90)
at com.fs.starfarer.api.impl.campaign.FleetInteractionDialogPluginImpl$1.pickedFleetMembers(FleetInteractionDialogPluginImpl.java:1385)
at com.fs.starfarer.ui.newui.oOOoOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO.advance(Unknown Source)
at com.fs.starfarer.ui.v.advanceImpl(Unknown Source)
at com.fs.starfarer.ui.Oo0O.advanceImpl(Unknown Source)
at com.fs.starfarer.ui.newui.Stringsuper.advanceImpl(Unknown Source)
at com.fs.starfarer.ui.o00O.advance(Unknown Source)
at com.fs.starfarer.ui.v.advanceImpl(Unknown Source)
at com.fs.starfarer.ui.o00O.advance(Unknown Source)
at com.fs.starfarer.campaign.CampaignState.advance(Unknown Source)
at com.fs.starfarer.BaseGameState.traverse(Unknown Source)
at com.fs.state.AppDriver.begin(Unknown Source)
at com.fs.starfarer.combat.CombatMain.main(Unknown Source)
at com.fs.starfarer.StarfarerLauncher.o00000(Unknown Source)
at com.fs.starfarer.StarfarerLauncher$1.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
[attachment deleted by admin]
Heyo, absolutely love your mod.
Recently i've been messing with as many mods as possible, and, after some playing around, i'll always get the following problem when loading my save.
Spoiler
7801779 [Thread-3] INFO com.fs.starfarer.campaign.save.CampaignGameManager - Loading C:\Program Files (x86)\Fractal Softworks\Starsector\starsector-core\..\saves\save_Zero_695767075943828095...
7801783 [Thread-3] INFO com.fs.starfarer.campaign.save.CampaignGameManager - Loading stage 2
7801783 [Thread-3] INFO com.fs.starfarer.campaign.save.CampaignGameManager - Loading stage 3
7804153 [Thread-3] INFO com.fs.starfarer.campaign.save.CampaignGameManager - Error loading
7804154 [Thread-3] ERROR com.fs.starfarer.campaign.save.CampaignGameManager - Failed calling method
---- Debugging information ----
message : Failed calling method
cause-exception : java.lang.NullPointerException
cause-message : null
method : com.fs.starfarer.campaign.fleet.FleetMember.readResolve()
class : com.fs.starfarer.campaign.fleet.FleetMember
required-type : com.fs.starfarer.campaign.fleet.FleetMember
converter-type : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
line number : 859352
class[1] : java.util.HashMap
converter-type[1] : com.thoughtworks.xstream.converters.collections.MapConverter
class[2] : com.fs.starfarer.campaign.ModAndPluginData
class[3] : com.fs.starfarer.campaign.CampaignEngine
converter-type[2] : com.fs.starfarer.campaign.save.I
version : not available
-------------------------------
com.thoughtworks.xstream.converters.ConversionException: Failed calling method
---- Debugging information ----
message : Failed calling method
cause-exception : java.lang.NullPointerException
cause-message : null
method : com.fs.starfarer.campaign.fleet.FleetMember.readResolve()
class : com.fs.starfarer.campaign.fleet.FleetMember
required-type : com.fs.starfarer.campaign.fleet.FleetMember
converter-type : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
line number : 859352
class[1] : java.util.HashMap
converter-type[1] : com.thoughtworks.xstream.converters.collections.MapConverter
class[2] : com.fs.starfarer.campaign.ModAndPluginData
class[3] : com.fs.starfarer.campaign.CampaignEngine
converter-type[2] : com.fs.starfarer.campaign.save.I
version : not available
-------------------------------
at com.thoughtworks.xstream.core.util.SerializationMembers.callReadResolve(SerializationMembers.java:82)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unma rshal(AbstractReflectionConverter.java:282)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:70)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50)
at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.rea dItem(AbstractCollectionConverter.java:73)
at com.thoughtworks.xstream.converters.collections.MapConverter.putCurrentEntryInt oMap(MapConverter.java:106)
at com.thoughtworks.xstream.converters.collections.MapConverter.populateMap(MapConverter.java:98)
at com.thoughtworks.xstream.converters.collections.MapConverter.populateMap(MapConverter.java:92)
at com.thoughtworks.xstream.converters.collections.MapConverter.unmarshal(MapConverter.java:87)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:70)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50)
at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.rea dItem(AbstractCollectionConverter.java:73)
at com.thoughtworks.xstream.converters.collections.MapConverter.putCurrentEntryInt oMap(MapConverter.java:110)
at com.thoughtworks.xstream.converters.collections.MapConverter.populateMap(MapConverter.java:98)
at com.thoughtworks.xstream.converters.collections.MapConverter.populateMap(MapConverter.java:92)
at com.thoughtworks.xstream.converters.collections.MapConverter.unmarshal(MapConverter.java:87)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:70)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50)
at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.rea dItem(AbstractCollectionConverter.java:73)
at com.thoughtworks.xstream.converters.collections.MapConverter.putCurrentEntryInt oMap(MapConverter.java:110)
at com.thoughtworks.xstream.converters.collections.MapConverter.populateMap(MapConverter.java:98)
at com.thoughtworks.xstream.converters.collections.MapConverter.populateMap(MapConverter.java:92)
at com.thoughtworks.xstream.converters.collections.MapConverter.unmarshal(MapConverter.java:87)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:70)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unma rshallField(AbstractReflectionConverter.java:503)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUn marshal(AbstractReflectionConverter.java:429)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unma rshal(AbstractReflectionConverter.java:281)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:70)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unma rshallField(AbstractReflectionConverter.java:503)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUn marshal(AbstractReflectionConverter.java:429)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unma rshal(AbstractReflectionConverter.java:281)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:70)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50)
at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:134)
at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32)
at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1486)
at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1466)
at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1346)
at com.fs.starfarer.campaign.save.CampaignGameManager.o00000(Unknown Source)
at com.fs.starfarer.campaign.CampaignState.dialogDismissed(Unknown Source)
at com.fs.starfarer.ui.Oo0O.dismiss(Unknown Source)
at com.fs.starfarer.ui.impl.o0oO.dismiss(Unknown Source)
at com.fs.starfarer.campaign.save.LoadGameDialog.actionPerformed(Unknown Source)
at com.fs.starfarer.ui.newnew.buttonPressed(Unknown Source)
at com.fs.starfarer.ui.I.Ò00000(Unknown Source)
at com.fs.starfarer.ui.I.processInput(Unknown Source)
at com.fs.starfarer.ui.Stringsuper.super(Unknown Source)
at com.fs.starfarer.BaseGameState.traverse(Unknown Source)
at com.fs.state.AppDriver.begin(Unknown Source)
at com.fs.starfarer.combat.CombatMain.main(Unknown Source)
at com.fs.starfarer.StarfarerLauncher.o00000(Unknown Source)
at com.fs.starfarer.StarfarerLauncher$1.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException
I've managed to pinpoint some of your logging as the main problem, although I don't know if the reason is your mod itself. I recovered my savefile just fine, just wanted to share the problem with you. If you want my save or anything else, I'd be glad to share.
How does one go about repairing their save? I have the same crash with my save file (and my last backup was a few hours prior, so I would rather not loose my progress).
If it's the same error, removing the "CURR_BATTLE_CHILD_PARENT_SHIPS" entry in campaign.xml will fix it. It'll look something like this:
<e>
<st>CURR_BATTLE_CHILD_PARENT_SHIPS</st>
<map z="385455">
... lots of stuff...
</map>
</e>
This whole structure needs to be removed, including the enclosing <e></e>.
I use a lot of mods and everything work fine except when I add Vayra Sector Unofficial 0.95 Update. After a battle I got a crash. It is your mod or Vayra Sector? It's strange because I can't reproduce it. 20 battles in a row no crash and than suddenly this:
Spoiler
5850251 [Thread-3] ERROR com.fs.starfarer.combat.CombatMain - java.lang.ClassCastException: data.scripts.campaign.intel.VayraPersonBountyIntel cannot be cast to com.fs.starfarer.api.impl.campaign.intel.PersonBountyIntel
java.lang.ClassCastException: data.scripts.campaign.intel.VayraPersonBountyIntel cannot be cast to com.fs.starfarer.api.impl.campaign.intel.PersonBountyIntel
at fleethistory.types.BattleRecord.checkPersonBounty(BattleRecord.java:228)
at fleethistory.listeners.BattleListener.reportBattleFinished(BattleListener.java:350)
at com.fs.starfarer.campaign.CampaignEngine.reportBattleFinished(Unknown Source)
at com.fs.starfarer.api.impl.campaign.FleetEncounterContext.applyAfterBattleEffect sIfThereWasABattle(FleetEncounterContext.java:790)
at com.fs.starfarer.api.impl.campaign.FleetInteractionDialogPluginImpl$4.coreUIDismissed(FleetInteractionDialogPluginImpl.java:1607)
at com.fs.starfarer.ui.newui.Stringsuper$2.coreUIDismissed(Unknown Source)
at com.fs.starfarer.ui.newui.K.dismiss(Unknown Source)
at com.fs.starfarer.coreui.k.actionPerformed(Unknown Source)
at com.fs.starfarer.ui.newnew.buttonPressed(Unknown Source)
at com.fs.starfarer.ui.I.xD20000(Unknown Source)
at com.fs.starfarer.ui.I.processInput(Unknown Source)
at com.fs.starfarer.ui.Stringsuper.super(Unknown Source)
at com.fs.starfarer.BaseGameState.traverse(Unknown Source)
at com.fs.state.AppDriver.begin(Unknown Source)
at com.fs.starfarer.combat.CombatMain.main(Unknown Source)
at com.fs.starfarer.StarfarerLauncher.o00000(Unknown Source)
at com.fs.starfarer.StarfarerLauncher$1.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)