champions-of-luneraria/Assets/Luneraria/View/LuneMatchDriver.cs
Martin Stickelbroeck 66867f3332 U3D Abnahme: Prüfung, Feld um das HUD, Bilder, Leistung
Das G3-HUD ist abgenommen; der Meilenstein U3 ist damit fertig.

- Prüfung (Port von verify_g3, Teile A–H plus I): 718 Prüfungen ohne
  Fehler. Teil I prüft die Feld-Darstellung um das HUD (U3-Zugabe aus
  dem Motivvergleich): Aufstellungsflächen, Grotteneingang, ruhender
  Boss, Namensschilder, Eigentümer-Ring, Ancient-Balken.
- Feld um das HUD: Namensschilder für Helden (mit Stufe), Angriffs-
  champions und den eingesetzten Boss („für Blau“), Eigentümer-Ring,
  Ancient-Balken bei Schaden, ruhende Schlundkrone auf dem Podest,
  eigener Grotteneingang, Aufstellungsflächen als eigene Objekte.
- Schriften korrigiert: Die Referenz deklariert Cantarell 560/700–760
  und Cinzel 700, wendet die Gewichte aber nie an (variation_opentype
  mit dem String-Schlüssel „wght“ wird von Godot ignoriert). G3 zeigt
  Regular 400, der Port ebenso — Cinzel-Regular statt Bold, keine
  Kontur zur Aufdickung. Laufweite aus spacing_glyph umgerechnet;
  dunkler Saum als Schatten statt TextCore-Kontur.
- Werkzeuge: HudViewsTests (14 G3-Motive), HudPlaytest (Spieltest über
  die echte Oberfläche per Befehlsdateien), ui_ms_per_frame im
  LuneBenchmark. Layout folgt den echten Panelhöhen, Kamera startet wie
  Godot _ready auf der eigenen Lane.
- Tests: EditMode 23/23, PlayMode 13/13, Kerntests 402/402, Verify
  718/0. Fingerabdrücke der Bot-Partien unverändert (DCE95C96556F3A1A,
  7B8E43AEFC0D60C5).
- Bilder: 14 Motive bei 1920×1080, Auflösungen 1152×720 bis 2560×1440,
  Prüf-Schlüsselbilder, Spieltest-Screenshots.
- Leistung (macOS-Player mit HUD, 116 Einheiten): 169 fps Übersicht,
  218 fps Mid nah; HUD-Skripte 0,090 bzw. 0,078 ms je Bild.
- Dokumentation: U3-UI (U3D, Schriftbefund), PORT-QA (U3), PORT-STATUS
  (U3 fertig, U4 nächster Schritt), KNOWN-BEHAVIOR-DIFFERENCES.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 12:55:06 +02:00

81 lines
3.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections.Generic;
using Luneraria.Core;
using UnityEngine;
namespace Luneraria.View
{
/// <summary>
/// Hosts a match in the scene (U2C/U2D; human seat and tempo since U3). Update only hands frame
/// time (times the speed) to the runner's fixed clock; it never decides anything in combat.
/// Seed, start round and extra gold are the public fixtures of the golden scenarios. With
/// HumanSlot &gt;= 0 the HUD plans that seat and planning waits for its Ready; tempo steps
/// (1×, 2×, 4×) and pause act only in combat, as in Godot (lune_game.gd).
/// </summary>
public sealed class LuneMatchDriver : MonoBehaviour
{
/// <summary>Tempo steps of the HUD's tempo button.</summary>
public static readonly int[] SpeedSteps = { 1, 2, 4 };
public int Seed = 2;
public int StartRound = 1;
public int ExtraGold;
public string Profile = "";
/// <summary>Optional Bünde of the six seats (fixtures like Godot's start option "bunds"); empty seats follow the seed.</summary>
[System.NonSerialized] public string[] Bunds;
/// <summary>The seat a human plays through the HUD; -1 for a bot match (U2 tests, benchmark).</summary>
public int HumanSlot = -1;
/// <summary>Match speed: simulated seconds per real second (tests run faster than 1).</summary>
public float Speed = 1f;
/// <summary>Index into SpeedSteps (the player's tempo, on top of Speed).</summary>
public int SpeedIndex;
public bool Paused;
public bool RecordTrace = true;
public LuneMatchRunner Runner { get; private set; }
/// <summary>Main-thread cost of the last frame's simulation (milliseconds).</summary>
public double LastAdvanceMs { get; private set; }
readonly System.Diagnostics.Stopwatch _clock = new System.Diagnostics.Stopwatch();
public int Tempo { get { return SpeedSteps[Mathf.Clamp(SpeedIndex, 0, SpeedSteps.Length - 1)]; } }
public void Restart()
{
var options = new MatchOptions { Seed = Seed, HumanSlot = HumanSlot, Bunds = Bunds != null ? new List<string>(Bunds) : new List<string>() };
Runner = new LuneMatchRunner(options, StartRound, ExtraGold, Profile);
if (RecordTrace)
Runner.Trace = new LuneTrace();
SpeedIndex = 0;
Paused = false;
}
/// <summary>Next tempo step (1× → 2× → 4× → 1×).</summary>
public void CycleSpeed()
{
SpeedIndex = (SpeedIndex + 1) % SpeedSteps.Length;
}
/// <summary>Pause exists only in combat; planning waits for the player anyway.</summary>
public bool TogglePause()
{
if (Runner == null || Runner.Current != LuneMatchRunner.Stage.Combat)
return false;
Paused = !Paused;
return true;
}
void Awake()
{
if (Runner == null)
Restart();
}
void Update()
{
_clock.Restart();
// Pause holds only the combat steps (Godot: a paused game still plans and settles).
if (!(Paused && Runner.Current == LuneMatchRunner.Stage.Combat))
Runner.Advance(Time.deltaTime * Speed * Tempo);
LastAdvanceMs = _clock.Elapsed.TotalMilliseconds;
}
}
}