Horizon's Gate

Horizon's Gate

Not enough ratings
[2021 Guide] Create a Modded Class
By PauI
A makeshift, unfinished, and rushed guide on creating a modded class at 4 AM.

Guide made in 2021.
2
   
Award
Favorite
Favorited
Unfavorite
0. Before You Start
Referencing
Modding is pretty hard if you don't know how anything works! That's fine since a lot of stuff for Horizon's Gate isn't hardcoded, meaning that you can going through the game files, especially class actions and support abilities, will help you get good. Additionally, you can copy paste existing abilities and modify them to work in many imaginable ways.
The game's files are stored in
C:\Program Files (x86)\Steam\steamapps\common\Horizon's Gate\Content

Debug Mode
In order to be able to refresh mods and access the build menu, you will need to enable debug mode. To do this, open the command console by pressing Shift + `, type in dm, and press Enter.
If this does not work for you, go to ...\AppData\Roaming\BoatTactics, open up config.ini, and change debugMode=False; to debugMode=True;.

Image Editing Software
Two programs that I use for editing png files are Paint Dot Net[www.getpaint.net] and GraphicsGale[graphicsgale.com]. If you have a program that you are more comfortable with, it will probably work too.

Modding Help and Questions
There is an official basic modding guide that can be found here:
https://steamhost.cn/steamcommunity_com/sharedfiles/filedetails/?id=2059418137

Being simply a passionate gamer, I am sadly not an omniscient modding expert. However, there is an official discord server you can join which also has a modding channel:
https://steamhost.cn/steamcommunity_com/app/1224290/discussions/0/1753528528117772103/
0.1 The Short Version of the Guide because there's too many unnecessary things that makes class modding harder than it should be
The tldr guide if you don't want to read through the entire guide.
1 Make your modded class folder with a text file for the actorClass, abilities, and passives.

1.1 (Optional) Make a class template or download it from
here so you don't have to set up class files again when creating new classes.

2. Make 5 abilities and 2-4 passives for your class. It is recommended to use existing abilities as a reference or template. Passive (support abilities) templates can be found in
C:\Program Files (x86)\Steam\steamapps\common\Horizon's Gate\Content\ModSamples

3. Make icons and sprites for your class abilities, passives, and armor sprites.

4. Configure the actorClass text file to have a unique ID, the IDs for all the abilities and passives, skills, etc.

5. Test your class to see if it works correctly.

5.1 (Optional) Balance your class through extensive testing.

6. Upload to Workshop.
1. Planning It Out
Planning out a class is technically optional but encouraged.

Use something like Notepad to write down your class concept, its five abilities, and what passives they might have. As you create your class, you can amend your concept as you see fit.


Class Role
What is the purpose of your class? Is it a weapon-specialized fighter with abilities revolving around certain elements or perhaps an all-rounder support that buffs your allies through unique ways. Alternatively, you can grab (or be inspired by) some cool concepts and classes from other sources and translate them over! The possibilities are endless...


Abilities
All classes have a total of five abilities.

While writing up abilities, you should phrase it as if it were the description of the ability. Not only do you now have the description for your ability, you can find similar, existing abilities that functions similar to what you have planned.

Additionally, there is no format in what balance of ability types you should have, so you can simply have all support-based abilities, half support and half offensive abilities, all simple or all complex, etc. Simple abilities are easier to make and should likely work well with other classes without many worries for balancing. Complex abilities are more difficult to work with and balance around, but they do tend to be more awesome and epic! Personally, I stick towards this style of ability sets, but it isn't a requirement to follow this format:
  • Simple/Main - A super simple ability or the ability that the class is based around.
  • Effect/AoE - A debuff ability, AoE ability, ranged ability, and/or buff ability, etc.
  • Effect/AoE - Same as above but preferably a different ability type.
  • Self/Req - The ability that leads to ULT or ability that inflicts an effect on self.
  • Ultimate - The expensive but epic and (over)powerful ability that beats people up.
Alternatively, you can brainstorm a large list of abilities before choosing five that you would decide to wrap up in a single class mod.

Passives
Generally, classes have between two and four passives.

These passives can be anything, from as a counter or start-of-combat effect to a requirement or overhaul for your class and its abilities!


Alternatively, you can skip doing any of this if planning things out isn't your strong suit.
2. Class Template
Now that you've planned out your class, it's time to layout the folders and text files where all the coding shenanigans go!

But if you want to skip all the tedious setups, go subscribe to this mod
https://steamhost.cn/steamcommunity_com/sharedfiles/filedetails/?id=2422138719
Copy the folder
C:\Program Files (x86)\Steam\steamapps\workshop\content\1224290\2422138719
and paste it in
C:\Users\...\AppData\Roaming\BoatTactics\Mods
Rename folders, text files, and AV/actorClass/etc IDs accordingly. After copy and pasting the folder, you can unsubscribe from the mod (unless you really like it... and in that case you can keep it subscribed).

If you hate organizing your mod, then you can skip this step.



If you would rather setup from scratch, then do this:
1. Create a new folder in
C:\Users\...\AppData\Roaming\BoatTactics\Mods
1.1 In that folder, create two folders (Armor and Icons), three text files (Actions, ActorClass, and Passives), and a 512x512 PNG image with the same name as your folder name.
2. Go to
C:\Program Files (x86)\Steam\steamapps\common\Horizon's Gate\Content\Data\SystemData\Definitions\actors
3. Open up actorClasses.txt, copy an ActorClass, and paste it into a new text file in the folder in your mods folder.
4. Respectively copy the icon_default, emptyPassiveSlot, and classIcon_none from
C:\Program Files (x86)\Steam\steamapps\common\Horizon's Gate\Content\Images\Icons\abilityIcons, C:\Program Files (x86)\Steam\steamapps\common\Horizon's Gate\Content\Images\Icons\passiveIcons, and C:\Program Files (x86)\Steam\steamapps\common\Horizon's Gate\Content\Images\Icons\classIcons
and paste it in your Icons folder.
5. Rename all the IDs and things. Super important.

Congrats! You've finished setting up the minimal folder for your class mod!
3.1 ActorClass and JournalEntry
The ActorClass is the main def for your class. In it, you specify the abilities and passives it contains. You will also specify what skills the class will modify when equipped as primary and what skills you can raise with * stat points.
The JournalEntry is the def for a journal entry (wow!).

That's pretty much it.

Here is a quick and messy rundown of the ActorClass and JournalEntry and their components.

[ActorClass]
The ActorClass is basically the main def for your class. You should set the ID to a unique ID as having the same IDs will cause overwrites.

Property
Description
icon
The 16x16 icon that will appear in the class menu. Set this to the unique name you gave to the class icon png file. (Ex. if your class icon is called classIcon_coolClass.png, then it should be icon=classIcon_coolClass;)
journalID
The ID for journal entry. Set to the ID of the related journal.
description
The tooltip that shows when hovering over the class icon in the class menu.
paletteUI
The palette color given to the upgrade icons at the bottom of each ability icon.
actions
This will give the class the actions specified by the ID.
supportAbilities
Your passives.
relevantStats
Specifies which stats can be upgraded with stat points (*).
requiredStat
Specifies what class XP is required to unlock the class. It is formatted as classID_XP_total;. The classID is the ActorClass ID. You can find the IDs for vanilla classes in the main game's actorClasses text file.
requiredAmt
Specifies amount of XP required in preceding class to unlock the class.
bodyPartSprite
Specifies the PNG file used for the body part's sprite. I recommend leaving these with sailor sprites until you start creating your own custom sprite. If you don't plan on creating your own sprite, you can mix and match from the main game's sprite folder: C:\Program Files (x86)\Steam\steamapps\common\Horizon's Gate\Content\Images\Actor\BodyParts\classes.
ActorClassEffect
Grants specified stat mods when the class is equipped as the primary class. actorValue defs can be found from the main game's existing classes and abilities. magnitude is the amount to increase/decrease the specified actorValue stat by. duration should always equal -1 (indefinite).


[JournalEntry]
The JournalEntry for the actorClass is relatively straightforward.

Property
Description
ID
The journalEntry's unique ID. Should be same as specified in the actorClass's journalID
rarity
Will affect how much money will be gained when selling info about this class to a researcher.
text
icon should be the same as the actorClass's icon. Change titles accordingly. Start your description after the <brAdj=> break.
3.2 Action Abilities
Creating the Action def
First, open up your actions text file. This is where all of your actions defs are gonna go:
Then, you open up the folder of the game's existing actions:
C:\Program Files (x86)\Steam\steamapps\common\Horizon's Gate\Content\Data\SystemData\Definitions\actions\class actions

Afterwards, find the ability that is mechanically similar to what you had in mind.

For example, if I wanted to make an action ability that inflicts poison on the target and then push them back, I would copy the action def of Warrior's Bash and the poison AvAffecter and AvAffecterAoE from Rogue's Poison Tip and paste them together in the mod's actions text file.

Afterwards, the IDs will all be changed to a new unique ID used by the modded class. The action will be executed from top to bottom (if not, use FXOnTile=delay; to delay a certain AvAffecter), so the poison AvAffecter and AoE must come before the Push AvAffecter and AoE.



Below are the rundowns of the components:

[Action]
Property
Description
icon
Specifies the PNG file to be used as the ability icon.
tooltip
The description of the ability that displays when you hover over the ability.
rankUpTooltip
The description that tells you what is upgraded when you rank up the ability.
tooltipIcons
The small icons that appear at the bottom of the description box.
tooltipTopRight
The small icons that appear on the top right of the description box.
mpCost
The MP Cost of the ability. Remember to include d:mpCostMult and d:mpCostMod (and others for charging/casting abilities) in order to make it compatible with Balancer's Quick Cast passive (and any other mods that may utilize the mpCost formulas).
castTime / chargeTime
The casting time in TTA (Time to Act) before the action is executed.
cooldown
The cooldown in TTA (Time to Act) for the action before it can be used again.
AIRatingBias
The tendency for the AI to use this ability over any other actions. A negative number will deter the AI from using the ability while a positive number will encourage the AI to use the ability. This is only really important if you plan to make your class compatible with AI.
XPCost
The XP Costs (in order from top to bottom) required to unlock the next rank. The number of XPCosts=; should equal your max rank. The first XPCost is the amount of XP required to first unlock the ability.
maxRank
Amount of ranks that the ability can be upgraded to. Should correspond to the number of XPCost properties in your action.
casterAnimation
Animation that the actor plays when the ability is activated. Defs for these can be found in other actions or here (link later).
casterAnimationSpeed
The speed that the animation plays at. Higher value is faster.
CanExceedMaxRankBy
Whether the action's rank can go above the maxRank (through ability tablets). From what I tested, the max exceed is 1 (but you yourself can always try to go higher!).
requiredWeaponElement
The required element of your held weapon in order to use this action. Can be omitted if your actions does not require a weapon.
FXOnTarget
Effect that plays on the target while casting.
FXOnCaster
Effect that plays on the Caster while casting.
special
Additional modifications or specifications that the action may have. For instance, special=doesNotConsumeCombatAction; makes the ability not use up the actor's action when executed.

[ActionAoE]
The ActionAoE acts as the area of target for your action (where you can select and target with your cursor).
  • cloneFrom My favorite thing to use. Specifies AoE and makes it easy as well. Outside of Actions, can be used to copy existing values of other defs and be used to perform soft overwrites.
  • shape The AoE shape of the action. Here is a list of shapes provided by Eldiran (Rad Codex) himself!
    plusShape = 0, //ignores move cost walkpathShape = 1, //accounts for move cost walkpathShape_straightLinesPlus2 = 111, //accounts for move cost lineShape = 2, wideLineShape = 3, //exactly like a line, except also includes adjacent tiles. Probably laggy if used on large AoEs. player = 5, playerParty = 6, allButPlayerParty = 66, allActors = 7, allTiles = 8, caster = 9, allActors_nonIncapped = 17, useWeaponAoE = 10, useWeaponAVAoE = 11, diagonalX = 25,
  • needsLoS Line of Sight
  • needsLoE Line of Effect
  • minRange Minimum range (min is 1) that your action or center point can target. Should only be specified when making ranged actions.
  • maxRange Maximum range that your action or center point can target. Should only be specified when making ranged actions.
  • maxRangeBonus Bonus added to range depending on specified formula
  • canSelectActors Boolean - if the action or avaffecter can select actors or not (usually for movement abilities or aesthetic FXs)
  • canSelectAllies Boolean - if the action or avaffecter can select allies
  • canSelectEnemies Boolean - if the action or avaffecter can select enemies
  • aoeCasterAsOrigin Boolean - if the action or avaffecter's center point is on the caster
  • There are more AoE defs but I've reached the character limit
3.2.1 AvAffecters
[AvAffecter]
The AvAffecter is where all the effects and mechanics are performed. They are succeeded by an AvAffecterAoE that specifies an AoE for the given AvAffecter. AvAffecters are executing in order from top to bottom.
  • visibleMiss boolean - if the Miss appears when the effect misses
  • visibleEvaluations boolean - if the percentages and effects are displayed in the pre-attack tooltip.
  • harmful boolean - if the effect is harmful. Required to be true when inflicting negative magnitude against HP and MP actorValues.
  • weaponAvAffecter boolean - if the action also utilizes the actor's held weapon's avaffecters.
  • showWeaponAvAffecterFX boolean - if action also displays FX made by the weapon's avaffecters
  • actorValue The specified effect or condition to inflict or modify on a target.
  • magnitude Power or change in the actorValue.
  • chance Accuracy of the effect. All chances use the same roll unless specified.
  • useSeparateChanceRoll Specifies that the AvAffecter uses a different roll than the roll before. Its use can be found most prominent in Brawler's Pummel.
  • duration The specified duration of the effect. -2 is permanent. -1 is indefinite. Anything >= 0 is defined in TTA (Time to Act). -3 is until the start of the actor's next turn. -4 is until the end of the actor's next turn. -5 is until the end of the actor's turn after the next turn, etc.
  • element The element that defines the effect. Used to trigger passive and environmental reactions, etc
  • FXOnHit Effect that plays when you hit the target
  • FXOnTile Effects that plays on the selected tile(s) when the ability is casted
  • FXOnHitColor/FXOnTileColor Color (XNA/C#) of the preceeding effect. Search up for XNA color chart to find all the available colors.

[AvAffecterAoE]
The same thing as ActionAoE but also overrides ActionAoE and only affects the preceeding AvAffecter.
3.2.2 Custom Sound Effects
Want to add custom sounds to your actions? Make your guy say some edgy catchphrase before doing an epic attack?

It's simple.

First download your song or SFX or whatever. If it isn't in .wav format then convert it. Length of the song or SFX too long? Trim it somehow (preferably at most down to 10 seconds if you're making a minstrel-like ability).

Afterwards, toss your finely trimmed .wav file into your mod folder. The example sfx I will use here is So_Good.wav.

Now make a random [drawOrderFX] and toss it in a text file somewhere!

Here's the [drawOrderFX] I have:
* This is LITERALLY the megapop draw order from the ModSamples folder but just has the ID called nothingFX and doesn't have [drawOrderFXLight] (I tried using the megapop drawOrder as well as no particleFX ID but both will result in a crash. If you find any vanilla drawOrder that works then uh please comment it :^) ).
[drawOrderFX] ID=nothingFX; texture=fx_pop; sourceRect=0,0,16,16; origin=0,0; pR = ; pG = ; pB = ; speed=1; timePerFrame=0.1; initialDelay = 0; duration=0.4; removeAtDestination = false; stopAtDestination = true; flickerEveryFrame = false; veloc=0,0; accel=0,0; rotVeloc=0; rotAccel=0; scaleVeloc=0; scaleAccel=0; alphaVeloc=0; alphaAccel=0; addRotToTextureID = false; rotateBasedOnVelocity = false; roundRotToNearest = 0; useTerrainDepth = false; loop = true; ignoreDarkness = false; scaleLightSizeAndAlpha = false; loopAroundZoneEdge = false; drawOnlyIfRoofsAreDrawn = false; playWhileGameIsPaused = false; spawnFXatEnd =; spawnFXatEndColor =; spawnFXatEndAoEID =; spawnFXatEndIfActorNear =; spawnFXatEndIfActorNearColor =; spawnFXatEndIfActorNear_distance = 1;

Alright now you gotta make your [FXData]. Pretty simple work:
[FXData] ID=sfx_soGood; -- sfx_ recommended naming convention particleID=nothingFX; -- the useless particle that you will not use numParticles=0; -- the particles will never exist! soundName=So_Good; -- .wav file name (without the extension) soundVolume = 1.5; -- adjust accordingly soundPitch = 0; soundDistanceMult = 1; soundDropoffDist = 10;

Now toss your new SFX into your action!
FXOnTile=sfx_soGood;

So good. You now know how to commit custom sound effects!
3.3 Passives
If you haven't already, grab the sample SupportAbility from
C:\Program Files (x86)\Steam\steamapps\common\Horizon's Gate\Content\ModSamples
and paste it into the passive text file in your class mod folder then edit it from there.

Passives were formerly hardcoded, so the only template available is in the ModSamples folder. It's best to look at other existing class mods or ask others on the discord if you need help with them.

Below are the rundowns for it I guess:

[SupportAbility]
  • ID Self explanatory at this point.
  • name Displayed name of the passive
  • icon Specified PNG file to be used as the passive icon
  • tooltip Displayed description when hovering over passive
  • XPCostUnlock The XP requirement to unlock the passive
  • supportAbilsToReplace Basically what other passives this passive cannot be used with
[SupportAbilityEffect]
The basic indefinite stat change passives. Super simple and easy to add.
  • actorValue Specifies what AV is being modified
  • magnitude amount changed by. Positive to increase, negative to decrease.
  • duration should always be -1
[SupportAbilityReaction]
Passive that reacts to certain effects through multipliers or an action reaction.
  • actorValue Specifies the effect that is causing the reaction. Otherwise if it is an element, use element instead.
  • element Specifies the element that is causing the reaction.
  • damageMultiplier multiplies the damage (for attacks) and accuracy (for status effects and conditions) by specified multiplier.
  • action The action that is executed when the specified effect or element is inflicted on the actor.
[Action]
Exact same format as an action ability, but with some additions to make it work as a passive reaction. The following is an example of an action for a SupportAbilityReaction:
[Action] ID=support_act; icon=icon_supportAbility; harmful=false; special=usableEvenWhenCantAct; special=usableEvenWhenReacting; special=usableEvenWhenYourTurn; [ActionAoE] ID=support_act; cloneFrom=oneTile; canSelectStackedActors=false; [AvAffecter] ID=support_act; actorValue=PhysDef; harmful=false; visibleMiss=false; magnitude=c:PhysAtk; duration=-6; chance=100 * m:cCritical; FXOnHit=screenShock_instant; [AvAffecterAoE] ID=support_act; cloneFrom=oneTile;

It is ideally required that you have all the defined specials in your SupportAbilityReaction's action. The ID for the action should also be the same as the one specified in your SupportAbilityReaction. It is also recommended that you use the visibleMiss boolean to avoid Miss spams.
3.4 Icons and Armor Sprites
Icons
Use your image editing software to create the icons for your class and its abilities and passives then rename them to match the names you specified for icons in your actorClass, actions, and passives text files.

I recommend grabbing the blank icons, recoloring them, then duplicating them to make the process less tedious.

Class Icon:
C:\...\steamapps\common\Horizon's Gate\Content\Images\Icons\classIcons\classIcon_none.png
Ability Icon:
C:\...\steamapps\common\Horizon's Gate\Content\Images\Icons\abilityIcons\icon_default.png
Passive Icon:
C:\...\steamapps\common\Horizon's Gate\Content\Images\Icons\passiveIcons\emptyPassiveSlot.png


For uniformity, it is highly recommended that you use the same or similar selection of color combinations for all of your icons. For instance, if your action ability's icon has a blue background, the class's palette, support ability icons, and probably also the class icon should have blue as the dominant color. Of course, you don't have to abide to this. It's your mod so do what you want!

Here's an example where red is the main color and green is the secondary color.





Armor Sprites
Armor sprites... The bane of my existence...

You can grab existing sprites that you can then edit from here:
C:\Program Files (x86)\Steam\steamapps\common\Horizon's Gate\Content\Images\Actor\BodyParts\classes

Copy and paste 1-2 arm(s), a torso, and 1-2 shoulder(s) into the armor folder in your mods folder. If you are planning to make custom sprites, rename the newly pasted sprites and change the bodyPart names in your actorClass text file to match the names for your PNG sprites. Afterwards, draw up and modify the sprites. Sprites use the RGB palette, so grab the colors from the game's other RGB sprites using the eyedropper if you need to.

Here is a general rundown of what each color supposedly does:
Violet: Transparent
Red: Color palette from worn armor (Armor color)
Blue: Color palette from actor's clothing (Clothing color)
Green: Color palette from actor's skin (Skin color)
Black: Outline of sprite (or just black)
White: Just white

Helpful Tip:
While in debug mode, enter build mode by pressing B and press CTRL + R to refresh your mods which also adds changes you make to your sprite. This makes it easier to do trial and error pixel spriting especially when using pdn or graphics gale :)

However, your game can crash or you might get warnings and errors if you refresh with other mods enabled, so it is best to use mod refresh for solely trial-and-error spriting. Although you can refresh abilities and passives this way, I would recommend restarting the game instead.

Alternatively instead of creating new sprites, you can just use the existing ones as is or even mix-and-match.
4. Finishing Touches and Upload to Workshop
Dependencies
If you have additional mod dependencies, such as relating to new status effects or items, either include them in the mod or make a requirement on the workshop for a separate mod dependency.

Debugging and Balancing
Make sure to rapidly test your class to see if it works. If there's a game crashing bug or something, identify the cause based on the error log and go in and fix up the most likely typo. Testing your class for formula scale problems and gamebreaking errors is a required phase that can take some time. Basically, make sure your class mod works! If some things slip through, then try to fix it as soon as possible once you find it or when someone reports it.

For balancing, I would recommend doing a few runs on Ruin difficulty or so. If you cannot do that (I can't either), then get someone else to playtest it for you. Although balancing is extremely recommended, you can also skip the whole balancing thing. You can continue balancing the mod after public release, after all.

Uploading to Workshop
1. Make sure your class mod folder is in the HG mod folder
C:\Users\Username\AppData\Roaming\BoatTactics\Mods\YourClassModFolder

2. Launch Horizon's Gate


3. Select Mods and go down to where your mod is at.


4. Click the Upload button and enter the Class tag.


5. Upload and go edit your workshop page.




And there you go. Class mod. Yay.
4 Comments
Ra'Ello 25 Jul, 2022 @ 1:43pm 
thank you very much
PauI  [author] 24 Jul, 2022 @ 12:38pm 
In the ActorClass def, there are two separate arm properties:
bodyPart1=armR;
bodyPartSprite1=sprite_arm;
bodyPart2=armL;
bodyPartSprite2=sprite_arm;

sprite_arm is the name of the png spritesheet. You can replace each with the different sprite.

All the vanilla spritesheets are in the directory C:\Program Files (x86)\Steam\steamapps\common\Horizon's Gate\Content\Images\Actor\BodyParts\classes\arms
Ra'Ello 24 Jul, 2022 @ 7:31am 
do you know how to make two different sprites for actor's pixel arms? Like the Ranger and Sharpshooter classes for example.
streets of rogue lineage