BL Coding Is hardcoded dialogue the expectation?

Users who are viewing this thread

Paige 404

Recruit
So as I've been digging through the codebase to get a handle on how to do things, I came in with the expectation that dialogue would be contained in xml files. I see files like conversations.xml, I see localizations of that file, and I figured "this must be where the dialogue is getting loaded from". And I think maybe that's how the developers had originally intended to approach it, because all of the dialogue in the extensive conversations.xml is old. It's Warband dialogue, probably for testing purposes when they were building the Bannerlord engine. Looking at TaleWorlds.CampaignSystem.ConversationManager, you can even see the internal method for loading that data: LoadConversations.

The localization xmls gets use, I think. You can see extra ones in the Languages folders, like std_TaleWorlds.CampaignSystem.xml (which, as far as I can tell, holds nearly all dialogue in the base campaign). But everything in them comes from the code.

We can see so much dialogue being hard coded in. As far as I can tell, the majority are in TaleWorlds.CampaignSystem.Sandbox.CampaignBehaviors, in lines like campaignGameStarter.AddPlayerLine("child_dialogue_rhyme_start", "child_dialogue_regular_start", "child_dialogue_rhyme_start", "{=65PA77cZ}(Rhyme) \"Rain rain go away,\"", null, null, 100, null, null); . But is that where they're supposed to live? Or is this just the state of the codebase for this early access release?

How are folks working around this? Extending CampaignBehavior classes to swap in? Reaching in the guts of the ConversationManager to alter dialogue how you see fit? Has anyone gotten dialogue loading from xml in a satisfying way?
 
Solution
Hey it wasn't even that hard in the end. This is all it took:

C#:
using TaleWorlds.Core;
using TaleWorlds.MountAndBlade;
using TaleWorlds.CampaignSystem;
using TaleWorlds.Library;

namespace UntestedMod
{
    public class MySubModule : MBSubModuleBase
    {
        protected override void OnGameStart(Game game, IGameStarter gameStarter)
        {
            if (game.GameType is Campaign && gameStarter is CampaignGameStarter campaignGameStarter)
            {
                campaignGameStarter.LoadGameTexts(BasePath.Name + "Modules/UntestedMod/ModuleData/untested_strings.xml");
            }
        }
    }
}

The same should work for any strings xml. Sweet success!

mr.master

Count
This is something that I'd like to know as well. I'm trying to add in more options for companion conversations, but right now, I'm trying to wrap my head around where the replacing should be done.
 
Upvote 0

mr_mouflon

Recruit
I've been trying to get the game to pick up new wanderer dialogue strings also, with no success. I think for now, it's not possible just with xml. True a lot of dialogue is kept in XML files, but the game only loads texts from its own modules, e.g.:

C#:
private void LoadXmlFiles(CampaignGameStarter gameInitializer)
        {
            gameInitializer.LoadGameTexts(BasePath.Name + "Modules/SandBox/ModuleData/minor_faction_conversations.xml");
            gameInitializer.LoadGameTexts(BasePath.Name + "Modules/SandBox/ModuleData/world_lore_strings.xml");
            gameInitializer.LoadGameTexts(BasePath.Name + "Modules/SandBox/ModuleData/companion_strings.xml");
            gameInitializer.LoadGameTexts(BasePath.Name + "Modules/SandBox/ModuleData/wanderer_strings.xml");
            gameInitializer.LoadGameTexts(BasePath.Name + "Modules/SandBox/ModuleData/comment_strings.xml");
            gameInitializer.LoadGameTexts(BasePath.Name + "Modules/SandBox/ModuleData/comment_on_action_strings.xml");
            gameInitializer.LoadGameTexts(BasePath.Name + "Modules/SandBox/ModuleData/trait_strings.xml");
            gameInitializer.LoadGameTexts(BasePath.Name + "Modules/SandBox/ModuleData/voice_strings.xml");
            gameInitializer.LoadGameTexts(BasePath.Name + "Modules/SandBox/ModuleData/action_strings.xml");
        }

I guess this is why there are no paths for strings in any of the SubModule.xml files, the game already knows which files it wants. So I don't think there's any way to get it to load new strings without either injecting new code or editing the vanilla modules directly. But then I don't know much about anything, so maybe there's a way.
 
Upvote 0

mr_mouflon

Recruit
You could invoke that method from your own code, and point it to your own .xml file.

Aha, I take it from that there's a difference between invoking and injecting when it comes to code? I am pretty much ignorant of all that. I suppose I better learn, but I honestly don't know where to begin. Every resource I look at wants to start with 20 lessons of hello world and x + y, feels like I'd have to get most of the way through a CS career to answer the question, how do I invoke this method in my code to get it to load strings from my xmls when it initializes a new game.
 
Upvote 0
Aha, I take it from that there's a difference between invoking and injecting when it comes to code? I am pretty much ignorant of all that. I suppose I better learn, but I honestly don't know where to begin. Every resource I look at wants to start with 20 lessons of hello world and x + y, feels like I'd have to get most of the way through a CS career to answer the question, how do I invoke this method in my code to get it to load strings from my xmls when it initializes a new game.
http://www.blackwasp.co.uk/ReflectionInvokeMethods.aspx that's a straightforward and uncomplicated tutorial on how to invoke methods in your own code. Invoking that method is only part of it though. As mentioned earlier, you'll need to patch other parts of the game, depending on where/what conditions you want that string to show up. It's not going to be very intuitive without some coding experience unfortunately. But I hope that whenever the dev tools come out it'll be easy for any and everyone to do.
 
Upvote 0

DeathDaisy

Recruit
Aha, I take it from that there's a difference between invoking and injecting when it comes to code? I am pretty much ignorant of all that. I suppose I better learn, but I honestly don't know where to begin. Every resource I look at wants to start with 20 lessons of hello world and x + y, feels like I'd have to get most of the way through a CS career to answer the question, how do I invoke this method in my code to get it to load strings from my xmls when it initializes a new game.
Im like you in that I find the hello world stuff infinitely tedious and boring. I find experimenting more fun so I sort of learned programming the other way around, by reading code that I think does what I want and trying to figure out why it works. I say "sort of" tho because its mostly hackjobs for a long while until you get the hang of it. something to try at least if you got some evenings to spend ^^
 
Upvote 0

mr_mouflon

Recruit
Hey it wasn't even that hard in the end. This is all it took:

C#:
using TaleWorlds.Core;
using TaleWorlds.MountAndBlade;
using TaleWorlds.CampaignSystem;
using TaleWorlds.Library;

namespace UntestedMod
{
    public class MySubModule : MBSubModuleBase
    {
        protected override void OnGameStart(Game game, IGameStarter gameStarter)
        {
            if (game.GameType is Campaign && gameStarter is CampaignGameStarter campaignGameStarter)
            {
                campaignGameStarter.LoadGameTexts(BasePath.Name + "Modules/UntestedMod/ModuleData/untested_strings.xml");
            }
        }
    }
}

The same should work for any strings xml. Sweet success!
 
Upvote 0
Solution

Paige 404

Recruit
I wonder how loaded xml ties into the conditional logic on dialogue trees. I'll have to play around with it when I have time later.
 
Upvote 0
Top Bottom