Payload Logo
warsaw-posts

Getting Started with BF4 WR Modding

Author

DesertShadow

Date Published

f35-sun

Prerequisites:

  • EA App (For BF4 verification)
  • Battlefield 4
  • Warsaw Revamped Account

1.) Open EA App and login.

This is for when WR-Launcher asks for first-time verification.

2.) Download and Install the Warsaw Revamped Launcher.

Login to https://warsaw.gg/ and download the launcher. Microsoft Smartscreen will block WR-Launcher. Click more more info and run anyway. In WR-Launcher click Sign In and use your Warsaw Revamped account to login thru the browser. Go back your Warsaw Launcher follow the instructions for verifying BF4.

3.) Configuring your server

Click on the Server Icon. Create a new Template.

In the template overview enable Official WR Experience Mod and Enable Workspace

Now click on the Start button to run your server.

Go to the server browser.

Click on the Play button for your Server.

Click on Soldier in the new dropdown.

Should be able to join your own server.

Go to your Documents/Warsaw Revamped/Servers/YourTemplateName/Admin folder.

Create any missing files:

Engine.txt

A few engine tweaks, like no preround, more TBA.

1Game.DisablePreRound 1
2Server.OutgoingHighFrequency 60

Startup.txt

This controls your server name in the listing, the RCON admin server. More TBA.

1admin.password "YOUR_PASSWORD_HERE"
2vars.serverName "YOUR_SEVER_NAME_HERE"
3vars.serverType "unranked"

Maplist.txt

The first entry here controls first map you load into. All mapcodes/gamemodes TBA.

1MP_Playground TutorialMP 1
2MP_Siege ConquestLarge0 1
3MP_Naval ConquestLarge0 2
4MP_Journey SquadDeathMatch0 2
5MP_Prison SquadDeathMatch0 2
6MP_Prison ConquestSmall0 2
7MP_Journey ConquestSmall0 2
8MP_Prison ConquestLarge0 2
9MP_Journey ConquestLarge0 2
10XP6_CMP ConquestLarge0 2
11MP_Naval ConquestLarge0 2
12MP_Naval SquadDeathMatch0 2
13XP0_Firestorm ConquestLarge0 2
14MP_Journey TeamDeathMatch0 2
15MP_Prison TeamDeathMatch0 2
16XP2_002 ConquestLarge0 2
17MP_Flooded TeamDeathMatch0 2
18MP_Siege ConquestSmall0 2
19MP_Prison GunMaster0 2
20MP_Siege SquadDeathMatch0 2
21MP_Abandoned Domination0 2
22MP_Flooded ConquestLarge0 2
23MP_Siege TeamDeathMatch0 2

4.) IDE setup

Download and install VSCode from

Open VSCode and press CTRL + Shift + X to open extensions menu.

Type luau and click the one by JohnnyMoganz. Install this extension.

Inside of ..Documents/Warsaw Revamped/Mods

(Create Mods folder if it doesn't exist yet)

Create the folder wr_official

Inside of wr_official create the folder .vscode

Inside of .vscode create the file settings.json

Paste in the following to the file:

1{
2 "luau-lsp.completion.autocompleteEnd": true,
3 "luau-lsp.completion.imports.requireStyle": "alwaysRelative",
4 "luau-lsp.require.directoryAliases": {
5 ".": "C:\\Users\\YOUR_USER_HERE\\Documents\\Warsaw Revamped\\Package Cache"
6 },
7 "luau-lsp.require.mode": "relativeToFile",
8 "luau-lsp.types.definitionFiles": [
9 "C:\\Users\\YOUR_USER_HERE\\Documents\\Warsaw Revamped\\Mod Toolkit\\API Definitions\\wr-core.d.luau",
10 "C:\\Users\\YOUR_USER_HERE\\Documents\\Warsaw Revamped\\Mod Toolkit\\API Definitions\\wr-gen.d.luau",
11 "C:\\Users\\YOUR_USER_HERE\\Documents\\Warsaw Revamped\\Mod Toolkit\\API Definitions\\wr-managers.d.luau"
12 ],
13 "luau-lsp.platform.type": "standard",
14 "luau-lsp.inlayHints.functionReturnTypes": true,
15 "luau-lsp.inlayHints.parameterNames": "all",
16 "luau-lsp.inlayHints.parameterTypes": true,
17 "luau-lsp.inlayHints.variableTypes": true
18}

In your .vscode/settings.json, update YOUR_USER_HERE with the username of your computer.

Double click on YOUR_USER_HERE and press CTRL + H to activate Find and Replace.

In lower box type your Windows User Name. Press CTRL + ALT + ENTER to replace all.

5.) Version control setup (OPTIONAL)

If you don't want version control, skip to section 6.

Instructions if you are okay with Github:

Create a Github Account at https://github.com

Download and install Github Desktop from https://desktop.github.com/download/

Complete the 2 minute tutorial to get the basics.

In Github Desktop, click on add existing repository and navigate to your wr_official folder.

It might prompt you to make a new repository, just follow the instructions.

6.) Modding Overview (file structure etc)

Each mod requires 3 files.

wr-config.toml

this file tells WR info about your mod

preinit.luau

this is the first file which executes. It has some niche use cases, such as setting up an reporting handler

init.luau

this is the entry point for your mod logic. Everything starts from here.

Pre-init phase is before a map has been loaded, essentially on startup. You can modify static datacontainers that don't change here, but some stuff will be restricted here because it's not initialized yet.

Init phase only exists while a map is loaded. Scripts are always reloaded between rounds.

To visualize it, you'll have pre-init -> map load -> init -> map load -> init -> map load -> init

7.) Creating and running a mod

Go to your Documents/Warsaw Revamped/Package Cache and extract the partitions zip folder. Rename the extracted folder to just partitions. Leave the zip on in there.

Go to the website

If Powback's EBX site is not loading anything for you (folder with no name), **clear your session / localstorage for the site** and refresh.

At the top left switch from Venice to Warsaw and hit refresh (f5).

Double Click on the warsaw folder

Click on Gameplay folder dropdown

Click on Weapons folder dropdown

Click on AK12 folder dropdown

Click on AK12.json file

In the middle section you will now see a SoldierWeaponBlueprint

This is where you can get the Partition and Instance GUIDs.

If an instance GUID is full of Zero's like this: 0000-0000-0000-0005 it is **invalid** and you must pick something higher up and drill down to whatever datacontainer you are trying to change.

Don't worry about copying them, the example code has everything already.

Inside of Documents/Warsaw Revamped/Mods/wr_official

Create the file wr-config.toml with content:

1[script]
2name = "wr_official"
3version = "0.1.0"
4author_ids = ["yourName"]
5description = "yourDescription"
6repository = "https://anyTextButShouldBeLinkToYourRepository"
7tags = ["official", "wr"]
8
9[dependencies]
10partitions = "0.1.0"

Create the file preinit.luau with content:

1--!strict
2
3local partitions = require("./partitions")
4
5print("PreInitializing of Mod")
6
7return nil

Create the file init.luau with content:

1--!strict
2
3require("Weapons/AK12")
4
5return nil

Create a folder called Weapons.

Inside of Weapons, create a file called AK12.luau

1--!strict
2local partitions = require("./partitions")
3
4local AK12 = {}
5
6print("Hello World!")
7
8local AK12SoldierWeaponBlueprint = {
9 partitionGuid = Guid("AE353FA9-58C8-41F0-B6FF-2E65C28D2D4A"),
10 instanceGuid = Guid("286A045F-C526-4339-A0F5-5FA5FB681D20")
11}
12
13function AK12:OnWeaponBlueprintLoad(p_SoldierWeaponBlueprint: SoldierWeaponBlueprint)
14 print("***** Found AK12 Blueprint!!!")
15 local s_SoldierWeaponData = p_SoldierWeaponBlueprint.object :: SoldierWeaponData
16 local s_WeaponFiringData = s_SoldierWeaponData.weaponFiring
17 local s_FiringFunctionData = s_WeaponFiringData.primaryFire
18 local s_Shot = s_FiringFunctionData.shot
19 s_Shot.initialSpeed.z = 50
20end
21
22partitions.onInstanceLoad(
23 AK12SoldierWeaponBlueprint.partitionGuid,
24 AK12SoldierWeaponBlueprint.instanceGuid,
25 AK12,
26 AK12.OnWeaponBlueprintLoad
27)
28
29return nil

For the function parameter we are annotating the p_SoldierWeaponBlueprint with type SoldierWeaponBlueprint (you can see the type in the EBX page).

After the print statement we are casting the p_SoldierWeaponBlueprint.object to SoldierWeaponData (you can see the type in the EBX page).

This allows us to see the fields in vscode, and it warns you when accessing a field that doesn't exist.

You should see Hello World! in the server log.

You will not see Found AK12 Blueprint!!! until you equip an AK12.

In BF4 things are only loaded when they are needed.

This also means if you switch from AK12 to something else, and nobody else has AK12, the changes are destroyed.

When you switch back from something else, to the AK12, you will see Found AK12 Blueprint!!! again and again.

This heavily complicates modding, because you have to make sure the things you are using are all loaded, and will continue to be loaded.

Sidenote: The prefixes before variable names are optional. I just have them to keep track of parameters and variables defined inside of functions.

8.) Example of modding not working.

Make the contents of Weapons/AK12.luau:

1--!strict
2
3local partitions = require("./partitions")
4
5local AK12 = {}
6
7local AK12SoldierWeaponBlueprint = {
8 partitionGuid = Guid("AE353FA9-58C8-41F0-B6FF-2E65C28D2D4A"),
9 instanceGuid = Guid("286A045F-C526-4339-A0F5-5FA5FB681D20")
10}
11
12local SmawProjectile = {
13 partitionGuid = Guid("168F529B-17F6-11E0-8CD8-85483A75A7C5"),
14 instanceGuid = Guid("90BAEBC0-C9E6-CB0B-7531-110499218677")
15}
16
17function AK12:OnEverythingLoaded(p_SoldierWeaponBlueprint: SoldierWeaponBlueprint, p_SmawProjectileBlueprint: ProjectileBlueprint)
18 print("Making AK12 fire SMAW projectiles")
19 local s_SoldierWeaponData = p_SoldierWeaponBlueprint.object :: SoldierWeaponData
20 local s_WeaponFiringData = s_SoldierWeaponData.weaponFiring
21 local s_FiringFunctionData = s_WeaponFiringData.primaryFire
22
23 local s_Shot = s_FiringFunctionData.shot
24 s_Shot.projectile = p_SmawProjectileBlueprint
25 s_Shot.projectileData = p_SmawProjectileBlueprint.object :: MissileEntityData
26end
27
28partitions.onAllInstancesLoaded(AK12, AK12.OnEverythingLoaded,
29 {
30 partition = AK12SoldierWeaponBlueprint.partitionGuid,
31 instance = AK12SoldierWeaponBlueprint.instanceGuid
32 },
33 {
34 partition = SmawProjectile.partitionGuid,
35 instance = SmawProjectile.instanceGuid
36 }
37)
38
39return nil

With this code we are attempting to take the SMAW's projectile and put it onto the AK12.

You have to spawn with AK12. Redeploy. Spawn with SMAW. Redeploy. Spawn with AK12 again and shoot quickly.

AK12 will shoot SMAW rockets for a second or two until the SMAW is cleaned up from map (because nobody has smaw).

Then your client will crash. :D:D:D:D

This problem is being worked on atm.

9.) How and where to deploy/distribute mods?

TBA. There will be a modding platfrom eventually. For now just your stuff onto github and share it in the discord.

10.) How to find and use other people's mods?

Check the WR discord for mod announcements

11.) How to join someone running a custom mod?

Host and whover joins must have the same exact mod in their Mods folder, with workspace enabled and Official WR enabled. We are working on a better solution.

12.) Resources

Lua compiler online. You can run whatever lua code to learn lua.

Powback's EBX viewer. An essential tool for BF3/BF4 modders.

Flashhit's EBX Dump. Can search EBX locally with this.

Sample WR_Mod. An easy drag+drop to start modding without manually making above files.

WR_Mods. Some example mods.

13.) Useful Extensions

StyLua by JohnnyMoganz. Formatter for lua/luau files.