Reading Mech data from MegaMek
MegaMek is licensed under the GNU General Public License v2.0
Therefore, this code is also licensed under GPLv2
The BattleTech IP is owned by The Topps Company, Inc and is licensed by Catalyst Game Labs.
The main website for BattleTech is here - BattleTech: The Board Game of Armored Combat
The MegaMek/megamek repository contains thousands of .mtf
files containing definitions for BattleTech mechs and their information, e.g. this file defining the Marauder 3R
Version:1.0 Marauder MAD-3R Config:Biped TechBase:Inner Sphere Era:2819 Source:TRO 3039 - Succession Wars Rules Level:1 Mass:75 Engine:300 Fusion Engine Structure:Standard Myomer:Standard Heat Sinks:16 Single Walk MP:4 Jump MP:0 ...
The MegaMek
program has logic to calculate the "Battle Value" of mechs which is composed of lots of individual values:
/** * Calculates the battle value of this mech. If the parameter is true, then * the battle value for c3 won't be added whether the mech is currently part * of a network or not. */ @Override public int calculateBattleValue(boolean ignoreC3, boolean ignorePilot) { // ... }
This simply script uses the (GPLv2 licensed) megamek.common
library to:
- Parse
.mtf
files intoMech
objects (usingmegamek.common.MechFileParser
) - Print out a few interesting values about Mechs' Battle Value
Tweaked the Mech.java file to print out the values we were interested in
Tested on Ubuntu 20.04 using openjdk-11-jdk (
sudo apt install openjdk-11-jdk
) and JRuby9.2.11.1
To allow for this to be a simple small script, JRuby was used to load and call the megamek.common
library.
Note: I ran into this error:
java.lang.NoClassDefFoundError: javax/xml/bind/PropertyException
This is because the JAXB APIs were removed from JDK 11, more info on StackOverflow.To resolve this, apply the provided diff to
build.gradle
which adds thejakarta.xml.bind
dependency.
- Clone the latest version of
MegaMek/megamek
SHA
ab24f5dcb0e3d7aab9394ae9449b5adcc312677c
at time of writinggit clone --depth 1 https://github.com/MegaMek/megamek.git
cd megamek
- Edit
megamek/src/megamek/common/Mech.java
to output whatever BV info you're interested ine.g. Apply the provided diff to
Mech.java
which prints the:- Total BV of all Defensive Equipment
- Defensive Movement Factor
- Total Weapons BV Adjusted For Heat
- Total BV
./gradlew build
- Run
jruby print_mech_info.rb
which prints these 3 values for all mechsThe script specifically prints info for all
.mtf
files in themegamek/data/mechfiles/mechs
folder
That's it!
Thank you MegaMek for doing this complex calculation and providing mech info.
MegaMek
and this Gist code are licensed under theGPLv2
If you want to load up a Mech
and call its methods:
- Choose an
.mtf
file (and note its path, e.g.megamek/data/mechfiles/mechs/3039u/Archer ARC-2R.mtf
) - Boot up an interactive JRuby session via
jirb
- Paste in the following code:
mtf_file_path = "megamek/data/mechfiles/mechs/3039u/Archer ARC-2R.mtf" # <-- path to .mtf $LOAD_PATH.push "megamek/build/launch4j/lib/" $LOAD_PATH.unshift "megamek/build/libs/" require "java" require "MegaMek.jar" require "jakarta.activation-api-1.2.1.jar" require "jakarta.xml.bind-api-2.3.2.jar" java_import "megamek.common.MechFileParser" mtf_file = Java::JavaIo::File.new mtf_file_path parser = Java::MegamekCommon::MechFileParser.new mtf_file mech = parser.get_entity
- Now you have a
Mech
object, e.g.Java::MegamekCommon::BipedMech
.
Try calling a method:irb(main):014:0> mech.display_name => "Archer ARC-2R" irb(main):020:0> mech.weapons.map(&:name) => ["Medium Laser", "Medium Laser", "LRM 20", "LRM 20", "Medium Laser", "Medium Laser"]
- You're good to go! Read the
Mech
API and poke around.