Page 1 of 1

Newbie modder, Really need some help with addme scripting

Posted: Sun May 10, 2020 4:39 pm
by GitFinda
Hello, So i've followed this tutorial ( http://www.gametoast.com/viewtopic.php? ... 96#p287596 ) in order to add my custom sides to the BF2 maps using the BF2 Modding Tools instead of just having them on my test map.

I'm pretty sure i've done everything well up until the part about addme scripting. In the OG tutorial linked above the step regarding addme scripting links to this tutorial (http://www.gametoast.com/viewtopic.php? ... 94#p281994) which i'm not really sure i understood.

I basically just went to the addme folder and filled in whatever i thought it meant i should, Yet after saving it and launching the game, While it didn't crash, It simply didn't load up my sides. I'm not sure what i'm doing wrong exactly. Maybe you guys can show me a filled in addme script so i'll get the idea of how i should do it? If you need me to add more info just let me know.

Are there any videos following this tutorial? I honestly have a MUCH easier time understanding a visual guide instead of a written one

Thanks in advance

Re: Newbie modder, Really need some help with addme scripting

Posted: Mon May 11, 2020 2:40 am
by Anakin
Welcome to GT, how about sharing your addme and we'll have a look at it. Not sure if there is a video tutorial about addme files. For some stuff such as map modding, 3d modeling, custom loadscreens, etc there are video tutorials.

Re: Newbie modder, Really need some help with addme scripting

Posted: Mon May 11, 2020 7:16 am
by GitFinda
Anakin wrote:
Mon May 11, 2020 2:40 am
Welcome to GT, how about sharing your addme and we'll have a look at it. Not sure if there is a video tutorial about addme files. For some stuff such as map modding, 3d modeling, custom loadscreens, etc there are video tutorials.
Thanks! and here you go btw "a" is the name i chose for my era just to more closely follow the tutorial
Hidden/Spoiler:
--Search through the missionlist to find a map that matches mapName,
--then insert the new flags into said entry.
--Use this when you know the map already exists, but this content patch is just
--adding new gamemodes (otherwise you should just add whole new entries to the missionlist)
function AddNewGameModes(missionList,myg1, newFlags)
for i, mission in missionList do
if mission.myg1a_con == myg then
for flag, value in pairs(newFlags) do
mission[flag] = value
end
end
end
end




--insert totally new maps here:
local sp_n = 1
local mp_n = 1
sp_n = table.getn(sp_missionselect_listbox_contents)

--add my modes to the singleplayer map selection screen

AddNewGameModes( sp_missionselect_listbox_contents, "myg1a_con", {era_a = 1, mode_con_c = 1,} )

AddNewGameModes( mp_missionselect_listbox_contents, "myg1a_con", {era_a = 1, mode_con_c = 1,} )

-- associate this mission name with the current downloadable content directory
-- (this tells the engine which maps are downloaded, so you need to include all new mission lua's here)
-- first arg: mapluafile from above
-- second arg: mission script name
-- third arg: level memory modifier. the arg to LuaScript.cpp: DEFAULT_MODEL_MEMORY_PLUS(x)

AddDownloadableContent("myg1","myg1a_con",4)

-- all done
newEntry = a
n = a

-- Now load our core.lvl into the shell to add our localize keys
ReadDataFile("Star Wars - Battlefront 2\\GameData\\addon\\PAM\\data\\_LVL_PC\\core.lvl")

Re: Newbie modder, Really need some help with addme scripting

Posted: Mon May 11, 2020 11:48 am
by Anakin
ok, you need the addme script that is introdcued by uop1.3


further you changed the variable name. This function does not work after you changed mapName to myg1. Do not change any of the functions. Only add function calls after --insert totally new maps here:

Code: Select all

function AddNewGameModes(missionList,myg1, newFlags)
try this script:

Code: Select all


-- recursively merges the second given table into the first given table
function MergeTables( mission, newFlags )
   --for each table entry,
   local array = type({})
   for key,value in pairs(newFlags) do      
      --check for nested tables
      if type(value) == array then
         --mission must have this key as a table too
         if type(mission[key]) ~= array then
            mission[key] = {}
         end
         --merge these two tables recursively
         MergeTables(mission[key], value)
      else
         --the key is a simple variable, so simply store it
         mission[key] = value
      end
   end
end

--Search through the missionlist to find a map that matches mapName,
--then insert the new flags into said entry.
--Use this when you know the map already exists, but this content patch is just
--adding new gamemodes (otherwise you should just add whole new entries to the missionlist)
function AddNewGameModes(missionList, mapName, newFlags)
   for i, mission in missionList do
      if mission.mapluafile == mapName then
         MergeTables(mission, newFlags)
      end
   end
end




--insert totally new maps here:
local sp_n = 1
local mp_n = 1
sp_n = table.getn(sp_missionselect_listbox_contents)

--add my modes to the singleplayer map selection screen

AddNewGameModes( sp_missionselect_listbox_contents, "myg1a_con", {era_a = 1, mode_con_c = 1,} )
AddNewGameModes( mp_missionselect_listbox_contents, "myg1a_con", {era_a = 1, mode_con_c = 1,} )

-- associate this mission name with the current downloadable content directory
-- (this tells the engine which maps are downloaded, so you need to include all new mission lua's here)
-- first arg: mapluafile from above
-- second arg: mission script name
-- third arg: level memory modifier. the arg to LuaScript.cpp: DEFAULT_MODEL_MEMORY_PLUS(x)

AddDownloadableContent("myg1","myg1a_con",4)

-- all done
newEntry = a
n = a

-- Now load our core.lvl into the shell to add our localize keys
ReadDataFile("Star Wars - Battlefront 2\\GameData\\addon\\PAM\\data\\_LVL_PC\\core.lvl")


Re: Newbie modder, Really need some help with addme scripting

Posted: Mon May 11, 2020 4:55 pm
by GitFinda
Anakin wrote:
Mon May 11, 2020 11:48 am
ok, you need the addme script that is introdcued by uop1.3


further you changed the variable name. This function does not work after you changed mapName to myg1. Do not change any of the functions. Only add function calls after --insert totally new maps here:

Code: Select all

function AddNewGameModes(missionList,myg1, newFlags)
try this script:

Code: Select all


-- recursively merges the second given table into the first given table
function MergeTables( mission, newFlags )
   --for each table entry,
   local array = type({})
   for key,value in pairs(newFlags) do      
      --check for nested tables
      if type(value) == array then
         --mission must have this key as a table too
         if type(mission[key]) ~= array then
            mission[key] = {}
         end
         --merge these two tables recursively
         MergeTables(mission[key], value)
      else
         --the key is a simple variable, so simply store it
         mission[key] = value
      end
   end
end

--Search through the missionlist to find a map that matches mapName,
--then insert the new flags into said entry.
--Use this when you know the map already exists, but this content patch is just
--adding new gamemodes (otherwise you should just add whole new entries to the missionlist)
function AddNewGameModes(missionList, mapName, newFlags)
   for i, mission in missionList do
      if mission.mapluafile == mapName then
         MergeTables(mission, newFlags)
      end
   end
end




--insert totally new maps here:
local sp_n = 1
local mp_n = 1
sp_n = table.getn(sp_missionselect_listbox_contents)

--add my modes to the singleplayer map selection screen

AddNewGameModes( sp_missionselect_listbox_contents, "myg1a_con", {era_a = 1, mode_con_c = 1,} )
AddNewGameModes( mp_missionselect_listbox_contents, "myg1a_con", {era_a = 1, mode_con_c = 1,} )

-- associate this mission name with the current downloadable content directory
-- (this tells the engine which maps are downloaded, so you need to include all new mission lua's here)
-- first arg: mapluafile from above
-- second arg: mission script name
-- third arg: level memory modifier. the arg to LuaScript.cpp: DEFAULT_MODEL_MEMORY_PLUS(x)

AddDownloadableContent("myg1","myg1a_con",4)

-- all done
newEntry = a
n = a

-- Now load our core.lvl into the shell to add our localize keys
ReadDataFile("Star Wars - Battlefront 2\\GameData\\addon\\PAM\\data\\_LVL_PC\\core.lvl")

Ah i see. And yeah i'll try this out when i get home. Thank you!

EDIT: Alright so i tried it out yet my side still doesn't show. I'll try starting the tutorial from scratch, Maybe i messed something up along the way

EDIT2
So i tried again and still no success. I must be missing something but i'm really clueless as to what. I'll try digging on youtube to see if maybe somebody has made a video on this

I still really do appreciate the help though

Re: Newbie modder, Really need some help with addme scripting

Posted: Wed May 13, 2020 8:54 am
by Sporadia
First thing to check, most modders work with Zerted's 1.3 patch installed. It's the mod that adds support for era_a, era_b etc so you need it installed for the method you're trying. Do you have it?

This is what a normal addme does: Adds your new maps, gametypes and eras to the mission select screen of instant action. Replaces stock missions (eg. cor1g_con) with ones that you have modded (this affects galactic conquest too). If desired, adds your missions to the multiplayer mission select screen too. Allows you to change the name and icon of any modded era or gametype (maybe the map too, but I've never done it). Then there's an extra line that loads all the mod's localization keys at the end.

If your modded mission shows up with all the right names/icons, and you don't get something like a 'mission can't be found' message when you launch, then the work of the addme is done. Any issues with how the mission works after it's loaded has nothing to do with the addme. If you're confident that you're loading the modded mission but there are a few units missing or it crashes because a whole side is missing etc then the problem is probably in how the side is munged, or the contents of the mission lua, or the actual side folder, not the addme. If you can't get your modded mission/era to show up and load in the first place, that's the addme. (Or I guess if you've set up localization correctly but all of your character/gun names are still missing, that could be a problem with the addme too but that's a very rare mistake). I'm pointing this out because I don't know what you mean by your 'side is missing.' Is the modded mission loading then, just missing a side? That's not the addme's problem.

If you're making changes to a stock mission, but none of the changes are taking effect: It can sometimes be difficult to tell whether you're loading a modded version of a stock mission or if the game's still loading the old stock lua/mission. There's an easy way to test this if you know how to use the debug tools, BF2_modtools.exe (or BF2_modtools_NoDVD.exe for steam). Open the mission lua and add the line print("This is a modded mission") into the beginning of ScriptInit(). Now when you load the mission with the debug tools, you will see 'This is a modded mission' appears in the debug log (BFront2.txt). If this line is missing, you're probably not loading the modded version of the mission so look for a problem with the addme. If the line does appear, then you definitely are loading the modded version of the mission and can be sure there's no problem with the addme (so look for the problem elsewhere).


LUA in the addme

First thing that goes in the addme is a function that adds new entries to the game's table of missions. There are a few versions of this (some better at certain tasks than others), I like to use the one from Zerted's example docs because it's guaranteed to be compatible with everything the 1.3 patch supports, including era mods:

Code: Select all

-- first two functions by gametoast user [RDH]Zerted
-- recursively merges the second given table into the first given table
function MergeTables( mission, newFlags )
   -- for each table entry,
   local array = type({})
   for key,value in pairs(newFlags) do      
      -- check for nested tables
      if type(value) == array then
         -- mission must have this key as a table too
         if type(mission[key]) ~= array then
            mission[key] = {}
         end
         -- merge these two tables recursively
         MergeTables(mission[key], value)
      else
         -- the key is a simple variable, so simply store it
         mission[key] = value
      end
   end
end

-- Search through the missionlist to find a map that matches mapName,
-- then insert the new flags into said entry.
-- Use this when you know the map already exists, but this content patch is just
-- adding new gamemodes (otherwise you should just add whole new entries to the missionlist)
function AddNewGameModes(missionList, mapName, newFlags)
   for i, mission in missionList do
      if mission.mapluafile == mapName then
         MergeTables(mission, newFlags)
      end
   end
end
You don't need to change these functions, just copy/paste them at the start of every addme.



Next you use the AddNewGameModes() function (defined at the beginning of the addme) to add every mission that you're modding in. A typical exception is your actual test world ie. ABC, because you'd normally add that a different way (not that it matters). But certainly any mission that you're taking seriously (and any stock mission that you're changing) should be added with AddNewGameModes(). This only half-adds them (gets them onto the mission select screen). You'll need an AddDownloadableContent() section to finish the job.

It's easier to explain how to do it with an example:

Code: Select all

AddNewGameModes(sp_missionselect_listbox_contents, "tat2%s_%s", {era_g = 1, mode_eli_g = 1, mode_con_g = 1})
The line above replaces the GCW conquest and the hero assualt on Mos Eisley with versions from my mod. It's only changing the singleplayer mission select screen because it contains sp_missionselect_listbox_contents. If you only wanted to make changes on multiplayer you'd use mp_missionselect_listbox_contents. If you want to make changes on both you can write the line twice (once of sp and once for mp). Mos Eisley is the map 'tat2', so to add mods on Mos Eisley you put "tat2%s_%s" second.

Third, you specify any era or gametypes which you are modding on that world. You put all of these inside { } as seen above. The code for hero assault is 'eli' and it's a GCW mission (era_g) so that's where mode_eli_g = 1 has come from. Similarly mode_con_g = 1 adds a GCW conquest mission, mode_ctf_c = 1 would add a CW 2flag ctf mission and so on.

But there's something else in this bit too, era_g = 1. I need this because I'm adding/changing missions in the GCW era. Without era_g = 1, none of the modded GCW missions will be added to this map (even though there's code like mode_eli_g = 1, they'll just be ignored). A more complex example, adding CW missions and GCW missions:

Code: Select all

AddNewGameModes(sp_missionselect_listbox_contents, "tat2%s_%s", {era_c = 1, era_g = 1, mode_1flag_c = 1, mode_con_c = 1, mode_ctf_c = 1, mode_eli_g = 1, mode_con_g = 1})
If I forgot era_g = 1, then only the CW missions would be added. If I forgot era_c = 1, only the GCW missions would be added. The example above adds the following to Mos Eisley:
Hidden/Spoiler:
* CW 1flag ctf
* CW conquest
* CW 2flag ctf
* GCW hero assault
* GCW conquest
(Pretend these * are bullet points)
And here's an example for missions added to several maps, some with a new era (era_a), same ideas apply:

Code: Select all

AddNewGameModes(sp_missionselect_listbox_contents, "dea1%s_%s", {era_a = 1, mode_con_a = 1})
AddNewGameModes(sp_missionselect_listbox_contents, "geo1%s_%s", {era_c = 1, mode_c_c = 1, mode_con_c = 1, mode_ctf_c = 1, mode_xl_c = 1})
AddNewGameModes(sp_missionselect_listbox_contents, "tat2%s_%s", {era_g = 1, mode_eli_g = 1, mode_con_g = 1})
AddNewGameModes(sp_missionselect_listbox_contents, "tat3%s_%s", {era_a = 1, era_c = 1, era_g = 1, mode_1flag_a = 1, mode_con_a = 1, mode_eli_c = 1, mode_con_g = 1})


Next thing in the addme is code to add your test world. I always add this the "old way," no reason why. This method is no good for changing mission names or replacing stock missions. But I guess it's worth seeing. If you eventually don't want your test world to appear on the mission select screen, just omit this code.

The old way of adding the test world missions to singeplayer:

Code: Select all

local sp_n = 0
sp_n = table.getn(sp_missionselect_listbox_contents)
sp_missionselect_listbox_contents[sp_n+1] = { isModLevel = 1, mapluafile = "ABC%s_%s", era_g = 1, era_c = 1, mode_con_g = 1, mode_con_c  = 1,}
The old way of adding the test world missions to multiplayer(just replaced 'sp' with 'mp'):

Code: Select all

local mp_n = 0
mp_n = table.getn(mp_missionselect_listbox_contents)
mp_missionselect_listbox_contents[mp_n+1] = { isModLevel = 1, mapluafile = "ABC%s_%s", era_g = 1, era_c = 1, mode_con_g = 1, mode_con_c  = 1,}
If you want, you can put this before the list of AddNewGameModes() commands rather than the end. Then you can use this code to add the test world missions to both sp and mp (slightly smarter):

Code: Select all

local sp_n = 0
local mp_n = 0
sp_n = table.getn(sp_missionselect_listbox_contents)
sp_missionselect_listbox_contents[sp_n+1] = { isModLevel = 1, mapluafile = "ABC%s_%s", era_g = 1, era_c = 1, mode_con_g = 1, mode_con_c  = 1,}
mp_n = table.getn(mp_missionselect_listbox_contents)
mp_missionselect_listbox_contents[mp_n+1] = sp_missionselect_listbox_contents[sp_n+1]


Next in the addme, you'll need some more code to properly add all the missions you've listed. Otherwise you'll have a load of entries in the mission select which don't actually launch anything. This is what AddDownloadableContent() is for. Let's say you've listed these missions in the AddNewGameModes() section:
  • Death Star era_a conquest
  • Mos Eisley GCW Hero Assault
  • Mos Eisley GCW Conquest
  • Coruscant era_a Conquest
  • Coruscant era_b Conquest
  • Coruscant era_b 2flag CTF
  • Coruscant GCW Hero Assault
Then this is the code you use to add those missions. (You always put a '4' at the end of AddDownloadableContent(), I don't know why but I know that it needs to be there):

Code: Select all

AddDownloadableContent("dea1", "dea1a_con", 4)
AddDownloadableContent("tat2", "tat2g_eli", 4)
AddDownloadableContent("tat2", "tat2g_con", 4)
AddDownloadableContent("cor1", "cor1a_con", 4)
AddDownloadableContent("cor1", "cor1b_con", 4)
AddDownloadableContent("cor1", "cor1b_ctf", 4)
AddDownloadableContent("cor1", "cor1g_eli", 4)
It's absolutely crucial that you always add your test world here. You need this for everything to work/munge correctly. Even if you don't want your test world in your mod, only remove the code which adds it to mission select screens (explained earlier). Don't remove these lines.

Code: Select all

AddDownloadableContent("ABC","ABCg_con",4)
AddDownloadableContent("ABC","ABCc_con",4)


Finally, here's how every addme ends, the last line loads the mod's localization (the modded unit, weapon, vehicle names that you set with the editlocalize tool):

Code: Select all

-- all done
newEntry = nil
n = nil

-- Now load our core.lvl into the shell to add our localize keys
ReadDataFile("..\\..\\addon\\ABC\\data\\_LVL_PC\\core.lvl")


How to change the name and icon of an era or gametype

I've just skipped over this but if you want to change the name of anything, then you do this inside the AddNewGameModes() commands.
So let's say you've started with this:

Code: Select all

AddNewGameModes(sp_missionselect_listbox_contents, "cor1%s_%s", {era_a = 1, mode_jhu_a = 1})
This adds 1 mission to Coruscant: A mission of gametype 'jhu' for era a. ('jhu' isn't a vanilla gametype like how 'con' is code for conquest, but it is supported by Zerted's 1.3 patch. era_a obviously isn't a vanilla era either, but it is supported by the 1.3 patch. Without that mod, you can't use custom eras or create custom gametypes.) When you're changing names and things, it might be easier to lay the line out like this:

Code: Select all

AddNewGameModes(sp_missionselect_listbox_contents, "cor1%s_%s", {
	era_a = 1,
	mode_jhu_a = 1
})
That was the same code (above), just presented differently (another recommendation from Zerted's docs). It makes everything clearer when you add the code to change the names (below):

Code: Select all

AddNewGameModes(sp_missionselect_listbox_contents, "cor1%s_%s", {
	era_a = 1,
	mode_jhu_a = 1,
	change = {
		era_a = {name = "Old Republic", icon2 = "kotor_icon"},
		mode_jhu = {name = "Jedi Training", about = "A Jedi training mission.", icon = "mode_icon_ord66"},
	},
})
The new code is everything inside change = { }. It changes the names and icons on each map independently, so to have a full era mod that spans multiple maps, you might end up typing out the same code a lot:

Code: Select all

AddNewGameModes(sp_missionselect_listbox_contents, "cor1%s_%s", {
	era_a = 1,
	mode_jhu_a = 1,
	change = {
		era_a = {name = "Old Republic", icon2 = "kotor_icon"},
		mode_jhu = {name = "Jedi Training", about = "A Jedi training mission.", icon = "mode_icon_ord66"},
	},
})
AddNewGameModes(sp_missionselect_listbox_contents, "dag1%s_%s", {
	era_a = 1,
	mode_jhu_a = 1,
	change = {
		era_a = {name = "Old Republic", icon2 = "kotor_icon"},
		mode_jhu = {name = "Jedi Training", about = "A Jedi training mission.", icon = "mode_icon_ord66"},
	},
})
But that's how it's done.

The icons referenced above are actually images taken from the 1.3 patch. So you can use all of these if you want, but they're either made by Zerted or someone else who worked on the mod:
Hidden/Spoiler:
Added era icon: bfx_cw_icon.tga
Added era icon: bfx_gcw_icon.tga
Added era icon: newsithwars_icon.tga
Added era icon: earth_icon.tga
Added era icon: front_icon.tga
Added era icon: halo_icon.tga
Added era icon: i_icon.tga
Added era icon: j_icon.tga
Added era icon: kotor_icon.tga
Added era icon: lego_icon.tga
Added era icon: newrep_icon.tga
Added era icon: oldsith_icon.tga
Added era icon: rvb_icon.tga
Added era icon: rebirth_icon.tga
Added era icon: toys_icon.tga
Added era icon: u_icon.tga
Added era icon: v_icon.tga
Added era icon: wacky_icon.tga
Added era icon: exGCW_icon.tga
Added era icon: yuz_icon.tga
Added era icon: z_icon.tga
Added mode icon: mode_icon_ins.tga
Added mode icon: mode_icon_c4.tga
Added mode icon: mode_icon_c3.tga
Added mode icon: mode_icon_c2.tga
Added mode icon: mode_icon_c1.tga
Added mode icon: mode_icon_avh.tga
Added mode icon: mode_icon_wav.tga
Added mode icon: mode_icon_survival.tga
Added mode icon: mode_icon_rpg.tga
Added mode icon: mode_icon_siege.tga
Added mode icon: mode_icon_vehicle.tga
Added mode icon: mode_icon_space.tga
Added mode icon: mode_icon_wea.tga
Added mode icon: mode_icon_jhu.tga
Added mode icon: mode_icon_tdf.tga
Added mode icon: mode_icon_hctf.tga
Added mode icon: mode_icon_race.tga
Added mode icon: mode_icon_koh.tga
Added mode icon: mode_icon_control.tga
Added mode icon: mode_icon_bf1.tga
Added mode icon: mode_icon_tdm.tga
Added mode icon: mode_icon_uber.tga
Added mode icon: mode_icon_vh.tga
Added mode icon: mode_icon_xtra.tga
Added mode icon: mode_icon_obj.tga
Added mode icon: mode_icon_dm.tga
Added mode icon: mode_icon_holo.tga
Added mode icon: mode_icon_ord66.tga
Added mode icon: mode_icon_lms.tga
Added mode icon: mode_icon_c.tga
Changed mode icon: mode_icon_XL.tga
Changed mode icon: mode_icon_eli.tga

Those are the icons listed in the 1.3 patch's changelogs. You can definitely add your own icons too but I can't remember how at the moment. There's probably a tutorial on another thread.

Edit: I didn't realise that you use 'icon2' to add era icons instead of 'icon'. Corrected it now.

Re: Newbie modder, Really need some help with addme scripting

Posted: Wed May 13, 2020 3:35 pm
by Benoz
To add custom icons you do the following:

► create a custom icon that has a square resolution
► create the folder textures in BF2_ModTools\data_ABC\Shell and save your custom icon there
► open up the shell.req and add your icon under "texture"
► add the following code into your addme.lua after function AddNewGameModes

Code: Select all

ReadDataFile("..\\..\\addon\\ABC\\data\\_LVL_PC\\shell.lvl")
Last thing you need to do is assign the custom icon to your era/mode. If it's an era, add the following to your addme:

Code: Select all

AddNewGameModes( sp_missionselect_listbox_contents, "ABC%s_%s", {
		era_c = 1, 
		mode_con_c = 1,
		change = {
			era_c = { icon2="custom_era_icon" },
		}
	} 
)
If it's the mode icon you want to change add this piece of code:

Code: Select all

AddNewGameModes( sp_missionselect_listbox_contents, "ABC%s_%s", {
		era_c = 1, 
		mode_con_c = 1,
		change = {
			mode_con = { icon="custom_mode_icon" },
		}
	} 
)