Introduction


Arc System Works fighting games, specifically those made in Unreal Engine by Team RED, can be heavily modded. From basic texture and model imports all the way to gameplay overhauls and custom characters, these games have a ton of modding potential. However, modding documentation for these games is incredibly lacking.

Guides for easier mods like texture and model imports are easy to find, but are outdated and lacking critical information. Meanwhile, documentation for editing gameplay scripts is harder to find and split across multiple resources. And there is only one document for custom characters, and it's incredibly lacking. More niche mod types such as UI mods or code mods have zero documentation at all, forcing anyone interested into asking around in Discord servers hoping for answers.

This book aims to fix that. Included within its pages will be thorough information on modding the Team RED games, primarily for the Unreal Engine 4 ones. Most information can be applied to every UE4 game. However, each game has its own quirks, so there will be more specific information in their own categories.

As Guilty Gear Xrd was made in Unreal Engine 3, a vastly different engine from Unreal Engine 4, most general information will not be directly applicable. Pages for it will be added later.

Contributing

If there is something missing that you would like to add, please leave an issue at the GitHub repository. If you have experience with writing Markdown, you may also make a pull request.

Installing Unreal Engine


Arc System Works has customized various aspects of UE4 to suit their needs.

This means that although we can install the plain vanilla UE4 and use that to make mods, we'd be missing on key features needed to make them work properly. Thankfully, Ryn has reverse-engineered several of these changes and implemented some of the key features we require into custom UE4 builds.

Download links below. Just pick the one matching the game you wish to mod. Note that the exact version is important; you cannot do things like use UE4.27 to mod DBFZ.

GameEngine
Dragon Ball FighterZUnreal Engine 4.17
Guilty Gear -Strive-Unreal Engine 4.25
DNF DuelUnreal Engine 4.25
Granblue Fantasy VersusUnreal Engine 4.21
GranBlue Fantasy Verus RisingUnreal Engine 4.27

Starting the editor


Extract all of the contents from the custom UE4 archive you downloaded in the previous step. You can use tools like WinRAR or 7-Zip to do so.

Once that is complete, you can fire up the engine with .\Engine\Binaries\Win64\UE4Editor.exe

You do not need the Epic Games Launcher for this.


The first boot of the UE4 editor usually takes a while to get going. If you want to check whether it's actually starting or not, open Task Manager (ctrl+shift+esc) and check for high CPU usage. This usually means it's busy compiling shaders.

Once Unreal finishes initializing, you will be met with the Project Browser menu. While you could create your own project from scratch, we highly recommend starting off with one of the premade custom projects.

Getting the project for your game


The prebuilt custom projects provide all of the custom asset types the game supports, and for newer games, they even include many assets from the game, such as UI elements or data tables.

Below are download links for each game:

Once you have downloaded the correct project, extract it to your Unreal Projects directory. If you've run the editor before, you can usually find it at Documents\Unreal Projects\.

You'll also need a working installation of Microsoft's Visual Studio in order for the editor to be able to compile the project.

  • Dragon Ball FighterZ requires Visual Studio 2017.
  • Guilty Gear -Strive-, DNF Duel, and Granblue Fantasy Versus Rising require Visual Studio 2019.

For more information on how to set up Visual Studio for UE4, read the official Unreal Engine documentation.

External tools


The usual stuff aside, several key pieces of software are used for nearly every aspect of modding these games. We recommend just getting all of them from the get-go.

In addition, several specialized tools were written specifically for modding Arc System Works games. However, they are specific in their functionality, so you'll find in their respective sections of this document whenever they are needed.

Using Fmodel


Using Umodel


Using AssetEditor


Using UAssetGUI


Using Blender


Note that this document will not cover the basics of Blender.

Several tools were created to make Blender compatible with modding Arc System Works games.

Modified gltf plugin

Download the modified gltf plugin

Fire up Blender, go to your Preferences > Add-ons. Type gltf into the search bar. If it doesn't show up, make sure you're in the 'Official' tab.

Disable it. Nuke it. Throw it out the window.

Now close Blender, and extract io_scene_gltf2_ue4.zip into your Blender addons directory. For Windows, this can be found in:

%appdata%\Blender Foundation\Blender\ <your Blender version> \scripts\addons\

Next, fire up Blender and go back to the Add-ons menu. If all went well, you'll find a new entry in there called Import-Export: glTF 2.0 format - For Unreal Engine Modding. Simply enable it, and you're good to go.

You can now import gltf meshes & skeletons via File > Import > glTF 2.0 (.glb/.gltf) - Unreal.

Aerthas' custom materials & shaders

Download BLENDER-Arc-System-Works-Shader

Not strictly needed for modding these games, but superb for preview models and textures within Blender itself.

Aerthas made a ton of practical videos on how to actually use his shader. Although the YouTube playlist is linked on that very Github page, don't mind if we link it here as well.

Scripts

Browse Arc-Sys-scripts

The most useful scripts have their own wiki pages, which also go into detail on how to use them.

A note on Blender FBX export into UE4

Vanilla Blender FBX export is kinda icky. If you're willing to pay up, consider Better Fbx Importer & Exporter instead.

Loose file loading


Mesh/Model


Texture/Colors


Animations


Hurt & hitboxes


Particles


Moveset


Movesets are defined on a per-character basis in a custom scripting engine developed by Arcsys. These scripts are called BBS.

Although the core battle state manager of Arcsys games is still somewhat of a mystery to us, BBS has since been blown wide open, allowing us to not just alter characters, but create entirely new ones as well.


We highly recommend you read A Sketch of the Arc System Works Engine Script, by pangaea, first.

For the sake of consistency, all example code uses internal Arcsys nomenclature. Game-specific code might be included where deemed necessary.

Extracting & injecting BBS


Automated method

All In One BBScript Tool

TODO: Upload generic versions of Broscar's DBFZ scripts


Manual method

Bulk extracting all BBS from the game

Open the game's pak in Fmodel, and open the package search window (ctrl+shift+f). Type in BBS_. Select all items in that window (ctrl+a), right click, and select 'Export Raw Data (.uasset)'.

The files will appear in the 'Output' directory, but with their original folder structure intact, which can be time consuming to work with. To consolidize all of these BBS files, you can slap any of these scripts into your FModel directory. When you run it, it'll copy all BBS files into a single folder named 'bbs'.

TODO: Slap scripts into a github and just offer download links. Also, create a Windows batch version.

#!/bin/bash
mkdir -p "./bbs/"
for f in `find "Output" -type f -name "BBS_*"`
    do cp -f "${f}" "./bbs/"
done

Extract a script from a UE4 container

Parse the script

Rebuild the script

Inject the script back into the UE4 container

Learning BBS


The two best tutors to learn BBS from, are Arcsys and you. Read the vanilla game scripts, try to understand them, and also just go in and get your hands dirty. Learn by experimentation.

Having said that, we're not throwing you completely into the deep-end. What follows on this page, is a sort of quick overview of how BBS is structured.

If you want an actual glossary encompassing nearly everything BBS, check out BBScript Documentation (Strive), DBFZ BBS doc or DBFZ BBS Lookup.

Note that the latter uses Broscar's bbscript for the name_given field and any code examples, so you can't directly copy-paste those unless you use the same system.

State

The very basis of a move. The game reads and executed a state from top to bottom. This is called the program flow.

When a state ends for a character object, that character object is returned to a neutral state by the battle state manager (CmnActStand while grounded, CmnActJump while airborne). When a state ends for an effect object, that effect object is deleted.

If you players to be able to enter a state directly (e.g. through user input), you'll have to register it with addMove and registerMove. However, that is not needed if you only interact with a state by jumping to it.

Subroutine

A subroutine is a bit of code in it's own block, seperate of states. It cannot contain sprites and has no real program flow, but it can contain pretty much every other function.

When you call a subroutine in your state, you can think of it like simply copy-pasting the code from that subroutine in it's place.

Subroutines are usually used to share one block of code with multiple different states.

If a subroutine starts with cmn, that means you'll find that specific subroutine inside CMNEF, and not inside the character's script.

Labels

Remember that states are read from top to bottom? With labels, you can instead have the game jump to a specific point within a state.

label: s32(loop)
sprite: s32(xxx034_13), 3
sprite: s32(xxx034_14), 3
sprite: s32(xxx034_12), 3
spriteEnd:
gotoLabel: s32(loop)

Congratulations, you just created an infinite loop! That's not very useful of course. Instead of gotoLabel, you can instead write gotoLabelIfOperation: s32(loop), (IS_LESS_OR_EQUAL), var(ActionTime), int(60). Now you'll get a loop, until ActionTime hits 61. ActionTime is a variable that tracks how long an object is in a certain state, in game ticks. If ActionTime is 61 or more, the gotoLabel function does not trigger, and regular state flow is resumed from that point onwards.

You can find more functions like gotoLabel, by visiting DBFZ BBS Lookup and clicking on the 'Flow' button next to the search bar.

Variables

Interrupts

Referred to as upon in the world of BBS. Why? Lol I dunno.

An interrupt executes a bit of code, the moment it's condition is triggered. This happens independent of program flow, meaning you can allow your objects to react to an event the moment it actually happens.

beginState: s32(ExampleMove) {
    upon: (IMMEDIATE) {
        copyVar: var(act1), int(0)
        upon: (IDLING) {
            if: var(act1) {
                addTension: 20
            } endIf:
        } endUpon:
        upon: (RECEIVE_ATTACK) {
            clearRegisteredUponCode: (IDLING)
        } endUpon:
    } endUpon:
    sprite: s32(avp022_01), 1
    sprite: s32(avp022_02), 1
    sprite: s32(avp022_03), 1
    copyVar: var(act1), int(1)
    sprite: s32(avp022_04), 1
    spriteEnd:
} endState:

When you register an interrupt, you simultaneously define what code runs when it is triggered. As you can see, calls to set interrupts can also be nested.

In the code above, upon: (IMMEDIATE) activates before everything else, even before the first sprite is drawn. It also registers 2 new interrupt. IDLING runs every game tick.

Can you guess what this entire bit of code does?

CMNEF

CMNEF is a special BBS file, used to share states and subroutines among all objects in the game. This makes it extremely potent for applying changes that affect all characters and all spawned effect objects. However, if you alter it, it means your mod becomes incompatible with any other mods that change it.

In short, if you're creating a single custom character, you're better off not changing it.

If you're making a complete overhaul / balance patch, use and abuse it.

Signals

Interacting with other objects

applyTo, triggerUponInObject, signals, copyVarFromObject, linkObject

Examples

Here is a document listing several techniques and how one can choose to implement them:

google doc

TODO: Split off the BBS snippets from the DBFZ Google Doc into their own document.

  • Armour
  • Locking out moves
  • Revive on death

Tips

In 10.1 there's a section called Bulk extracting all BBS from the game. If you parse all of them, you can use them to find the various uses of a certain bit of code in all vanilla game scripts. Notepad++, for example, allows you to search for bits of text in multiple files (ctrl+shift+f). Just point it at the directoy where all those parsed scripts are stored, and you're good to go!

How BBS works in-game


Generic states

The battle state manager looks for, and uses, several default states. This means the developers don't have to explicitly handle generic state transitions. If a standing move ends, characters start looping CmnActStand. If a character gets hit, they'll go into the state that matches the hit reaction.

The battle state manager is also able to affect program flow within those default states.

beginState: s32(CmnActJump) {
	label: s32(_Upper)
	label: s32(upperloop)
	sprite: s32(kfs021_00), 3
	sprite: s32(kfs021_01), 3
	sprite: s32(kfs021_02), 3
	spriteEnd:
	gotoLabel: s32(upperloop)
	label: s32(_UpperToTop)
	sprite: s32(kfs021_03), 2
	sprite: s32(kfs021_04), 2
	sprite: s32(kfs022_00), 2
	sprite: s32(kfs022_01), 2147483647
	label: s32(_Top)
	sprite: s32(kfs022_02), 2147483647
	label: s32(_TopToDown)
	sprite: s32(kfs022_03), 3
	sprite: s32(kfs022_04), 2147483647
	label: s32(_Down)
	label: s32(downloop)
	sprite: s32(kfs022_05), 3
	sprite: s32(kfs022_06), 3
	sprite: s32(kfs022_07), 3
	spriteEnd:
	gotoLabel: s32(downloop)
} endState:

As you can see, there are several different labels in this CmnActJump state, but you won't ever find a function that actually jumps to _TopToDown. Instead, the battle state manager does so itself when the proper conditions are met (e.g. airborne, Y-speed less than 0).

The battle state manager can also add function calls whenever it detects certain active state names. For example, DBFZ's CmnActMikiwameMove (Vanish) will initiate a worldStop, even if all relevant calls in the script have been deleted.

Generic subroutines

The battle state manager is also able to call a subroutine for an object on it's own accord. Here are a few notable ones:

SubroutineFunctionality
OnIdlingCalled every game tick, no matter which state the object is in.
Affected by worldStop.
OnLanding
OnDamage
OnGuard
OnFrameStepCalled every game tick, no matter which state the object is in.
Not affected by worldStop.

For DBFZ, OnIdling is called even for assist characters that are off-screen.

Thinking outside the box


BBS allows you to do much more than simply change damage numbers and spawn funny projectiles.

Although it's a bit limited by the very nature of functioning inside of a fighting game framework, you can effectively achieve nearly anything you want with it, as long as you're willing to get creative.

This page serves to highlight a few of these techniques, and lists some examples of what is truly possible with BBS.

Utilising secondary 'helper' objects

Changing character moves by only changing CMNEF

Dynamically altering the move registry

Examples

  • Stage hazards in DBFZ
  • Lethal League in DBFZ
  • FPS in DBFZ

TODO: Actually make these things publicly available and do small write-ups on them.

Per-game BBS specifics


Although the concept of BBS is shared among all modern Arc System Works games, their exact implementation still differs per title.

In this section, you'll find various bits of information pertaining BBS in their respective games. This includes tweaks, bugfixes, and other bits of documentation managed by the community.

Strive


DBFZ


Bugs

  • BRS: Replace createParticle: s32'bg_ roundsmokeL', 0 with createParticle: s32'bg_groundsmokeL', 0
  • ASN: Do a global search and replace to turn Don’t into Dont
  • JNNEF: Do a global search for KidanFire', 0, 100 and remove the odd symbol at the beginning of every one of them.
  • FRN: The subroutine named FDownLoop_Type is missing 1 function.
    • Add storeValue: (VARIABLE), 52, (STATIC), 1 if you're using old bbscript.
    • Add storeValue: Mem(52), Val(1) if you're using regular bbscript 1.0(+).
    • Add copyVar: var(act7), int(1) if you're using Broscar's bbscript.
    • Add Unknown46: Unknown, Unknown, Unknown, Unknown if you're using Burritoscript.

Broscar's workflow

A consequence of DBFZ barely having any modders active in BBS, is that Broscar has been pushing forward solo, with little regard for existing BBS conventions. You may choose to go along for the ride.

ProsCons
Easy to use tools that allow for very fast iterationThe first setup requires a bit more work
Detailed documentationUses a different 'dialect' of BBS.
All concepts of BBS still apply, but functions and variables use different keywords.
Automatically fixes the parser bugs for BRS, ASN and JNNEFAssumes you have some experience with programming
Has better indentation, code folding and works with the Function list feature of Notepad++

https://github.com/dobosken/bbscript

https://github.com/dobosken/dbfz_npp

https://dobosken.github.io/dbfz_bbs_lookup/

TODO: Clean up and share build scripts. Check if ye olde Windows versions still work.

Audio


UI Modding


Due to limitations of creating custom projects in earlier Unreal Engine versions, this section is not applicable to Dragon Ball FighterZ or Granblue Fantasy Versus. At the current moment, it is not currently feasible to mod UI in those games.

If you are modding Guilty Gear -Strive-, DNF Duel, or Granblue Fantasy Versus Rising, continue with this section.

UMG basics


UMG (Unreal Motion Graphics) is the built-in UI framework in Unreal Engine, and is what Team RED uses in all of their games for UI. As such, learning the basics of UMG is critical to modding.

This topic is beyond the scope of this guide, but I will leave useful resources for using UMG here:

Once you feel like you have a decent grasp on UI modding, proceed with this section.

Finding widgets


In Team RED Unreal Engine 4 games, all widgets can be found in RED\Content\UI. The overall contents of the folder differ per game, but names are fairly consistent.

  • The HUD for battles can be found in UI\battle in most games. In Strive, it can be found in UI\Battle_Xrd3.
  • Widgets with Allset in their names refer to the "master" widget. This widget is the one that's directly displayed, containing all other widgets used for its section.
  • Strive tends to postfix its UI folders with Xrd3. This was the codename for Strive during development.

Look inside the folder in the custom project, and try to find the UI element you're looking for. There will be a visual preview of the widget upon opening it. Once you find it, feel free to get creative! Design is incredibly subjective, so I will not provide a tutorial on that. But before you do, make sure to check out the next page, as there are several common pitfalls that could ruin your mod.

Common pitfalls


Modding UI can be quite complicated, and you may run into crashes. Here are several of the common pitfalls I've personally run into, and how they can be avoided.

  • If the game crashes upon loading the UI element, there is a very good chance that you deleted a part of the widget. Never delete parts of the widget, as the game may try to reference it. Even something as innocuous as a text box could crash the game if it was missing. Instead, set its visibility to Collapsed.
  • (Strive/DNF) If your UI elements don't appear in-game, you most likely did not package the Allset widget. In earlier versions of Unreal Engine, the widget hierarchy is "baked" into every widget, and only the directly created widget has its hierarchy referenced. This means that all of your changes to the child widget will be disregarded unless you also package the Allset widget.
  • Some widgets may also contain Blueprint code. If this code is not properly replicated, the game may act unpredictably. Replicating this code deserves a section of its own, but I will leave you with the primary tool I use to replicate blueprint code: kismet-analyzer by trumank.
  • If parts of a widget are pure black, there is a good chance that they use a material. The material can be found under the Details panel for the UI element. The autogenerated materials are broken by default for UI elements, but they likely contain a texture that can be used to preview the material. You'll know if it's the right one because it will resemble the UI element in-game. Simply plug that texture into Final Color, and its alpha channel into Opacity and Opacity Mask.

Creating a .pak archive

Installing your mod