Skip to main content

TypeDefinitions

Shared Luau type definitions used across Vetra and VetraNet.

These are imported for type annotations only, there is no runtime cost. You generally do not need to require this module directly.

Types

CastTrajectory

interface CastTrajectory {
StartTimenumber--

Runtime.TotalRuntime when this segment began.

EndTimenumber--

Runtime.TotalRuntime when closed; -1 while active.

OriginVector3--

World-space start position of this arc.

InitialVelocityVector3--

Velocity at StartTime in studs/second.

AccelerationVector3--

Constant acceleration for this arc (gravity + extra + initial drag).

}

Represents one continuous parabolic arc of a projectile's flight path.

A new segment is appended to Runtime.Trajectories on every bounce or mid-flight kinematic change via the Set* / Add* methods on VetraCast. EndTime of -1 indicates the segment is still active.

BulletSnapshot

interface BulletSnapshot {
Idnumber--

Unique identifier.

OriginVector3--

Muzzle position at fire time.

DirectionVector3--

Initial unit direction.

Speednumber--

Initial speed in studs/second.

PositionVector3?--

Current world-space position, or nil before the first frame.

VelocityVector3--

Current velocity vector.

Aliveboolean--

Whether the cast is still being simulated.

Lifetimenumber--

Seconds of simulated time elapsed since creation.

PathLengthnumber--

True accumulated path distance (bounces included).

DistanceTravelednumber--

Alias for PathLength (API compatibility).

}

Read-only snapshot of a BulletContext's state at a point in time. Returned by BulletContext:GetSnapshot.

BulletContextConfig

interface BulletContextConfig {
OriginVector3--

Required. World-space muzzle position.

DirectionVector3--

Required. Unit direction vector.

Speednumber--

Required. Initial speed in studs/second.

RaycastParamsRaycastParams?--

Optional per-bullet raycast filter. Takes priority over Behavior.RaycastParams when set. Default: nil

SolverDataany?--

Internal, used by the solver to attach lifecycle hooks. Do not set from weapon code.

}

Configuration table passed to BulletContext.new.

SpeedProfile

interface SpeedProfile {
DragCoefficientnumber?--

Drag coefficient override for this regime.

DragModelDragModel?--

Drag model override for this regime.

NormalPerturbationnumber?--

Bounce noise override for this regime.

MaterialRestitution{[Enum.Material]number}?--

Per-material restitution overrides.

Restitutionnumber?--

Base restitution override for this regime.

}

Per-speed-regime behavior overrides. Assigned to SupersonicProfile or SubsonicProfile on a VetraBehavior. The solver blends in the matching profile's values when the bullet crosses the speed of sound (343 studs/s).

All fields are optional. Omitted fields continue using the base behavior values.

VetraBehavior

interface VetraBehavior {
AccelerationVector3?--

Extra acceleration on top of gravity (e.g. rocket thrust). Default: Vector3.zero

MaxDistancenumber?--

Max flight distance in studs. Default: 500

MaxSpeednumber?--

Speed ceiling; bullet terminates if exceeded. Default: math.huge

MinSpeednumber?--

Termination speed threshold in studs/sec. Default: 1

RaycastParamsRaycastParams?--

Raycast filter. Used if BulletContext.RaycastParams is not set, before falling back to an empty RaycastParams.new(). Default: nil

GravityVector3?--

Gravitational acceleration (negative Y = downward). Default: workspace gravity downward.

CastFunction((
RaycastParams
) → RaycastResult?)?--

Custom cast function (serial solver only). Default: nil

BulletMassnumber?--

Bullet mass for penetration and impact-force calculations. Default: 0

DragCoefficientnumber?--

Drag coefficient. 0 = no drag. Default: 0

DragModelDragModel?--

Drag model type. Default: "Quadratic"

DragSegmentIntervalnumber?--

Seconds between drag + Magnus recalculation steps. Default: 0.05

CustomMachTable{{number}}?--

Custom Mach→Cd table pairs when DragModel = "Custom".

WindResponsenumber?--

Multiplier on the solver's wind vector (Vetra:SetWind). 1.0 = full effect, 0.0 = immune. Default: 1.0

SpeedThresholds{number}?--

Sorted list of speeds (studs/s) that fire OnSpeedThresholdCrossed. Default: {}

SupersonicProfileSpeedProfile?--

Behavior overrides when bullet speed is >= 343 studs/s. Default: nil

SubsonicProfileSpeedProfile?--

Behavior overrides when bullet speed is < 343 studs/s. Default: nil

SpinVectorVector3?--

Spin axis (direction) x angular velocity (magnitude, rad/s). Vector3.zero = disabled. Default: Vector3.zero

MagnusCoefficientnumber?--

Magnus lift coefficient. Typical range: 0.00005–0.001. 0 = disabled. Default: 0

SpinDecayRatenumber?--

Rate at which SpinVector magnitude decreases per second. 0 = no decay. Default: 0

GyroDriftRatenumber?--

Lateral drift acceleration magnitude in studs/s². nil = disabled. Default: nil

GyroDriftAxisVector3?--

Reference axis for drift direction. nil = world UP (right-hand rifling). Default: nil

TumbleSpeedThresholdnumber?--

Speed below which tumbling begins. nil = disabled. Default: nil

TumbleDragMultipliernumber?--

Drag multiplied by this factor while tumbling. Default: 3.0

TumbleLateralStrengthnumber?--

Chaotic lateral acceleration magnitude in studs/s². Default: 0

TumbleOnPierceboolean?--

Begin tumbling on first pierce regardless of speed. Default: false

TumbleRecoverySpeednumber?--

Speed above which tumbling ends. nil = tumble is permanent. Default: nil

HomingPositionProvider((
posVector3,
velVector3
) → Vector3?)?--

Called every frame for target position. Return nil to disengage. Default: nil

CanHomeFunctionCanHomeCallback?--

Gate callback; return false to disengage. Default: nil

HomingStrengthnumber?--

Steering force in degrees/second. Default: 90

HomingMaxDurationnumber?--

Max seconds of active homing before OnHomingDisengaged fires. Default: 3

HomingAcquisitionRadiusnumber?--

Min target distance in studs to engage. 0 = engage immediately on fire. Default: 0

TrajectoryPositionProvider((elapsednumber) → Vector3?)?--

Override bullet position each frame with a sampled curve. Return nil to end the override and terminate. Default: nil

CanPierceFunctionCanPierceCallback?--

Pierce gate; return true to pierce. Default: nil

MaxPierceCountnumber?--

Lifetime pierce limit. Default: 3

PierceSpeedThresholdnumber?--

Min speed to attempt pierce (studs/s). Default: 50

PierceSpeedRetentionnumber?--

Speed fraction kept per pierce [0,1]. Default: 0.8

PierceNormalBiasnumber?--

Min approach angle for pierce [0,1]. 1.0 = all angles, 0.0 = perpendicular only. Default: 1.0

PierceDepthnumber?--

Max wall thickness per pierce in studs. 0 = no per-pierce depth limit. Default: 0

PierceForcenumber?--

Total momentum force budget for penetration. 0 = disabled. Default: 0

PierceThicknessLimitnumber?--

Hard cap on wall thickness for the exit-point raycast in studs. Default: 500

FragmentOnPierceboolean?--

Spawn fragment child bullets when a pierce occurs. Default: false

FragmentCountnumber?--

Number of fragments to spawn per pierce. Default: 3

FragmentDeviationnumber?--

Angular half-angle spread of the fragment cone in degrees. Default: 15

CanBounceFunctionCanBounceCallback?--

Bounce gate; return true to bounce. Default: nil

MaxBouncesnumber?--

Lifetime bounce limit. Default: 5

BounceSpeedThresholdnumber?--

Min speed to attempt bounce (studs/s). Default: 20

Restitutionnumber?--

Energy retention per bounce [0,1]. Default: 0.7

MaterialRestitution{[Enum.Material]number}?--

Per-material multipliers, combined with Restitution. Default: {}

NormalPerturbationnumber?--

Random surface-normal noise for rough surfaces. 0 = clean reflection. Default: 0.0

ResetPierceOnBounceboolean?--

Reset pierce state after each confirmed bounce. Default: false

HighFidelitySegmentSizenumber?--

Sub-segment length in studs (starting value). Default: 0.5

HighFidelityFrameBudgetnumber?--

Millisecond budget per cast per frame for sub-segment raycasts. Default: 4

AdaptiveScaleFactornumber?--

Adaptive sizing multiplier, must be > 1. Default: 1.5

MinSegmentSizenumber?--

Hard floor for adaptive segment size (studs). Default: 0.1

MaxBouncesPerFramenumber?--

Per-frame bounce cap across all sub-segments. Default: 10

CornerTimeThresholdnumber?--

Min seconds between bounces (Pass 1). Default: 0.002

CornerPositionHistorySizenumber?--

Bounce position history size, positive integer (Pass 3 & 4). Default: 4

CornerDisplacementThresholdnumber?--

Min bounce separation in studs (Pass 3). Default: 0.5

CornerEMAAlphanumber?--

EMA smoothing factor for velocity direction (0,1) (Pass 2). Default: 0.4

CornerEMAThresholdnumber?--

EMA oscillation threshold (Pass 2). Must be > |1 - 2·alpha|. Default: 0.25

CornerMinProgressPerBouncenumber?--

Min studs of progress per bounce over history (Pass 4). 0 disables Pass 4. Default: 0.3

LODDistancenumber?--

Studs from the LOD origin beyond which this bullet steps at reduced frequency. 0 = always full frequency. Default: 0

CosmeticBulletTemplateBasePart?--

Part cloned per fire call. Default: nil

CosmeticBulletContainerInstance?--

Parent for the cosmetic object. Defaults to workspace. Default: nil

CosmeticBulletProvider((contextBulletContext) → Instance?)?--

Provider function; takes priority over Template. Default: nil

AutoDeleteCosmeticBulletboolean?--

When true, the cosmetic Instance is destroyed automatically on termination. Set to false to manage cleanup yourself. Default: true

BatchTravelboolean?--

Include this cast in OnTravelBatch instead of firing individual OnTravel events. Default: false

WindResponsenumber?--

Multiplier on the solver's wind vector. 1.0 = fully affected, 0.0 = immune. Default: 1.0

VisualizeCastsboolean?--

Enable trajectory visualizer for this cast. Default: false

}

Complete configuration for a projectile cast. All fields are optional — any omitted field falls back to a safe built-in default.

Prefer constructing this via BehaviorBuilder rather than by hand to get typed setters, build-time validation, and a frozen result. For fields not exposed by the builder (drag, Magnus, homing config, tumble, etc.), pass a raw table or a table that inherits from a built behavior via __index.


Physics


Aerodynamic Drag


Wind


Supersonic / Subsonic Profiles


Magnus Effect


Gyroscopic Drift


Tumble


Homing


Trajectory Provider


Pierce


Fragmentation


Bounce


High Fidelity


Corner Trap Detection


LOD


Cosmetic


Batch Travel


Wind Sensitivity


Debug

DragModel

type DragModel = "Linear" | "Quadratic" | "Exponential" | "G1" | "G2" | "G3" | "G4" | "G5" | "G6" | "G7" | "G8" | "GL" | "Custom"

Drag model used to compute aerodynamic deceleration each DragSegmentInterval.

Analytic models:

  • "Linear", deceleration ∝ speed.
  • "Quadratic", deceleration ∝ speed² (default). Most physically accurate for subsonic bullets.
  • "Exponential", deceleration ∝ eˢᵖᵉᵉᵈ. Models exotic high-drag shapes.

G-series empirical models (Mach-indexed Cd lookup tables):

  • "G1", flat-base spitzer; general-purpose standard.
  • "G2", Aberdeen J projectile; large-caliber / atypical shapes.
  • "G5", boat-tail spitzer; mid-range rifles.
  • "G6", semi-spitzer flat-base; shotgun slugs.
  • "G7", long boat-tail; modern long-range / sniper standard.
  • "G8", flat-base semi-spitzer; hollow points / pistols.
  • "GL", lead round ball; cannons / muskets / buckshot.

User-supplied:

  • "Custom", requires CustomMachTable = { {mach, cd}, ... } in the behavior.

NetworkMode

type NetworkMode = "ClientAuthoritative" | "ServerAuthority" | "SharedAuthority"

Authority mode that controls which side may call :Fire() on a VetraNet handle.

  • "ClientAuthoritative", clients send fire requests; server validates. (Default)
  • "ServerAuthority", only server code may initiate bullets; client fire requests are silently dropped.
  • "SharedAuthority", both client and server may fire; client requests go through validation, server calls bypass it.

Pass via NetworkConfig.Mode. Prefer Vetra.Enums.NetworkMode over raw strings.

TerminationReason

type TerminationReason = "hit" | "distance" | "speed" | "corner_trap" | "manual"

The reason a cast was terminated. Passed as the second argument to OnPreTermination signal handlers.

  • "hit", bullet struck a surface and was not pierced or bounced.
  • "distance", MaxDistance was reached.
  • "speed", speed dropped below MinSpeed or exceeded MaxSpeed.
  • "corner_trap", corner-trap detection terminated the cast.
  • "manual", Terminate() was called explicitly, or the solver was destroyed.

NetworkConfig

interface NetworkConfig {
MaxOriginTolerancenumber?--

Max studs between client-reported and server-reconstructed fire origin. Default: 15

MaxConcurrentPerPlayernumber?--

Maximum in-flight bullets per player at any time. Default: 20

TokensPerSecondnumber?--

Token-bucket refill rate for fire-rate limiting. Default: 10

BurstLimitnumber?--

Maximum burst tokens. Must be >= TokensPerSecond. Default: 20

DriftThresholdnumber?--

Studs of positional drift before cosmetic correction begins. Default: 2

CorrectionRatenumber?--

Lerp speed for cosmetic drift correction in studs/second. Default: 8

LatencyBuffernumber?--

Extra seconds to delay local cosmetic spawn. 0 = use measured RTT automatically. Default: 0

ReplicateStateboolean?--

Broadcast bullet state every Heartbeat to all clients for cosmetic correction. Default: true

ModeNetworkMode?--

Authority mode. Controls which side may call :Fire(). Default: "ClientAuthoritative"

}

Optional configuration table passed to VetraNet.new() as the third argument. All fields are optional, unset fields fall back to built-in defaults.

SpatialPartitionConfig

interface SpatialPartitionConfig {
HotRadiusnumber?--

Studs radius around an interest point for HOT tier (full-frequency simulation). Default: 150

WarmRadiusnumber?--

Studs radius for WARM tier (must be >= HotRadius). Default: 400

FallbackTierstring?--

Tier for bullets outside all warm radii. "HOT", "WARM", or "COLD". Default: "HOT"

UpdateIntervalnumber?--

Frames between spatial grid rebuilds. Default: 3

}

Optional configuration for the LOD spatial partition system. Passed as SpatialPartition inside the FactoryConfig to Vetra.new() or Vetra.newParallel().

Show raw api
{
    "functions": [],
    "properties": [],
    "types": [
        {
            "name": "CastTrajectory",
            "desc": "Represents one continuous parabolic arc of a projectile's flight path.\n\nA new segment is appended to `Runtime.Trajectories` on every bounce or\nmid-flight kinematic change via the `Set*` / `Add*` methods on [VetraCast].\n`EndTime` of `-1` indicates the segment is still active.",
            "fields": [
                {
                    "name": "StartTime",
                    "lua_type": "number",
                    "desc": "`Runtime.TotalRuntime` when this segment began."
                },
                {
                    "name": "EndTime",
                    "lua_type": "number",
                    "desc": "`Runtime.TotalRuntime` when closed; `-1` while active."
                },
                {
                    "name": "Origin",
                    "lua_type": "Vector3",
                    "desc": "World-space start position of this arc."
                },
                {
                    "name": "InitialVelocity",
                    "lua_type": "Vector3",
                    "desc": "Velocity at `StartTime` in studs/second."
                },
                {
                    "name": "Acceleration",
                    "lua_type": "Vector3",
                    "desc": "Constant acceleration for this arc (gravity + extra + initial drag)."
                }
            ],
            "source": {
                "line": 28,
                "path": "docs/TypeDefinitions.lua"
            }
        },
        {
            "name": "BulletSnapshot",
            "desc": "Read-only snapshot of a [BulletContext]'s state at a point in time.\nReturned by [BulletContext:GetSnapshot].",
            "fields": [
                {
                    "name": "Id",
                    "lua_type": "number",
                    "desc": "Unique identifier."
                },
                {
                    "name": "Origin",
                    "lua_type": "Vector3",
                    "desc": "Muzzle position at fire time."
                },
                {
                    "name": "Direction",
                    "lua_type": "Vector3",
                    "desc": "Initial unit direction."
                },
                {
                    "name": "Speed",
                    "lua_type": "number",
                    "desc": "Initial speed in studs/second."
                },
                {
                    "name": "Position",
                    "lua_type": "Vector3?",
                    "desc": "Current world-space position, or nil before the first frame."
                },
                {
                    "name": "Velocity",
                    "lua_type": "Vector3",
                    "desc": "Current velocity vector."
                },
                {
                    "name": "Alive",
                    "lua_type": "boolean",
                    "desc": "Whether the cast is still being simulated."
                },
                {
                    "name": "Lifetime",
                    "lua_type": "number",
                    "desc": "Seconds of simulated time elapsed since creation."
                },
                {
                    "name": "PathLength",
                    "lua_type": "number",
                    "desc": "True accumulated path distance (bounces included)."
                },
                {
                    "name": "DistanceTraveled",
                    "lua_type": "number",
                    "desc": "Alias for PathLength (API compatibility)."
                }
            ],
            "source": {
                "line": 49,
                "path": "docs/TypeDefinitions.lua"
            }
        },
        {
            "name": "BulletContextConfig",
            "desc": "Configuration table passed to [BulletContext.new].",
            "fields": [
                {
                    "name": "Origin",
                    "lua_type": "Vector3",
                    "desc": "Required. World-space muzzle position."
                },
                {
                    "name": "Direction",
                    "lua_type": "Vector3",
                    "desc": "Required. Unit direction vector."
                },
                {
                    "name": "Speed",
                    "lua_type": "number",
                    "desc": "Required. Initial speed in studs/second."
                },
                {
                    "name": "RaycastParams",
                    "lua_type": "RaycastParams?",
                    "desc": "Optional per-bullet raycast filter. Takes priority over `Behavior.RaycastParams` when set. Default: `nil`"
                },
                {
                    "name": "SolverData",
                    "lua_type": "any?",
                    "desc": "Internal, used by the solver to attach lifecycle hooks. Do not set from weapon code."
                }
            ],
            "source": {
                "line": 64,
                "path": "docs/TypeDefinitions.lua"
            }
        },
        {
            "name": "SpeedProfile",
            "desc": "Per-speed-regime behavior overrides. Assigned to `SupersonicProfile` or\n`SubsonicProfile` on a `VetraBehavior`. The solver blends in the matching\nprofile's values when the bullet crosses the speed of sound (343 studs/s).\n\nAll fields are optional. Omitted fields continue using the base behavior values.",
            "fields": [
                {
                    "name": "DragCoefficient",
                    "lua_type": "number?",
                    "desc": "Drag coefficient override for this regime."
                },
                {
                    "name": "DragModel",
                    "lua_type": "DragModel?",
                    "desc": "Drag model override for this regime."
                },
                {
                    "name": "NormalPerturbation",
                    "lua_type": "number?",
                    "desc": "Bounce noise override for this regime."
                },
                {
                    "name": "MaterialRestitution",
                    "lua_type": "{ [Enum.Material]: number }?",
                    "desc": "Per-material restitution overrides."
                },
                {
                    "name": "Restitution",
                    "lua_type": "number?",
                    "desc": "Base restitution override for this regime."
                }
            ],
            "source": {
                "line": 83,
                "path": "docs/TypeDefinitions.lua"
            }
        },
        {
            "name": "VetraBehavior",
            "desc": "Complete configuration for a projectile cast. All fields are optional —\nany omitted field falls back to a safe built-in default.\n\nPrefer constructing this via [BehaviorBuilder] rather than by hand to get\ntyped setters, build-time validation, and a frozen result. For fields not\nexposed by the builder (drag, Magnus, homing config, tumble, etc.), pass a\nraw table or a table that inherits from a built behavior via `__index`.\n\n---\n\n**Physics**\n\n---\n\n**Aerodynamic Drag**\n\n---\n\n**Wind**\n\n---\n\n**Supersonic / Subsonic Profiles**\n\n---\n\n**Magnus Effect**\n\n---\n\n**Gyroscopic Drift**\n\n---\n\n**Tumble**\n\n---\n\n**Homing**\n\n---\n\n**Trajectory Provider**\n\n---\n\n**Pierce**\n\n---\n\n**Fragmentation**\n\n---\n\n**Bounce**\n\n---\n\n**High Fidelity**\n\n---\n\n**Corner Trap Detection**\n\n---\n\n**LOD**\n\n---\n\n**Cosmetic**\n\n---\n\n**Batch Travel**\n\n---\n\n**Wind Sensitivity**\n\n---\n\n**Debug**",
            "fields": [
                {
                    "name": "Acceleration",
                    "lua_type": "Vector3?",
                    "desc": "Extra acceleration on top of gravity (e.g. rocket thrust). Default: `Vector3.zero`"
                },
                {
                    "name": "MaxDistance",
                    "lua_type": "number?",
                    "desc": "Max flight distance in studs. Default: `500`"
                },
                {
                    "name": "MaxSpeed",
                    "lua_type": "number?",
                    "desc": "Speed ceiling; bullet terminates if exceeded. Default: `math.huge`"
                },
                {
                    "name": "MinSpeed",
                    "lua_type": "number?",
                    "desc": "Termination speed threshold in studs/sec. Default: `1`"
                },
                {
                    "name": "RaycastParams",
                    "lua_type": "RaycastParams?",
                    "desc": "Raycast filter. Used if `BulletContext.RaycastParams` is not set, before falling back to an empty `RaycastParams.new()`. Default: `nil`"
                },
                {
                    "name": "Gravity",
                    "lua_type": "Vector3?",
                    "desc": "Gravitational acceleration (negative Y = downward). Default: workspace gravity downward."
                },
                {
                    "name": "CastFunction",
                    "lua_type": "((Vector3, Vector3, RaycastParams) -> RaycastResult?)?",
                    "desc": "Custom cast function (serial solver only). Default: `nil`"
                },
                {
                    "name": "BulletMass",
                    "lua_type": "number?",
                    "desc": "Bullet mass for penetration and impact-force calculations. Default: `0`"
                },
                {
                    "name": "DragCoefficient",
                    "lua_type": "number?",
                    "desc": "Drag coefficient. `0` = no drag. Default: `0`"
                },
                {
                    "name": "DragModel",
                    "lua_type": "DragModel?",
                    "desc": "Drag model type. Default: `\"Quadratic\"`"
                },
                {
                    "name": "DragSegmentInterval",
                    "lua_type": "number?",
                    "desc": "Seconds between drag + Magnus recalculation steps. Default: `0.05`"
                },
                {
                    "name": "CustomMachTable",
                    "lua_type": "{ { number } }?",
                    "desc": "Custom Mach→Cd table pairs when `DragModel = \"Custom\"`."
                },
                {
                    "name": "WindResponse",
                    "lua_type": "number?",
                    "desc": "Multiplier on the solver's wind vector (`Vetra:SetWind`). `1.0` = full effect, `0.0` = immune. Default: `1.0`"
                },
                {
                    "name": "SpeedThresholds",
                    "lua_type": "{ number }?",
                    "desc": "Sorted list of speeds (studs/s) that fire `OnSpeedThresholdCrossed`. Default: `{}`"
                },
                {
                    "name": "SupersonicProfile",
                    "lua_type": "SpeedProfile?",
                    "desc": "Behavior overrides when bullet speed is >= 343 studs/s. Default: `nil`"
                },
                {
                    "name": "SubsonicProfile",
                    "lua_type": "SpeedProfile?",
                    "desc": "Behavior overrides when bullet speed is < 343 studs/s. Default: `nil`"
                },
                {
                    "name": "SpinVector",
                    "lua_type": "Vector3?",
                    "desc": "Spin axis (direction) x angular velocity (magnitude, rad/s). `Vector3.zero` = disabled. Default: `Vector3.zero`"
                },
                {
                    "name": "MagnusCoefficient",
                    "lua_type": "number?",
                    "desc": "Magnus lift coefficient. Typical range: 0.00005–0.001. `0` = disabled. Default: `0`"
                },
                {
                    "name": "SpinDecayRate",
                    "lua_type": "number?",
                    "desc": "Rate at which `SpinVector` magnitude decreases per second. `0` = no decay. Default: `0`"
                },
                {
                    "name": "GyroDriftRate",
                    "lua_type": "number?",
                    "desc": "Lateral drift acceleration magnitude in studs/s². `nil` = disabled. Default: `nil`"
                },
                {
                    "name": "GyroDriftAxis",
                    "lua_type": "Vector3?",
                    "desc": "Reference axis for drift direction. `nil` = world UP (right-hand rifling). Default: `nil`"
                },
                {
                    "name": "TumbleSpeedThreshold",
                    "lua_type": "number?",
                    "desc": "Speed below which tumbling begins. `nil` = disabled. Default: `nil`"
                },
                {
                    "name": "TumbleDragMultiplier",
                    "lua_type": "number?",
                    "desc": "Drag multiplied by this factor while tumbling. Default: `3.0`"
                },
                {
                    "name": "TumbleLateralStrength",
                    "lua_type": "number?",
                    "desc": "Chaotic lateral acceleration magnitude in studs/s². Default: `0`"
                },
                {
                    "name": "TumbleOnPierce",
                    "lua_type": "boolean?",
                    "desc": "Begin tumbling on first pierce regardless of speed. Default: `false`"
                },
                {
                    "name": "TumbleRecoverySpeed",
                    "lua_type": "number?",
                    "desc": "Speed above which tumbling ends. `nil` = tumble is permanent. Default: `nil`"
                },
                {
                    "name": "HomingPositionProvider",
                    "lua_type": "((pos: Vector3, vel: Vector3) -> Vector3?)?",
                    "desc": "Called every frame for target position. Return `nil` to disengage. Default: `nil`"
                },
                {
                    "name": "CanHomeFunction",
                    "lua_type": "CanHomeCallback?",
                    "desc": "Gate callback; return `false` to disengage. Default: `nil`"
                },
                {
                    "name": "HomingStrength",
                    "lua_type": "number?",
                    "desc": "Steering force in degrees/second. Default: `90`"
                },
                {
                    "name": "HomingMaxDuration",
                    "lua_type": "number?",
                    "desc": "Max seconds of active homing before `OnHomingDisengaged` fires. Default: `3`"
                },
                {
                    "name": "HomingAcquisitionRadius",
                    "lua_type": "number?",
                    "desc": "Min target distance in studs to engage. `0` = engage immediately on fire. Default: `0`"
                },
                {
                    "name": "TrajectoryPositionProvider",
                    "lua_type": "((elapsed: number) -> Vector3?)?",
                    "desc": "Override bullet position each frame with a sampled curve. Return `nil` to end the override and terminate. Default: `nil`"
                },
                {
                    "name": "CanPierceFunction",
                    "lua_type": "CanPierceCallback?",
                    "desc": "Pierce gate; return `true` to pierce. Default: `nil`"
                },
                {
                    "name": "MaxPierceCount",
                    "lua_type": "number?",
                    "desc": "Lifetime pierce limit. Default: `3`"
                },
                {
                    "name": "PierceSpeedThreshold",
                    "lua_type": "number?",
                    "desc": "Min speed to attempt pierce (studs/s). Default: `50`"
                },
                {
                    "name": "PierceSpeedRetention",
                    "lua_type": "number?",
                    "desc": "Speed fraction kept per pierce `[0,1]`. Default: `0.8`"
                },
                {
                    "name": "PierceNormalBias",
                    "lua_type": "number?",
                    "desc": "Min approach angle for pierce `[0,1]`. `1.0` = all angles, `0.0` = perpendicular only. Default: `1.0`"
                },
                {
                    "name": "PierceDepth",
                    "lua_type": "number?",
                    "desc": "Max wall thickness per pierce in studs. `0` = no per-pierce depth limit. Default: `0`"
                },
                {
                    "name": "PierceForce",
                    "lua_type": "number?",
                    "desc": "Total momentum force budget for penetration. `0` = disabled. Default: `0`"
                },
                {
                    "name": "PierceThicknessLimit",
                    "lua_type": "number?",
                    "desc": "Hard cap on wall thickness for the exit-point raycast in studs. Default: `500`"
                },
                {
                    "name": "FragmentOnPierce",
                    "lua_type": "boolean?",
                    "desc": "Spawn fragment child bullets when a pierce occurs. Default: `false`"
                },
                {
                    "name": "FragmentCount",
                    "lua_type": "number?",
                    "desc": "Number of fragments to spawn per pierce. Default: `3`"
                },
                {
                    "name": "FragmentDeviation",
                    "lua_type": "number?",
                    "desc": "Angular half-angle spread of the fragment cone in degrees. Default: `15`"
                },
                {
                    "name": "CanBounceFunction",
                    "lua_type": "CanBounceCallback?",
                    "desc": "Bounce gate; return `true` to bounce. Default: `nil`"
                },
                {
                    "name": "MaxBounces",
                    "lua_type": "number?",
                    "desc": "Lifetime bounce limit. Default: `5`"
                },
                {
                    "name": "BounceSpeedThreshold",
                    "lua_type": "number?",
                    "desc": "Min speed to attempt bounce (studs/s). Default: `20`"
                },
                {
                    "name": "Restitution",
                    "lua_type": "number?",
                    "desc": "Energy retention per bounce `[0,1]`. Default: `0.7`"
                },
                {
                    "name": "MaterialRestitution",
                    "lua_type": "{ [Enum.Material]: number }?",
                    "desc": "Per-material multipliers, combined with `Restitution`. Default: `{}`"
                },
                {
                    "name": "NormalPerturbation",
                    "lua_type": "number?",
                    "desc": "Random surface-normal noise for rough surfaces. `0` = clean reflection. Default: `0.0`"
                },
                {
                    "name": "ResetPierceOnBounce",
                    "lua_type": "boolean?",
                    "desc": "Reset pierce state after each confirmed bounce. Default: `false`"
                },
                {
                    "name": "HighFidelitySegmentSize",
                    "lua_type": "number?",
                    "desc": "Sub-segment length in studs (starting value). Default: `0.5`"
                },
                {
                    "name": "HighFidelityFrameBudget",
                    "lua_type": "number?",
                    "desc": "Millisecond budget per cast per frame for sub-segment raycasts. Default: `4`"
                },
                {
                    "name": "AdaptiveScaleFactor",
                    "lua_type": "number?",
                    "desc": "Adaptive sizing multiplier, must be `> 1`. Default: `1.5`"
                },
                {
                    "name": "MinSegmentSize",
                    "lua_type": "number?",
                    "desc": "Hard floor for adaptive segment size (studs). Default: `0.1`"
                },
                {
                    "name": "MaxBouncesPerFrame",
                    "lua_type": "number?",
                    "desc": "Per-frame bounce cap across all sub-segments. Default: `10`"
                },
                {
                    "name": "CornerTimeThreshold",
                    "lua_type": "number?",
                    "desc": "Min seconds between bounces (Pass 1). Default: `0.002`"
                },
                {
                    "name": "CornerPositionHistorySize",
                    "lua_type": "number?",
                    "desc": "Bounce position history size, positive integer (Pass 3 & 4). Default: `4`"
                },
                {
                    "name": "CornerDisplacementThreshold",
                    "lua_type": "number?",
                    "desc": "Min bounce separation in studs (Pass 3). Default: `0.5`"
                },
                {
                    "name": "CornerEMAAlpha",
                    "lua_type": "number?",
                    "desc": "EMA smoothing factor for velocity direction `(0,1)` (Pass 2). Default: `0.4`"
                },
                {
                    "name": "CornerEMAThreshold",
                    "lua_type": "number?",
                    "desc": "EMA oscillation threshold (Pass 2). Must be `> |1 - 2·alpha|`. Default: `0.25`"
                },
                {
                    "name": "CornerMinProgressPerBounce",
                    "lua_type": "number?",
                    "desc": "Min studs of progress per bounce over history (Pass 4). `0` disables Pass 4. Default: `0.3`"
                },
                {
                    "name": "LODDistance",
                    "lua_type": "number?",
                    "desc": "Studs from the LOD origin beyond which this bullet steps at reduced frequency. `0` = always full frequency. Default: `0`"
                },
                {
                    "name": "CosmeticBulletTemplate",
                    "lua_type": "BasePart?",
                    "desc": "Part cloned per fire call. Default: `nil`"
                },
                {
                    "name": "CosmeticBulletContainer",
                    "lua_type": "Instance?",
                    "desc": "Parent for the cosmetic object. Defaults to `workspace`. Default: `nil`"
                },
                {
                    "name": "CosmeticBulletProvider",
                    "lua_type": "((context: BulletContext) -> Instance?)?",
                    "desc": "Provider function; takes priority over Template. Default: `nil`"
                },
                {
                    "name": "AutoDeleteCosmeticBullet",
                    "lua_type": "boolean?",
                    "desc": "When `true`, the cosmetic Instance is destroyed automatically on termination. Set to `false` to manage cleanup yourself. Default: `true`"
                },
                {
                    "name": "BatchTravel",
                    "lua_type": "boolean?",
                    "desc": "Include this cast in `OnTravelBatch` instead of firing individual `OnTravel` events. Default: `false`"
                },
                {
                    "name": "WindResponse",
                    "lua_type": "number?",
                    "desc": "Multiplier on the solver's wind vector. `1.0` = fully affected, `0.0` = immune. Default: `1.0`"
                },
                {
                    "name": "VisualizeCasts",
                    "lua_type": "boolean?",
                    "desc": "Enable trajectory visualizer for this cast. Default: `false`"
                }
            ],
            "source": {
                "line": 243,
                "path": "docs/TypeDefinitions.lua"
            }
        },
        {
            "name": "DragModel",
            "desc": "Drag model used to compute aerodynamic deceleration each `DragSegmentInterval`.\n\n**Analytic models:**\n- `\"Linear\"`, deceleration ∝ speed.\n- `\"Quadratic\"`, deceleration ∝ speed² (default). Most physically accurate for subsonic bullets.\n- `\"Exponential\"`, deceleration ∝ eˢᵖᵉᵉᵈ. Models exotic high-drag shapes.\n\n**G-series empirical models (Mach-indexed Cd lookup tables):**\n- `\"G1\"`, flat-base spitzer; general-purpose standard.\n- `\"G2\"`, Aberdeen J projectile; large-caliber / atypical shapes.\n- `\"G5\"`, boat-tail spitzer; mid-range rifles.\n- `\"G6\"`, semi-spitzer flat-base; shotgun slugs.\n- `\"G7\"`, long boat-tail; modern long-range / sniper standard.\n- `\"G8\"`, flat-base semi-spitzer; hollow points / pistols.\n- `\"GL\"`, lead round ball; cannons / muskets / buckshot.\n\n**User-supplied:**\n- `\"Custom\"`, requires `CustomMachTable = { {mach, cd}, ... }` in the behavior.",
            "lua_type": "\"Linear\" | \"Quadratic\" | \"Exponential\" | \"G1\" | \"G2\" | \"G3\" | \"G4\" | \"G5\" | \"G6\" | \"G7\" | \"G8\" | \"GL\" | \"Custom\"",
            "source": {
                "line": 269,
                "path": "docs/TypeDefinitions.lua"
            }
        },
        {
            "name": "NetworkMode",
            "desc": "Authority mode that controls which side may call `:Fire()` on a VetraNet handle.\n\n- `\"ClientAuthoritative\"`, clients send fire requests; server validates. **(Default)**\n- `\"ServerAuthority\"`, only server code may initiate bullets; client fire requests are silently dropped.\n- `\"SharedAuthority\"`, both client and server may fire; client requests go through validation, server calls bypass it.\n\nPass via `NetworkConfig.Mode`. Prefer `Vetra.Enums.NetworkMode` over raw strings.",
            "lua_type": "\"ClientAuthoritative\" | \"ServerAuthority\" | \"SharedAuthority\"",
            "source": {
                "line": 284,
                "path": "docs/TypeDefinitions.lua"
            }
        },
        {
            "name": "TerminationReason",
            "desc": "The reason a cast was terminated. Passed as the second argument to\n`OnPreTermination` signal handlers.\n\n- `\"hit\"`, bullet struck a surface and was not pierced or bounced.\n- `\"distance\"`, `MaxDistance` was reached.\n- `\"speed\"`, speed dropped below `MinSpeed` or exceeded `MaxSpeed`.\n- `\"corner_trap\"`, corner-trap detection terminated the cast.\n- `\"manual\"`, `Terminate()` was called explicitly, or the solver was destroyed.",
            "lua_type": "\"hit\" | \"distance\" | \"speed\" | \"corner_trap\" | \"manual\"",
            "source": {
                "line": 300,
                "path": "docs/TypeDefinitions.lua"
            }
        },
        {
            "name": "NetworkConfig",
            "desc": "Optional configuration table passed to `VetraNet.new()` as the third argument.\nAll fields are optional, unset fields fall back to built-in defaults.",
            "fields": [
                {
                    "name": "MaxOriginTolerance",
                    "lua_type": "number?",
                    "desc": "Max studs between client-reported and server-reconstructed fire origin. Default: `15`"
                },
                {
                    "name": "MaxConcurrentPerPlayer",
                    "lua_type": "number?",
                    "desc": "Maximum in-flight bullets per player at any time. Default: `20`"
                },
                {
                    "name": "TokensPerSecond",
                    "lua_type": "number?",
                    "desc": "Token-bucket refill rate for fire-rate limiting. Default: `10`"
                },
                {
                    "name": "BurstLimit",
                    "lua_type": "number?",
                    "desc": "Maximum burst tokens. Must be `>= TokensPerSecond`. Default: `20`"
                },
                {
                    "name": "DriftThreshold",
                    "lua_type": "number?",
                    "desc": "Studs of positional drift before cosmetic correction begins. Default: `2`"
                },
                {
                    "name": "CorrectionRate",
                    "lua_type": "number?",
                    "desc": "Lerp speed for cosmetic drift correction in studs/second. Default: `8`"
                },
                {
                    "name": "LatencyBuffer",
                    "lua_type": "number?",
                    "desc": "Extra seconds to delay local cosmetic spawn. `0` = use measured RTT automatically. Default: `0`"
                },
                {
                    "name": "ReplicateState",
                    "lua_type": "boolean?",
                    "desc": "Broadcast bullet state every Heartbeat to all clients for cosmetic correction. Default: `true`"
                },
                {
                    "name": "Mode",
                    "lua_type": "NetworkMode?",
                    "desc": "Authority mode. Controls which side may call `:Fire()`. Default: `\"ClientAuthoritative\"`"
                }
            ],
            "source": {
                "line": 320,
                "path": "docs/TypeDefinitions.lua"
            }
        },
        {
            "name": "SpatialPartitionConfig",
            "desc": "Optional configuration for the LOD spatial partition system. Passed as\n`SpatialPartition` inside the `FactoryConfig` to `Vetra.new()` or\n`Vetra.newParallel()`.",
            "fields": [
                {
                    "name": "HotRadius",
                    "lua_type": "number?",
                    "desc": "Studs radius around an interest point for HOT tier (full-frequency simulation). Default: `150`"
                },
                {
                    "name": "WarmRadius",
                    "lua_type": "number?",
                    "desc": "Studs radius for WARM tier (must be >= HotRadius). Default: `400`"
                },
                {
                    "name": "FallbackTier",
                    "lua_type": "string?",
                    "desc": "Tier for bullets outside all warm radii. `\"HOT\"`, `\"WARM\"`, or `\"COLD\"`. Default: `\"HOT\"`"
                },
                {
                    "name": "UpdateInterval",
                    "lua_type": "number?",
                    "desc": "Frames between spatial grid rebuilds. Default: `3`"
                }
            ],
            "source": {
                "line": 336,
                "path": "docs/TypeDefinitions.lua"
            }
        }
    ],
    "name": "TypeDefinitions",
    "desc": "Shared Luau type definitions used across Vetra and VetraNet.\n\nThese are imported for type annotations only, there is no runtime cost.\nYou generally do not need to require this module directly.",
    "source": {
        "line": 9,
        "path": "docs/TypeDefinitions.lua"
    }
}