Bifrost Mod Kit

Bifrost mods are folders in the game's mods folder. Each one has a mod.json that lists what it adds or changes: game data rows, text, art, music or sounds. They load when the game starts. Below is what you can change, with examples from the sample mods.

mods\sample-skin\mod.json

{
  "id": "sample-skin",
  "name": "Sample skin",
  "version": "1.0",
  "tables": {
    "costumeTypes": [{
      "copy": "Bear",
      "set": {
        "CostumeName": "BHSampleTealbear",
        "CostumeID": "@id",
        "CostumeIndex": "@id/OwnerHero",
        "Body1_Define": "0x1A8C82",
        "Special_Define": "0xD4A017"
      }
    }]
  },
  "strings": { "English": { "BHSample_Tealbear_DisplayName": "Tealbear" } }
}

Getting started

  1. 1

    Make a folder

    Next to Brawlhalla.exe, create mods\my-first-mod.

  2. 2

    Add mod.json

    It needs an id, a name and a version, then whatever the mod changes. The example renames a menu button.

  3. 3

    Start the game

    Mods load when the game starts. The Mods screen shows yours and lets you turn it off.

  4. 4

    Check the report

    Documents\Bifrost\bh-mods.txt says what loaded, what changed, and why anything was skipped.

mods\my-first-mod\mod.json

{
  "id": "my-first-mod",
  "name": "My first mod",
  "version": "1.0",
  "strings": {
    "English": { "UI_MainMenu_Offline": "Practice" }
  }
}

After a restart, the Offline button on the main menu says "Practice".

What you can change

Click a card for details and an example. Visual mods are fine online. Gameplay mods only work offline and in custom rooms where everyone has the same mods.

SkinsVisualRecoloured skinsCopy an existing skin and change its colours.Details
How
Copy an existing skin in costumeTypes, give it a new CostumeName, use @id for its IDs and set new colours.
In game
Character select, next to that legend's other skins. You own it right away. Mods > ADDED ITEMS has a preview.
Note
You can't pick IDs yourself. @id takes the next free one, and it comes out the same on every PC with the same mods.

sample-skin

{ "copy": "Bear", "set": {
  "CostumeName": "BHSampleTealbear",
  "CostumeID": "@id",
  "CostumeIndex": "@id/OwnerHero",
  "DisplayNameKey": "BHSample_Tealbear_DisplayName",
  "Body1_Define": "0x1A8C82" } }
SkinsVisualSkins with custom artNew art, weapons, signature effects and sounds. Added as a new skin, the original stays.Details
How
An art-only SWF loaded through assets, plus MasterFileList and BoneSources rows. palette makes colour schemes work on it, animationAliases borrows lock-in animations, soundBanks adds its sounds.
From a .bmod
Drop a community .bmod skin into the mods folder and the game converts it. It becomes a new skin instead of replacing the original.
In game
Character select, with its weapons and signatures. People who don't have the mod see the skin it was copied from.

mod.json (parts)

"assets": { "bones/Bones_MySkin.swf": "bones/Bones_MySkin.swf" },
"animationAliases": { "MySkin": "Xavier" },
"soundBanks": [ "audio/MySkin.bnk" ],
"palette": { "costume": "MySkin",
  "colours": { "3a7bd5": ["1a8c82", 0.016, -0.067, -0.02] } }
ColoursVisualColour schemesExtra colours in the colour picker.Details
How
ColorSchemeTypes rows. The in-game Colour editor can write these for you.
In game
The colour picker, for every legend. Bifrost allows up to 1024 colour schemes (the game stops at 160).
Note
The game is strict about this table. Copy a full existing row and edit that.

sample-tables

"ColorSchemeTypes": [
  "<ColorSchemeType ColorSchemeName=\"BHSampleTeal\">
    <ColorSchemeID>@id</ColorSchemeID>
    <Body1_Swap>0x37BEAE</Body1_Swap> ...
  </ColorSchemeType>"
]
ItemsVisualWeapon skins, avatars and emotesAlso emojis, sidekicks, KO effects, borders and titles. Each one starts as a copy of a game item.Details
How
Rows in weaponSkinTypes, avatarTypes, TauntTypes, EmojiTypes, SpawnBotTypes, TrailEffectTypes, SeasonBorderTypes or MonikerTypes.
In game
The normal loadout and podium pickers, already owned. Added podiums, player themes and companions are owned too.
Note
Emotes, sidekicks, KO effects and borders can go up to ID 1023.

sample-items

"weaponSkinTypes": [{ "copy": "HammerJade", "set": {
  "WeaponSkinName": "HammerBHSampleTeal",
  "WeaponSkinID": "@id", "DbID": "@id",
  "Weapon_Define": "0x1A8C82" } }],
"MonikerTypes": [{ "copy": "Birthday01", "set": {
  "@MonikerName": "BHSampleTitle", "MonikerID": "@id",
  "Color": "0x8FE3DA" } }]
LegendsGameplayNew legendsA new playable legend with its own name, stats, stances and default skin.Details
How
A HeroTypes row (stats have to add up to 22), a default skin in costumeTypes, ten RuneTypes stance rows, and default weaponSkinTypes for both weapons.
In game
The character select roster.
Limits
For now a new legend uses another legend's animations, weapons, portrait and sounds. tools/check_legend_mod.py runs the game's checks on it before you start the game.

sample-legend

"HeroTypes": [{ "copy": "Viking", "set": {
  "@HeroName": "BHSampleHero", "HeroID": "@id",
  "HeroDisplayName": "SAMPLE VIKING (MOD)",
  "Strength": "7", "Dexterity": "5",
  "Weight": "6", "Speed": "4" } }]
LegendsGameplayStats and stancesChange a legend's stance stats, or what a stat point does for everyone.Details
How
A stance row in RuneTypes for one legend's stance, or a StatTypes copy for a stat value.
Editor
The Move editor's LEGEND and STAT POINTS tabs do the same and save a mod.
In game
Any match with that legend, and the stance panel in the loadout window.

mod.json

"RuneTypes": [ { "stance": "Viking", "index": 0,
                 "set": { "Strength": "9" } } ],
"StatTypes": [ { "copy": "Speed5",
                 "set": { "RunSpeed": "50" } } ]
MovesGameplayMovesDamage, knockback, timing, hitboxes, movement and follow-ups. Around 3,700 moves.Details
How
powerTypes rows. Copy a move and set the columns you want to change (there are 184).
Editor
The Move editor in Training changes moves while you play, shows hitboxes, and saves a mod. There's also a web version on this site.
Note
You can't blank a column. Use 0.

mod.json

"powerTypes": [
  { "copy": "BaseNeutral",
    "set": { "BaseDamage": "30", "RecoverTime": "6" } }
]
ModesGameplayGame modesNew modes for Couch Party and custom rooms, based on an existing mode's rules.Details
How
A ScoringTypes row and a GameModeTypes row, usually copies of an existing mode. You can change lives, score to win, teams, items, timers, maps, icon, name and description.
In game
The mode list in Couch Party and custom rooms.
Bots
Bots know how to play King of the Hill style modes. Other new modes get normal bots.

sample-mode: King of the Hill

"ScoringTypes": [{ "copy": "COLORPLATFORMS", "set": {
  "@ScoringName": "BHKINGOFTHEHILL", "@Enabled": "True",
  "ScoringID": "@id", "IconName": "a_ScoringIcon_CLIMB" } }],
"GameModeTypes": [{ "copy": "DefaultColorPlatforms", "set": {
  "@GameModeName": "BHKingOfTheHill", "GameModeID": "@id",
  "ScoringType": "BHKINGOFTHEHILL" } }]
AnimationsGameplayAnimationsLoad an extra animation file after the game's to replace an animation.Details
How
A MasterFileList row pointing at an .anm file in your mod folder.
Note
There's no animation editor yet, so this one is harder.

sample-anim

"MasterFileList": [
  "<File Stage=\"Anim\" Name=\"mods/sample-anim/Animation_BHSample.anm\" ... />"
]
MapsGameplayNew mapsYour own stage with platforms, spawns, kill lines, art, music and bot paths.Details
How
A LevelDesc_*.xml layout listed in files, a LevelTypes row, and +Name added to the map lists it should be in.
Editor
The map editor (on this site too) lays it out, checks it, makes the bot paths and exports the mod.
Testing
F8 in the menus reloads map files, so you don't need to restart. The next match on that map uses your changes.

sample-map

"tables": {
  "LevelTypes": [ "<LevelType LevelName=\"BHSampleFlats\">
    <DisplayName>Sample Flats (mod)</DisplayName>
    <LevelID>@id</LevelID> ...</LevelType>" ],
  "LevelSetTypes": [ "<LevelSetType LevelSetName=\"StandardAll\">
    <LevelTypes>+BHSampleFlats</LevelTypes></LevelSetType>" ]
},
"files": [ "LevelDesc_BHSampleFlats.xml" ]
Map artVisualMap artDifferent art for the game's existing maps. Each player picks what they want per map.Details
How
A mapArt block: your art files (at the same paths as the game's), which maps they're for, and thumbnails.
In game
Mods > MAP ART. For each map pick the game's art, a mod's, shuffle (random each time) or mass (every piece random). Thumbnails and loading screens match.
Note
No restart needed to turn it on or off.

mod.json

"mapArt": {
  "files": [ "mapArt/Backgrounds/BG_Sakura.png" ],
  "maps": { "SmallBrawlhaven": "Sakura Brawlhaven" },
  "mapTypes": { "SmallBrawlhaven": [ "1v1" ] }
}
MusicVisualMusicMP3s for the menu, character select, results screen, maps, or any one track.Details
How
A music block with your tracks (title and volume are optional) and what they replace. *battle means every map.
Tool
tools/make_music_pack.py makes a music mod from a folder of MP3s.
In game
Mods > AUDIO lists every change and whether it's active. No restart needed.

sample-music

"music": {
  "tracks": {
    "calm": { "file": "music/quiet-a.mp3", "title": "Calm", "volume": 0.9 },
    "bright": "music/quiet-b.mp3"
  },
  "replaces": { "DefaultUI": "calm", "*battle": "bright" }
}
SoundsVisualSoundsReplace any sound: the announcer, menu sounds, hits, voices, moves.Details
How
A sounds block that maps a game sound event to your MP3.
Event names
Set "soundLog": true and the game logs every sound it plays. tools/sound_events.py lists them all.
Tool
tools/make_sound_pack.py makes a mod from MP3s named after their events.

mod.json

"sounds": {
  "VO_Announcer_InGame_Brawl_Play": "sounds/brawl.mp3"
}
TextVisualTextChange menu text, item names and descriptions, or add text for your own items.Details
How
strings, per language, using the game's text keys.
In game
Anywhere the game uses that key.

sample-strings

"strings": {
  "English": {
    "UI_MainMenu_Offline": "Offline (sample mod)"
  }
}
LanguagesVisualNew languagesAdd a language to the Language setting.Details
How
A LanguageTypes row (copied from an existing language) and strings under the new name.
Note
Fonts and untranslated text come from the language you copied, so stick to characters its fonts have.

sample-language: Pirate

"tables": { "LanguageTypes": [ { "copy": "English",
  "set": { "@LanguageName": "Pirate", "DnaCode": "en-PI" } } ] },
"strings": { "Pirate": {
  "UI_MainMenu_Play": "Set Sail", "UI_Back": "Belay" } }

Other data tables work the same way (map lists, custom game types, music, effect swaps and so on).

Example mods

These come with Bifrost in examples/mods. Copying one into your mods folder is a good way to start.

sample-stringsText

Changes the text of the main menu's Offline button.

sample-tablesColours

Adds a teal colour scheme and renames Bödvar on character select.

sample-languageLanguage

Adds Pirate, a copy of English with menu text reworded.

sample-skinSkin

Adds Sample Tealbear, a teal and gold Bödvar skin based on Bear.

sample-itemsItems

Adds a hammer, avatar, emote, emoji, sidekick, KO effect, border and title.

sample-legendLegend

Adds Sample Viking: own stats, stances, weapons and a green default skin.

sample-mapMap

Adds Sample Flats, a small map using the art from Plains of Passage.

sample-modeMode

Adds King of the Hill to Couch Party and custom rooms; the hill moves every 15 seconds.

sample-musicMusic

Replaces the menu and map music. Put your own MP3s in under the same names.

sample-animAnimation

Stretches Bödvar's hammer idle. Build its .anm from your own game files first.

sample-lone-kingCode mode

King of the Hill where the hill scores only while one team holds it alone. Needs a source build.

Editors and tools

The editors save normal mod folders, so you can turn them off or share them like any other mod.

Colour editor

Mods > COLOUR EDITOR

  • Hue, saturation and brightness for each part (hair, main, second, special, cloth, weapon, hands)
  • Edit single shades as RRGGBB
  • Preview on any legend and skin, idle or doing an emote or attack
  • Start from an existing scheme or import XML

→ mods\my-colors

Move editor

Training > Settings > PRACTICE

  • The common columns of a move, grouped, or all 184
  • Hitboxes shown on the legend, drag to move or resize, step through frames
  • Stance stats and stat points
  • Changes apply right away in Training

→ mods\my-moves or mods\moves-<name>

Web map editor

Bifrost > Map Editor on this site, or tools/map-editor

  • Platforms, collisions, spawns and art, using the same pieces the game's maps use
  • Drag the kill box, and all ~40 map settings have help text
  • Makes bot paths for you
  • A Check tab that finds problems and fixes most of them

→ <id>.zip, unzip it and press F8

Creator toolWhat it does
tools/preview_content_mod.pyApplies your mods to the game's tables and prints what the game will do, before you start it.
tools/check_legend_mod.pyRuns the game's own legend, skin and stance checks on a legend mod.
tools/bmod_import.pyThe same .bmod conversion the game does, from the command line. Also converts loose sound banks.
tools/make_music_pack.pyA folder of MP3s into a music mod (menu, character select, maps, victory).
tools/make_sound_pack.pyMP3s named after sound events into a sounds mod.
tools/sound_events.pyLists every sound event name the game has.
tools/map-editorThe web map editor.

The Python tools are in Bifrost's source code. They read the game data from your own install.

mod.json reference

Mods load in a fixed order, requirements first and then by id, so the same mods give the same result on every PC.

FieldDoes
id, name, versionRequired. The id is what makes a mod unique: letters, digits, dot, dash, underscore.
author, description, previewShown in the Mods screen. preview is a PNG or JPG in the folder.
requiresMod ids that must load first.
tablesAdd or change rows of any game data table.
stringsText, per language.
filesXML files such as map layouts.
assetsThe game reads your file instead of one of its own.
paletteShade-preserving colour schemes for a skin with its own art: each drawn shade (hex) lists its anchor colour (one of the skin's Define colours, hex) and its hue, lightness and saturation offsets from it.
animationAliasesShare another skin's lock-in and select animations.
soundBanksWwise sound banks in the mod folder.
mapArt, music, soundsArt for existing maps, tracks, sound effects.
In a tableMeans
"<Row ...>...</Row>"An XML row in the game's own format. Same name as a game row: changes it. New name: adds it.
"a,b,c"A CSV line in the table's column order.
{ "copy": "Name", "set": {...} }Copy a game row and change only what you name. A new name makes a new row.
{ "add": "..." }Added as it is, for tables whose rows have no name.
{ "stance": "Hero", "index": n, "set": {...} }Change one stance of one legend.
@id · @id/GroupThe next free ID, or the next free number within a group (a legend's skin slot).
+NameAdd to a list instead of replacing it, such as a map set.
@noneEmpty a cell in a copied row.

Load report

Each start writes Documents\Bifrost\bh-mods.txt. Lines start with one of these.

loadedThe mod loaded.
skipped <why>A missing or broken mod.json, a missing field, an id already used, or a missing requirement.
offSwitched off in the Mods screen.
conflictTwo mods change the same thing; the later one in load order wins.
row added / row changedEvery table row your mod touched.
renamedTwo mods added an item with the same name, so the later one was renamed.

If the game stops while loading, a row probably failed one of the game's checks: a missing field, stats that don't add up to 22, a legend with fewer than ten stances, or a map with no background or bot paths. Copying full rows and running the checker tools catches most of these.

Mod settings

In Documents\Bifrost\bh-mod-settings.json. Most of these are set from the Mods screen.

disabledMods you switched off in the Mods screen.
mapArtYour art choice per map: default, a mod, shuffle or mass.
soundLogtrue logs every sound event to Documents\Bifrost\bh-sounds.txt.
shareModsfalse never offers to send your mods to a room.
hillBotsfalse turns off the hill-holding bots in King of the Hill style modes.

.bmod files

Community .bmod files are turned into normal Bifrost mods by the game itself. A skin from a .bmod is added as a new skin next to the one it was made for, so the original stays.

  1. 1

    Add it

    Drop the .bmod into the mods folder, or press IMPORT .BMOD on the Mods screen and pick it.

  2. 2

    Converted

    At the main menu the game converts it into a mod folder and moves the .bmod inside it. A popup lists what was added.

  3. 3

    Restart

    Map art works straight away. Skins, weapon skins and avatars show up after the game restarts.

  4. 4

    Remove

    Delete the mod's folder, or turn it off in the Installed tab like any other mod.

Works for skins, weapon skins, avatars and map art. Sound banks that come as loose .bnk files next to the .bmod aren't converted in game; tools/bmod_import.py still handles those. A file that can't be read stays in the mods folder and isn't tried again until it changes. Adding the same .bmod twice just says it's already imported.

Sharing mods

Bifrost servers have a mod library. Mods are only uploaded when you send them, and public ones have to be approved by the server's reviewers first.

  1. 1

    Upload

    Send a mod from the Mods screen, private or public. You need to be signed in with Discord.

  2. 2

    Share key

    Each upload gets a key like ABCD-2345. Anyone with the key can install it.

  3. 3

    Review

    Public mods wait until a reviewer tries them and approves or rejects them.

  4. 4

    Community tab

    Approved mods show up for everyone, sorted by likes and downloads.

  5. 5

    Updates

    People who got it from the Community tab get new versions automatically.

Servers only accept data, images, audio and art-only SWFs (no code). Limits: 64 MB per mod, 30 mods or 512 MB per account.

Mods online

VisualFine anywhere

  • Skins, colours, weapon skins, avatars, emotes, emojis, sidekicks, borders, KO effects, titles
  • Text, languages, map art, music and sounds
  • Other players see your item if they have the mod, otherwise the game item it was copied from

GameplayCustom rooms

  • Legends, stats, moves, game modes, maps, animations, any other table
  • Blocked in casual and ranked queues
  • In custom rooms everyone needs the same gameplay mods. The host can send theirs to the room
  • Shared replays remember their mods and offer to download them

Limits

  • New mods need a restart. Map art, music and sounds don't, and F8 reloads map files.
  • IDs are picked for you. Use @id and every PC gets the same number.
  • When two mods change the same thing, the one that loads later wins. The report lists these.
  • New legends reuse existing art. Animations, weapons, portrait and sounds come from the legend you copied.
  • Music has to be MP3. The welcome announcer line can't be replaced.
  • Mods can't contain code. New screens or new game rules need changes to Bifrost itself.
  • Only in Bifrost. The Official client doesn't support mods.
  • Mod items are unlocked. Anything a mod adds is owned as soon as it loads.