From Battletech Modding Wiki
Jump to: navigation, search

The .json files in the data/events/ directory control most of the random events found in BattleTech, but they are all registered in the game's database. Once properly registered, all gameplay changes can be performed purely within the json files.

The following is a work in progress as reverse engineered by the community. There are strange edge-cases and unknown failures, so always work in stages and never try a new trial with an event of unknown functionality.

Basic Event Information

Events are stored as JSON files in the data/events/ directory, and are named with the following format:

Event_Type is either "event" or "forcedevent", and scope is "co" for company or "mw" for mechwarrior. Other scopes appear to be supported, but do not appear to be used in HBS events.

Current proposed best practice is naming mod files:

The editor appears to make all data case correct, but it is unknown if the system is case sensitive.

All events must be entered into the database. This is straightforward, but due to foreign cells, the requirement list ID needs to be defined first. In my experience this can be purely numeric or a GUID, but alphanumeric falls apart. Mod users should have unique prefix codes within the hexadecimal region. IE: BTB is not acceptable, but B1B is. A current list of modmaker prefixes is available.

Also, you need to add the JSONs to the versionmanifest, but the tag files do not need to be included. The image file must also be added to the manifest.


The editor has some error checking, but much of the system has to be coded by hand. Also, unfortunately, it is not designed to run with the release version. Missing files have been extracted from the release version and linked below.

All HBS events will error out when loaded. This is due to image issues, and can be safely ignored. The editor is looking for png files in the /streamingassets/sprites/illustrations directory. Image sizes are 750x300 pixels. Keeping this png for the duration of your work is recommended, but there's no need to distribute it. The game itself ignores the .png extension in the json, and looks in the illustrations directory for a dds file of the same name. Only DXT1 compression with generated mipmaps have been testes at this time, but it is likely anything Unity supports is supported by the game. The image is mirrored vertically, and must be flipped in your image editing program to appear upright in-game!

Tags are selected from the files located in /resources/Tags, and while you can re-select a different file to draw tags from, that doesn't mean the game itself will process it. These tags are only used by the editor, and the game finds them within the database.

The use of the editor is straightforward, but this section may be improved with images (strong hint). Until then, the event type and scope should be self-explanatory, and the weight is simply how often that event is selected. Current understanding is that if you have two events with a weight of 50, there's a 50/50 chance of selecting any given event, while 50 and 100 would be a 33/67 split.

The name and image are also straightforward, but remember you need a png for the editor and an inverted dds for the game. It is possible but unconfirmed that the human readable name needs to be identical between the json and database.

The Constants Filter is currently a mystery. It's likely to enumerate constants in event results so the SimGameConstants file can make balance changes.

The details window displays what the player will first see, and the name of the options at the bottom are the human-readable options the player selects. Inside of these options, the details mean nothing to the player. Within the results set, the name means nothing and the details are shown to the player as the second text screen in the event. The weight functions as above.

The results on this page open a new window, and these options are straightforward, but the syntax is not. See the below tables for syntax.

Please note the temporary checkbox. Changes to medical and repair facilities are temporary (and are usually accompanied by the MODIFIED_STAT_MedTechSkill or MODIFIED_STAT_MechTechSkill tag) while funds, morale, reputation, etc. are all permanent actions. Unless, of course, you want morale to go back up/down after an event completes.

Results syntax

The forced event and action syntax are provided in-editor. The syntax most likely used is in the leftmost window. Example:


This is composed of the variable, the type, and the modifier. So far only System.Int32 has been seen, but there are a world of variables not yet identified. If someone in the know would share the structure of the variables, that would be a game changer.

As a note, constants are used as follows:

Variable Description
MedTechSkill Mech Repair Skill Value
MechTechSkill Medical Value
Funds Current C-Bill balance
Reputation.Davion Reputation with Federated Suns
Reputation.Marik Reputation with the FWL
Reputation.MagistracyOfCanopus Reputation with the Magistry

The reputation seems straightforward within the Reputation container, but other powers or the MRB's location have not been confirmed.

Displaying variables in the text

The following are the currently known and useful variables usable in event text. Entering "I have some coffee for you, Commander {COMMANDER.LastName}, but we only have {COMPANY.Funds} C-Bills left!" will output "I have come coffee for you, Commander Johnson, but we only have 45678 C-Bills left!" There is a way to change that to 45,678 in other circumstances (.ToCommaSeparatedString) but has not been shown to work in the details field.

Mechwarrior Type Prefix
Primary Mechwarrior TGT_MW
Secondary Mechwarrior SCN_MW
Tertiary Mechwarror TRT_MW

Mechwarrior Variables
Variable Type Notes
ArmorDamageInflicted float
BonusHealth int32
Callsign string
CanBeHeadShot bool
CanBeInspired bool
CanDFA bool
CanEject bool
CanPilot bool
DeathDate int32
Description HumanDescriptionDef
Det string his/her/their lower case
Det_c string His/Her/Their upper case
FirstName string
Gender Gender
GUID string
Gunnery int32
Guts int32
HasAnyInspiredEffect bool Combat Only
HasEjected bool Combat Only
HasFuryInspiredEffect bool Combat Only
HasHighMorale bool Use Tags Instead
HasLowMorale bool Use Tags Instead
HasMoraleInspiredEffect bool Combat Only
Health int32
Hire Date int32
Injuries int32
InjuryReasonDescription string
IsIncapacitated bool
IsPlayerCharacter bool
LastName string
LethalInjuries bool
MaxTargets int32
MechsKilled int32
Name string
NeedsInjury bool
Obj string
Obj_c string
OthersKilled int32
pilotDef PilotDef
Piloting int32
Pos string
Pos_c string
Refl string
Refl_c string
SpentXP int32
StatCollection StatCollection Uncertain if accessible in events
StructureDamageInflicted float
Subj string he/she/they, lower case
Subj_c string He/She/They, upper case
Tactics int32
Team Team
TeamId string
TotalDamageInflicted float
TotalHealth int32
TotalXP int32
UnitsKilled int32
UnspentXP int32

The below notes are examples and their findings are being folded into the above information; they will be deleted when the above tables are reliably complete.

Variable/Command Description
COMPANY.Funds Current C-Bill balance
COMPANY.Morale Current Morale, 1 - 50
COMMANDER.LastName Commander's Surname
COMMANDER.FirstName Commander's Given Name
COMMANDER.Callsign Commander's Callsign
COMMANDER.Tactics Tactics skill. Guts, Piloting, and Gunnery are likely similar. 1 - 10
TGT_MW.SUBJ Primary Mechwarrior in event - He/She/They (uncertain)
TGT_MW.Gender?NonBinary:recover|Default:recovers If Male/Female, the word "recovers" is used, else it displays "recover"
TGT_MW.DET Outputs "his," "her," or "their"
[[TGT_MW,{TGT_MW.Callsign}]] Likely highlights the MW's callsign with a tooltip.
[[SCN_MW,{SCN_MW.Callsign}]] As above, but for secondary mechwarrior
{SCN_MW.SUBJ} Outputs he, she, or they for secondary mechwarrior. - Note capitalization
{SCN_MW.SUBJ_C}{SCN_MW.Gender?NonBinary:'re|Default:'s} Outputs He's, She's, or They're. - Note capitalization

As the Commander is a Mechwarrior, it's likely that all the commander's variables work for mechwarriors and vice versa.

Final Notes

Comparison fields all seem to use variables as defined by scope, such as Company comparisons of Travel and MedTechSkill, likely making them accessible in ways similar to "COMPANY.Travel" in text.

Similarly, you can test for mechwarrior injuries in the comparison field with Injuries, so it's very possible TGT_MW.Injuries would return the number of wounds they have taken (with 0 being uninjured).

While this is ugly to use directly, it may be possible to do things like
{COMPANY.Travel?1:We're in transit.|Default:We're in orbit.}
This leads to options for altering text based on conditions or backgrounds without making wholly new events.


  • Is the json properly formed? Try to load it in the event editor, if it fails, the file is malformed.
  • Is the database entry correct?
  • Did you export/save the database?
  • Is the json in the VersionManifest?
  • Is your editing program locking access to any file? (Example: Excel will lock the versionmanifest, Wordpad will not)
  • Is everything spelled correctly?

Example SQL Query

INSERT INTO 'RequirementList'('RequirementListID','RequirementListTypeID') VALUES (`RequirementList`,0);
INSERT INTO 'EventDef'('EventDefID','Name','EventScopeID','RequirementListID','AllRequiredTagsTagSetID','AllExcludedTagsTagSetID','AllOptionRequiredTagsTagSetID','AllOptionExcludedTagsTagSetID','AllAwardedTagsTagSetID','AllRemovedTagsTagSetID','EventTypeID','EventPublishStateID') VALUES ('`EventID`','`EventName`',0,`RequirementList`,NULL,NULL,NULL,NULL,NULL,NULL,0,2);

You must run these queries in this order and the RequirementList fields must match and use only hexidecimal characters (0-9, a-f)

External resources

Wiki Quick Nav: File Formats | Other Tweaks and Adjustments | Tools and Scripts | Troubleshooting | Style Guide