Difference between revisions of "Script Modding Guide"

From Holdfast: Nations At War
Jump to navigation Jump to search
 
(131 intermediate revisions by 4 users not shown)
Line 1: Line 1:
= SDK Modding Script Documentation =
+
{{ContentTemplateModernInline
 +
| welcome = Getting Started
 +
| blurb  = Set up your environment, understand core concepts, and ship your first Holdfast script mod.
  
To start with script modding in holdfast, create a new mod and in this mod’s folder create a new script. This script should implement the shared interface “IHoldfastSharedMethods”.
+
| sections_title  = On this page
 +
| sections_content =
 +
* [[#Getting Started|Overview]]
 +
* [[#Setting Up Your Environment|Setting Up Your Environment]]
 +
** [[#Connecting Unity to your editor|Connect Unity ↔ Editor]]
 +
** [[#Creating your mod|Create Your Mod]]
 +
* [[#Core Concepts|Core Concepts]]
 +
** [[#Shared Interface|Shared Interface]]
 +
** [[#Client or Server, what are those?!|Client vs Server]]
 +
** [[#Mod Install and Load Types|Install & Load Types]]
 +
** [[#Mod Variables|Mod Variables]]
 +
** [[#Security Concerns|Security]]
 +
** [[#Gotchya's|Gotchas]]
 +
* [[#RC commands specific for modding use|RC Commands for Modding]]
 +
* [[#IHoldfastGame|IHoldfastGame]]
 +
* [[#IHoldfastSharedMethods|IHoldfastSharedMethods]]
 +
* [[#IHoldfastSharedMethods2|IHoldfastSharedMethods2]]
 +
* [[#IHoldfastSharedMethods3|IHoldfastSharedMethods3]]
 +
* [[#SharedMethods Copy/Paste|SharedMethods Copy/Paste]]
 +
* [[#Key Scene GameObjects|Key Scene GameObjects]]
 +
** [[#ClientScene GameObjects|ClientScene]]
 +
** [[#Main Canvas GameObjects|Main Canvas]]
 +
** [[#Menu Canvas GameObjects|Menu Canvas]]
 +
* [[#Code Examples & Resources|Code Examples & Resources]]
 +
* [[#Support|Support]]
  
For example, here’s a mod that’s called “LineFormer” that has the script called “LineFormer.cs” which implements the IHoldfastSharedMethods interface.
+
| featured_title  = Gameplay
 +
| featured_content = {{:{{FULLPAGENAME}}/Body}}
  
[[File:Script Modding Create Project.png|thumb]]
+
| image_content    =
 
+
| layout          = auto
= New RC commands specific for modding use =
+
| two_col        = no
=== Make carbon player bots not do any auto input===
+
| left_width      = 320px
  rc carbonPlayers ignoreAutoControls <true/false>
+
  | aside_width    = 320px
=== Send network trajectory info to client without showing it to players===
+
  | gap            = 1rem
  rc set drawFirearmTajectoriesInfo <true/false>
+
  | show_toc        = no
=== Send "quiet" messages to the client that only modding support can read ===
+
  | show_section_edit = no
This message is not shown to the player anywhere.
+
}}
  rc serverAdmin quietPrivateMessage <player_id> <message>
 
=== Broadcasts a "quiet" message to all clients that only modding support can read == =
 
This message is not shown to the player anywhere.
 
  rc serverAdmin quietBroadcastMessage <message>
 
 
 
= IHoldfastSharedMethods =
 
///using UnityEngine;
 
 
 
namespace HoldfastSharedMethods {
 
  /// <summary>
 
  /// Main Interface, implement this script and place the script in the root of your mod.
 
  /// </summary>
 
  public interface IHoldfastSharedMethods {
 
      /// <summary>
 
      /// The game will share an int when the mod loads. A random synchronized value (same on client and server), for example useful if you need a seed for a map generator.
 
      /// </summary>
 
      void OnSyncValueState(int value);
 
 
 
      /// <summary>
 
      /// The game will share the current synchronized time (same on client and server) on every frame of the game.
 
      /// </summary>
 
      void OnUpdateSyncedTime(double time);
 
 
 
      /// <summary>
 
      /// The game will return the seconds since the round started on every frame of the game.
 
      /// </summary>
 
      void OnUpdateElapsedTime(float time);
 
 
 
      /// <summary>
 
      /// The game will share the current remaining time on every frame of the game.
 
      /// </summary>
 
      void OnUpdateTimeRemaining(float time);
 
 
 
      /// <summary>
 
      /// The game will return if the mod is loaded on a server.
 
      /// </summary>
 
      void OnIsServer(bool server);
 
 
 
      /// <summary>
 
      /// The game will return if the mod is loaded on a client, if it is, you'll retrieve the current player's steam id.
 
      /// </summary>
 
      void OnIsClient(bool client, ulong steamId);
 
 
 
      /// <summary>
 
      /// The game will call this on round start with details regarding the current round.
 
      /// </summary>
 
      void OnRoundDetails(int roundId, string serverName, string mapName, FactionCountry attackingFaction, FactionCountry defendingFaction, GameplayMode gameplayMode,
 
        GameType gameType);
 
 
 
      /// <summary>
 
      /// The game will call this once with all the config variables set on the config file of the server.
 
      /// Note: you will receive all variables, so make sure to filter only the ones you care about.
 
      /// </summary>
 
      void PassConfigVariables(string[] value);
 
 
 
      /// <summary>
 
      /// The game will call this when a player or a bot joins the round.
 
      /// </summary>
 
      void OnPlayerJoined(int playerId, ulong steamId, string name, string regimentTag, bool isBot);
 
 
 
      /// <summary>
 
      /// The game will call this when a player leaves the round.
 
      /// Note: Bots cannot leave, they'll keep respawning once dead.
 
      /// </summary>
 
      void OnPlayerLeft(int playerId);
 
 
 
      /// <summary>
 
      /// The game will call this when a player spawns in game.
 
      /// </summary>
 
      void OnPlayerSpawned(int playerId, int spawnSectionId, FactionCountry playerFaction, PlayerClass playerClass, int uniformId, GameObject playerObject);
 
 
 
      /// <summary>
 
      /// The game will call this when a player is hurt in game.
 
      /// </summary>
 
      void OnPlayerHurt(int playerId, byte oldHp, byte newHp, EntityHealthChangedReason reason);
 
 
 
      /// <summary>
 
      /// The game will call this when a player is killed by another player.
 
      /// </summary>
 
      void OnPlayerKilledPlayer(int killerPlayerId, int victimPlayerId, EntityHealthChangedReason reason, string details);
 
 
 
      /// <summary>
 
      /// The game will call this when a player receives any score.
 
      /// </summary>
 
      void OnScorableAction(int playerId, int score, ScorableActionType reason);
 
 
 
      /// <summary>
 
      /// The game will call this when a player shoots his gun.
 
      /// </summary>
 
      void OnPlayerShoot(int playerId, bool dryShot);
 
 
 
      /// <summary>
 
      /// The game will call this when a bullet.
 
      /// Note: This requires `rc set drawFirearmTajectories true` or `rc set drawFirearmTajectoriesInfo true`.
 
      /// </summary>
 
      void OnShotInfo(int playerId, int shotCount, Vector3[][] shotsPointsPositions, float[] trajectileDistances, float[] distanceFromFiringPositions,
 
        float[] horizontalDeviationAngles, float[] maxHorizontalDeviationAngles, float[] muzzleVelocities, float[] gravities,
 
        float[] damageHitBaseDamages, float[] damageRangeUnitValues, float[] damagePostTraitAndBuffValues, float[] totalDamages,
 
        Vector3[] hitPositions, Vector3[] hitDirections, int[] hitPlayerIds, int[] hitDamageableObjectIds, int[] hitShipIds, int[] hitVehicleIds);
 
 
 
      /// <summary>
 
      /// The game will call this when a player successfully blocks another player.
 
      /// </summary>
 
      void OnPlayerBlock(int attackingPlayerId, int defendingPlayerId);
 
 
 
      /// <summary>
 
      /// The game will call this when a player starts a secondary attack (shove).
 
      /// </summary>
 
      void OnPlayerMeleeStartSecondaryAttack(int playerId);
 
 
 
      /// <summary>
 
      /// The game will call this when a player swaps their weapon.
 
      /// </summary>
 
      void OnPlayerWeaponSwitch(int playerId, string weapon);
 
 
 
      /// <summary>
 
      /// The game will call this when a player starts carrying an object.
 
      /// </summary>
 
      void OnPlayerStartCarry(int playerId, CarryableObjectType carryableObject);
 
 
 
      /// <summary>
 
      /// The game will call this when a player stops carrying an object.
 
      /// </summary>
 
      void OnPlayerEndCarry(int playerId);
 
 
 
      /// <summary>
 
      /// The game will call this when a player shouts using the ingame voice commands(not voip).
 
      /// </summary>
 
      void OnPlayerShout(int playerId, CharacterVoicePhrase voicePhrase);
 
 
 
      /// <summary>
 
      /// The game will call this when the console command is used.
 
      /// Note: This will be only called on the client, or on the server that is executing the console command.
 
      /// </summary>
 
      void OnConsoleCommand(string input, string output, bool success);
 
 
 
      /// <summary>
 
      /// The game will call this when a player requests a remote console login.
 
      /// Note: This will be called on the client that is executing the request, and the server. Not other people.
 
      /// </summary>
 
      void OnRCLogin(int playerId, string inputPassword, bool isLoggedIn);
 
 
 
      /// <summary>
 
      /// The game will call this when a player requests a remote console command.
 
      /// Note: This will be called on the client that is doing the request, and the server. Not other people.
 
      /// </summary>
 
      void OnRCCommand(int playerId, string input, string output, bool success);
 
 
 
      /// <summary>
 
      /// The game will call this when a message is received in the chat system.
 
      /// </summary>
 
      void OnTextMessage(int playerId, TextChatChannel channel, string text);
 
 
 
      /// <summary>
 
      /// The game will call this when an administrator does an admin action using the rc commands or the P menu.
 
      /// </summary>
 
      void OnAdminPlayerAction(int playerId, int adminId, ServerAdminAction action, string reason);
 
 
 
      /// <summary>
 
      /// The game will call this when an object is damaged.
 
      /// </summary>
 
      void OnDamageableObjectDamaged(GameObject damageableObject, int damageableObjectId, int shipId, int oldHp, int newHp);
 
 
 
      /// <summary>
 
      /// The game will call this when an object is interacted with.
 
      /// </summary>
 
      void OnInteractableObjectInteraction(int playerId, int interactableObjectId, GameObject interactableObject, InteractionActivationType interactionActivationType,
 
        int nextActivationStateTransitionIndex);
 
 
 
      /// <summary>
 
      /// The game will call this when an emplacement (sapper object) is initially placed.
 
      /// </summary>
 
      void OnEmplacementPlaced(int itemId, GameObject objectBuilt, EmplacementType emplacementType);
 
 
 
      /// <summary>
 
      /// The game will call this when an emplacement (sapper object) is fully constructed.
 
      /// </summary>
 
      void OnEmplacementConstructed(int itemId);
 
 
 
      /// <summary>
 
      /// The game will call this when a capture point is fully captured.
 
      /// </summary>
 
      void OnCapturePointCaptured(int capturePoint);
 
 
 
      /// <summary>
 
      /// The game will call this when a capture point changes owner.
 
      /// </summary>
 
      void OnCapturePointOwnerChanged(int capturePoint, FactionCountry factionCountry);
 
 
 
      /// <summary>
 
      /// The game will call this when a capture data changes.
 
      /// </summary>
 
      void OnCapturePointDataUpdated(int capturePoint, int defendingPlayerCount, int attackingPlayerCount);
 
 
 
      /// <summary>
 
      /// The game will call this when a buff is applied to a player.
 
      /// Note: Buffs that already exist on a player may stack, so this call will be called multiple times even if a player already has the buff.
 
      /// </summary>
 
      void OnBuffStart(int playerId, BuffType buff);
 
 
 
      /// <summary>
 
      /// The game will call this when a buff is removed from a player.
 
      /// </summary>
 
      void OnBuffStop(int playerId, BuffType buff);
 
 
 
      /// <summary>
 
      /// The game will call this when a faction vs faction round is over.
 
      /// Note: Most of them except for Army Deathmatch.
 
      /// </summary>
 
      void OnRoundEndFactionWinner(FactionCountry factionCountry, FactionRoundWinnerReason reason);
 
 
 
      /// <summary>
 
      /// The game will call this when a free for all round is over.
 
      /// Note: Only Army Deathmatch.
 
      /// </summary>
 
      void OnRoundEndPlayerWinner(int playerId);
 
 
 
      /// <summary>
 
      /// The game will call this when a vehicle(horse) is spawned.
 
      /// </summary>
 
      void OnVehicleSpawned(int vehicleId, FactionCountry vehicleFaction, PlayerClass vehicleClass, GameObject vehicleObject, int ownerPlayerId);
 
 
 
      /// <summary>
 
      /// The game will call this when a vehicle(horse) is hurt.
 
      /// </summary>
 
      void OnVehicleHurt(int vehicleId, byte oldHp, byte newHp, EntityHealthChangedReason reason);
 
 
 
      /// <summary>
 
      /// The game will call this when a vehicle(horse) is killed by a player.
 
      /// </summary>
 
      void OnPlayerKilledVehicle(int killerPlayerId, int victimVehicleId, EntityHealthChangedReason reason, string details);
 
 
 
      /// <summary>
 
      /// The game will call this when a ship is spawned.
 
      /// </summary>
 
      void OnShipSpawned(int shipId, GameObject shipObject, FactionCountry shipfaction, ShipType shipType, int shipName);
 
 
 
      /// <summary>
 
      /// The game will call this when a ship takes damage.
 
      /// </summary>
 
      void OnShipDamaged(int shipId, int oldHp, int newHp);
 
  }
 
}///
 
 
 
= Examples =
 
https://github.com/CM2Walki/HoldfastMods
 

Latest revision as of 10:54, 18 September 2025

Getting Started

Set up your environment, understand core concepts, and ship your first Holdfast script mod.

Navigation menu