HighFleet – HighFleet Modding Guide Tutorial

HighFleet – HighFleet Modding Guide Tutorial 1 - steamlists.com
HighFleet – HighFleet Modding Guide Tutorial 1 - steamlists.com

Everything you need to know before you start to mod the game.
 
 

Intro

Ever wanted to make this garbage gun more useful? Something seems to be too OP for you? Want to make an invulnerable meme machine? Or making a global serious rebalance mod? This guide is there to help you.
 
 
Do not forget to check my Total Rebalance mod: Nexus – [nexusmods.com] 
 
 
HighFleet - HighFleet Modding Guide Tutorial - Intro - 5A40171
 
 
Disclaimer: the guide is still not complete and some sections are not finished/properly described. The completion deadline is indefinite.
 
 
 

.seria Structure

The game keeps most of its stuff in .seria files – be it a save, ship file or a config. It’s useful to understand it before moving on other things.
 
 
.seria consists of nodes which are delimited by parentheses. Parentheses are always on a new line and there is no other stuff on the same line. All nodes except the root also have a header – some attribute-value pair, where a value is typically a some int. Header value shouldn’t be unique. Example of a non-root node (contents replaced by “…”):
 
 

m_stats=2051
{
...
}

 
 
Node contents may be a combination of the following:
 

  • An attribute-value pair
     
     
     

    m_children=15
    {
    ...
    m_classname=Body
    ...
    }
  • A nested node
     
     
     

    m_children=15
    {
    ...
    m_mesh=1073741827
    {
    ...
    }
    }
  • (Only for mesh nodes) a sequence of floats
     
     
     

    {
    m_classname=Mesh
    m_size=4
    -3.53553
    5.32097
    -3.53553
    -5.32097
    3.53553
    -5.32097
    3.53553
    5.32098
    }

We’ll talk about meshes later.
 
 
Attribute-value pairs may repeat:
 
 

m_children=15
{
...
m_sectors=1
m_sectors=1
m_sectors=1
m_sectors=1
m_sectors=1
m_sectors=1 #360 "m_sectors" entries in total
...
}

 
 
That’s how the game handles arrays. For example, 360 “m_sectors” entries denote a firing or a sensor arc in a ship file, one for each degree.
 
 
If you’re going to parse/edit .seria,
 
DO NOT
 
EVER
 
INDENT.
 
That will break the file.
 
 
That’s basically all you need to know before parsing a .seria file; part configuration files and even saves follow this structure, so you can potentially modify saves with this knowledge.
 
 
 

Libraries/OL.seria

OL.seria holds a first fraction of modules’ parameters. Most of them (if not all) don’t require keeping their states in a save file, i.e. you can alter them and see changes in the game immediately after booting + loading a save/ship file. It also holds the parameters you are most likely going to tweak – weapon clip size, reload speed, cost, fuel amount, engine thrust/consumption and many more.
 
 
This is a simple two-level .seria file, where each part got a
 

m_stats=2051
{
...
}

 
entry without nested nodes. The most potentially interesting entries are:
 

  • m_oid is one of the internal module names, under which it’s being referred in another files. It’s good to learn them for modules you’re going to tweak.
  • m_price is a price in gold. While a ship cost is being written into a ship file, the game automatically recomputes it after start (at least for shipworks; not confirmed for campaign mode).
  • m_repair_cost is a total repair time, units unknown
  • m_icon_name is a thumbnail name. Thumbnails are registered in Media/Tex/Static*.res files.
  • m_mdl_crew_need are crew requirements
  • m_mdl_ammobox_need are ammo requirements. Amusingly, may be set to a float value like 0.5 and it will work.
  • m_mdl_power_need are power requirements, kW
  • m_weapon_load_amount is a weapon ammo clip
  • m_weapon_load_time is a clip reload time in units. Unit = 4/7 (~0.571) seconds. For aircraft this is a maintenance time in hours.
  • m_weapon_rate is a clip unload speed, rounds per minute
  • m_weapon_caliber is a weapon caliber index. The main weapon stat – a shell type used.
  • m_missile_explosive is a tactical/arcade missile explosive charge.
  • m_missile_ap defines how damage passes through armor. Only for missiles, sadly.
  • m_launched_health is a missile health after launch.
  • m_launched_range is a range for aircraft/tactical/arcade missiles. For strategic assets it’s measured in km.
  • m_launched_speed is a global map speed for aircraft/tactical/arcade(yes) missiles in m/s.
  • m_launched_speed2 is an arcade speed for aircraft/tactical/arcade missiles (seems to be km/h?)
  • m_mdl_rotation is a turret rotation speed. Sounds not that interesting, but values like 1.5 and lower may really affect how comfy is the gun to use. The units seem to be rad/s.
  • m_resources is a stackable attribute which defines how many “resources” it’s needed to construct a part (hull/deck/armor).

 
The list is incomplete but contains the most important things.
 
 
 

Libraries/parts.seria

This file holds another (bigger and more technical) fraction of module stats. These are being written in a ship/save file – technically, a parts.seria entry is being cloned with some minor changes/additional attributes. That means that anything you alter in the parts.seria will not transfer into already existing ship files and saves. Only parts freshly picked from the shipworks will have new stats.
 
 
There’s a way to (partially) update ship files – see the corresponding section.
 
 
The file structure is more complex:
 
 

{
... #Root node tech stuff
m_children=15 #An example entry; there are lots of entries like this
{
attribute_one=value_one
attribute_two=value_two
...
m_mesh=1073741827 #Entries contain a single mesh node...
{
...
}
attribute_three=value_three
...
m_sprites=536870915 #...and one/multiple sprite nodes...
{
...
}
m_sprites=536870915
{
...
}
m_sprites=536870915
{
...
}
m_slots=2147483651 #...and zero/one/multiple slot nodes
{
...
}
m_slots=2147483651
{
...
}
opt_attr_one=value_four
opt_attr_two=value_five
...
}
... #Other module entries
}

 
It may have not only attr=value pairs but also an additional level of nested nodes. The child node types are m_mesh (single), m_sprites (multiple) and m_slots (optional, multiple).
 
 
Potentially interesting attributes:
 

  • m_id is a node id. Means nothing by itself, but is important to track if your game keeps crashing.
  • m_master_id is a parent node id. If it’s wrong, your game won’t load/will freeze at shipworks.
  • m_oid is the same m_oid as in OL.seria.
  • m_density affects a module mass. More about that below.
  • m_mass stat IS NOT A MODULE MASS but is a number used for GUI mass computations and display.
  • m_burn_hp. Probably a module HP against fire. I also suppose that it may affect how much time you have to loot the part in the crash site mini-game, but that’s unconfirmed.
  • m_health and m_health_max are module HP. Note that m_health is the current module state which makes sense only in a ship file -> may be an initial module state.
  • m_explosive is a boom damage once this module is destroyed.
  • m_rescue_explosive is whether this module will destroy another loot if not looted in the crash site mini-game.
  • m_floor_type is a module height along Z-axis. For example, large tanks have it set to 3.
  • m_spasmcode is a repeating attribute at the end of an entry. I don’t know what it does exactly (I think something with arcs/obstruction), but it’s good to consider if you want to parse a file properly.

 

Meshes

 
A mesh structure is fixed:
 
 

m_mesh=1073741827
{
m_classname=Mesh #Common attribute for (almost) all nodes
m_size=4 #How many points are there in a mesh
3.13553 #Each pair of numbers is a point X and Y coordinates
-3.13553
3.13553
3.13553
-3.13553
3.13553
-3.13553
-3.13553
}

 
Note: the X/Y axes are directed right/down respectively. If you want to visualize a mesh in-game, simply select a part and its white contour will be its mesh.
 
 
The game doesn’t have any particular mass stat but computes the mass with “Mesh Volume * m_density” formula. A mesh volume is a min(mesh width, mesh height) * mesh area, where mesh area may be computed with the Gauss formula for polygon. So, if we change a side of a square mesh (keeping its square) the mass will grow cubic; if we extend the longer side of a rectangle mesh then the mass will grow linearly.
 
 

Sprites

 
The sprite structure is a one-level node with a variable amount of attributes (technically, with the same but some have implicit values set).
 

m_sprites=536870915
{
m_classname=Sprite
m_code=536870915 #Should be same as a header value
m_animation_name=ap_07
m_position.y=-7
m_stage=-2
m_mask=0
m_animation_mode=4
m_scale.x=1.4
m_scale.y=1.4
}

 
The sprite attributes are not well-studied yet; here are some I already know:
 

  • m_animation_name is a sprite name which is registered in Media/Tex/Ships1.res file. Here’s an entry from the file:
     
     
     
     
     

    Animation ap_07
    {
     texture = Ships1
     rect = 3,3,140,140
     hotspot = 70,70
     zorder = 0.000000
     resgroup = 0
     frames = 40
    }

     
     
     
    An animation may be either a frame-by-frame animation or a single sprite.

  • m_position.x and m_position.y are sprite offsets relative the the part zero point.
  • m_scale.x and m_scale.y are sprite scaling factors. It’s not recommended to stretch/squeeze sprites much since they will be too low-res/too sharp. Dithering may mask sprite issues though.
  • m_angle is a sprite rotation in rad.
  • m_stage seems to be a sprite layer OR a condition under which a sprite is being drawn (on mouse hovering, on being placed, …)

 

Slots

 
Slots are module attachments. They may be either side attachments or internal attachments (like ones provided by hull).
 
 

m_slots=2147483651
{
m_classname=Slot
m_code=2147483651 #Should be same as a header value
m_master.id=7246492521041933693 #Should be same as a part id
m_type=5
m_position.x=1.78571
m_position.y=5.4888
}

 
 

  • m_position – you know what is this. Can be set up based on mesh contour. Note that if you place an external slot inside a mesh it won’t work.
  • m_type is a slot type – external, internal, internal large, … . There are several, but I haven’t studied them yet.
  • is_slave. Seems to be set to false for internal slots.

 
 
 

Ship Files

Ship files contain:
 

  • Module entries very similar to ones in parts.seria
  • Joint entries which define connections between parts
  • Special Creature entry with ship global stats

 
An example (Archangel file):
 
 

{
m_classname=Node
m_code=7
m_id=-492343618703753414
m_name=Archangel
m_children=31
{...}
m_children=15
{...}
m_children=15
{...}
...
m_children=15
{...}
m_joints=8589934595
{...}
m_joints=8589934595
{...}
...
m_joints=8589934595
{...}
}

 

  • m_children=15 are part nodes
  • m_joints=8589934595 are joint nodes

 
The list of parts on the first nested level is not complete — these are guns, legs, gimbaled engines and dummy nodes without mass and density. The rest of the modules are children of the m_children=31 node:
 
 

{
m_classname=Frame
m_code=31
m_id=1883400248470934012
m_state=2
m_master_id=-492343618703753414
m_owner_id=-9178736643823363944
m_children=15
{...}
m_children=15
{...}
...
m_children=15
{...}
m_center.x=0.000152588
m_center.y=18.7003
m_mass=7826850.0
m_mesh=1073741827
{
m_classname=Mesh
m_size=0
}
}

 
 
The first m_children=15 child node there is unique – that’s a bridge:
 
 

{
m_classname=Body
m_code=15
m_id=481579170968876493
m_name=COMBRIDGE
...
m_children=47
{...}
...
m_mesh=1073741827
{...}
...
m_oid=MDL_COMBRIDGE_01
...
m_sprites=536870915
{...}
...
m_sprites=536870915
{...}
m_slots=2147483651
{...}
...
m_slots=2147483651
{...}
}

 
 
And finally – the m_children=47 node, which hauls the ship’s global stats:
 
 

{
m_classname=Creature
m_code=47
...
m_mesh=1073741827
{...}
m_layer=0
m_health=10
m_health_lock=true
m_ship_name=Archangel
m_playable=true
m_alignment=1
m_card_caption={align=2}{font=courier_28}ÀÐÕÀÍÃÅË@{font=myriad_10}ÓÄÀÐ. ËÅÃÊÈÉ ÊÐÅÉÑÅÐ
m_card_main={align=0}{font=flash_large}ÒßÃÀ/ÂÅÑ: [email protected]ÑÊÎÐÎÑÒÜ: 190 êì/÷@ÄÀËÜÍÎÑÒÜ: 820 êì@
m_card_arma={align=0}{font=flash_large}ÂÎÎÐÓÆÅÍÈÅ:@004X CANNON [email protected] CANNON [email protected] MISSILE
m_card_modules=MDL_CANNON_57_2=4,MDL_ENGINE_04=8,MDL_ENGINE_05=2,MDL_CANNON_180_2=2,MDL_MISSILE_01=2,
m_bio_caption={align=2}{color=2281701376}{font=courier_28}[email protected]¹981
m_bio_snapshot=no_photo
...
creatureId=2
m_damageCounter=8360
versionCompatibility=Ñîâìåñòèì ñ âåðñèåé 1.15
}

 
(The abracadabras are cyrillic decoding issues; everything looks OK in the game)
 
 
This node contains lots of ship global stats, which define how far/fast/long it can fly/see/be seen. It’s important to know that there’s no sense to change them if you want to alter ship’s speed, range or sensor strength; these are used mostly for spawn computations or GUI visualisations. What’s really important there is the m_flagship flag which you may set to “true” is you want the ship to be recognised as a flagship.
 
 
If you want to mess with ship stats, it’s better to change ship module stats and then force the game to recompute global stats. Module entries are very similar to ones in parts.seria, with some differences:
 

  • Guns, sensors, jammers, missiles, … (everything with an arc) get a m_sectorsrepeating attribute, 360 entries per part. It’s one/zero for guns/missiles, ELINT power value for ELINT (zero, full or half if obstructed) and radar range in km for radars (zero/full/half).
  • m_position.*, m_scale.* and m_angle attributes now make sense and define the module location. m_scale is being used to flip symmetric parts like legs/engines.
  • Maybe some other misc stuff I missed, since I avoid touching the tech attributes

 
Read the corresponding guide section about ship updating after you changed the module values.
 
 
 

Save Files

This section is under construction, since I’m styding this at the moment. But with a save editing you can potentially do:
 

  • Spawn additional enemy groups, alter compositions of already existing ones
  • Change shop stocks
  • Change intel amounts in cities
  • Many more

You can also change your cash bonus there (“m_scores” root node attribute, e.g. m_scores=76886) and unlock ships (including hidden/unused/AI-only) by flipping a corresponding flag.
 
 
 

Localization Files

There are two main reasons to edit localization files:
 

  1. Making description entries for new parts/ships
  2. Altering events’ outcomes

 
Localization files are located at Data/Dialogs folder. Refer to this guide for details:
 
HighFleet Dialogue Modification – [steamcommunity.com] 
 
 

Ship entries

 
There are two entries you may want to edit if you want to add a ship desc:
 
 

#SHIP_NAME_Nomad Nomad

 
A “SHIP_NAME_*” entry is mainly needed for Russian version where it allows to add a cyrillic ship name. The “*” should be replaced with a ship “m_name” root node attribute value (or a “m_ship_name” in ship global stats? They are mostly the same).
 
 

#SHIP_DESC_NOMAD Romani heavy strategic cruisers, which have been serving as a core of command groups for decades. Despite their age, they have undergone an extensive amount of upgrades and participated in field tests of the state-of-the-art AEW systems, which were planned to be installed later on the newest Sevastopol-class cruisers under construction.

 
“SHIP_DESC_*” is what you’re looking for if you want to add a description visible at a campaign start. Note that a ship name plugged in “*” is capitalized there. Also note that a tag and a text are being separated by tabulations and have no newlines.
 
 

Part entries

 
 

#MDL_CANNON_220 M-22
#MDL_CANNON_220_SDESC CANNON
#MDL_CANNON_220_DESC A 180mm large-caliber cannon with an increased fire rate.

 
If you want to add a module entry there, you will need an entry for a name, type and description (MDL_*, MDL_*_SDESC, MDL_*_DESC where * is a module m_oid).
 
 

Events

 
Dialogue files also contain some rewards/penalties you get from events. While some outcomes are being hardcoded (like new ships, forced stays, no repairs/refueling in a city, …), cash/rep/morale may be altered there.
 
 

#INTERCOM_FASIL_1 <NPC=FASIL><SIDE=0><SHADOW=1>Yes, Duke?<ANS=I’d like to ask you for a loan to supply this campaign, Prince.>
#INTERCOM_FASIL_2 <NPC=FASIL>War is an expensive undertaking, is it not, my Duke?
<ANS=Alas, it most certainly is. Can you lend me a hand, Prince?>
<ANS=I’ve changed my mind, Prince. My apologies. That will be all.|EXIT>
#INTERCOM_FASIL_3 <TRG=INTERCOM_FASIL|1><NPC=FASIL>Very well. I’ll get the money together.<SCR=STOP|GOLD=10000|FASIL=-1>
#INTERCOM_FASIL_SHORT <NPC=FASIL>Very well. I’ll get the money together.<SCR=STOP|GOLD=10000|FASIL=-1>

 
You may also tweak a dialogue “direction” in terms of sprites/fade effects.
 
 
 

Making New Parts

Before we move on making new parts, let’s denote what we won’t be able to do:
 

  • We cannot add new parts into shipworks without replacing something that already exists
  • We cannot add new parts into stores (* without save editing)

 
The process is very similar to the one described in this guide, with minor alterations:
 
Making Wheels Available in Ship Editor – [steamcommunity.com] 
 
 
The pipeline is following:
 

  1. Choose a vanilla module which is closest to something you’re going to make
  2. Duplicate its entry in OL.seria, alter its m_oid and stats
  3. Go to Libraries/constructor.seria (make a backup) and remove the
     
     
     
     
     

    m_children=15
    {
    ...
    m_oid=ITEM_EMERGENCY
    ...
    }
    

     
     
     
    node to free some space.

  4. Go to parts.seria, pick a vanilla module entry and paste it into constructor.seria instead of a deleted node.
  5. Set m_oid, m_master_id (!!!important!!!!, the value is the constructor.seria root node “m_id” value)
  6. Alter the stuff you want – HP, density, mass, …
  7. Do not forget about module mesh, sprites, slots.
  8. Start the game and go into shipworks

Now the last module category will be replaced with the module you just created. Note that you don’t need an entry in parts.seria – once you install a part on a ship, it will be written in a ship file and will only refer to OL.seria.
 
 
HighFleet - HighFleet Modding Guide Tutorial - Making New Parts - 87FAA93
 
The game got some unsused sprites, but there isn’t much. OTOH, you can still create new visuals if you are creative with the sprites you already have. For example, the M-22 180mm cannon was created based on a Mk-1-180 sprite with a new barrel made of Sprint+flare and a muzzle brake made of a hull block.
 
 
Don’t forget to create corresponding entries in dialogue files, otherwise the name and description will be empty.
 
 
 

Ship Replacements and Updating

Another potential mod you may want to develop is vanilla ship replacements. Vanilla ships are treated in a separate way and are kept in Objects/Designs folder. They cannot be deleted in the game neither overwritten in the shipworks.
 
 

Replacements

 
If you’re going to replace a vanilla ship with your own, the pipeline is following:
 

  1. Open both vanilla and custom ships in editor
  2. Change the custom ship’s “m_name” (root node attr) to the vanilla ship value
  3. Change the name in “m_card_caption” (global stats section) to the vanilla name
  4. Change the “m_ship_name” stat (global stats section) to the vanilla name
  5. (Optional) change the “m_combatvalue” stat, which affects how many instances of the ship will spawn in shipworks testing (and maybe in garrisons).
  6. (Optional, old versions) change the “m_card_snapshot” path (global stats section) to the vanilla snapshot path (which you will also need to replace)

Note that from version 1.151 the game won’t generate snapshots and will derive them from a ship file, so the last step will be redundant and the “m_card_snapshot” won’t be present.
 
 

Ship updating

 
You may want to update all the ships (including vanilla) after you tweak parts.seria or ship modules. There are 79 vanilla ships, so pick a vacation and start from Archa…
 
 
JK, lol, there are some mechanisms implemented which are intended to help you with that:
 

  • The game may update some stats by itself
  • DIY scripts may be written to update ship files

 
If you launch a new version of the game first time, it will update everything in Ships folder and will place the old copies in Ships_backup. What it does recompute:
 

  • Weapon firing arcs
  • Sensor arcs (it may fail there)
  • All global stats
  • Density/mass (probably, not confirmed)
  • Elevation (probably, not confirmed)

To force the game to do that, open Config.ini and change “CORE_LAST_LOADED_VERSION=1.15” value to some older one, like 1.14 or 1.1.
 
 
However, it won’t pull all the data from parts.seria by itself. If you modified the parts.seria and want a ship to get new values, before performing the step above you need to alter part entries in a ship file first. I have written some Python scripts for that by myself, and will release them soon.
 
 
So, the ship update pipeline is the following:
 

  1. Pick a ship file
  2. Alter by yourself/update with a script module entries there
  3. Put it into Ships folder (make a folder backup, just in case)
  4. Change the game version in Config.ini to some older one
  5. Run the game

 
 
 

Conclusion

HF is a fascinating game, and as any fascinating game a mod support will significantly contribute to its life cycle. Assuming that it’s a two-people pet project, i’d vote for filling the game with content by players and focusing on an extensive mod support by devs, as many other great games (e.g. Rimworld) do.
 
 
 

Planned sections

Textures – how to edit and add some new.
 
Levels – how to manipulate them in a meaningful way.
 
 

Written by Radiant Dawn

 
 
I hope you enjoy the Guide we share about HighFleet – HighFleet Modding Guide Tutorial; if you think we forget to add or we should add more information, please let us know via commenting below! See you soon!
 
 


Be the first to comment

Leave a Reply

Your email address will not be published.


*