Skip to content

Technisches Waffensystem und 3D-Anbindung

Status: vier spielbare technische Startwaffen; finale Modelle, Animationen, Audio und VFX fehlen bewusst.

Architektur und Verzeichnisse

Die Godot-freie Basis liegt in den einzelnen Typdateien unter Shared/Weapons, Shared/Loadouts und Shared/Progression. Godot-Input erzeugt Authority-Commands; AdvancedWeaponController sendet Fire-, Reload- und Switch-Absichten über IDungeonCombatCommandPort. DungeonCombatNetworkSync ist der ENet-Adapter; Tests können einen Port ohne SceneTree einsetzen.

Wichtige Pfade:

  • src/HolodeckArena.Shared/Weapons: Definitionen, Fire-Behaviors, Netzwerkvalidierung und Content.
  • src/HolodeckArena.Shared/Loadouts: Validierung, Hash und effektive numerische Werte.
  • src/HolodeckArena.Game3D/Features/Combat: Controller und Damage-Pipeline.
  • src/HolodeckArena.Game3D/Features/Weapons/Runtime: Präsentations- und Event-Hooks.
  • src/HolodeckArena.Game3D/Features/Weapons/<Archetyp>: technische PackedScenes.
  • tests/HolodeckArena.Game3D.Tests/Weapons: Domain- und Scene-Contract-Tests.

Es gibt keine ID-Switches im PlayerController. WeaponFireBehaviorCatalog löst Strategien nach WeaponArchetype auf. Eine fünfte Gattung benötigt Definition und Behavior-Registrierung, aber keine PlayerController-Änderung.

Implementierte Startwaffen

ID Archetyp Verhalten Scene
weapon.pulse_rifle Pulse Rifle automatisch, deterministische Streuung, Hitscan, Falloff PulseRifle/PulseRifleMk1.tscn
weapon.plasma_shotgun Plasma Shotgun mehrere deterministische Pellets, starker Falloff PlasmaShotgun/PlasmaShotgunMk1.tscn
weapon.rail_rifle Rail Rifle halbautomatisch, sortierte/deduplizierte Penetrationen RailRifle/RailRifleMk1.tscn
weapon.arc_cannon Arc Cannon Primärziel plus deterministische Kette ohne Doppeltreffer ArcCannon/ArcCannonMk1.tscn

Die technischen Werte liegen in WeaponDefinitionFactory und WeaponTechnicalDefinitionFactory. Basis-Resources werden nie mutiert. WeaponStatCalculator erzeugt numerische Werte in den Schichten Modifikation, Mastery und temporär. WeaponTechnicalStatResolver erzeugt ebenfalls neue Records für Pellet-, Penetrations-, Falloff- und Arc-Änderungen.

Scene-Vertrag

Jede Weapon-Scene besitzt:

  • WeaponRoot mit WeaponView3D;
  • leeres VisualRoot für das finale Modell;
  • MuzzleMarker, ProjectileSpawnMarker und AimOriginMarker;
  • AudioRoot, VfxRoot und standardmäßig unsichtbares DebugRoot.

Fehlende Visual-, Audio- oder VFX-Nodes blockieren Gameplay nicht. WeaponView3D bietet Events für Fire, Reload, Ammo, Equip, Hit, ArcJump und RailPenetration. WeaponHudViewModel stellt Active ID/Name, Magazin, Reserve, Reloadfortschritt, Slots, Locks, Mastery und Mods bereit, ohne eine neue große HUD-Scene zu erzwingen.

Der Player besitzt WeaponSocketPrimary, WeaponSocketSecondary, WeaponSocketHolsteredPrimary und WeaponSocketHolsteredSecondary. Die aktive Runtime verwendet die beiden Equip-Sockets. Lokale Position/Rotation kommen aus WeaponVisualHooks; kein Skeleton- oder Bone-Name ist fest codiert.

Loadout, Progression, Mastery und Run-Regeln

Nur ValidatedRunLoadout aus LoadoutValidator darf als Run-Artefakt gelten. Wenn eine aktive RunDefinition ein validiertes Loadout und RunRules enthält, übergibt DungeonRun3DController dieses vor Combat-Start an den Player. Ohne Run-Loadout bleibt das dokumentierte Default-Loadout Pulse Rifle plus Plasma Shotgun erhalten.

Official Runs verwenden ProgressionPolicy.Disabled und NormalizeWeaponStats; persönliche Mastery und Unlockvorteile fließen nicht in effektive Werte ein. Fun/Community können Unlocks, Mods und Mastery anwenden. Diese Entscheidung liegt zentral in RunRules, LoadoutValidator, WeaponStatCalculator und WeaponTechnicalStatResolver, nicht in einzelnen Waffen.

Alle vier Weapons besitzen Unlock-IDs und Mastery-Tracks. Zusätzliche technisch wirksame Perks existieren für Shotgun, Rail und Arc; Pulse verwendet den vorhandenen Track. Beispiel-Mods:

  • Pulse: mod.extended_magazine;
  • Shotgun: mod.focused_plasma_choke;
  • Rail: mod.penetrator_coil;
  • Arc: mod.chain_capacitor.

Eine Dev-Freischaltung soll über einen expliziten Development-Progression-Snapshot oder Official/Fixed-Loadout-Regeln erfolgen. Es gibt absichtlich keinen globalen Produktions-Bypass.

Combat, Determinismus, Replay und Netzwerk

WeaponShotIdentity leitet den Seed aus Run-ID, Player-ID, Weapon-Instance-ID und ShotSequence per SHA-256 ab. Fire-Behaviors verwenden nur diesen Seed. Rail sortiert nach Distanz und Entity-ID; Arc wählt nach Distanz und anschließend ordinaler Entity-ID. Globale Zufallsquellen werden nicht verwendet.

AdvancedWeaponController beachtet Fire-Rate, Magazin, Reserve, Reload, Wechsel/Reload-Abbruch, Faction und tote Ziele. Treffer werden aggregiert und als WeaponDamageRequest zentral angewendet. ShotRecorded, WeaponSwitched und die WeaponView3D-Events liefern kompakte Hooks für Recorder, Statistik, HUD, Audio und VFX.

WeaponShotCommand und WeaponShotValidator bereiten Servervalidierung vor: doppelte Shot-ID, Weapon-ID, aktiver Slot, AmmoSequence und Fire-Rate werden geprüft; Client-Damage wird ignoriert und aus dem serverseitigen Catalog abgeleitet. Die aktuelle Headless-Architektur autorisiert Dungeon-Combat noch nicht. Diese Contracts sind daher kein behaupteter ENet-End-to-End-Schutz; vor Competitive Multiplayer müssen sie in eine serverseitige Dungeon-Simulation eingebunden werden.

Neue Waffe erstellen

  1. Stabile weapon.*-ID und WeaponDefinition in WeaponDefinitionFactory anlegen.
  2. Eine typisierte WeaponFireBehaviorDefinition und technische Definition ergänzen.
  3. Falls nötig IWeaponFireBehavior implementieren und im Behavior-Catalog registrieren.
  4. Scene mit dem vollständigen Marker-Vertrag anlegen.
  5. Scene-Pfad und Visual-/Audio-/VFX-IDs registrieren.
  6. Unlock in UnlockService, Mastery-Track/Perks und mindestens einen kompatiblen Mod ergänzen.
  7. Loadout-/Official-/Fun-Regeln und Balanceversion prüfen.
  8. Behavior-, Ammo-, Network- und Scene-Contract-Tests ergänzen.

Neue Modifikation erstellen

Numerische Effekte verwenden WeaponStatModifier. Komplexe Effekte erhalten eine stabile GameplayEffectId und eine immutable Transformation im WeaponTechnicalStatResolver. Slot, Weapon-/Category-Kompatibilität, Unlock, Localization-fähiger Name, Version und optionaler Visual-Hook gehören in die Definition. Danach Locked-, Slot-, Compatibility-, Official- und Stat-Prioritätstests ergänzen.

So füge ich einer technisch vorbereiteten Waffe ein finales 3D-Modell hinzu

  1. Die betreffende *Mk1.tscn im Godot-Editor öffnen.
  2. Das Modell als Kind von VisualRoot instanziieren. Gameplay-Nodes niemals unter das importierte Modell verschieben.
  3. Lokale Position, Rotation und Skalierung am Modell beziehungsweise über WeaponVisualHooks.EquipPosition/EquipRotationDegrees ausrichten. Player-Socket und Skeleton bleiben unabhängig.
  4. MuzzleMarker exakt an die Laufmündung setzen; lokale Vorwärtsrichtung muss mit der Waffen-/Aim-Richtung übereinstimmen.
  5. Für Projektilvisuals ProjectileSpawnMarker setzen. Hitscan-Gameplay benötigt trotzdem kein Projektilmesh.
  6. AimOriginMarker so setzen, dass der Ray nicht im Player-Collider startet.
  7. AnimationPlayer unter VisualRoot oder einem Präsentationskind ergänzen und über WeaponFired, ReloadStarted, ReloadCompleted, Equipped und Unequipped triggern. Fehlende Clips müssen ignoriert werden.
  8. Muzzle Flash unter VfxRoot instanziieren und auf WeaponFired reagieren; Hit-, Arc- und Rail-VFX verwenden WeaponHit, ArcJumped und RailPenetrated.
  9. Projectile-Mesh/Trail an die projektilbezogene Präsentation binden; keine Schadenslogik in VFX-Scripts legen.
  10. AudioStreamPlayer3D unter AudioRoot ergänzen und Fire-/Reload-IDs auf Streams abbilden. Fehlende Streams dürfen keinen Fehler erzeugen.
  11. DebugRoot im Editor temporär sichtbar machen, Marker prüfen und vor Commit wieder deaktivieren.
  12. Scene direkt laden, danach Developer-Run testen: beide Slots, Wechsel, leeres Magazin, Reload/Wechselabbruch, Tod während Fire, alle Treffermechaniken und Scene-Wechsel.

Tests, Performance und typische Fehler

Ausführen:

dotnet test tests/HolodeckArena.Game3D.Tests/HolodeckArena.Game3D.Tests.csproj --filter FullyQualifiedName~Weapon
dotnet build "src/HolodeckArena.Game3D/Holodeck Arena 3D.csproj"
godot --headless --path src/HolodeckArena.Game3D --editor --quit

Keine Catalog-/Resource-Suche, LINQ, Reflection oder neue Random-Instanz pro Frame/Schuss. Node-Referenzen und Scenes werden beim Equip aufgelöst. Candidate-, Target- und Damage-Collections werden wiederverwendet. Bei Projectile-Ausbau ist Pooling Pflicht.

Typische Fehler sind unbekannte persistente ID, nicht validiertes Loadout, falscher Mod-Slot, fehlende Scene/Marker, mutierte Basisdefinition, doppelter Entity-Hit, globale Random-Nutzung, Client-Damage als Wahrheit und versehentlich aktive Mastery in Official Runs. Scene-Contract-Tests erkennen fehlende Dateien und Marker; Domain-Tests decken Deduplizierung, Reichweite, Falloff, Determinismus, Reload und Network-Validation ab.