BattletechModders / ModTek

Mod system for HBS's PC game BattleTech.
GNU Lesser General Public License v2.1
119 stars 34 forks source link

Mod Dev Feature Request: Logging Flashpoint Set Next Milestone ID #198

Open korgano opened 2 years ago

korgano commented 2 years ago

I'm currently developing a Flashpoint mod and have discovered a major issue in my mod, but am unable to diagnose it because I have no idea if the game is reading the "Set Next Milestone ID" field from a Flashpoint_AddContract entry in the milestoneSets file.

Ideally, the logging would include:

The most relevant code segments are in BattleTech.SimGameEvent under GetSetNextMilestoneIdList and HasSetNextMilestoneId. Neither function has any logging code, and the game's own debug code is not configured to provide the data needed.

CptMoore commented 2 years ago

MissionControl and FlashpointEnabler are mods dedicated to contracts and flashpoints respectively. Maybe they already have some debug logging for your use-case?

ModTek is not the best place to add use-case specific logging, mainly due to lack of knowledge and manpower.

korgano commented 2 years ago

I checked their Githubs just now, but I don't think that they actually have anything that's applicable to this situation.

Considering that ModTek is unifying a lot of logging for the benefit of mod developers, and is basically the only universal mod utility for BattleTech, it does make more sense to incorporate such functionality, especially when this would benefit everyone who would actually make Flashpoint mods.

And to be honest, if I had the knowledge, I'd do it myself, but I'm completely incompetent at the kind of coding required.

Like, I think this would work, but I have no idea if it does or how to make it happen with a Harmony patch:

SimGameEventResult.logger.LogDebug("Flashpoint.MilestoneID - Set Next Milestone");

public List<string> GetSetNextMilestoneIdList()
        {
            List<string> list = new List<string>();
            if (this.Actions != null)
            {
                foreach (SimGameResultAction simGameResultAction in this.Actions)
                {
                    if (simGameResultAction.Type == SimGameResultAction.ActionType.Flashpoint_SetNextMilestone)
                    {
                        list.Add(simGameResultAction.value);
                  SimGameEventResult.logger.LogDebug(string.Format("\t\t{0}", simGameResultAction.value);
                    }
                    else if (simGameResultAction.Type == SimGameResultAction.ActionType.Flashpoint_AddContract)
                    {
                        list.Add(simGameResultAction.additionalValues[6]);
                       SimGameEventResult.logger.LogDebug(string.Format("\t\t{0}", simGameResultAction.additionalValues[6]);
                    }
                    else if (simGameResultAction.Type == SimGameResultAction.ActionType.Flashpoint_StartContract)
                    {
                        list.Add(simGameResultAction.additionalValues[6]);
                        SimGameEventResultlogger.LogDebug(string.Format("\t\t{0}", simGameResultAction.additionalValues[6]);
                    }
                    else if (simGameResultAction.Type == SimGameResultAction.ActionType.Flashpoint_CompleteFlashpoint && !string.IsNullOrEmpty(simGameResultAction.value))
                    {
                        list.Add(simGameResultAction.value);
                        SimGameEventResult.logger.LogDebug(string.Format("\t\t{0}", simGameResultAction.value);
                    }
                }
            }
            return list;
        }
CptMoore commented 2 years ago

Considering that ModTek is unifying a lot of logging for the benefit of mod developers

True but ModTek is still operating on a very high level. Like lately uncaught exception logging and better threading support for logging was added. We barely have resources to do those crucial things.

Also ModTek is a universal platform for modders, that also means not to get into the way of debugging! Every time a method gets patched with Harmony, you can't debug that method anymore with dnSpy. So adding more logging would do more harm.

Try dnSpyEx with dnSpyEx mono dlls. There you can debug with breakpoints and see where the code goes through!

  1. download dnSpyEx
  2. download the mono dll from dnSpyEx mono dlls matching your bt ( 2018.4.2 ) and put it into BATTLETECH\MonoBleedingEdge\EmbedRuntime
  3. start dnSpyEx and add all dlls from BATTLETECH\BattleTech_Data\Managed and Mods\*\*.dll to its project window
  4. find the spot you want to debug, place a breakpoint
  5. start the game
  6. connect dnSpyEx to Unity (default port etc..)
  7. your breakpoint should be hit as long as no mods patch the method with your breakpoint (see harmony_summary.log)
korgano commented 2 years ago

@CptMoore: Here is a better solution that can be added to the debugging information page:

Flashpoint Milestone Debugging

Errors in FlashPoint milestones can cause various types of errors, including failure to exit conversations. Given the length of these files and lack of debug code for milestones in ModTek & BattleTech, external tools must be used.

Windows: Using PowerShell, enter the following code:

cd [filepath to milestoneSet folder]
Select-String -Path ".\*.json" -Pattern "[milestone prefix - for example, ms_fp]" |Select-Object -ExpandProperty Line |Out-File milestones.txt

This will generate a .txt file with the following output, allowing for faster and easier examination and verification:

    "StartingMilestoneID" : "ms_fp_debugDemo_001_Start",
                "Id" : "ms_fp_debugDemo_001_Start",
                            "value" : "ms_fp_debugDemo_002_TalkForCancel",
                "Id" : "ms_fp_debugDemo_002_TalkForCancel",
                            "value" : "ms_fp_debugDemo_003_BranchForCancel",
                "Id" : "ms_fp_debugDemo_003_BranchForCancel",
                            "value" : "ms_fp_debugDemo_100_Mission1",
                            "value" : "ms_fp_debugDemo_400_CancelComplete",
                "Id" : "ms_fp_debugDemo_100_Mission1",
                                "ms_fp_debugDemo_101_TalkBrief1",
                "Id" : "ms_fp_debugDemo_101_TalkBrief1",
                            "value" : "ms_fp_debugDemo_102_Mission2",
                "Id" : "ms_fp_debugDemo_102_Mission2",
                                "ms_fp_debugDemo_103_mission3",
                                "ms_fp_debugDemo_402_HalfReward",
                "Id" : "ms_fp_debugDemo_103_Mission3",
                                "ms_fp_debugDemo_201_Talk2",
                                "ms_fp_debugDemo_402_HalfReward",
                "Id" : "ms_fp_debugDemo_201_Talk2",
                            "value" : "ms_fp_debugDemo_202_Branch2",
                "Id" : "ms_fp_debugDemo_202_Branch2",
                            "value" : "ms_fp_debugDemo_300_Op3A",
                            "value" : "ms_fp_debugDemo_301_Op3B",
                            "value" : "ms_fp_debugDemo_401_Cancel_HalfCredit",
                "Id" : "ms_fp_debugDemo_300_Op3A",
                                "ms_fp_debugDemo_302_Talk3",
                                "ms_fp_debugDemo_401_Cancel-Half",
                "Id" : "ms_fp_debugDemo_301_Op3B",
                                "ms_fp_debugDemo_302_Talk3",
                                "ms_fp_debugDemo_401_Cancel-Half",
                "Id" : "ms_fp_debugDemo_302_Talk3",
                            "value" : "ms_fp_debugDemo_303_Branch3",
                "Id" : "ms_fp_debugDemo_303_Branch3",
                "Details" : "ms_fp_debugDemo_303_Branch3",
                            "value" : "ms_fp_debugDemo_304_Showdown",
                            "value" : "ms_fp_debugDemo_401_Cancel-Half",
                "Id" : "ms_fp_debugDemo_304_Showdown",
                                "ms_fp_debugDemo_305_BaseDefense",
                                "ms_fp_debugDemo_305_BaseDefense",
                "Id" : "ms_fp_debugDemo_305_BaseDefense",
                                "ms_fp_debugDemo_306_FinalTalk",
                                "ms_fp_debugDemo_306_FinalTalk",
                "Id" : "ms_fp_debugDemo_306_FinalTalk",
                            "value" : "ms_fp_debugDemo_307_Completion",
                "Id" : "ms_fp_debugDemo_307_Completion",
                            "value" : "ms_fp_debugDemo_308_Rewards",
                "Id" : "ms_fp_debugDemo_308_Rewards",
                "Id" : "ms_fp_debugDemo_401_Cancel-Half",
                            "value" : "ms_fp_debugDemo_402_HalfReward",
                "Id" : "ms_fp_debugDemo_402_HalfReward",
                "Id" : "ms_fp_debugDemo_400_CancelComplete",
                            "value" : "ms_fp_debugDemo_403_CancelReward",