Files
UE5-Modular-Game-Framework/docs/game/weapons-index.md
Lefteris Notas 040db37720 Add UI Overrides and Weapons Index documentation for Project Void
- Created ui-overrides.md detailing game-specific Widget Blueprint overrides, including purpose, widget index, visual styling, and accessibility requirements.
- Established weapons-index.md outlining all held weapon actors, including their components, logic, and comparisons for gameplay mechanics.
2026-05-21 22:27:57 +03:00

12 KiB
Raw Blame History

Weapons Index — All Held Weapon Actors

Game: Project Void | Build Phase: 10 Framework Systems: 69_BP_WeaponBase, 70_BPC_AmmoComponent, 74_BPC_FirearmSystem, 76_BPC_MeleeSystem, 77_BPC_RecoilSystem, 78_BPC_ReloadSystem


Purpose

Defines the 4 held weapon/tool actors used by the player. Each is spawned by BPC_EquipmentSlotSystem when an item is equipped and attached to the player's hand socket.


Weapon Catalog

# Actor Type Damage Fire Rate Mag Size Slot Interfaces
1 BP_Pistol_Held Firearm 15 0.15s (hitscan) 12 PrimaryWeapon I_UsableItem
2 BP_Shotgun_Held Firearm 45 (total) 1.0s (pellets) 2 PrimaryWeapon I_UsableItem
3 BP_Flashlight_Held Tool 0 Tool I_UsableItem, I_Toggleable
4 BP_Crowbar_Held Melee/Tool 20 0.8s (swing) Tool I_UsableItem, I_MeleeWeapon

1. BP_Pistol_Held (Full build in item-pistol.md)

Quick Reference:

Components:
  ├─ SkeletalMeshComponent (slide animation)
  ├─ SceneComponent "MuzzleSocket"
  ├─ AudioComponent "FireSound"
  ├─ AudioComponent "ReloadSound"
  └─ ParticleSystemComponent "MuzzleFlash"

Core Loop:
  IA_Fire → UseItem() → Ammo check → Hitscan → Damage → Recoil → Timer lockout
  IA_Reload → Reload() → BPC_AmmoComponent.ConsumeAmmo() → update magazine

States:
  ├─ Idle (can fire)
  ├─ Firing (timer lockout)
  ├─ Empty (out of ammo — click sound)
  └─ Reloading (animation, blocked input)

2. BP_Shotgun_Held

Parent: BP_WeaponBase (69)

Components

# Component Name Purpose
1 SkeletalMeshComponent WeaponMesh Break-action double barrel
2 SceneComponent MuzzleSocket End of barrel
3 AudioComponent FireSound Loud shotgun blast
4 AudioComponent ReloadSound Shell insertion click
5 AudioComponent BreakOpenSound Opening action sound
6 AudioComponent BreakCloseSound Closing action snap
7 ParticleSystemComponent MuzzleFlash Large muzzle flash
8 PointLightComponent MuzzleLight Brief flash on fire

Variables

Variable Type Default Purpose
CurrentShells Int 2 Shells currently loaded (0-2)
MaxShells Int 2 Always 2 for double-barrel
bIsFiring Bool false Fire lockout
bIsReloading Bool false Reload lockout
bIsBrokenOpen Bool false Break-action state
WeaponData DA_ItemData* Shotgun Data Asset
PelletCount Int 6 Pellets per shot
PelletSpreadAngle Float 5.0 Degrees of spread cone

Fire Logic (Pellet Spread)

UseItem() → (called by IA_Fire or IA_Fire+IA_Aim for ADS)
   │
   ├─ bIsFiring? → Return False
   ├─ bIsReloading? → Return False
   ├─ bIsBrokenOpen? → Auto-close barrels → wait 0.3s
   │
   ├─ CurrentShells > 0? → Branch
   │    ├─ True:
   │    │    ├─ Set bIsFiring = true
   │    │    ├─ CurrentShells -= 1
   │    │    │
   │    │    ├─ [Fire Both Barrels if 2 shells loaded?]
   │    │    │    └─ Designer option: single or double fire
   │    │    │         └─ Default: single fire (double on alt-fire)
   │    │    │
   │    │    ├─ [Multi-Trace Pellet System]
   │    │    │    │
   │    │    │    ├─ For i = 0 to PelletCount:
   │    │    │    │    ├─ Calculate spread direction:
   │    │    │    │    │    ├─ BaseDir: Camera forward vector
   │    │    │    │    │    └─ Apply Random Cone (PelletSpreadAngle)
   │    │    │    │    │
   │    │    │    │    ├─ Start: MuzzleSocket.GetWorldLocation
   │    │    │    │    ├─ End: Start + SpreadDir * FireRange
   │    │    │    │    │
   │    │    │    │    └─ Line Trace By Channel (Visibility)
   │    │    │    │         ├─ Hit? → Branch
   │    │    │    │         │    ├─ True:
   │    │    │    │         │    │    ├─ HitActor → I_Damageable?
   │    │    │    │         │    │    │    └─ ApplyDamage(PelletDamage, ...)
   │    │    │    │         │    │    └─ Spawn impact decal
   │    │    │    │         │    └─ False: continue
   │    │    │    │    └─ Draw debug line (editor only, color per pellet)
   │    │    │    │
   │    │    │    └─ Track total pellets hit for combat feedback
   │    │    │
   │    │    ├─ [Effects]
   │    │    │    ├─ MuzzleFlash → Activate
   │    │    │    ├─ FireSound → Play
   │    │    │    ├─ MuzzleLight → SetVisibility(true) → Delay(0.05) → false
   │    │    │    └─ Camera shake (heavy): PlayCameraShake(ShotgunKick)
   │    │    │
   │    │    ├─ [Recoil]
   │    │    │    └─ BPC_RecoilSystem.ApplyRecoil(WeaponData, ×3 heavy multiplier)
   │    │    │
   │    │    ├─ [Post-Fire]
   │    │    │    ├─ Delay(FireRateTimer) → Set bIsFiring = false
   │    │    │    └─ IF CurrentShells == 0 → Auto-break-open for reload
   │    │    │         └─ Set bIsBrokenOpen = true, play break animation
   │    │    │
   │    │    └─ Return True
   │    │
   │    └─ False: (empty)
   │         ├─ Play click/empty sound
   │         └─ Return False

Reload Logic (Shell-by-Shell)

Reload()
   │
   ├─ CurrentShells >= MaxShells? → Return (full)
   ├─ bIsReloading? → Return (already reloading)
   │
   ├─ [If not broken open] → Play break-open animation → Set bIsBrokenOpen = true
   │
   ├─ Set bIsReloading = true
   │
   ├─ [Shell Loop — reload one shell at a time]
   │    │
   │    ├─ BPC_AmmoComponent.GetAmmoCount(ShellAmmoTypeTag)
   │    │
   │    ├─ While CurrentShells < MaxShells AND BPC_AmmoComponent.AmmoCount > 0:
   │    │    ├─ BPC_AmmoComponent.ConsumeAmmo(ShellAmmoTypeTag, 1)
   │    │    ├─ CurrentShells += 1
   │    │    ├─ Play ReloadSound (shell click)
   │    │    └─ Delay(ShellReloadDelay = 0.8s)
   │    │
   │    └─ [Player CAN fire mid-reload if at least 1 shell loaded]
   │         └─ If IA_Fire pressed during reload:
   │              ├─ Stop reload loop
   │              ├─ Play break-close animation
   │              ├─ Set bIsBrokenOpen = false
   │              ├─ Set bIsReloading = false
   │              └─ Process Fire (with whatever shells are loaded)
   │
   ├─ [Reload Complete]
   │    ├─ Play break-close animation
   │    ├─ Set bIsBrokenOpen = false
   │    ├─ Set bIsReloading = false
   │    └─ Broadcast OnReloadComplete

Damage Falloff

CalculatePelletDamage(BaseDamage, Distance):
   │
   ├─ IF Distance <= 500: multiplier = 1.0  (point-blank: devastating)
   ├─ IF Distance <= 1500: multiplier = 0.7 (close range: lethal)
   ├─ IF Distance <= 2500: multiplier = 0.4 (medium: wounding)
   └─ IF Distance > 2500: multiplier = 0.15 (long: minor)
   │
   └─ Return BaseDamage × multiplier / PelletCount

3. BP_Flashlight_Held (Full build in item-flashlight.md)

Quick Reference:

  • Implements I_UsableItem and I_Toggleable
  • UseItem() → toggles light on/off
  • Battery consumed at 2%/second while on
  • Battery restored by using DA_Item_Battery from consumable system
  • SpotLightComponent with Cone Angle: 15° / 30°

4. BP_Crowbar_Held

Parent: Actor | Implements: I_UsableItem, I_MeleeWeapon

Components

# Component Name Purpose
1 StaticMeshComponent CrowbarMesh Rusted crowbar model
2 BoxComponent SwingHitbox Melee hit detection (disabled until swing)

Variables

Variable Type Default Purpose
SwingDamage Float 20.0 Damage per swing
SwingCooldown Float 0.8 Seconds between swings
bIsSwinging Bool false Swing lockout
SwingRange Float 250.0 Units of reach
SwingArc Float 90.0 Degrees of arc

Melee Logic

UseItem() → BPC_MeleeSystem.Swing(Self)
   │
   ├─ bIsSwinging? → Return False
   │
   ├─ Set bIsSwinging = true
   │
   ├─ [Swing Animation]
   │    └─ Timeline (0.0 → 1.0 over 0.3s) → Update crowbar rotation
   │
   ├─ [Swing Hitbox — enable at 0.15s (mid-swing)]
   │    ├─ Delay(0.15) → SwingHitbox.SetCollisionEnabled(QueryOnly)
   │    ├─ OnComponentBeginOverlap(SwingHitbox, OtherActor):
   │    │    ├─ OtherActor → DoesImplementInterface(I_Damageable)?
   │    │    │    ├─ True:
   │    │    │    │    ├─ ApplyDamage(SwingDamage, Self, Melee, HitLocation, HitDirection)
   │    │    │    │    ├─ Play hit sound (metal thud)
   │    │    │    │    └─ BPC_CombatFeedbackComponent.ShowHitMarker()
   │    │    │    └─ False: Play wall/object hit sound
   │    │    └─ (Hit each actor only once per swing — use a hit-set)
   │    │
   │    └─ Delay(0.15) → SwingHitbox.SetCollisionEnabled(NoCollision)
   │
   ├─ [Swing Complete]
   │    ├─ Delay(SwingCooldown) → Set bIsSwinging = false
   │    └─ Return True

Pry Function

CanPryOpen(DoorActor: BP_DoorActor*) → Boolean
   └─ Return (DoorActor.IsBarricaded())

PryDoor(DoorActor: BP_DoorActor*)
   ├─ DoorActor.Open() (forces open, breaks barricade)
   ├─ Play wood/metal break sound
   ├─ DoorActor.SetLocked(false) permanently
   └─ SS_AudioManager.PlaySFX("crowbar_pry")

Weapon Animation Notifies (GASP Integration)

All held weapons fire animation notifies that the GASP AnimBP listens to:

Notify Weapon Purpose
Notify_Fire Pistol, Shotgun Triggers fire animation blend
Notify_ReloadStart Pistol, Shotgun Enters reload animation state
Notify_ReloadEnd Pistol, Shotgun Exits reload animation state
Notify_MeleeSwing Crowbar Triggers melee swing blend
Notify_Equip All Weapon equip animation
Notify_Unequip All Weapon holster animation
Notify_AimDownSights Pistol, Shotgun ADS pose transition
Notify_HipFire Pistol, Shotgun Hip fire pose transition

These are added to montage slots in the GASP child AnimBP, NOT in the weapon BP itself.


Quick Comparison

Feature Pistol Shotgun Flashlight Crowbar
Role Ranged DPS Burst damage Vision Utility + Melee
Best Range Medium-Long Close Infinite (light) Melee
Ammo Management Magazine Shell-by-shell Battery (%) None
Reload Strategy Dump + reload Tactical (can interrupt) Replace battery N/A
Recoil Light Heavy None None
ADS Benefit Higher accuracy Tighter spread N/A N/A
Stress Impact None +5 (loud) -1/sec (safe light) None
Silent? No No Yes No (swing noise)
Attracts Enemies? Yes (2000u radius) Yes (3000u radius) Yes (800u radius) Yes (1200u radius)

Notes for Expansion

  • Add weapon degradation: pistol jams after 100 shots without cleaning
  • Add flashlight flicker: battery below 10% causes random light flicker (horror mechanic)
  • Add shotgun slug ammo: alternate ammo type — single slug instead of pellets, longer range
  • Add crowbar upgrade: wrap with cloth → silent melee swings (no enemy alert)
  • Add aim-assist for controller players (configurable in accessibility)
  • Add weapon inspection animation: hold reload key to inspect weapon (cosmetic)
  • Multiplayer: all fire/reload must be server-authoritative with client prediction for effects

Weapons Index for Project Void. See GAMEINDEX.md for full game structure. See item-pistol.md and item-flashlight.md for detailed build walkthroughs.