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
.mtffiles intoMechobjects (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.gradlewhich adds thejakarta.xml.binddependency.
- Clone the latest version of
MegaMek/megamekSHA
ab24f5dcb0e3d7aab9394ae9449b5adcc312677cat time of writinggit clone --depth 1 https://github.com/MegaMek/megamek.git
cd megamek- Edit
megamek/src/megamek/common/Mech.javato output whatever BV info you're interested ine.g. Apply the provided diff to
Mech.javawhich 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.rbwhich prints these 3 values for all mechsThe script specifically prints info for all
.mtffiles in themegamek/data/mechfiles/mechsfolder
That's it!
Thank you MegaMek for doing this complex calculation and providing mech info.
MegaMekand this Gist code are licensed under theGPLv2
If you want to load up a Mech and call its methods:
- Choose an
.mtffile (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
Mechobject, 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
MechAPI and poke around.