champions-of-luneraria/Assets/Luneraria/View/LuneClock.cs
Martin Stickelbroeck 3871b3e2e6 U2C Simulation/View Binding
Fester Simulationstakt und Ansichten, die nur lesen; Nachweis, dass die Partie
bei jeder Bildrate dieselbe ist.

- LuneClock: Akkumulator, ganze Schritte zu 0,05 s, Alpha zum Interpolieren.
- LuneMatchRunner: Host-Ablauf einer Bot-Partie (Planung über die
  Befehlsschnittstelle, Kampf im festen Takt, Abrechnung, nächste Runde);
  LuneMatchDriver reicht in Update nur Bildzeit weiter.
- LuneTrace: Fingerabdruck der Partie (jeder Schritt, jede Abrechnung) und der
  reine Kernlauf zum Vergleich.
- Ansichten: LuneMatchView, LuneUnitView (interpolierte Position, Blickrichtung,
  Clips aus Kampfereignissen, Teamring, Lebensbalken), LuneBuildingView mit
  Einsturz und Ruine aus den autoritativen HP, Turmblitze, LuneCameraRig wie
  lune_camera.gd, vorläufige Debug-Anzeige (kein HUD; U3 portiert das G3-HUD).
- Einheitenbibliothek: Kohlenbeißer aus 131 Teilen zu einem Mesh, Animator-
  Controller mit den Blender-Clips, Ring- und Balkenmeshes, Markermaterialien.
- Tests: EditMode (30/60/120 fps, unbegrenzt, Ruckler, 8x Tempo; Seed 2 und
  Seed 9 ab Runde 21) und PlayMode in der Szene bei echten Bildraten 30, 60,
  120 und unbegrenzt: überall derselbe Fingerabdruck wie der Kern.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 17:31:18 +02:00

49 lines
1.5 KiB
C#

using System;
namespace Luneraria.View
{
/// <summary>
/// Fixed simulation tick (U2C): frame time goes into an accumulator, and whole steps of
/// LuneBalance.SimStep (0.05 s) come out. The frame rate only decides how many steps run in a
/// frame, never what a step does, so every frame rate produces the same sequence of steps.
/// Alpha is the fraction of the next step already elapsed; views interpolate with it.
/// </summary>
public sealed class LuneClock
{
public readonly double Step;
/// <summary>Upper bound per frame; a stalled frame is caught up over the next frames.</summary>
public int MaxStepsPerFrame = 200;
double _accumulator;
public LuneClock(double step)
{
Step = step;
}
public double Alpha { get { return Math.Min(1.0, _accumulator / Step); } }
public void Reset()
{
_accumulator = 0.0;
}
/// <summary>Adds frame time and runs whole steps; step returns false when it has to stop.</summary>
public int Advance(double seconds, Func<bool> step)
{
if (seconds > 0.0)
_accumulator += seconds;
int count = 0;
while (_accumulator >= Step && count < MaxStepsPerFrame)
{
_accumulator -= Step;
count++;
if (!step())
{
_accumulator = 0.0;
break;
}
}
return count;
}
}
}