---
# System prepended metadata

title: Whip's Railgun Framework Analysis - The Framework That Saved Space Engineers Modding

---

# Goal
To map out Whip's Railgun Framework for easier understanding.
https://steamcommunity.com/sharedfiles/filedetails/?id=2013340341


# RexxarsCommunicationFramework/
# RexxarsCommunicationFramework/Communication.cs

1.  `Communication` class:

    -   This is a static class containing methods for communication.
    -   It uses various Space Engineers and Rexxar's Framework namespaces.
2.  `private static List<IMyPlayer> _playerCache = new List<IMyPlayer>();`

    -   A private static list of `IMyPlayer` objects used to cache player information.
3.  `public static void Register()`

    -   This method registers a message handler using `MyAPIGateway.Multiplayer.RegisterMessageHandler`. It registers a handler for a message with the ID `FrameworkConstants.NETID_RECHARGE_SYNC`.
4.  `public static void Unregister()`

    -   This method unregisters the message handler previously registered in the `Register` method. It also sets the `_playerCache` list to `null`.
5.  `private static void MessageHandler(byte[] bytes)`

    -   This method handles incoming messages. It deserializes the received byte array into a `Message` object and then calls either the server or client handling logic based on whether the script is running on the server or a client.
6.  `public static void SendMessageTo(ulong steamId, Message message, bool reliable = true)`

    -   This method sends a message to a specific player identified by their Steam ID. It serializes the `Message` object into a byte array and sends it using `MyAPIGateway.Multiplayer.SendMessageTo`.
7.  `public static void SendMessageToServer(Message message, bool reliable = true)`

    -   This method sends a message to the server. It serializes the `Message` object into a byte array and sends it using `MyAPIGateway.Multiplayer.SendMessageToServer`.
8.  `public static void SendMessageToClients(Message message, bool reliable = true, params ulong[] ignore)`

    -   This method sends a message to all clients except those specified in the `ignore` parameter (if any). It serializes the `Message` object into a byte array and sends it to each client using a loop.
9.  `Extensions` class:

    -   This is a static class that defines an extension method for `IEnumerable<T>`. The method is named `Contains`, and it checks if a given `IEnumerable` contains a specific element. This method is similar to the built-in `Enumerable.Contains` method but is available as an extension method.


# RexxarsCommunicationFramework/Message.cs
1.  `using` Statements:

    -   The script includes several `using` statements to import required namespaces, including `System`, `System.Collections.Generic`, `System.Linq`, `System.Text`, `System.Threading.Tasks`, `Sandbox.ModAPI`, and `ProtoBuf`. These namespaces provide access to various C# and Space Engineers-related functionalities.
2.  `[ProtoInclude(1354, typeof(SettingsMessage))]`:

    -   This is an attribute used to indicate that this base class (`Message`) can be included as a parent class for other classes in Protobuf serialization. It specifies a unique tag (1354) and the type (`SettingsMessage`) that can be included as a child class.
3.  `[ProtoContract]`:

    -   This attribute is used to mark the class as a contract for Protocol Buffers (Protobuf) serialization. It tells the Protobuf serializer that instances of this class should be serialized and deserialized.
4.  `public abstract class Message`:

    -   This is an abstract base class named `Message` defined in the `Rexxar.Communication` namespace.
    -   It is marked as `abstract`, which means it cannot be instantiated directly but serves as a blueprint for derived classes.
5.  `[ProtoMember(1)] public ulong SenderId;`:

    -   This attribute marks the `SenderId` field as a serializable member for Protobuf serialization. The field stores the Steam ID of the sender of the message.
    -   `[ProtoMember(1)]` indicates that this field should be serialized with tag 1 in the Protobuf format.
6.  `public Message()` Constructor:

    -   This is the constructor for the `Message` class.
    -   It initializes the `SenderId` field with the Steam ID of the local player using `MyAPIGateway.Multiplayer.MyId`. This ensures that each message carries the sender's Steam ID.
7.  `public abstract void HandleServer();` and `public abstract void HandleClient();`:

    -   These are abstract methods defined within the `Message` class.
    -   They are declared as `abstract`, which means any class derived from `Message` must provide concrete implementations for these methods.
    -   These methods are intended to be overridden by derived classes to define the specific handling logic for server and client sides when a message of that type is received.
# RexxarsCommunicationFramework/Settings.cs

1.  `using` Statements:

    -   The script includes several `using` statements to import required namespaces, including `System`, `System.Collections.Generic`, `System.Diagnostics`, `System.Linq`, `System.Text`, `System.Threading.Tasks`, `Rexxar.Communication`, `ProtoBuf`, `Sandbox.Game.EntityComponents`, `Sandbox.ModAPI`, `SpaceEngineers.Game.ModAPI`, `VRage.ModAPI`, `VRage.Utils`, `VRageMath`, and `System.Collections.Concurrent`. These namespaces provide access to various C# and Space Engineers-related functionalities.
2.  `public class Settings`:

    -   This is a public class named `Settings` defined within the `Rexxar` namespace.
    -   It appears to manage settings related to railguns in the game.
3.  `public static readonly Guid EntityGuid`:

    -   A static readonly field that holds a unique GUID (`EntityGuid`) for identifying entities related to railgun settings.
4.  `public struct RailgunSettings`:

    -   A nested `struct` named `RailgunSettings` defined within the `Settings` class.
    -   It is marked with `[ProtoContract]`, indicating that instances of this struct can be serialized and deserialized using Protobuf.
5.  `_readCache` and `_writeCache`:

    -   These are private static `ConcurrentDictionary<long, RailgunSettings>` fields used to cache railgun settings.
    -   `_readCache` is used for reading settings, and `_writeCache` is used for writing settings.
6.  `public static RailgunSettings GetSettings(IMyEntity entity)`:

    -   This method retrieves railgun settings for a given entity.
    -   It first checks the `_readCache` to see if the settings are cached and returns them if found.
    -   If not found in the cache, it attempts to retrieve settings from the entity's storage and deserializes them from a base64 string.
    -   If no settings are found, it creates default settings with `Recharging` set to `true`.
7.  `public static void SetSettings(IMyEntity entity, RailgunSettings settings)`:

    -   This method sets railgun settings for a given entity.
    -   It updates both the `_writeCache` and `_readCache` with the new settings.
8.  `public static void ConsumeSync(IEnumerable<KeyValuePair<long, RailgunSettings>> settingsCollection)`:

    -   This method updates the `_writeCache` and `_readCache` with settings provided in a collection.
9.  `public static void SyncSettings()`:

    -   This method sends the railgun settings to the server using the `Communication.Communication.SendMessageToServer` method.
10. `public static void CommitSettings()`:

    -   This method commits the railgun settings to the entity's storage.
    -   It serializes settings to binary and stores them in the entity's storage as a base64 string.
11. `public static void Unload()`:

    -   This method is called to unload the `Settings` class.
    -   It sets both the `_writeCache` and `_readCache` to `null`.

# RexxarsCommunicationFramework/SettingsMessage.cs
1.  `using` Statements:

    -   The script includes several `using` statements to import required namespaces, including `System`, `System.Collections.Concurrent`, `System.Collections.Generic`, `System.Linq`, `System.Text`, `System.Threading.Tasks`, `ProtoBuf`, `Sandbox.ModAPI`, and `VRage.Serialization`. These namespaces provide access to various C# and Space Engineers-related functionalities.
2.  `[ProtoContract] public class SettingsMessage : Message`:

    -   This is a public class named `SettingsMessage` defined within the `Rexxar.Communication` namespace.
    -   It is marked with `[ProtoContract]`, indicating that instances of this class can be serialized and deserialized using Protobuf.
    -   It inherits from the `Message` class, which was discussed earlier.
3.  `[ProtoMember(1)] private ConcurrentDictionary<long, Settings.RailgunSettings> _settings;`:

    -   This private field `_settings` is marked with `[ProtoMember(1)]`, indicating that it should be serialized with tag 1 in the Protobuf format.
    -   It is a `ConcurrentDictionary` that stores `Settings.RailgunSettings` objects, presumably representing railgun settings for various entities.
4.  `public SettingsMessage(ConcurrentDictionary<long, Settings.RailgunSettings> settings)` Constructor:

    -   This constructor takes a `ConcurrentDictionary<long, Settings.RailgunSettings>` as a parameter and initializes the `_settings` field with the provided settings.
5.  `public SettingsMessage()` Constructor:

    -   This is a parameterless constructor.
6.  `public override void HandleServer()`:

    -   This method overrides the `HandleServer` method from the base `Message` class.
    -   It is called when this message is received by the server.
    -   It checks if `_settings` is not null and has at least one entry. If not, it returns early.
    -   It then calls `Settings.ConsumeSync(_settings)` to update the server's settings cache with the received settings.
    -   The sender's Steam ID is set to `MyAPIGateway.Multiplayer.MyId`.
    -   It calls `Communication.SendMessageToClients(this, ignore: this.SenderId)` to broadcast the updated settings to all clients, excluding the sender.
    -   Finally, it calls `Settings.CommitSettings()` to save the updated settings to entity storage.
7.  `public override void HandleClient()`:

    -   This method overrides the `HandleClient` method from the base `Message` class.
    -   It is called when this message is received by a client.
    -   Similar to the server handler, it checks if `_settings` is not null and has at least one entry. If not, it returns early.
    -   It calls `Settings.ConsumeSync(_settings)` to update the client's settings cache with the received settings.
    -   Finally, it calls `Settings.CommitSettings()` to save the updated settings to entity storage.



# WhipsWeaponFramework/
# WhipsWeaponFramework/FrameworkWeaponAPI.cs

## Constants
- **FIXED_GUN_REGESTRATION_NETID, TURRET_REGESTRATION_NETID, REGESTRATION_REQUEST_NETID**: Network IDs for different message handling purposes.
- **FIXED_GUN_CONFIG_SYNC_NETID, TURRET_CONFIG_SYNC_NETID, CLIENT_CONFIG_SYNC_REQUEST_NETID, SERVER_CONFIG_SYNC_REQUEST_FINISHED_NETID**: Network IDs for configuration synchronization.

## Variables
- **FixedGunWeaponConfigs, TurretWeaponConfigs**: Concurrent dictionaries holding configurations for fixed guns and turrets respectively.

## Methods

### Register()
- Registers message handlers for fixed gun and turret registration.
- Sends registration requests and sets up additional message handlers for configuration synchronization depending on if it's server or client.

### Unregister()
- Unregisters message handlers for fixed gun and turret registrations.
- Removes additional message handlers for configuration synchronization depending on if it's server or client.

### SendClientConfigSyncRequest()
- Used by a client to request configuration synchronization from the server.

### ServerSendConfigSyncResponse(byte[] b)
- Handles the server's side of sending configuration data in response to a client's request.

### OnClientConfigSyncFinished(byte[] b)
- Marks the completion of configuration synchronization for the client.

### HandleFixedGunConfigSyncMessage(byte[] b)
- Handles incoming configuration updates for fixed guns on the client side.

### HandleTurretConfigSyncMessage(byte[] b)
- Handles incoming configuration updates for turrets on the client side.

### HandleFixedGunRegistration(object o)
- Handles the registration of a new fixed gun, validating and storing its configuration.

### HandleTurretRegistration(object o)
- Handles the registration of a new turret, validating and storing its configuration.

### ValidateConfig(WeaponConfig config, bool isFixed)
- Validates the configuration of a weapon (either fixed or turret), ensuring it's not duplicated and is properly identified.


# WhipsWeaponFramework/ShieldApi.cs

## Variables
- Various private delegates: Functions for interacting with shields in various ways, like attacking the shield, setting heat, checking if a point is in the shield, etc.
- **Channel**: A long constant used for message handling.
- **IsReady**: A boolean indicating if the API is ready.
- **_isRegistered**: A boolean indicating if the API is registered.

## Methods

### Load()
- Registers message handlers and sends a mod message for API endpoint request if not yet ready. Returns the readiness state.

### Unload()
- Unregisters message handlers and sets readiness state to false.

### ApiLoad(IReadOnlyDictionary<string, Delegate> delegates)
- Initializes the API by assigning the appropriate functions to the delegates based on the provided dictionary. Sets the API as initialized.

### RayAttackShield(...)
- Performs a ray attack on a shield and returns the impact point, if any.

### LineAttackShield(...)
- Performs a line attack on a shield and returns the impact point, if any.

### PointAttackShield(...)
- Performs a point attack on a shield and returns whether the attack was successful.

### SetShieldHeat(...)
- Sets the shield's heat.

### OverLoadShield(...)
- Triggers shield overload.

### SetCharge(...)
- Sets the shield's charge level.

### RayIntersectShield(...)
- Checks if a ray intersects with the shield and returns the intersection point, if any.

### LineIntersectShield(...)
- Checks if a line intersects with the shield and returns the intersection point, if any.

### PointInShield(...)
- Checks if a point is inside the shield.

### GetShieldPercent(...)
- Gets the shield's percentage.

### GetShieldHeat(...)
- Gets the shield's heat level.

### GetChargeRate(...)
- Gets the shield's charge rate.

### HpToChargeRatio(...)
- Converts hitpoints to charge ratio.

### GetMaxCharge(...)
- Gets the shield's maximum charge.

### GetCharge(...)
- Gets the shield's current charge.

### GetPowerUsed(...)
- Gets the power used by the shield.

### GetPowerCap(...)
- Gets the shield's power capacity.

### GetMaxHpCap(...)
- Gets the shield's maximum hitpoints capacity.

### IsShieldUp(...)
- Checks if the shield is up.

### ShieldStatus(...)
- Returns the shield's status.

### EntityBypass(...)
- Checks or sets if an entity is bypassing the shield.

### GridHasShield(...)
- Checks if a grid has a shield.

### GridShieldOnline(...)
- Checks if a grid's shield is online.

### ProtectedByShield(...)
- Checks if an entity is protected by a shield.

### GetShieldBlock(...)
- Gets the shield block associated with an entity.

### MatchEntToShieldFast(...)
- Matches an entity to its shield block quickly, option for only if online.

### ClosestShieldInLine(...)
- Finds the closest shield in a line and returns the distance and the shield block.

### IsShieldBlock(...)
- Checks if a block is a shield block.

### GetClosestShield(...)
- Gets the closest shield block to a position.

### GetDistanceToShield(...)
- Gets the distance to the shield from a position.

### GetClosestShieldPoint(...)
- Gets the closest point on a shield to a position.


# WhipsWeaponFramework/WeaponBlockBase.cs

## Classes
1. **WeaponBlockGatlingTurretBase**: Inherits from WeaponBlockTurretBase for Gatling Turrets.
2. **WeaponBlockMissileTurretBase**: Inherits from WeaponBlockTurretBase for Missile Turrets.
3. **WeaponBlockTurretBase**: Abstract class that provides base functionality for turret weapons.
4. **WeaponBlockGatlingFixed**: Inherits from WeaponBlockFixedBase for fixed Gatling guns.
5. **WeaponBlockMissileFixed**: Inherits from WeaponBlockFixedBase for fixed Missile Launchers.
6. **WeaponBlockMissileFixedReloadable**: Inherits from WeaponBlockFixedBase for reloadable Missile Launchers.
7. **WeaponBlockFixedBase**: Abstract class that provides base functionality for fixed weapons.
8. **WeaponBlockBase**: Abstract class that provides base functionality for all weapon blocks.

### Key Methods in WeaponBlockBase

#### Init(MyObjectBuilder_EntityBase objectBuilder)
- Initializes the weapon block, sets up update needs, and catches any exceptions during initialization.

#### GetBulletOriginAndDirection(ref Vector3D origin, ref Vector3D direction)
- Calculates the origin and direction for bullets based on the gun's muzzle world matrix.

#### TryGetWeaponConfig()
- Attempts to retrieve the weapon configuration and sets the configuration tick.

#### Initialize()
- Performs initialization steps including setting up configurations, terminal controls, ammo properties, and power draw.

#### GetShootProperty()
- Retrieves and sets the shoot property for the weapon.

#### SetShootSound()
- Sets up the sound to be played when the weapon shoots.

#### SetPowerDraw()
- Configures the power draw parameters for the weapon.

#### UpdateOnceBeforeFrame()
- Runs once before the next frame, initializing weapon settings and catching any exceptions.

#### UpdateBeforeSimulation()
- Regularly updates before each simulation step, handling weapon firing, muzzle flash, and reload mechanics.

#### SetAmmoProperties()
- Configures ammo properties based on the weapon's configuration.

#### ComputeRateOfFireParameters()
- Calculates parameters related to the weapon's rate of fire and reload time.

#### GetTurretMaxRange()
- Retrieves and sets the maximum range for turret weapons.

#### SetPowerSink()
- Sets up the power sink component for the weapon.

#### GetPowerInput()
- Calculates the power input required by the weapon based on its current state and operation.

#### ShowReloadMessage()
- Displays a reload message when the weapon is reloading.

#### GetTurretPowerDrawConstants(float start, float end, float maxRange)
- Sets constants for calculating the turret's power draw.

#### CalculateTurretPowerDraw(float currentRange)
- Calculates the power draw based on the current range of the turret.

### Abstract Methods
- **CreateTerminalControlsInvoke()**: Method that needs to be implemented to create custom terminal controls for the weapon.

## Structure and Functionality
The script is structured to provide a base class for different types of weapon blocks in Space Engineers, such as fixed guns and turrets. It handles various aspects of weapon behavior, including initialization, power management, shooting mechanics, ammo properties, and terminal control creation. The weapon types inherit from these base classes and can further specialize their behavior. The script is clearly part of a larger framework intended to extend or modify the weapons system in Space Engineers, offering customizability and additional functionality for mod developers.

# WhipsWeaponFramework/WeaponConfig

## Summary
The `WeaponConfig` class serves as a configuration model for weapon blocks in Space Engineers. It utilizes ProtoBuf for serialization, indicating it's used for data exchange, likely between the game and mods or between different game components.

## Properties

### Non-INI Configurable Properties
- **BlockSubtype**: The subtype of the block.
- **ConfigID**: Identifier for the configuration.
- **ConfigFileName**: The name of the configuration file.
- **FireSoundName**: Name of the firing sound.
- **DrawMuzzleFlash**: Boolean to determine if muzzle flash should be drawn.
- **MuzzleFlashSpriteName**: The name of the muzzle flash sprite.
- **MuzzleFlashDuration**: Duration of the muzzle flash effect.
- **MuzzleFlashScale**: Scale of the muzzle flash effect.
- **BulletSpawnForwardOffsetMeters**: Offset for bullet spawning.
- **ShowReloadMessage**: Boolean to determine if a reload message should be shown.
- **ReloadMessage**: The reload message text.
- **FireSoundVolumeMultiplier**: Multiplier for fire sound volume.
- **HitImpulse**: The impulse generated by a hit.

### INI Configurable Properties
- **TracerColor**: Color of the tracer.
- **TracerScale**: Scale of the tracer.
- **ArtificialGravityMultiplier**: Multiplier for artificial gravity effects.
- **NaturalGravityMultiplier**: Multiplier for natural gravity effects.
- **ShouldDrawProjectileTrails**: Boolean to determine if projectile trails should be drawn.
- **ProjectileTrailFadeRatio**: Fade ratio for the projectile trail.
- **ExplodeOnContact**: Boolean to determine if the projectile should explode on contact.
- **ContactExplosionRadius**: Radius of the explosion on contact.
- **ContactExplosionDamage**: Damage from the explosion on contact.
- **PenetrateOnContact**: Boolean to determine if the projectile should penetrate on contact.
- **PenetrationDamage**: Damage from penetration.
- **PenetrationRange**: Range of penetration.
- **ExplodePostPenetration**: Boolean to determine if there should be an explosion after penetration.
- **PenetrationExplosionRadius**: Radius of the explosion post-penetration.
- **PenetrationExplosionDamage**: Damage from the explosion post-penetration.
- **IdlePowerDrawBase**: Base power draw while idle.
- **ReloadPowerDraw**: Power draw while reloading.
- **MuzzleVelocity**: Velocity of the muzzle.
- **MaxRange**: Maximum range of the weapon.
- **DeviationAngleDeg**: Angle of deviation in degrees.
- **RecoilImpulse**: Impulse from recoil.
- **ShieldDamageMultiplier**: Multiplier for damage against shields.
- **RateOfFireRPM**: Rate of fire in rounds per minute.

### Other Non-INI Configurable Properties
- **DrawImpactSprite**: Boolean to determine if an impact sprite should be drawn.
- **ImpactSpriteName**: Name of the impact sprite.
- **ImpactSpriteDuration**: Duration of the impact sprite effect.
- **ImpactSpriteScale**: Scale of the impact sprite effect.
- **ProximityDetonationRange**: Range for proximity detonation.
- **ShouldProximityDetonate**: Boolean to determine if proximity detonation should occur.
- **ProximityDetonationArmingRange**: Arming range for proximity detonation.
- **ConfigVersionKey**: Key for the configuration version.

## TurretWeaponConfig

### Summary
`TurretWeaponConfig` extends `WeaponConfig` for additional properties specific to turret weapons.

### Additional Property
- **IdlePowerDrawMax**: Maximum power draw while idle for turret weapons.

## Overview
The classes seem to be part of a modding framework for Space Engineers to allow fine-tuned control and configuration of weapons, providing a wide range of parameters to customize weapon behavior, appearance, and performance. The use of ProtoBuf suggests that this configuration might be serialized and transferred or stored efficiently, possibly to handle game saves, multiplayer synchronization, or mod settings.


# WhipsWeaponFramework/WeaponSession.cs

## Summary
`WeaponSession` is a session component for Space Engineers that appears to manage weapon behavior including projectile simulation, configuration loading, and shield API integration.

## Member Fields
- `SessionInit`: Boolean indicating if the session has been initialized.
- `IsServer`: Boolean indicating if the session is running on the server.
- `_realProjectiles`: List of `WeaponProjectile` representing real projectiles.
- `_shadowProjectiles`: List of `WeaponProjectileShadow` representing shadow projectiles.
- `_tracers`: List of `WeaponTracer` representing tracers.
- `_ticksSinceConfigLoad`: Counter for ticks since the last configuration load.
- `ConfigRefreshTick`: Tick count for when the configuration should be refreshed.
- `CurrentTick`: Current tick count.
- `myIni`: `MyIni` instance for INI file handling.
- `Instance`: Static instance of `WeaponSession` for access from other classes.
- `ShieldMod`: Boolean indicating if the shield mod is installed.
- `ShieldApiLoaded`: Boolean indicating if the Shield API has been loaded.
- `ShieldApi`: Instance of `ShieldApi`.

## Methods

### BeforeStart()
- Base initialization and checks if the shield mod is installed.

### UpdateAfterSimulation()
- Handles session initialization, settings synchronization, and client configuration request.

### UpdateBeforeSimulation()
- Initializes the Shield API if necessary and simulates projectiles.

### SimulateProjectiles()
- Simulates real projectiles on the server side and projectile shadows on the client side.

### ShootProjectile(WeaponFireData fireData, WeaponConfig config)
- Creates a new `WeaponProjectile` and sends its data to clients.

### CreateShadow(WeaponFireSyncData fireSyncData)
- Creates a shadow projectile from synchronized data.

### AddTracer(WeaponTracer tracerData)
- Adds a tracer to the tracer list.

### Draw()
- Draws tracers.

### AddProjectile(WeaponProjectile projectile)
- Adds a real projectile to the projectile list.

### LoadData()
- Initializes logger, registers weapon API, and sets session and server status.

### UnloadData()
- Closes logger, unregisters communication and weapon API, and unloads shield API.

### LoadConfig(WeaponConfig config)
- Loads weapon configuration from world or local storage and applies settings.

### SaveConfig(WeaponConfig config, bool verbose = true, string settings = "", bool worldConfigFound = false)
- Saves the given configuration to world or local storage.

## Overview
The script is organized to provide session-wide management of weapon configurations, including handling projectiles, tracers, and shield interactions. It integrates closely with the `FrameworkWeaponAPI` and the `ShieldApi`, indicating a system designed for enhanced and possibly customizable weapon behavior in Space Engineers. It seems to be focused on providing a robust framework for weapon management, including handling network synchronization of weapon data and ensuring configurations are up-to-date and applied correctly across sessions.

# WhipsWeaponFramework/WeaponSync.cs

## Summary
`WeaponSync` is a session component in Space Engineers designed to handle synchronization of weapon firing data across clients, particularly for multiplayer gameplay. It ensures that when a weapon is fired, all necessary information is correctly propagated to all clients to simulate the firing visually and functionally.

## Member Fields
- `scriptInit`: Boolean indicating if the script has been initialized.

## Methods

### UpdateBeforeSimulation()
- Initializes the script and registers a message handler for processing fire synchronization data.

### SendToClients(WeaponFireSyncData data)
- Serializes weapon firing data and sends it to other clients.
- If not in a dedicated server environment, it also creates a shadow projectile for local visualization.

### ProcessFireSyncData(byte[] data)
- Deserializes received data and creates a shadow projectile based on it.
- Only runs on client-side, ignores processing on dedicated servers.

### UnloadData()
- Unregisters the message handler when the session component is unloaded.

## Structures

### WeaponFireSyncData
- **Origin**: The origin point of the fired projectile.
- **Direction**: The direction vector of the projectile.
- **ShooterVelocity**: The velocity of the shooter at the time of firing.
- **TracerColor**: Color vector for the tracer.
- **DrawTrails**: Whether to draw trails for the projectile.
- **ProjectileTrailScale**: The scale of the projectile trail.
- **TrailDecayRatio**: How quickly the trail fades.
- **MuzzleVelocity**: The muzzle velocity of the projectile.
- **MaxRange**: The maximum range of the projectile.
- **ArtGravityMult**: Artificial gravity multiplier for the projectile.
- **NatGravityMult**: Natural gravity multiplier for the projectile.
- **ShooterID**: The ID of the shooter entity.
- **DrawImpactSprite**: Whether to draw an impact sprite upon hitting a target.
- **ShouldProximityDetonate**: Whether the projectile should detonate near targets.
- **ProximityDetonationRange**: The range at which proximity detonation occurs.
- **ProximityDetonationArmingRange**: The minimum distance before the projectile arms for proximity detonation.

## Overview
`WeaponSync` focuses on managing the networked aspect of weapons in Space Engineers, ensuring that all players have a consistent and synchronized experience regarding weapon usage. It uses ProtoBuf for efficient serialization of the weapon fire data, which includes various parameters like origin, direction, velocity, and special effects related to the projectile. This class is crucial for multiplayer aspects of weapon systems, making sure every player sees and experiences the same event when a weapon is fired.




# WhipsWeaponFramework/Constants/
# WhipsWeaponFramework/Constants/FrameworkConstants.cs

## Summary
`FrameworkConstants` is a class in the `Whiplash.WeaponFramework` namespace that appears to define constants used throughout the weapon framework for Space Engineers, likely for consistency and easier maintenance of the code.

## Constants

### Debugging
- **DEBUG_MSG_TAG**: "Railgun Weapon Framework" — Tag used for debugging messages related to the framework.
- **LOG_NAME**: "RailgunFramework.log" — The name of the log file for the framework.
- **DAMAGE_LOG_NAME**: "RailgunDamage.log" — The name of the log file specifically for logging damage related events.

### Network Traffic IDs
- **NETID_FIRE_SYNC**: 1507 — Network ID used for synchronizing weapon fire events.
- **NETID_RECHARGE_SYNC**: 3896 — Network ID used for synchronizing weapon recharge events.

## Overview
The `FrameworkConstants` class holds critical identifiers and names used across the Weapon Framework. These constants include tags for debugging, log file names, and network IDs for different synchronization events. This class ensures that there is a single source of truth for these values, reducing the risk of discrepancies and making the codebase easier to maintain and understand.

# WhipsWeaponFramework/Constants/MyIniConstants.cs

## Summary
`MyIniConstants` is a class within the `Whiplash.WeaponFramework` namespace, which defines a set of string constants used as keys for INI configuration in the weapon framework for Space Engineers. These keys represent different configuration parameters for weapons, such as power usage, explosion properties, and visual effects.

## Constants

### Gravity Multipliers
- **INI_KEY_ART_GRAV**: "Artificial gravity multiplier"
- **INI_KEY_NAT_GRAV**: "Natural gravity multiplier"

### Projectile Properties
- **INI_KEY_DRAW_TRAILS**: "Draw projectile trails"
- **INI_KEY_TRAIL_DECAY**: "Projectile trail decay ratio"

### Explosion Properties
- **INI_KEY_SHOULD_EXP**: "Explode on contact"
- **INI_KEY_EXP_RAD**: "Contact Explosion radius (m)"
- **INI_KEY_EXP_DMG**: "Contact Explosion damage"
- **INI_KEY_PEN**: "Penetrate on contact"
- **INI_KEY_PEN_DMG**: "Penetration damage pool"
- **INI_KEY_PEN_RANGE**: "Penetration range"
- **INI_KEY_SHOULD_EXP_PEN**: "Explode after penetration"
- **INI_KEY_EXP_PEN_RAD**: "Penetration explosion radius (m)"
- **INI_KEY_EXP_PEN_DMG**: "Penetration explosion damage"

### Power Properties
- **INI_KEY_PWR_IDLE**: "Idle power (MW)"
- **INI_KEY_PWR_RELOAD**: "Reload power (MW)"

### Firing and Weapon Properties
- **INI_KEY_MUZZLE_VEL**: "Muzzle velocity (m/s)"
- **INI_KEY_MAX_RANGE**: "Max range (m)"
- **INI_KEY_DEVIANCE**: "Spread angle (°)"
- **INI_KEY_TRACER_SCALE**: "Tracer scale"
- **INI_KEY_RECOIL**: "Recoil impulse"
- **INI_KEY_IMPULSE**: "Impact impulse"
- **INI_KEY_SHIELD_MULT**: "Shield Damage Multiplier (for DarkStar's Shield Mod)"
- **INI_KEY_ROF**: "Rate of fire (RPM)"
- **INI_KEY_TRACER_COLOR**: "Tracer color (RGB where color channels range from 0 to 1)"

### Proximity Detonation
- **INI_KEY_PROXIMITY_DET**: "Should proximity detonate"
- **INI_KEY_PROXIMITY_DET_RANGE**: "Proximity detonation radius (m)"
- **INI_KEY_PROXIMITY_DET_ARM_RANGE**: "Proximity detonation arming range (m)"

### Configuration Version
- **INI_KEY_CONFIG_VERSION_KEY**: "Config version key"
- **INI_VALUE_DEFAULT_VERSION_KEY**: "__default__"

### Turret Power Properties
- **INI_KEY_TURRET_PWR_MIN_RANGE**: "Turret idle power at min range (MW)"
- **INI_KEY_TURRET_PWR_MAX_RANGE**: "Turret idle power at max range (MW)"

## Overview
`MyIniConstants` provides a standardized set of keys for accessing and modifying weapon configuration settings via INI files in the weapon framework. These constants ensure consistency across the codebase and make it easier to manage and read the configuration values related to various weapon properties. The constants cover a wide range of weapon aspects from power usage to firing behavior and visual effects, reflecting the framework's comprehensive approach to weapon customization.




# WhipsWeaponFramework/Projectiles/
# WhipsWeaponFramework/Projectiles/WeaponProjectile.cs

## Summary
`WeaponProjectile` is a class within the `Whiplash.WeaponProjectiles` namespace, intended to simulate the behavior of projectiles fired from weapons in Space Engineers. It handles the physics of the projectile's movement, including gravity effects, collision detection with various entities, and explosion handling.

## Properties and Fields

- **Killed**: Indicates whether the projectile is no longer active.
- **DeviatedDirection**: Stores the direction of the projectile after applying deviation.

## Constants

- **Tick**: Represents the duration of a single tick in seconds, used for time calculations.
- **RaycastDelayTicks**: Number of ticks to delay raycasting, used for performance optimization.

## Constructor

- **WeaponProjectile(WeaponFireData fireData, WeaponConfig config)**: Initializes a new instance of the `WeaponProjectile` class using the firing data and weapon configuration.

## Methods

### Update()
- Main update method for the projectile, called on each tick to simulate movement, handle gravity effects, check for collisions, and possibly detonate.

### CreateExplosion(Vector3D position, Vector3D direction, float radius, float damage, IMyEntity hitEntity = null, float scale = 1f)
- Creates an explosion at the specified position with the given parameters.

### GetObjectsToPenetrate(Vector3D start, Vector3D end)
- Determines which entities will be penetrated by the projectile based on its trajectory.

### SortObjectsToPenetrate(Vector3D start)
- Sorts the list of entities to be penetrated based on their distance from the projectile's origin.

### DamageObjectsToPenetrate(float damage)
- Applies damage to each entity in the penetration list, deducting from the damage pool until exhausted.

### Kill()
- Marks the projectile as killed and performs any necessary cleanup or final actions.

## Structures

- **PenetratedEntityContainer**: Contains information about an entity that has been penetrated by the projectile.

## Overview
`WeaponProjectile` represents a single projectile in the game world, handling its entire lifecycle from launch to impact or detonation. It takes into account weapon and projectile configuration, simulating realistic physics including gravity effects and collision detection with entities and voxels. The class also manages explosive and penetration effects, determining damage and impact based on the weapon's settings and the targets it encounters.

# WhipsWeaponFramework/Projectiles/WeaponProjectileShadow.cs

## Summary
`WeaponProjectileShadow` is a class within the `Whiplash.WeaponProjectiles` namespace, intended to simulate the behavior of projectile shadows in Space Engineers. These shadows are used for visual representation of projectiles on the client side in a multiplayer environment, ensuring that clients see projectiles approximately where they should be without needing to simulate the full physics of the projectile.

## Properties and Fields
- **DrawingImpactSprite**: Indicates if the impact sprite is being drawn.
- **Remove**: Indicates if the shadow should be removed.
- Various private fields for storing properties of the projectile such as color, scale, position, velocity, and whether it should draw trails or impact sprites.

## Constructor
- **WeaponProjectileShadow(WeaponFireSyncData fireSyncData)**: Initializes a new instance of the class using firing synchronization data.

## Methods

### Update()
- Updates the shadow projectile each tick, simulating its motion, checking for impacts, and handling the drawing of tracers and impact sprites.

### DrawLastTracer()
- Updates the last tracer's endpoint to the current position of the shadow.

### SimulateShadow()
- Simulates the motion of the shadow projectile, including applying gravity and checking for impacts with voxels or shields.

### DrawImpactSprite()
- Draws an impact sprite at the point of collision if the original projectile had an impact sprite configured.

## Overview
The `WeaponProjectileShadow` class is crucial for providing a synchronized and visually accurate representation of weapon fire in a multiplayer scenario. While the actual hit detection and damage calculations are performed server-side, this class ensures that clients see the projectile moving and impacting targets, enhancing the immersive experience. It deals with network latency and other challenges by simplifying the simulation to the essential visual elements and ensuring they align as closely as possible with the server's simulation.

# WhipsWeaponFramework/Projectiles/WeaponProjectileShadow

## Summary
`WeaponProjectileShadow` is a class within the `Whiplash.WeaponProjectiles` namespace, intended to simulate the behavior of projectile shadows in Space Engineers. These shadows are used for visual representation of projectiles on the client side in a multiplayer environment, ensuring that clients see projectiles approximately where they should be without needing to simulate the full physics of the projectile.

## Properties and Fields
- **DrawingImpactSprite**: Indicates if the impact sprite is being drawn.
- **Remove**: Indicates if the shadow should be removed.
- Various private fields for storing properties of the projectile such as color, scale, position, velocity, and whether it should draw trails or impact sprites.

## Constructor
- **WeaponProjectileShadow(WeaponFireSyncData fireSyncData)**: Initializes a new instance of the class using firing synchronization data.

## Methods

### Update()
- Updates the shadow projectile each tick, simulating its motion, checking for impacts, and handling the drawing of tracers and impact sprites.

### DrawLastTracer()
- Updates the last tracer's endpoint to the current position of the shadow.

### SimulateShadow()
- Simulates the motion of the shadow projectile, including applying gravity and checking for impacts with voxels or shields.

### DrawImpactSprite()
- Draws an impact sprite at the point of collision if the original projectile had an impact sprite configured.

## Overview
The `WeaponProjectileShadow` class is crucial for providing a synchronized and visually accurate representation of weapon fire in a multiplayer scenario. While the actual hit detection and damage calculations are performed server-side, this class ensures that clients see the projectile moving and impacting targets, enhancing the immersive experience. It deals with network latency and other challenges by simplifying the simulation to the essential visual elements and ensuring they align as closely as possible with the server's simulation.

# WhipsWeaponFramework/Projectiles/WeaponTracer.cs

## Summary
`WeaponTracer` is a class in the `Whiplash.WeaponTracers` namespace that handles the visualization of tracers for projectiles in Space Engineers. It simulates the visual path of the projectile, including bullet trails and tracer effects, enhancing the immersive experience of firing weapons.

## Properties and Fields
- **Remove**: Indicates if the tracer should be removed (used for cleanup).
- **To**: The end point of the tracer's line.
- Various private fields for storing properties such as the direction, velocity, color, and scale of the tracer.

## Constants
- **TrailKillThreshold**: The threshold for when a trail should be considered "dead" and removed.
- **Tick**: The duration of a single tick in seconds, used for time calculations.

## Constructor
- **WeaponTracer(Vector3D direction, Vector3D velocity, Vector3D lineFrom, Vector3D lineTo, Vector3 tracerColor, float tracerScale, float decayRatio, bool drawFullTracer, bool drawTrail)**: Initializes a new instance of the class with specified properties for the tracer.

## Methods

### Draw()
- Handles the drawing of the tracer each tick. It updates the tracer's position based on velocity, draws bullet trails, and removes the tracer when it's no longer visible. It conditionally draws a full tracer or just an impact point based on configuration.

## Overview
The `WeaponTracer` class is a critical component for the visual representation of weapon fire in Space Engineers. It ensures that as weapons are fired, the resulting tracers are rendered in the game world, providing visual feedback and enhancing realism. The class handles the dynamic aspects of tracer appearance, including movement, fading, and length, to simulate real-world tracer behavior closely.




# WhipsWeaponFramework/Utils
# WhipsWeaponFramework/Utils/Logger

## Namespace
`Whiplash.Utils`

## Summary
`Logger` is a utility class within the `Whiplash.Utils` namespace, designed to facilitate logging in the Space Engineers environment. It provides methods to write log entries with varying severity levels and supports writing both to a file and the game's log for easy debugging and tracking.

## Properties and Fields
- **Default**: Static instance of Logger used as a default logger.
- **Severity**: Enum representing the severity of the log message (Info, Warning, Error).
- **_fileName**: The name of the file where logs are written.
- **_messageTag**: A tag prepended to each log message for easy identification.
- **_log**: StringBuilder used to build log messages.
- **_writer**: TextWriter used to write logs to the file.

## Constants
- **LOG_MESSAGE_FORMAT**: Format string for log messages.
- **DATE_FORMAT**: Format string for date and time in log messages.

## Constructor
- **Logger(string fileName, string messageTag)**: Initializes a new logger with the specified file name and message tag.

## Methods

### CreateDefault(string fileName, string messageTag)
- Static method to create and set a default logger instance.

### WriteLine(string line, Severity severity = Severity.Info, bool writeToGameLog = true)
- Writes a log entry with the specified message, severity, and optionally to the game log.

### Close()
- Writes a closing message to the log and then closes the TextWriter.

### GetSeverityString(Severity severity)
- Returns a string representation of the specified severity level.

## Overview
The `Logger` class is an essential tool for developers, allowing for systematic logging of information, warnings, and errors during mod development and gameplay. It enhances debugging capabilities and ensures that developers and users can track and diagnose issues effectively. The class's design allows for flexibility in log management, making it an invaluable component in the Space Engineers modding toolkit.

# WhipsWeaponFramework/Utils/MyIniHelper

## Namespace
`Whiplash.Utils`

## Summary
`MyIniHelper` is a utility class within the `Whiplash.Utils` namespace designed to facilitate the manipulation of the `MyIni` object in Space Engineers. It provides methods to handle complex data types like `Vector3D` within the INI files, simplifying the process of reading and writing these types to and from INI configurations.

## Methods

### SetVector3(string sectionName, string vectorName, ref Vector3 vector, MyIni ini)
- Adds a `Vector3` to a `MyIni` object under the specified section and key.
- **Parameters**:
    - `sectionName`: The section of the INI file.
    - `vectorName`: The key under which the vector will be stored.
    - `vector`: The `Vector3` data to store.
    - `ini`: The `MyIni` instance.

### GetVector3(string sectionName, string vectorName, MyIni ini, Vector3? defaultVector = null)
- Parses a `MyIni` object for a `Vector3D`, returning the vector found at the specified section and key, or a default value if not found or parsing fails.
- **Parameters**:
    - `sectionName`: The section of the INI file.
    - `vectorName`: The key under which the vector is stored.
    - `ini`: The `MyIni` instance.
    - `defaultVector`: Optional default value to return if the key is not found or parsing fails.

## Overview
The `MyIniHelper` class is a straightforward utility designed to extend the functionality of the `MyIni` object in Space Engineers, specifically for handling vector data. It encapsulates the complexity of converting between `Vector3` objects and their string representation in INI files. This class is a small but important part of a larger system, contributing to cleaner, more maintainable code by abstracting repetitive and error-prone tasks into simple, reusable methods.

# WhipsWeaponFramework/Utils/VectorMath

## Namespace
`Whiplash.Utils`

## Summary
`VectorMath` is a static utility class within the `Whiplash.Utils` namespace designed to provide common vector-related mathematical operations used throughout the Space Engineers weapon framework. It includes methods for normalizing vectors, calculating reflections, projections, and angles between vectors, and other useful vector operations.

## Methods

### SafeNormalize(Vector3D a)
- Normalizes a vector only if it is non-zero and non-unit, otherwise returns zero or the original vector.

### Reflection(Vector3D a, Vector3D b, double rejectionFactor = 1)
- Reflects vector `a` over vector `b` with an optional rejection factor.

### Rejection(Vector3D a, Vector3D b)
- Rejects vector `a` on vector `b`, effectively removing the component of `a` that is parallel to `b`.

### Projection(Vector3D a, Vector3D b)
- Projects vector `a` onto vector `b`, returning the component of `a` that is parallel to `b`.

### ScalarProjection(Vector3D a, Vector3D b)
- Computes the scalar projection of `a` onto `b`, which is the magnitude of the projection of `a` onto `b`.

### AngleBetween(Vector3D a, Vector3D b)
- Computes the angle between vectors `a` and `b` in radians.

### CosBetween(Vector3D a, Vector3D b)
- Computes the cosine of the angle between vectors `a` and `b`.

### IsDotProductWithinTolerance(Vector3D a, Vector3D b, double tolerance)
- Returns whether the normalized dot product between two vectors is greater than the given tolerance. This method is useful for determining if two vectors are "more parallel" than the specified angle.

## Overview
The `VectorMath` class provides a collection of static methods for various vector calculations, which are essential in physics simulations and graphical representations in the Space Engineers environment. These methods are used to manipulate and understand the orientation, direction, and relative positioning of objects in 3D space, enhancing the functionality and realism of the game's physics and visual effects.

