#BGME Battle Themes - dynamic script generation with victory music tied to battle music

116 messages ยท Page 1 of 1 (latest)

green marshBOT
#

Based off this code it seems you can dynamically generate a script with a list of songs pulled from the config. is there a way to dynamically generate a script while tying battle music to victory music, or is it better to keep the individual config files and load those as needed like in RBT's current implementation?

@stark hollow hi hello :D if there is no way to do this then I can keep RBT as is but it is kinda painful having 5 million different PMEs to keep track of right now....

ryo
var normalSongsList = new List<string>();
if (config.Normal_Song1)
  normalSongsList.Add("SongNameUsedInScript");

// Do the same for other types of songs.

// Create script.
var script = $"
const normalSongs = [{string.Join(',', normalSongsList)}]\n

const BATTLE_THEME = random_song(normalSongs)
";

// Write script to a file.
var modDir = modLoader.GetDirectoryForModId(modConfig.ModId);
var outputFile = Path.Join(modDir, "output.theme.pme");
File.WriteAllText(outputFile, script);

// Add with API.
battleThemeApi.AddPath(modConfig.ModId, outputFile);

more or less what'd you need. You add each song name to a list of songs if the setting for it is enabled. In the script, you combine then insert them into the array of songs. Then write to a file and add that file to battle themes.

Jump

[Go to message!](#1340192878940524585 message)

red quest
#

I'd like to be able to dynamically write a battle themes script based on user config, but bc I have unique victory music, I wouldn't want to just do something like this implementation. this seems like I would just be doing a list of battle music and a list of victory music, so maybe I'd have the P2 battle theme and then it might choose the P4 victory theme

#

obviously I'd want P2 battle and victory music to go together, and P4 battle and victory music together

stark hollow
#

it kind of sounds like you're trying to merge all your battle themes into one single script

#

which you can, but do know it will make rbt count as a single battle theme. if someone adds another battle theme, all of rbt will only have 50% chance of playing, then 25% with another, etc

red quest
#

is that the case for lyn mix too?

#

hmm let's put it this way then... would it be possible to move the battle themes mainly to code? figured it would be easier to not have all those config files

stark hollow
stark hollow
red quest
#

I'm wondering if that might be better. currently I have 3 duplicates for the different victory music settings

stark hollow
#

this would really benefit from you explaining what you're hoping to do

#

what it is you're currently doing vs what'd you like for it to be

red quest
#

currently: I have a script for each theme + victory theme setting. there's 3 victory theme settings so 3 duplicates.

I wanted to move it entirely into the code in hopes of simplifying things a little bit. just less files and potentially simplifying it down so there are less duplicates

stark hollow
#

and what are those

red quest
#

wdym "those"

stark hollow
#

the victory settings

red quest
#
  • default base game victory (no change to victory theme)
  • source victory (P1/2 has continuous battle music)
  • alternate victory (P1/2 would have distinct victory themes similar to what P5R does for its DLC costumes)
stark hollow
#

is it a global setting?

red quest
#

yea

#

in code, it just loads the set of all enabled themes depending on what setting is set

stark hollow
#

then you just need to insert the appropriate victory music in the battle_victory_set

#

i think for default you can use -1

#

i'd probably make a function that takes in the source and alternate songs to use, have the function check the config setting, and return either of those or -1

red quest
#

alright. gonna have to look into making functions ๐Ÿ˜”

that reference code seems to still end up making a script file; is it necessary to have a dedicated script file generated regardless?

stark hollow
#

hm, no actually, you can add a script directly

#

i just forgor

red quest
#

how would you do that?

stark hollow
#

hm, no actually, you can't add a script directly

#

i just mispork

red quest
#

dang so I would end up needing the files after all

#

well I think this can still make things slightly less complicated

stark hollow
#

i mean you're saying you want to generate them at runtime, so files or not is kinda moot

red quest
#

true

#

if I could load them directly I'd also be ok with that but this is fine really

#

so function wise... I have an idea of how to do the actual logic but I'm trying to figure out how I should format the input (especially in the context of, it should be linked to a specific battle theme)

stark hollow
#

format the input?

red quest
#

yeah. you said make a function that takes in the source and alternate songs

red quest
#

i just ended up doing something like this... a little not very clean but oh well

        string VictoryMusic(string faithful, string looping)
        {
            if (config.VictoryConfig == Config.Victory.SourceVictoryTheme)
            {
                return faithful;
            }
            if (config.VictoryConfig == Config.Victory.AlternateVictoryTheme)
            {
                return looping;
            }
            else
            {
                return "-1";
            }
        }
red quest
#

it seems to play bgm id 1

stark hollow
#

yeh, that's right naostare

stark hollow
red quest
#

I was hoping to find a way to make a loop for it somehow

#

just so i wouldnt have to copy paste a ton

#

but it's ok

stark hollow
#

what's stopping you?

red quest
#

probably my lack of knowledge to be honest

stark hollow
red quest
#

me

#

here let me send what I've got so far and maybe it can be optimized further..

stark hollow
#

mood though, it's hard to know what can be simplified if you dont even know what tools are available

red quest
#
        if (config.N_P1_NormalBattle)
        {
            string battleThemeName = "P1_NormalBattle";
            var outputFile = Path.Join(modDir, $"battle-themes/options/{battleThemeName}.pme");
            File.WriteAllText(outputFile, $"const BATTLE_THEME = battle_victory_set({battleThemeName}, {VictoryMusic("P1_NormalBattle", "P1_NameEntry")})");
            battleThemeApi.AddPath(modConfig.ModId, outputFile);
        }

        if (config.N_P1_PSP_ALonePrayer)
        {
            string battleThemeName = "P1_PSP_ALonePrayer";
            var outputFile = Path.Join(modDir, $"battle-themes/options/{battleThemeName}.pme");
            File.WriteAllText(outputFile, $"const BATTLE_THEME = battle_victory_set({battleThemeName}, {VictoryMusic("P1_PSP_ALonePrayer", "P1_PSP_DreamofButterfly")})");
            battleThemeApi.AddPath(modConfig.ModId, outputFile);
        }
stark hollow
#

nani

#

syntax highlighting

red quest
#

yea

#

anyways, there's a few things here...

#

first: my config is named N_P1_Normal_Battle, N_P1_PSP_ALonePrayer, etc.
the N_ was there in case I wanted to look into adding advantage and disadvantage music later, but I'm not going to do that rn. but it would be nice to just have the string battleThemeName pull directly from the config name and remove the first two letters

#

second: the victory music is hardcoded. I wish I could tie it to the config option somehow

#

then theoretically I could do something like

foreach (var theme in themes)
{
    if (config.theme)
    {
        var outputFile = Path.Join(modDir, $"battle-themes/options/{theme}.pme");
        File.WriteAllText(outputFile, $"const BATTLE_THEME = battle_victory_set({theme}, {VictoryMusic({victory1}, {victory2})})");
        battleThemeApi.AddPath(modConfig.ModId, outputFile);
    }
}

rather than copying the above for each config option and changing the hardcoded values
maybe this code isn't perfect but hopefully it gets the point across

#

(any further simplications would be appreciated too haha)

stark hollow
#

to make it loopable, you can just create a model that holds the actual unique properties of a theme

#

battle theme name, the two victory music, and what enables it

#

then create a list of of each theme

#

and iterate over it

#
var config = new Config();

var themes = new BattleTheme[]
{
    new("P1_NormalBattle", "P1_NormalBattle", "P1_NameEntry", () => config.EnableTheme1),
    new("P1_NormalBattle", "P1_NormalBattle", "P1_NameEntry", () => config.EnableTheme1),
    new("P1_NormalBattle", "P1_NormalBattle", "P1_NameEntry", () => config.EnableTheme1),
};

foreach (var theme in themes)
{
    // Write to file and add path here.
}


record BattleTheme(string Name, string Victory1, string Victory2, Func<bool> IsEnabled);

class Config
{
    public bool EnableTheme1 { get; set; }
}
#

@red quest

stark hollow
red quest
#

is EnableTheme1 supposed to be each config setting?

red quest
red quest
#

don't know what i'm doing anything wrong but BattleTheme and record don't seem to want to register, and adding that class Config kinda breaks a lot of stuff lol

i'm struggling to understand what is happening with half of this code ngl </3 as you stated.... intelligent ๐Ÿ’–

stark hollow
#

the config class wasn't something for you to copy, just an object with a property as an example for the IsEnabled func naostare

red quest
#

i thought it was ๐Ÿ˜” that's one of the things that confused me a lot lol

stark hollow
red quest
#

it no work ๐Ÿ˜”

#

hang on lol

#

so my code is a bit of a mess right now so bear with that

  • it doesn't want to register record as anything but a variable that doesn't exist
  • what is BattleTheme supposed to be because second pic is the error I'm getting for that one
stark hollow
#

you know what a class is right?

#

like an object, with some properties and maybe functions

#

a record is just a class, that also forces the properties to be unchangable

#

like classes, you can't define it inside a function/constructor

red quest
#

i see - i did not know records were a thing lol

#

but knowing it's kinda like a class is helpful

#

ok we are cooking. this is gonna be long as shit though lol

#

ty

red quest
#

I think I might not really understand calling the different parts of theme or something; I was trying to use different strings to separate them out and then call them in my for loop, but when I try to load it, it only ever uses my victory1 no matter what my config setting is (I call them sourceVictory/alternateVictory respectively)

        string VictoryMusic(string Faithful, string Looping)
        {
            if (config.VictoryConfig == Config.Victory.SourceVictoryTheme)
            {
                return Faithful;
            }
            if (config.VictoryConfig == Config.Victory.AlternateVictoryTheme)
            {
                return Looping;
            }
            else
            {
                return "DISABLE_BGM";
            }
        }

        var themes = new BattleTheme[]
        {
            new("P1_NormalBattle", "P1_NormalBattle", "P1_NameEntry", () => config.N_P1_NormalBattle),
            new("P1_PSP_ALonePrayer", "P1_PSP_ALonePrayer", "p1_psp_DreamofButterfly", () => config.N_P1_PSP_ALonePrayer),
        };

        foreach (var theme in themes)
        {
            string battleTheme = theme.Name;
            string sourceVictory = theme.SourceVictory;
            string alternateVictory = theme.AlternateVictory;
            var outputFile = Path.Join(modDir, $"battle-themes/options/{battleTheme}.pme");
            File.WriteAllText(outputFile, $"const BATTLE_THEME = battle_victory_set({battleTheme}, {VictoryMusic(sourceVictory, alternateVictory)})");
            battleThemeApi.AddPath(modConfig.ModId, outputFile);
        }
#

like it does generate the file and it does mostly work, it just isn't taking my function into account...

#

hopefully the rest of it seems ok... took me longer than I would've liked to figure out those 3 strings bc I was thinking in python lists where it's like, oh yeah I should do theme[0], theme[1], etc...

red quest
#

I figured out why it wasn't taking my function into account - I was using the wrong config.VictoryConfig. fixed by doing

            string VictoryMusic(string Faithful, string Looping)
            {
                if (this.config.VictoryConfig == Config.Victory.SourceVictoryTheme)
                {
                    return Faithful;
                }
                if (this.config.VictoryConfig == Config.Victory.AlternateVictoryTheme)
                {
                    return Looping;
                }
                else
                {
                    return "DISABLE_BGM";
                }
            }
#

the last thing... I think that the foreach is loading PMEs even when their configs are deselected

red quest
#

I'm wondering if that just considers it always enabled with my current code

stark hollow
#
foreach (var theme in themes)
{
    string battleTheme = theme.Name;
    string sourceVictory = theme.SourceVictory;
    string alternateVictory = theme.AlternateVictory;
    var outputFile = Path.Join(modDir, $"battle-themes/options/{battleTheme}.pme");
    File.WriteAllText(outputFile, $"const BATTLE_THEME = battle_victory_set({battleTheme}, {VictoryMusic(sourceVictory, alternateVictory)})");
    battleThemeApi.AddPath(modConfig.ModId, outputFile);
}
#

you should add check on theme.IsEnabled, and skip with continue; if false

red quest
#

yea I should have updated with that bc I was trying to mess with that

#

the check I attempted to add was indeed theme.IsEnabled but it was throwing an error (let me open VS again to get said error)

#

which. what does this mean why can't this func<bool> be converted to a bool

stark hollow
#

it'd be theme.IsEnabled()

red quest
#

ahhh i see

#
            if (theme.IsEnabled());
            {
                battleThemeApi.AddPath(modConfig.ModId, outputFile);
            }

is there anything else to do here? because like... it still seems to be ignoring my config ๐Ÿ˜”

#

oh wait you did say to add continue

#

I need to go to bed soon ๐Ÿ’€

#

well i guess if it didn't satisfy that criteria it shouldn't have worked anyways regardless of if i added continue or not

anyways. i removed the extra semi colon from the if statement and added an else statement but otherwise it seems happy to ignore my config still...

            if (theme.IsEnabled())
            {
                battleThemeApi.AddPath(modConfig.ModId, outputFile);
            }
            else
            {
                continue;
            }
stark hollow
#

idk what you mean by ignoring your config

#

it literally can't ๐Ÿ˜ญ

red quest
#

it literally is ๐Ÿ˜”
I'm trying to just have it play one (1) song from the config by deselecting all the other ones but it's just playing all possible songs

#

it's like it's just loading all scripts regardless of config settings or something

red quest
#

i think i solved it and it was really stupid ๐Ÿ’€

#

I had a second instance of config being defined, and was using that when i should have been using this.config in that model instead