The Ultimate HighFleet Modding Guide

The Ultimate HighFleet Modding Guide

Intro


The Ultimate HighFleet Modding Guide image 1

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[www.nexusmods.com]

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.

MeshesA 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.

SpritesThe 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, ...)

SlotsSlots 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}ÒßÃÀ/ÂÅÑ: 4@ÑÊÎÐÎÑÒÜ: 190 êì/÷@ÄÀËÜÍÎÑÒÜ: 820 êì@ m_card_arma={align=0}{font=flash_large}ÂÎÎÐÓÆÅÍÈÅ:@004X CANNON 2x57mm@002X CANNON 2x180mm@002X 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}PROFILE@¹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_sectors repeating 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 moreYou 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:

Making description entries for new parts/ships

Altering events' outcomes

Localization files are located at Data/Dialogs folder. Refer to this guide for details:

HighFleet Dialogue Modification

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

#SHIP_NAME_Nomad NomadA "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).

EventsDialogue 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


The Ultimate HighFleet Modding Guide image 114

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

The pipeline is following:

Choose a vanilla module which is closest to something you're going to make

Duplicate its entry in OL.seria, alter its m_oid and stats

Go to Libraries/constructor.seria (make a backup) and remove the

m_children=15 { ... m_oid=ITEM_EMERGENCY ... } node to free some space.

Go to parts.seria, pick a vanilla module entry and paste it into constructor.seria instead of a deleted node.

Set m_oid, m_master_id (!!!important!!!!, the value is the constructor.seria root node "m_id" value)

Alter the stuff you want - HP, density, mass, ...

Do not forget about module mesh, sprites, slots.

Start the game and go into shipworksNow 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.

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.

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

Open both vanilla and custom ships in editor

Change the custom ship's "m_name" (root node attr) to the vanilla ship value

Change the name in "m_card_caption" (global stats section) to the vanilla name

Change the "m_ship_name" stat (global stats section) to the vanilla name

(Optional) change the "m_combatvalue" stat, which affects how many instances of the ship will spawn in shipworks testing (and maybe in garrisons).

(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 updatingYou 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:

Pick a ship file

Alter by yourself/update with a script module entries there

Put it into Ships folder (make a folder backup, just in case)

Change the game version in Config.ini to some older one

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.

Source: https://steamcommunity.com/sharedfiles/filedetails/?id=2768442721					

More HighFleet guilds