U5.5 Gesamtprüfung: Glutpakt-Heer alt und neu

ArmyViewsTests stellt alle zehn Glutpakt-Truppen und die Heldin in einer
Partie auf, Bilder von Aufstellung und Kampf mit alten Modellen und
Meshy-Figuren; Maßtabelle und Befund zu Größen und Lesbarkeit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Martin Stickelbroeck 2026-10-10 18:19:43 +02:00
parent 9e253f4a19
commit c144a96706
14 changed files with 136 additions and 0 deletions

View file

@ -0,0 +1,98 @@
using System;
using System.Collections;
using System.Linq;
using Luneraria.Core;
using Luneraria.View;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;
namespace Luneraria.UI.Tests
{
/// <summary>
/// U5.5 overall check of a whole Glutpakt army in the real game: the human seat buys all ten
/// Glutpakt troops (the upgrades as their base troop, then upgraded) and hires the hero
/// Funkenlanze in round 3; the camera shows the formation close and at lane distance, the fight
/// close, at lane distance and from above the map. Like HudViewsTests, commands go straight to
/// the match followed by the preview rebuild. A capture tool, not part of the suite:
/// -testFilter "Luneraria.UI.Tests.ArmyViewsTests"; LUNE_EVIDENCE names the folder below
/// docs/port/screenshots (default u5.5-heer).
/// </summary>
[Explicit("Bildwerkzeug: nur gezielt per -testFilter")]
public sealed class ArmyViewsTests
{
static readonly string[] Bunds = { "wurzelbund", "glutpakt", "glutpakt", "wurzelbund", "wurzelbund", "glutpakt" };
static readonly string[] Troops = { "g01", "g02", "g03", "g04", "g05", "g06", "g07", "g08", "g09", "g10" };
string _folder;
IEnumerator Shot(HudSession s, string label)
{
yield return s.Shot(_folder + label + ".png");
}
static void Send(HudSession s, Command command)
{
CommandResult result = s.Match.Submit(HudSession.Human, command);
Assert.IsTrue(result.Ok, command.Type + ": " + result.Message);
s.Game.RebuildPreview();
s.Sync();
}
static Vec2 Centre(System.Collections.Generic.IEnumerable<LuneUnit> units)
{
var list = units.ToList();
Assert.IsNotEmpty(list, "own figures on the field");
double x = list.Average(u => u.Position.X), y = list.Average(u => u.Position.Y);
return new Vec2(x, y);
}
[UnityTest, Timeout(900000)]
public IEnumerator Glutpakt()
{
string evidence = Environment.GetEnvironmentVariable("LUNE_EVIDENCE");
_folder = "docs/port/screenshots/" + (string.IsNullOrEmpty(evidence) ? "u5.5-heer" : evidence) + "/";
var s = new HudSession();
yield return s.Open(1920, 1080, seed: 4, bunds: Bunds);
s.Match.RoundNumber = 3;
s.Me.Draft.Gold = 100000;
foreach (string troop in Troops)
{
string baseId = ContentData.Units.Keys.FirstOrDefault(id => DataCatalog.UpgradeOf(id) == troop);
Send(s, Command.Buy(baseId ?? troop, s.Me.Lane));
if (baseId != null)
Send(s, Command.Upgrade(s.Me.Draft.Roster.Last().Uid));
}
Send(s, Command.HeroBuy("held_funkenlanze"));
s.Me.Draft.Gold = 400;
s.Sync();
yield return new WaitForSecondsRealtime(.5f);
Assert.AreEqual(Troops.Length, s.Me.Draft.Roster.Count(e => Troops.Contains(e.TypeId)), "all ten Glutpakt troops");
Vec2 formation = Centre(s.View.Preview.Units.Where(u => u.Team == s.Me.Team && (Troops.Contains(u.Def.Id) || u.Kind == "hero")));
s.Rig.LookAt(formation, 14f, true);
yield return new WaitForSecondsRealtime(.5f);
yield return Shot(s, "01-aufstellung-nah");
s.Rig.LookAt(formation, 22f, true);
yield return new WaitForSecondsRealtime(.5f);
yield return Shot(s, "02-aufstellung-lane");
s.Game.Key(KeyCode.Space);
yield return HudSession.Frames(1);
Assert.AreEqual(LuneMatchRunner.Stage.Combat, s.Runner.Current, "combat of round 3");
yield return s.Fight(9.0);
s.Driver.Paused = true;
// The front of the own army (as in FigureViewsTests): the troop furthest along the lane.
Vec2 front = s.Match.Combat.Units.Where(u => u.Alive && u.Team == s.Me.Team && Troops.Contains(u.Def.Id))
.OrderByDescending(u => u.Progress).First().Position;
s.Rig.LookAt(front, 14f, true);
yield return new WaitForSecondsRealtime(.5f);
yield return Shot(s, "03-kampf-nah");
s.Rig.LookAt(front, 22f, true);
yield return new WaitForSecondsRealtime(.5f);
yield return Shot(s, "04-kampf-lane");
s.Rig.LookAt(front, 40f, true);
yield return new WaitForSecondsRealtime(.5f);
yield return Shot(s, "05-kampf-weit");
s.Close();
}
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 7c2956cd43a154c82b6ec5f3da0f2687

View file

@ -240,6 +240,15 @@ Hinweis: Die Projektdateien des .NET-Harness (`tools/dotnet/*/*.csproj`) fehlten
| Bild | `screenshots/u5.5-g04/` | | Bild | `screenshots/u5.5-g04/` |
| Commits | `luneraria/u5.5-g04` | | Commits | `luneraria/u5.5-g04` |
## U5.5 · Gesamtprüfung Glutpakt-Heer
| Punkt | Ergebnis |
| --- | --- |
| Werkzeug | `ArmyViewsTests`: alle zehn Truppen und die Heldin in einer Partie, alt und neu (je 1/1) |
| Bild | `screenshots/u5.5-heer/vorher/`, `nachher/` |
| Befund | Größenrangfolge stimmt; Basaltbastion und Glasballiste deutlich größer; Meshy-Heer einheitlicher, in der Lane-Weite schwerer zu unterscheiden; Helligkeit gleich |
| Commits | `luneraria/u5.5-heer` |
## Ausblick ## Ausblick
Der Pilot entscheidet über eine Serie weiterer Meshy-Figuren (Kosten je Figur, Lizenz, Stilgleichheit). Offen bleiben außerdem Künstler-Sculpts für Anatomie/Gesicht/Haar, LOD und Material-Atlanten sowie die Build-Module für Windows und Linux. Der Pilot entscheidet über eine Serie weiterer Meshy-Figuren (Kosten je Figur, Lizenz, Stilgleichheit). Offen bleiben außerdem Künstler-Sculpts für Anatomie/Gesicht/Haar, LOD und Material-Atlanten sowie die Build-Module für Windows und Linux.

View file

@ -655,3 +655,30 @@ Stresstest mit 36 Basaltbastionen (`-luneBenchmarkArmy g04`), je drei Läufe geg
### Stand der Glutpakt ### Stand der Glutpakt
Alle zehn Truppen der Glutpakt sind Meshy-Figuren (g01 bis g10, dazu die Heldin Funkenlanze über `g05`). Ausgegeben wurden dafür 726 Credits (Pilot 86, Funkenlanze 110, Glasballiste 54, die übrigen sieben je 68). Die Phase-4- und Phase-15/18/19-Modelle bleiben im Projekt; eine Zeile `replaces` im Manifest stellt die alte Figur wieder her. Alle zehn Truppen der Glutpakt sind Meshy-Figuren (g01 bis g10, dazu die Heldin Funkenlanze über `g05`). Ausgegeben wurden dafür 726 Credits (Pilot 86, Funkenlanze 110, Glasballiste 54, die übrigen sieben je 68). Die Phase-4- und Phase-15/18/19-Modelle bleiben im Projekt; eine Zeile `replaces` im Manifest stellt die alte Figur wieder her.
## U5.5 · Gesamtprüfung: das Glutpakt-Heer
Stand 10. Oktober 2026, Zweig `luneraria/u5.5-heer` (auf `luneraria/u5.5-g04`). Neues Bildwerkzeug `ArmyViewsTests` (PlayMode, `Explicit`): Der menschliche Sitz kauft in Runde 3 alle zehn Glutpakt-Truppen (Aufwertungen als Grundtruppe gekauft und aufgewertet) und wirbt die Heldin Funkenlanze an; Bilder von Aufstellung (nah, Lane) und Kampf (nah an der Spitze, Lane, weit). Dieselbe Partie einmal mit den alten Modellen (alle `replaces` entfernt) und einmal mit den Meshy-Figuren: `screenshots/u5.5-heer/vorher/` und `nachher/`.
Maße (Breite × Höhe × Tiefe in m) alt → neu:
| Truppe | alt | Meshy |
| --- | --- | --- |
| g01 Kohlenbeißer | 1,58 × 1,35 × 0,89 | 1,72 × 1,35 × 0,77 |
| g02 Schlackenklaue | 1,79 × 1,50 × 0,98 | 1,65 × 1,50 × 0,84 |
| g03 Schlackenwacht | 1,78 × 1,35 × 0,87 | 1,54 × 1,35 × 0,69 |
| g04 Basaltbastion | 1,76 × 2,25 × 0,85 | 2,39 × 2,10 × 1,05 |
| g05 Funkenlanze | 1,57 × 1,45 × 0,45 (Phase 18: 2,0 hoch) | 1,15 × 1,80 × 1,72 (mit Lanze) |
| g06 Glasballiste | 1,85 × 1,43 × 1,61 | 1,85 × 1,39 × 2,53 |
| g07 Aschenwerfer | 1,64 × 1,35 × 1,25 | 1,73 × 1,35 × 0,75 |
| g08 Kraterrufer | 1,83 × 1,50 × 1,49 | 2,01 × 1,50 × 0,89 |
| g09 Herdhüter | 1,25 × 1,45 × 1,08 | 1,55 × 1,45 × 0,79 |
| g10 Sonnenesse | 1,33 × 1,60 × 1,17 | 1,72 × 1,60 × 0,98 |
Befund:
- **Größen:** Die Höhen der Phase-4-Modelle sind gehalten (Skelett auf die alte Höhe gesetzt). Die Rangfolge stimmt: Aufwertungen sind größer als ihre Grundform, die Basaltbastion ist die größte Figur. Ausreißer sind die Basaltbastion (+0,6 m breiter) und die Glasballiste (+0,9 m länger); in der Aufstellung überdecken sie Nachbarn.
- **Lesbarkeit:** Die alten Modelle unterscheiden sich von oben stark durch Grundformen (offene Kessel mit oranger Füllung, heller Ofen). Die Meshy-Figuren teilen eine Materialsprache (Basalt, Gold, Glutrisse) und wirken als Heer geschlossener, sind aber in der Lane-Weite schwerer auseinanderzuhalten; Kessel und Kraterschale sind von oben weniger sichtbar, weil die Figuren in der Ruhehaltung nach vorn geneigt stehen. Herdhüter und Sonnenesse bleiben durch den hellen Stein und Mantel gut erkennbar. Die mittlere Helligkeit der Aufstellung ist gleich (Luma 0,45 / 0,44, `tools/port/png_stats.py`).
- **Heldin:** Truppe und Heldin Funkenlanze teilen das Modell `g05`; im Feld unterscheidet sie nur der goldene Heldenring und das Namensschild.
- **Nicht geprüft:** Animationen im Gegeneinander (Treffer, Tod) nur stichprobenweise in den Kampfbildern.
Vorschläge (offen, nicht umgesetzt): Ruhehaltung ohne Vorneigung für die Kessel-Figuren (eigener Leerlauf-Clip oder Kopfknochen ruhig stellen), die Basaltbastion auf rund 1,9 m Breite skalieren, die Glasballiste kürzen; eine eigene Erscheinung für die Heldin.

Binary file not shown.

After

Width:  |  Height:  |  Size: 720 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 738 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 666 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 666 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 629 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 716 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 743 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 671 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 672 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 635 KiB