H1 Sylvara: Figur, Skin-System, Oberfläche, Nachweise

Meshy-Figur Sylvara (20.709 Dreiecke, Lane-Fassung 4.999) mit zwei Sicheln
als eigene Modelle, Clips leap/ultimate, 116 Credits. Skin-System: hero_skin
als kosmetische Planungswahl, Blutmond als Varianten-Skin (skin_variant.py,
AI_*_Blutmond, Dress mit Skin). Heldenfenster mit Reiter Ultimate & Skin,
Befehlsplatz der Heldenkarte, Mondring. Ultimate zündet nicht im Sprungschritt.
Kern 500/500, EditMode 30/30, PlayMode 15/15, Verify 718/0, Selbsttest 30/30,
Fingerabdrücke unverändert; Balance 50 % wie Ringborke/Funkenlanze; Leistung
gleich der Funkenlanze-Heldin.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Martin Stickelbroeck 2026-10-10 18:06:58 +02:00
parent 60992f1091
commit 805f5754c9
122 changed files with 64451 additions and 59498 deletions

View file

@ -0,0 +1,703 @@
{
"id": "sylvara",
"group": "Characters",
"source": "tools/meshy/build_figure.py",
"exporter_version": 11,
"blender": "5.2.2 LTS",
"fbx_settings": {
"use_selection": true,
"use_visible": false,
"use_active_collection": false,
"global_scale": 1.0,
"apply_unit_scale": true,
"apply_scale_options": "FBX_SCALE_UNITS",
"axis_forward": "Y",
"axis_up": "Z",
"bake_space_transform": false,
"object_types": [
"ARMATURE",
"EMPTY",
"MESH"
],
"use_mesh_modifiers": true,
"use_mesh_modifiers_render": true,
"mesh_smooth_type": "OFF",
"use_subsurf": false,
"use_mesh_edges": false,
"use_tspace": false,
"use_triangles": false,
"colors_type": "LINEAR",
"prioritize_active_color": true,
"use_custom_props": false,
"add_leaf_bones": false,
"primary_bone_axis": "Y",
"secondary_bone_axis": "X",
"use_armature_deform_only": true,
"armature_nodetype": "NULL",
"bake_anim": true,
"bake_anim_use_all_bones": true,
"bake_anim_use_nla_strips": false,
"bake_anim_use_all_actions": true,
"bake_anim_force_startend_keying": true,
"bake_anim_step": 1.0,
"bake_anim_simplify_factor": 0.0,
"path_mode": "STRIP",
"embed_textures": false,
"batch_mode": "OFF"
},
"checks": [
{
"check": "turn_applied",
"ok": true,
"detail": "[]"
},
{
"check": "units_metric",
"ok": true,
"detail": "METRIC"
},
{
"check": "unit_scale_1",
"ok": true,
"detail": "1.0"
},
{
"check": "no_negative_scale",
"ok": true,
"detail": "{}"
},
{
"check": "object_scale_1",
"ok": true,
"detail": "{}"
},
{
"check": "mesh_names_unique",
"ok": true,
"detail": "['SylvaraBody_LOD0', 'SylvaraBody_LOD1', 'SylvaraSichelL_LOD0', 'SylvaraSichelL_LOD1', 'SylvaraSichelR_LOD0', 'SylvaraSichelR_LOD1']"
},
{
"check": "material_slots_filled",
"ok": true,
"detail": "{}"
},
{
"check": "normals_unit_length",
"ok": true,
"detail": "{}"
},
{
"check": "no_blend_shapes",
"ok": true,
"detail": "{}"
},
{
"check": "triangles_match_godot",
"ok": true,
"detail": "30782 fbx / 30782 godot"
},
{
"check": "one_armature",
"ok": true,
"detail": "['SylvaraRig']"
},
{
"check": "single_root_bone",
"ok": true,
"detail": "['Root']"
},
{
"check": "root_bone_name",
"ok": true,
"detail": "['Root']"
},
{
"check": "bone_count_match_godot",
"ok": true,
"detail": "25 / 25"
},
{
"check": "bone_names_portable",
"ok": true,
"detail": "[]"
},
{
"check": "skinned_meshes_present",
"ok": true,
"detail": ""
},
{
"check": "clips_match_godot",
"ok": true,
"detail": "[]"
},
{
"check": "required_clips_present",
"ok": true,
"detail": "[]"
},
{
"check": "roundtrip_mesh_names",
"ok": true,
"detail": "[]"
},
{
"check": "roundtrip_triangles",
"ok": true,
"detail": "30782 / 30782"
},
{
"check": "roundtrip_materials",
"ok": true,
"detail": "[]"
},
{
"check": "roundtrip_bones",
"ok": true,
"detail": "[]"
},
{
"check": "roundtrip_clips",
"ok": true,
"detail": "['ability', 'attack_a', 'attack_b', 'death', 'hit', 'idle', 'leap', 'ultimate', 'walk']"
}
],
"generator": {
"clips": {
"idle": {
"source": "Idle",
"frames": [
0.0,
96.0
],
"seconds": 4.0,
"loop": true,
"contact_seconds": -1.0
},
"walk": {
"source": "Run_02",
"frames": [
0.0,
16.799999237060547
],
"seconds": 0.75,
"loop": true,
"contact_seconds": -1.0
},
"attack_a": {
"source": "Left_Slash",
"frames": [
0,
40
],
"seconds": 0.9167,
"loop": false,
"contact_seconds": 0.4125
},
"attack_b": {
"source": "Right_Hand_Sword_Slash",
"frames": [
0,
36
],
"seconds": 0.9167,
"loop": false,
"contact_seconds": 0.331
},
"hit": {
"source": "Hit_Reaction",
"frames": [
0,
20
],
"seconds": 0.5,
"loop": false,
"contact_seconds": -1.0
},
"ability": {
"source": "Over_Shoulder_Throw",
"frames": [
50,
100
],
"seconds": 1.0,
"loop": false,
"contact_seconds": 0.64
},
"death": {
"source": "dying_backwards",
"frames": [
0.0,
52.80000305175781
],
"seconds": 2.2083,
"loop": false,
"contact_seconds": -1.0
},
"leap": {
"source": "Run_and_Leap",
"frames": [
30,
64
],
"seconds": 0.7083,
"loop": false,
"contact_seconds": -1.0
},
"ultimate": {
"source": "Double_Blade_Spin",
"frames": [
10,
62
],
"seconds": 1.4167,
"loop": false,
"contact_seconds": 0.7356
}
},
"textures": {
"glow_share": 0.0001,
"palette_gains": {},
"size": [
2048,
2048
]
},
"unit": 0.009999999776482582,
"lod": {
"lod0_triangles": 20709,
"lod1_triangles": 4999,
"lod1_vertices": 2483,
"welded_triangles": 20709,
"lod0_screen": 0.2
},
"props": [
{
"name": "SylvaraSichelR",
"triangles": 2039,
"textures": {
"glow_share": 0.0036,
"palette_gains": {},
"size": [
2048,
2048
]
},
"lod": {
"lod0_triangles": 2039,
"lod1_triangles": 498,
"lod1_vertices": 252,
"welded_triangles": 2039,
"lod0_screen": 0.2
}
},
{
"name": "SylvaraSichelL",
"triangles": 2039,
"textures": "shared",
"lod": {
"lod0_triangles": 2039,
"lod1_triangles": 498,
"lod1_vertices": 252,
"welded_triangles": 2039,
"lod0_screen": 0.2
}
}
]
},
"inputs_sha256": {
"tools/meshy/sylvara/figure.json": "e4e1e7825da9f46de29cd7929ca5c6556d7e5499dc435eed3a2620f0ffaef7a4",
"assets-source/meshy/sylvara/sylvara-skelett.glb": "804b57fe084907ae262dd79bf5c4fb6d76cba854cee97b97d1454d13cb96ee6c",
"assets-source/meshy/sylvara/sylvara-animationen.glb": "07a35bc2d0ae302aade82dfd813088990b6c005a67440f0dba467f6feceb3fd8",
"assets-source/meshy/sylvara/sylvara-sichel.glb": "ba1ca8b506b65732c534c05c9e0814595c649a5061599d32e615780f8c917e30"
},
"source_sha256": "e057f399ecb829cccfce78983c8dce2be2904c58d4e60e6c2c1ade5681cc60d8",
"removed_modifiers": 0,
"kind": "skinned",
"fps": 24.0,
"objects": 7,
"meshes": {
"SylvaraBody_LOD0": {
"mesh": "SylvaraBody_LOD0",
"triangles": 20709,
"vertices": 24339,
"ngons": 0,
"materials": [
"AI_Sylvara"
],
"uv_layers": [
"UVMap"
],
"color_attributes": [],
"active_color": null,
"custom_normals": true,
"normals_unit_length": true,
"bad_normals": 0,
"degenerate_triangles": 0,
"shape_keys": 0,
"skinned": true,
"scale": [
1.0,
1.0,
1.0
],
"bounds_unity": {
"min": [
-0.4455,
-0.0,
-0.2036
],
"max": [
0.4455,
1.75,
0.2036
]
}
},
"SylvaraSichelR_LOD0": {
"mesh": "SylvaraSichelR_LOD0",
"triangles": 2039,
"vertices": 3357,
"ngons": 0,
"materials": [
"AI_SylvaraSichel"
],
"uv_layers": [
"UVMap"
],
"color_attributes": [],
"active_color": null,
"custom_normals": true,
"normals_unit_length": true,
"bad_normals": 0,
"degenerate_triangles": 0,
"shape_keys": 0,
"skinned": true,
"scale": [
1.0,
1.0,
1.0
],
"bounds_unity": {
"min": [
0.2745,
0.9098,
-0.0177
],
"max": [
0.7444,
1.1783,
0.6007
]
}
},
"SylvaraSichelL_LOD0": {
"mesh": "SylvaraSichelL_LOD0",
"triangles": 2039,
"vertices": 3357,
"ngons": 0,
"materials": [
"AI_SylvaraSichel"
],
"uv_layers": [
"UVMap"
],
"color_attributes": [],
"active_color": null,
"custom_normals": true,
"normals_unit_length": true,
"bad_normals": 0,
"degenerate_triangles": 0,
"shape_keys": 0,
"skinned": true,
"scale": [
1.0,
1.0,
1.0
],
"bounds_unity": {
"min": [
-0.5021,
0.7858,
-0.0161
],
"max": [
-0.0143,
1.0206,
0.6024
]
}
},
"SylvaraBody_LOD1": {
"mesh": "SylvaraBody_LOD1",
"triangles": 4999,
"vertices": 2483,
"ngons": 0,
"materials": [
"AI_Sylvara"
],
"uv_layers": [
"UVMap"
],
"color_attributes": [],
"active_color": null,
"custom_normals": false,
"normals_unit_length": true,
"bad_normals": 0,
"degenerate_triangles": 0,
"shape_keys": 0,
"skinned": true,
"scale": [
1.0,
1.0,
1.0
],
"bounds_unity": {
"min": [
-0.4439,
-0.0001,
-0.2046
],
"max": [
0.4453,
1.7502,
0.203
]
}
},
"SylvaraSichelR_LOD1": {
"mesh": "SylvaraSichelR_LOD1",
"triangles": 498,
"vertices": 252,
"ngons": 0,
"materials": [
"AI_SylvaraSichel"
],
"uv_layers": [
"UVMap"
],
"color_attributes": [],
"active_color": null,
"custom_normals": false,
"normals_unit_length": true,
"bad_normals": 0,
"degenerate_triangles": 0,
"shape_keys": 0,
"skinned": true,
"scale": [
1.0,
1.0,
1.0
],
"bounds_unity": {
"min": [
0.2733,
0.9098,
-0.0188
],
"max": [
0.7436,
1.1775,
0.6008
]
}
},
"SylvaraSichelL_LOD1": {
"mesh": "SylvaraSichelL_LOD1",
"triangles": 498,
"vertices": 252,
"ngons": 0,
"materials": [
"AI_SylvaraSichel"
],
"uv_layers": [
"UVMap"
],
"color_attributes": [],
"active_color": null,
"custom_normals": false,
"normals_unit_length": true,
"bad_normals": 0,
"degenerate_triangles": 0,
"shape_keys": 0,
"skinned": true,
"scale": [
1.0,
1.0,
1.0
],
"bounds_unity": {
"min": [
-0.503,
0.7869,
-0.0172
],
"max": [
-0.015,
1.0201,
0.6025
]
}
}
},
"armatures": {
"SylvaraRig": {
"bones": [
"Root",
"Hips",
"Spine02",
"Spine01",
"Spine",
"neck",
"Head",
"head_end",
"headfront",
"LeftShoulder",
"LeftArm",
"LeftForeArm",
"LeftHand",
"RightShoulder",
"RightArm",
"RightForeArm",
"RightHand",
"LeftUpLeg",
"LeftLeg",
"LeftFoot",
"LeftToeBase",
"RightUpLeg",
"RightLeg",
"RightFoot",
"RightToeBase"
],
"roots": [
"Root"
]
}
},
"empties": {},
"bounds_unity": {
"min": [
-0.503,
-0.0001,
-0.2046
],
"max": [
0.7444,
1.7502,
0.6025
]
},
"clips": [
{
"name": "ability",
"frames": [
0.0,
24.0
],
"seconds": 1.0,
"loop": false,
"contact_seconds": 0.64
},
{
"name": "attack_a",
"frames": [
0.0,
22.0
],
"seconds": 0.9167,
"loop": false,
"contact_seconds": 0.4125
},
{
"name": "attack_b",
"frames": [
0.0,
22.0
],
"seconds": 0.9167,
"loop": false,
"contact_seconds": 0.331
},
{
"name": "death",
"frames": [
0.0,
53.0
],
"seconds": 2.2083,
"loop": false,
"contact_seconds": -1.0
},
{
"name": "hit",
"frames": [
0.0,
12.0
],
"seconds": 0.5,
"loop": false,
"contact_seconds": -1.0
},
{
"name": "idle",
"frames": [
0.0,
96.0
],
"seconds": 4.0,
"loop": true,
"contact_seconds": -1.0
},
{
"name": "leap",
"frames": [
0.0,
17.0
],
"seconds": 0.7083,
"loop": false,
"contact_seconds": -1.0
},
{
"name": "ultimate",
"frames": [
0.0,
34.0
],
"seconds": 1.4167,
"loop": false,
"contact_seconds": 0.7356
},
{
"name": "walk",
"frames": [
0.0,
18.0
],
"seconds": 0.75,
"loop": true,
"contact_seconds": -1.0
}
],
"expected_from_godot": {
"triangles": 30782,
"bones": 25,
"clips": [
"idle",
"walk",
"attack_a",
"attack_b",
"hit",
"ability",
"death",
"leap",
"ultimate"
]
},
"meshes_with_ngons": {},
"meshes_without_uv": [],
"triangles": 30782,
"fbx": "Assets/Luneraria/Art/Characters/sylvara.fbx",
"fbx_bytes": 3895276,
"ok": true
}

View file

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 2682cb9fe0d9d4c699bfdd6a74dae754
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View file

@ -0,0 +1,402 @@
fileFormatVersion: 2
guid: 6ec31d870bd7f4b71b9810cb0a14ba9a
ModelImporter:
serializedVersion: 24300
internalIDToNameTable: []
externalObjects: {}
materials:
materialImportMode: 2
materialName: 0
materialSearch: 1
materialLocation: 1
searchTexturesGlobally: 0
animations:
legacyGenerateAnimations: 4
bakeSimulation: 0
resampleCurves: 0
optimizeGameObjects: 0
removeConstantScaleCurves: 0
motionNodeName:
animationImportErrors:
animationImportWarnings:
animationRetargetingWarnings:
animationDoRetargetingWarnings: 0
importAnimatedCustomProperties: 0
importConstraints: 0
animationCompression: 0
animationRotationError: 0.5
animationPositionError: 0.5
animationScaleError: 0.5
animationWrapMode: 0
extraExposedTransformPaths: []
extraUserProperties: []
clipAnimations:
- serializedVersion: 16
name: ability
takeName: SylvaraRig|ability
internalID: -4503705687715001949
firstFrame: 0
lastFrame: 24
wrapMode: 0
orientationOffsetY: 0
level: 0
cycleOffset: 0
loop: 0
hasAdditiveReferencePose: 0
loopTime: 0
loopBlend: 0
loopBlendOrientation: 0
loopBlendPositionY: 0
loopBlendPositionXZ: 0
keepOriginalOrientation: 0
keepOriginalPositionY: 1
keepOriginalPositionXZ: 0
heightFromFeet: 0
mirror: 0
bodyMask: 01000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000
curves: []
events:
- time: 0.64
functionName: OnLuneContact
data:
objectReferenceParameter: {instanceID: 0}
floatParameter: 0
intParameter: 0
messageOptions: 0
transformMask: []
maskType: 3
maskSource: {instanceID: 0}
additiveReferencePoseFrame: 0
- serializedVersion: 16
name: attack_a
takeName: SylvaraRig|attack_a
internalID: -1919402484897520342
firstFrame: 0
lastFrame: 22
wrapMode: 0
orientationOffsetY: 0
level: 0
cycleOffset: 0
loop: 0
hasAdditiveReferencePose: 0
loopTime: 0
loopBlend: 0
loopBlendOrientation: 0
loopBlendPositionY: 0
loopBlendPositionXZ: 0
keepOriginalOrientation: 0
keepOriginalPositionY: 1
keepOriginalPositionXZ: 0
heightFromFeet: 0
mirror: 0
bodyMask: 01000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000
curves: []
events:
- time: 0.44998363
functionName: OnLuneContact
data:
objectReferenceParameter: {instanceID: 0}
floatParameter: 0
intParameter: 0
messageOptions: 0
transformMask: []
maskType: 3
maskSource: {instanceID: 0}
additiveReferencePoseFrame: 0
- serializedVersion: 16
name: attack_b
takeName: SylvaraRig|attack_b
internalID: 3192667631615220872
firstFrame: 0
lastFrame: 22
wrapMode: 0
orientationOffsetY: 0
level: 0
cycleOffset: 0
loop: 0
hasAdditiveReferencePose: 0
loopTime: 0
loopBlend: 0
loopBlendOrientation: 0
loopBlendPositionY: 0
loopBlendPositionXZ: 0
keepOriginalOrientation: 0
keepOriginalPositionY: 1
keepOriginalPositionXZ: 0
heightFromFeet: 0
mirror: 0
bodyMask: 01000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000
curves: []
events:
- time: 0.3610778
functionName: OnLuneContact
data:
objectReferenceParameter: {instanceID: 0}
floatParameter: 0
intParameter: 0
messageOptions: 0
transformMask: []
maskType: 3
maskSource: {instanceID: 0}
additiveReferencePoseFrame: 0
- serializedVersion: 16
name: death
takeName: SylvaraRig|death
internalID: -5948886425661693005
firstFrame: 0
lastFrame: 53
wrapMode: 0
orientationOffsetY: 0
level: 0
cycleOffset: 0
loop: 0
hasAdditiveReferencePose: 0
loopTime: 0
loopBlend: 0
loopBlendOrientation: 0
loopBlendPositionY: 0
loopBlendPositionXZ: 0
keepOriginalOrientation: 0
keepOriginalPositionY: 1
keepOriginalPositionXZ: 0
heightFromFeet: 0
mirror: 0
bodyMask: 01000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000
curves: []
events: []
transformMask: []
maskType: 3
maskSource: {instanceID: 0}
additiveReferencePoseFrame: 0
- serializedVersion: 16
name: hit
takeName: SylvaraRig|hit
internalID: -6666208762527400351
firstFrame: 0
lastFrame: 12
wrapMode: 0
orientationOffsetY: 0
level: 0
cycleOffset: 0
loop: 0
hasAdditiveReferencePose: 0
loopTime: 0
loopBlend: 0
loopBlendOrientation: 0
loopBlendPositionY: 0
loopBlendPositionXZ: 0
keepOriginalOrientation: 0
keepOriginalPositionY: 1
keepOriginalPositionXZ: 0
heightFromFeet: 0
mirror: 0
bodyMask: 01000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000
curves: []
events: []
transformMask: []
maskType: 3
maskSource: {instanceID: 0}
additiveReferencePoseFrame: 0
- serializedVersion: 16
name: idle
takeName: SylvaraRig|idle
internalID: 2006597815458582218
firstFrame: 0
lastFrame: 96
wrapMode: 0
orientationOffsetY: 0
level: 0
cycleOffset: 0
loop: 0
hasAdditiveReferencePose: 0
loopTime: 1
loopBlend: 0
loopBlendOrientation: 0
loopBlendPositionY: 0
loopBlendPositionXZ: 0
keepOriginalOrientation: 0
keepOriginalPositionY: 1
keepOriginalPositionXZ: 0
heightFromFeet: 0
mirror: 0
bodyMask: 01000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000
curves: []
events: []
transformMask: []
maskType: 3
maskSource: {instanceID: 0}
additiveReferencePoseFrame: 0
- serializedVersion: 16
name: leap
takeName: SylvaraRig|leap
internalID: 6552078401007846946
firstFrame: 0
lastFrame: 17
wrapMode: 0
orientationOffsetY: 0
level: 0
cycleOffset: 0
loop: 0
hasAdditiveReferencePose: 0
loopTime: 0
loopBlend: 0
loopBlendOrientation: 0
loopBlendPositionY: 0
loopBlendPositionXZ: 0
keepOriginalOrientation: 0
keepOriginalPositionY: 1
keepOriginalPositionXZ: 0
heightFromFeet: 0
mirror: 0
bodyMask: 01000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000
curves: []
events: []
transformMask: []
maskType: 3
maskSource: {instanceID: 0}
additiveReferencePoseFrame: 0
- serializedVersion: 16
name: ultimate
takeName: SylvaraRig|ultimate
internalID: 2887585251524934922
firstFrame: 0
lastFrame: 34
wrapMode: 0
orientationOffsetY: 0
level: 0
cycleOffset: 0
loop: 0
hasAdditiveReferencePose: 0
loopTime: 0
loopBlend: 0
loopBlendOrientation: 0
loopBlendPositionY: 0
loopBlendPositionXZ: 0
keepOriginalOrientation: 0
keepOriginalPositionY: 1
keepOriginalPositionXZ: 0
heightFromFeet: 0
mirror: 0
bodyMask: 01000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000
curves: []
events:
- time: 0.51923484
functionName: OnLuneContact
data:
objectReferenceParameter: {instanceID: 0}
floatParameter: 0
intParameter: 0
messageOptions: 0
transformMask: []
maskType: 3
maskSource: {instanceID: 0}
additiveReferencePoseFrame: 0
- serializedVersion: 16
name: walk
takeName: SylvaraRig|walk
internalID: -4974581367025399602
firstFrame: 0
lastFrame: 18
wrapMode: 0
orientationOffsetY: 0
level: 0
cycleOffset: 0
loop: 0
hasAdditiveReferencePose: 0
loopTime: 1
loopBlend: 0
loopBlendOrientation: 0
loopBlendPositionY: 0
loopBlendPositionXZ: 0
keepOriginalOrientation: 0
keepOriginalPositionY: 1
keepOriginalPositionXZ: 0
heightFromFeet: 0
mirror: 0
bodyMask: 01000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000
curves: []
events: []
transformMask: []
maskType: 3
maskSource: {instanceID: 0}
additiveReferencePoseFrame: 0
isReadable: 1
meshes:
lODScreenPercentages:
- 0.25
- 0.01
globalScale: 1
meshCompression: 0
addColliders: 0
useSRGBMaterialColor: 1
sortHierarchyByName: 1
importPhysicalCameras: 1
importVisibility: 0
importBlendShapes: 0
importCameras: 0
importLights: 0
nodeNameCollisionStrategy: 1
fileIdsGeneration: 2
swapUVChannels: 0
generateSecondaryUV: 0
useFileUnits: 1
keepQuads: 0
weldVertices: 1
bakeAxisConversion: 1
preserveHierarchy: 0
skinWeightsMode: 0
maxBonesPerVertex: 4
minBoneWeight: 0.001
optimizeBones: 1
generateMeshLods: 0
meshLodGenerationFlags: 0
maximumMeshLod: -1
meshOptimizationFlags: -1
indexFormat: 0
secondaryUVAngleDistortion: 8
secondaryUVAreaDistortion: 15.000001
secondaryUVHardAngle: 88
secondaryUVMarginMethod: 1
secondaryUVMinLightmapResolution: 40
secondaryUVMinObjectScale: 1
secondaryUVPackMargin: 4
useFileScale: 1
strictVertexDataChecks: 0
tangentSpace:
normalSmoothAngle: 60
normalImportMode: 0
tangentImportMode: 3
normalCalculationMode: 4
legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0
blendShapeNormalImportMode: 1
normalSmoothingSource: 0
referencedClips: []
importAnimation: 1
humanDescription:
serializedVersion: 3
human: []
skeleton: []
armTwist: 0.5
foreArmTwist: 0.5
upperLegTwist: 0.5
legTwist: 0.5
armStretch: 0.05
legStretch: 0.05
feetSpacing: 0
globalScale: 1
rootMotionBoneName:
hasTranslationDoF: 0
hasExtraRoot: 0
skeletonHasParents: 1
lastHumanDescriptionAvatarSource: {instanceID: 0}
autoGenerateAvatarMappingIfUnspecified: 1
animationType: 2
humanoidOversampling: 1
avatarSetup: 1
addHumanoidExtraRootOnlyWhenUsingAvatar: 1
importBlendShapeDeformPercent: 1
remapMaterialsIfMaterialImportModeIsNone: 0
additionalBone: 0
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,304 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1102 &-8263460516112938798
AnimatorState:
serializedVersion: 6
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: walk
m_Speed: 1
m_CycleOffset: 0
m_Transitions: []
m_StateMachineBehaviours: []
m_Position: {x: 50, y: 50, z: 0}
m_IKOnFeet: 0
m_WriteDefaultValues: 1
m_Mirror: 0
m_SpeedParameterActive: 0
m_MirrorParameterActive: 0
m_CycleOffsetParameterActive: 0
m_TimeParameterActive: 0
m_Motion: {fileID: -4974581367025399602, guid: 6ec31d870bd7f4b71b9810cb0a14ba9a, type: 3}
m_Tag:
m_SpeedParameter:
m_MirrorParameter:
m_CycleOffsetParameter:
m_TimeParameter:
--- !u!1107 &-7487683440626816043
AnimatorStateMachine:
serializedVersion: 6
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Base Layer
m_ChildStates:
- serializedVersion: 1
m_State: {fileID: -2376582923454785072}
m_Position: {x: 200, y: 0, z: 0}
- serializedVersion: 1
m_State: {fileID: 8373015746321733221}
m_Position: {x: 235, y: 65, z: 0}
- serializedVersion: 1
m_State: {fileID: -4146940425522892775}
m_Position: {x: 270, y: 130, z: 0}
- serializedVersion: 1
m_State: {fileID: 4268394846306323914}
m_Position: {x: 305, y: 195, z: 0}
- serializedVersion: 1
m_State: {fileID: 2992695161437185625}
m_Position: {x: 340, y: 260, z: 0}
- serializedVersion: 1
m_State: {fileID: -638290553263424564}
m_Position: {x: 375, y: 325, z: 0}
- serializedVersion: 1
m_State: {fileID: 6638643318457833971}
m_Position: {x: 410, y: 390, z: 0}
- serializedVersion: 1
m_State: {fileID: -6911695650363282165}
m_Position: {x: 445, y: 455, z: 0}
- serializedVersion: 1
m_State: {fileID: -8263460516112938798}
m_Position: {x: 480, y: 520, z: 0}
m_ChildStateMachines: []
m_AnyStateTransitions: []
m_EntryTransitions: []
m_StateMachineTransitions: {}
m_StateMachineBehaviours: []
m_AnyStatePosition: {x: 50, y: 20, z: 0}
m_EntryPosition: {x: 50, y: 120, z: 0}
m_ExitPosition: {x: 800, y: 120, z: 0}
m_ParentStateMachinePosition: {x: 800, y: 20, z: 0}
m_DefaultState: {fileID: -2376582923454785072}
--- !u!1102 &-6911695650363282165
AnimatorState:
serializedVersion: 6
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: ultimate
m_Speed: 1
m_CycleOffset: 0
m_Transitions: []
m_StateMachineBehaviours: []
m_Position: {x: 50, y: 50, z: 0}
m_IKOnFeet: 0
m_WriteDefaultValues: 1
m_Mirror: 0
m_SpeedParameterActive: 0
m_MirrorParameterActive: 0
m_CycleOffsetParameterActive: 0
m_TimeParameterActive: 0
m_Motion: {fileID: 2887585251524934922, guid: 6ec31d870bd7f4b71b9810cb0a14ba9a, type: 3}
m_Tag:
m_SpeedParameter:
m_MirrorParameter:
m_CycleOffsetParameter:
m_TimeParameter:
--- !u!1102 &-4146940425522892775
AnimatorState:
serializedVersion: 6
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: attack_a
m_Speed: 1
m_CycleOffset: 0
m_Transitions: []
m_StateMachineBehaviours: []
m_Position: {x: 50, y: 50, z: 0}
m_IKOnFeet: 0
m_WriteDefaultValues: 1
m_Mirror: 0
m_SpeedParameterActive: 0
m_MirrorParameterActive: 0
m_CycleOffsetParameterActive: 0
m_TimeParameterActive: 0
m_Motion: {fileID: -1919402484897520342, guid: 6ec31d870bd7f4b71b9810cb0a14ba9a, type: 3}
m_Tag:
m_SpeedParameter:
m_MirrorParameter:
m_CycleOffsetParameter:
m_TimeParameter:
--- !u!1102 &-2376582923454785072
AnimatorState:
serializedVersion: 6
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: idle
m_Speed: 1
m_CycleOffset: 0
m_Transitions: []
m_StateMachineBehaviours: []
m_Position: {x: 50, y: 50, z: 0}
m_IKOnFeet: 0
m_WriteDefaultValues: 1
m_Mirror: 0
m_SpeedParameterActive: 0
m_MirrorParameterActive: 0
m_CycleOffsetParameterActive: 0
m_TimeParameterActive: 0
m_Motion: {fileID: 2006597815458582218, guid: 6ec31d870bd7f4b71b9810cb0a14ba9a, type: 3}
m_Tag:
m_SpeedParameter:
m_MirrorParameter:
m_CycleOffsetParameter:
m_TimeParameter:
--- !u!1102 &-638290553263424564
AnimatorState:
serializedVersion: 6
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: hit
m_Speed: 1
m_CycleOffset: 0
m_Transitions: []
m_StateMachineBehaviours: []
m_Position: {x: 50, y: 50, z: 0}
m_IKOnFeet: 0
m_WriteDefaultValues: 1
m_Mirror: 0
m_SpeedParameterActive: 0
m_MirrorParameterActive: 0
m_CycleOffsetParameterActive: 0
m_TimeParameterActive: 0
m_Motion: {fileID: -6666208762527400351, guid: 6ec31d870bd7f4b71b9810cb0a14ba9a, type: 3}
m_Tag:
m_SpeedParameter:
m_MirrorParameter:
m_CycleOffsetParameter:
m_TimeParameter:
--- !u!91 &9100000
AnimatorController:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: sylvara
serializedVersion: 5
m_AnimatorParameters: []
m_AnimatorLayers:
- serializedVersion: 5
m_Name: Base Layer
m_StateMachine: {fileID: -7487683440626816043}
m_Mask: {fileID: 0}
m_Motions: []
m_Behaviours: []
m_BlendingMode: 0
m_SyncedLayerIndex: -1
m_DefaultWeight: 0
m_IKPass: 0
m_SyncedLayerAffectsTiming: 0
m_Controller: {fileID: 9100000}
--- !u!1102 &2992695161437185625
AnimatorState:
serializedVersion: 6
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: death
m_Speed: 1
m_CycleOffset: 0
m_Transitions: []
m_StateMachineBehaviours: []
m_Position: {x: 50, y: 50, z: 0}
m_IKOnFeet: 0
m_WriteDefaultValues: 1
m_Mirror: 0
m_SpeedParameterActive: 0
m_MirrorParameterActive: 0
m_CycleOffsetParameterActive: 0
m_TimeParameterActive: 0
m_Motion: {fileID: -5948886425661693005, guid: 6ec31d870bd7f4b71b9810cb0a14ba9a, type: 3}
m_Tag:
m_SpeedParameter:
m_MirrorParameter:
m_CycleOffsetParameter:
m_TimeParameter:
--- !u!1102 &4268394846306323914
AnimatorState:
serializedVersion: 6
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: attack_b
m_Speed: 1
m_CycleOffset: 0
m_Transitions: []
m_StateMachineBehaviours: []
m_Position: {x: 50, y: 50, z: 0}
m_IKOnFeet: 0
m_WriteDefaultValues: 1
m_Mirror: 0
m_SpeedParameterActive: 0
m_MirrorParameterActive: 0
m_CycleOffsetParameterActive: 0
m_TimeParameterActive: 0
m_Motion: {fileID: 3192667631615220872, guid: 6ec31d870bd7f4b71b9810cb0a14ba9a, type: 3}
m_Tag:
m_SpeedParameter:
m_MirrorParameter:
m_CycleOffsetParameter:
m_TimeParameter:
--- !u!1102 &6638643318457833971
AnimatorState:
serializedVersion: 6
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: leap
m_Speed: 1
m_CycleOffset: 0
m_Transitions: []
m_StateMachineBehaviours: []
m_Position: {x: 50, y: 50, z: 0}
m_IKOnFeet: 0
m_WriteDefaultValues: 1
m_Mirror: 0
m_SpeedParameterActive: 0
m_MirrorParameterActive: 0
m_CycleOffsetParameterActive: 0
m_TimeParameterActive: 0
m_Motion: {fileID: 6552078401007846946, guid: 6ec31d870bd7f4b71b9810cb0a14ba9a, type: 3}
m_Tag:
m_SpeedParameter:
m_MirrorParameter:
m_CycleOffsetParameter:
m_TimeParameter:
--- !u!1102 &8373015746321733221
AnimatorState:
serializedVersion: 6
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: ability
m_Speed: 1
m_CycleOffset: 0
m_Transitions: []
m_StateMachineBehaviours: []
m_Position: {x: 50, y: 50, z: 0}
m_IKOnFeet: 0
m_WriteDefaultValues: 1
m_Mirror: 0
m_SpeedParameterActive: 0
m_MirrorParameterActive: 0
m_CycleOffsetParameterActive: 0
m_TimeParameterActive: 0
m_Motion: {fileID: -4503705687715001949, guid: 6ec31d870bd7f4b71b9810cb0a14ba9a, type: 3}
m_Tag:
m_SpeedParameter:
m_MirrorParameter:
m_CycleOffsetParameter:
m_TimeParameter:

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a9f7e924f692041b38fc5703d10e1cec
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 9100000
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 MiB

View file

@ -0,0 +1,117 @@
fileFormatVersion: 2
guid: 8f1bc24b849964290904cc174a86981f
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 MiB

View file

@ -0,0 +1,117 @@
fileFormatVersion: 2
guid: c8632afd5853d44d982ae859be8956e1
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 0
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 1
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 MiB

View file

@ -0,0 +1,117 @@
fileFormatVersion: 2
guid: d8311d476a8454de69778369b6523d29
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 0
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 MiB

View file

@ -0,0 +1,117 @@
fileFormatVersion: 2
guid: a6874598666524dfaa83369fe4e3bf2a
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 6 MiB

View file

@ -0,0 +1,117 @@
fileFormatVersion: 2
guid: e6cf36fcdead84dd2a220b270e74b1df
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 MiB

View file

@ -0,0 +1,117 @@
fileFormatVersion: 2
guid: a2ec696a4b29947e7bc1e9500caca183
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 0
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 1
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

View file

@ -0,0 +1,117 @@
fileFormatVersion: 2
guid: 19438d2ac4c6d4ca392685991f987ed5
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 0
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 MiB

View file

@ -0,0 +1,117 @@
fileFormatVersion: 2
guid: 5d8c0f56d849d484db5734f49a273a4b
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

View file

@ -57,7 +57,10 @@ namespace Luneraria.Core
new HeroSpec { Id = "held_quellgeflecht", Name = "Quellgeflecht", Title = "Hüterin der Quelle", Model = "w10", Cost = 260, RoleText = "Unterstützung / Heilung", Provisional = true, Summary = "Heilt Verbündete in 4,5 m und stärkt die Armee im Gefecht.", Base = new UnitDef { MaxHp = 1300.0, Damage = 28.0, AttackType = 2, ArmorType = 2, AttackRange = 4.5, Speed = 2.0, Ability = "w10" } },
new HeroSpec { Id = "held_funkenlanze", Name = "Funkenlanze", Title = "Schützin des Glutpakts", Model = "g05", Cost = 260, RoleText = "Fernkampf / Schaden", Provisional = true, Summary = "Hoher Einzelschaden aus der zweiten Reihe.", Base = new UnitDef { MaxHp = 950.0, Damage = 46.0, AttackType = 1, ArmorType = 0, AttackRange = 6.0, Speed = 2.0, Ability = "g05" } },
// H1 (not in the Godot reference): first hero of the champions concept, docs/luneraria/CHAMPIONS-KONZEPT.md.
new HeroSpec { Id = "held_sylvara", Name = "Sylvara", Title = "Die Mondklinge", Model = "sylvara", Cost = 260, RoleText = "Assassine / Nahkampf", Provisional = false, Summary = "Springt in die zweite Reihe, wirft Sicheln und wirbelt mit dem Mondsicheltanz durch Gruppen.", Base = new UnitDef { MaxHp = 1450.0, Damage = 42.0, AttackType = 0, ArmorType = 0, AttackRange = 1.2, Speed = 2.8, Ability = "sylvara" } }
new HeroSpec { Id = "held_sylvara", Name = "Sylvara", Title = "Die Mondklinge", Model = "sylvara", Cost = 260, RoleText = "Assassine / Nahkampf", Provisional = false, Summary = "Springt in die zweite Reihe, wirft Sicheln und wirbelt mit dem Mondsicheltanz durch Gruppen.",
PassiveText = "Mondsprung: einmal pro Kampf auf den nächsten Fernkämpfer oder Unterstützer in 8 m, der höchstens 2 Begleiter in 3 m hat. Der erste Treffer danach macht 150 % Schaden; Mondschleier schützt 4 s mit 25 % ihrer Lebenspunkte.",
AbilityText = "Sichelwurf: ab 4 s alle 6 s 90 % Schaden an ihrem Ziel und bis zu 2 weiteren Gegnern in 2,5 m.",
UltimateName = "Mondsicheltanz", UltimateText = "Einmal pro Kampf, frühestens nach 2 s: 220 % Schaden an bis zu 5 Gegnern in 5 m, die 2 s um 30 % verlangsamt werden; danach Mondschleier. Wann er ausgelöst wird, legst du in der Planung fest.", Base = new UnitDef { MaxHp = 1450.0, Damage = 42.0, AttackType = 0, ArmorType = 0, AttackRange = 1.2, Speed = 2.8, Ability = "sylvara", AbilityDescription = "Mondsprung auf ungeschützte Fernkämpfer · Sichelwurf alle 6 s · Ultimate Mondsicheltanz nach Planungsregel." } }
);
/// <summary>Heroes of the Godot reference; ContentTests compares exactly these, later heroes follow them.</summary>
@ -91,6 +94,16 @@ namespace Luneraria.Core
} }
};
/// <summary>
/// H1: cosmetic skins per hero (docs/luneraria/CHAMPIONS-KONZEPT.md, skin system). The
/// standard look is "" and not listed. A skin swaps materials (AI_Sylvara -> AI_Sylvara_Blutmond);
/// silhouette, weapon type and team accent stay, the rules never read it.
/// </summary>
public static readonly Dictionary<string, TalentOption[]> HeroSkins = new Dictionary<string, TalentOption[]>
{
{ "held_sylvara", new[] { new TalentOption("blutmond", "Blutmond", "Variante: rote Klingen und Runen, dunkelrotes Tuch, nachgedunkeltes Silber.") } },
};
/// <summary>
/// H1: trigger rules of a hero's ultimate, chosen in planning; the first is the default.
/// Heroes without an entry have no ultimate. The rule decides when the single charge per

View file

@ -40,6 +40,8 @@ namespace Luneraria.Core
public double AttackSpeedBonus;
/// <summary>Heroes with an ultimate (H1): the trigger rule chosen in planning, "" = none.</summary>
public string UltimateRule = "";
/// <summary>H1: cosmetic skin of a hero ("" = standard); the view swaps materials, the rules never read it.</summary>
public string Skin = "";
// Attack champions.
public string ChampionId = "";
public string Priority = "";
@ -67,6 +69,11 @@ namespace Luneraria.Core
public string RoleText = "";
public bool Provisional;
public string Summary = "";
/// <summary>H1 heroes describe their own kit; reference heroes show the ability of their troop model.</summary>
public string PassiveText = "";
public string AbilityText = "";
public string UltimateName = "";
public string UltimateText = "";
/// <summary>Level-1 values without items and talents.</summary>
public UnitDef Base = new UnitDef();
}

View file

@ -56,6 +56,25 @@ namespace Luneraria.Core
public static bool HasUltimate(string heroId) { return UltimateRulesOf(heroId).Length > 0; }
/// <summary>H1: cosmetic skins of a hero besides the standard look.</summary>
public static TalentOption[] SkinsOf(string heroId)
{
TalentOption[] skins;
return ContentData.HeroSkins.TryGetValue(heroId ?? "", out skins) ? skins : new TalentOption[0];
}
public static bool ValidSkin(string heroId, string skin)
{
if (string.IsNullOrEmpty(skin))
return true;
foreach (TalentOption option in SkinsOf(heroId))
{
if (option.Id == skin)
return true;
}
return false;
}
/// <summary>The rule a hero's ultimate follows: the chosen one if valid, else the default, "" without ultimate.</summary>
public static string UltimateRuleFor(HeroState hero)
{
@ -114,6 +133,7 @@ namespace Luneraria.Core
if (hero.Talents.Contains("glutsalve") || hero.Talents.Contains("neumond"))
attackSpeed += 0.20;
definition.UltimateRule = UltimateRuleFor(hero);
definition.Skin = ValidSkin(hero.HeroId, hero.Skin) ? hero.Skin ?? "" : "";
definition.Talents = new List<string>(hero.Talents);
definition.DamageBonus = damageBonus;
definition.ReductionBonus = reduction;

View file

@ -966,6 +966,7 @@ namespace Luneraria.Core
/// </summary>
void SylvaraStep(LuneUnit unit, Dictionary<string, bool> gates)
{
bool leaping = false;
if (!unit.LeapUsed)
{
foreach (LuneUnit other in NearbyMobile(unit, SylvaraLeapRange, 1000))
@ -977,11 +978,13 @@ namespace Luneraria.Core
unit.LeapTarget = other;
unit.LeapStrike = true;
unit.LeapSerial += 1;
leaping = true;
break;
}
}
}
if (unit.UltimateUsed || string.IsNullOrEmpty(unit.Def.UltimateRule) || unit.CombatTime + 0.000001 < LuneContent.UltimateDelay)
// The dance waits for the landing: in the leap step she still stands at her old place.
if (leaping || unit.UltimateUsed || string.IsNullOrEmpty(unit.Def.UltimateRule) || unit.CombatTime + 0.000001 < LuneContent.UltimateDelay)
return;
bool release = false;
switch (unit.Def.UltimateRule)

View file

@ -306,6 +306,16 @@ namespace Luneraria.Core
}
return Result(false, "Unbekannter Ultimate-Auslöser.");
}
case "hero_skin":
{
if (hero == null)
return Result(false, "Skins benötigen einen Helden.");
string skin = command.TypeId ?? "";
if (!LuneContent.ValidSkin(hero.HeroId, skin))
return Result(false, "Unbekannter Skin.");
hero.Skin = skin;
return Result(true, skin.Length == 0 ? "Standard-Aussehen gewählt." : "Skin gewählt.");
}
case "champion_book":
{
string championId = command.ChampionId ?? "";
@ -476,6 +486,8 @@ namespace Luneraria.Core
return false;
if (!string.IsNullOrEmpty(hero.Ultimate) && LuneContent.UltimateRuleFor(hero) != hero.Ultimate)
return false;
if (!LuneContent.ValidSkin(hero.HeroId, hero.Skin))
return false;
}
return draft.NewBookings.Count <= LuneContent.MaxBookings;
}

View file

@ -36,6 +36,8 @@ namespace Luneraria.Core
public List<string> FreshItems = new List<string>();
/// <summary>Trigger rule of the ultimate (H1), "" = the hero's default rule.</summary>
public string Ultimate = "";
/// <summary>H1: cosmetic skin ("" = standard), chosen freely in planning, visible to everyone.</summary>
public string Skin = "";
public HeroState Clone()
{
@ -236,5 +238,7 @@ namespace Luneraria.Core
public static Command BossLaneChoice(string lane) { return new Command { Type = "boss_lane", Lane = lane }; }
/// <summary>H1: trigger rule of the hero's ultimate; the rule id travels in TypeId.</summary>
public static Command UltimateRule(string rule) { return new Command { Type = "ultimate_rule", TypeId = rule }; }
/// <summary>H1: cosmetic skin of the hero ("" = standard); the skin id travels in TypeId.</summary>
public static Command HeroSkin(string skin) { return new Command { Type = "hero_skin", TypeId = skin }; }
}
}

View file

@ -213,6 +213,34 @@ namespace Luneraria.EditorTools
Directory.CreateDirectory(Folder + "/Units");
foreach (KeyValuePair<string, Material> pair in imported)
Add(set, pair.Key, Create(Folder + "/Units/" + pair.Key + ".mat", UnitSpec(pair.Key, pair.Value)), null, null);
SkinMaterials(set, imported);
}
/// <summary>
/// H1 skins (variant stage): tools/meshy/skin_variant.py writes a recoloured albedo
/// ai-<figure>_<skin>-albedo-2k.png beside the maps of a Meshy figure. Each becomes a
/// Surface material AI_<Figure>_<Skin> with the standard normal and ORM maps;
/// LuneMaterialSet.Dress takes it for heroes that carry the skin.
/// </summary>
static void SkinMaterials(LuneMaterialSet set, SortedDictionary<string, Material> imported)
{
foreach (KeyValuePair<string, Material> pair in imported)
{
if (UnitFamily(pair.Key) != "authored")
continue;
string stem = Textures + "/ai-" + pair.Key.Substring(3).ToLowerInvariant();
foreach (string path in Directory.GetFiles(Textures, Path.GetFileName(stem) + "_*-albedo-2k.png").OrderBy(p => p, StringComparer.Ordinal))
{
string file = Path.GetFileName(path);
string skin = file.Substring(Path.GetFileName(stem).Length + 1, file.Length - Path.GetFileName(stem).Length - 1 - "-albedo-2k.png".Length);
if (skin.Length == 0 || skin.Contains("_"))
continue;
string name = LuneMaterialSet.SkinKey(pair.Key, skin);
Spec spec = UnitSpec(pair.Key, pair.Value);
spec.UvAlbedo = Map(Textures + "/" + file, TextureImporterType.Default, true);
Add(set, name, Create(Folder + "/Units/" + name + ".mat", spec), null, null);
}
}
}
/// <summary>Plain Surface material of a figure: imported colour, roughness and emission plus the family's set.</summary>

View file

@ -47,6 +47,7 @@ namespace Luneraria.EditorTools
library.BoltLight[team] = LuneMaterialFactory.TeamLight[team];
}
library.HeroRing = Marker("Ring_Hero", LuneMaterialFactory.Hex("f2c96b"), 2.2f, false);
library.MoonBurst = Marker("Ring_MoonBurst", LuneMaterialFactory.Hex("8fb8ff"), 4f, false);
for (int team = 0; team < 2; team++)
{
library.OwnerRing[team] = Marker("Ring_Owner_" + team, LuneMaterialFactory.TeamColor[team], 3f, false);

View file

@ -217,6 +217,14 @@ MonoBehaviour:
Neutral: {fileID: 2100000, guid: 93a8cf8007ee9440bb5da876affb71ff, type: 2}
Blau: {fileID: 0}
Rot: {fileID: 0}
- Key: AI_Sylvara
Neutral: {fileID: 2100000, guid: 00ddb73ac97f84f3aa8a67f370518a03, type: 2}
Blau: {fileID: 0}
Rot: {fileID: 0}
- Key: AI_SylvaraSichel
Neutral: {fileID: 2100000, guid: 865f4661bd87d4a2898d8136100264bf, type: 2}
Blau: {fileID: 0}
Rot: {fileID: 0}
- Key: BB_Basalt
Neutral: {fileID: 2100000, guid: 37c64b9b93d784d8ba407e7c9682aae4, type: 2}
Blau: {fileID: 0}
@ -729,3 +737,11 @@ MonoBehaviour:
Neutral: {fileID: 2100000, guid: 09c239a4cf52e4af4969869c24b078ff, type: 2}
Blau: {fileID: 0}
Rot: {fileID: 0}
- Key: AI_Sylvara_Blutmond
Neutral: {fileID: 2100000, guid: aa1c3bf7df6bd46ddbe3d0c8051d5b82, type: 2}
Blau: {fileID: 0}
Rot: {fileID: 0}
- Key: AI_SylvaraSichel_Blutmond
Neutral: {fileID: 2100000, guid: fda7007d8c5bb46db9bf32c4940caab8, type: 2}
Blau: {fileID: 0}
Rot: {fileID: 0}

View file

@ -0,0 +1,33 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Ring_MoonBurst
m_Shader: {fileID: 4800000, guid: 5674755340f3b446aad7884cd0870a4f, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 1
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs: []
m_Ints: []
m_Floats:
- _Cull: 0
- _ZTest: 4
m_Colors:
- _Color: {r: 1.0987095, g: 1.9172809, b: 4, a: 1}
m_BuildTextureStacks: []
m_AllowLocking: 1

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c79261fd1aa5e42479782d3bac53f7ba
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,68 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: AI_Sylvara
m_Shader: {fileID: 4800000, guid: 9809bd5750e264586bd30e14a6f1bd4e, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_LightmapFlags: 0
m_EnableInstancingVariants: 1
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _AlbedoMap:
m_Texture: {fileID: 2800000, guid: 8f1bc24b849964290904cc174a86981f, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _NormalMap:
m_Texture: {fileID: 2800000, guid: c8632afd5853d44d982ae859be8956e1, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OrmMap:
m_Texture: {fileID: 2800000, guid: d8311d476a8454de69778369b6523d29, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _StoneMap:
m_Texture: {fileID: 2800000, guid: 2e11a30a0df8143ab84722ec0a116b6d, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _Cull: 2
- _Energy: 1
- _Flicker: 0
- _Glow: 1.25
- _Metallic: 1
- _Mode: 0
- _NormalStrength: 1
- _ObjectSpace: 0
- _Quality: 1
- _Relief: 0.016
- _Rim: 0.35
- _Roughness: 1
- _Seed: 0
- _ShadowNormalScale: 0
- _StoneScale: 1
- _UvMaps: 1
- _VertexColor: 0
m_Colors:
- _AlbedoMean: {r: 1, g: 1, b: 1, a: 1}
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _OrmMean: {r: 1, g: 1, b: 1, a: 1}
- _RimColor: {r: 0.8, g: 0.86, b: 1, a: 1}
m_BuildTextureStacks: []
m_AllowLocking: 1

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 00ddb73ac97f84f3aa8a67f370518a03
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,68 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: AI_SylvaraSichel
m_Shader: {fileID: 4800000, guid: 9809bd5750e264586bd30e14a6f1bd4e, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_LightmapFlags: 0
m_EnableInstancingVariants: 1
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _AlbedoMap:
m_Texture: {fileID: 2800000, guid: e6cf36fcdead84dd2a220b270e74b1df, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _NormalMap:
m_Texture: {fileID: 2800000, guid: a2ec696a4b29947e7bc1e9500caca183, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OrmMap:
m_Texture: {fileID: 2800000, guid: 19438d2ac4c6d4ca392685991f987ed5, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _StoneMap:
m_Texture: {fileID: 2800000, guid: 2e11a30a0df8143ab84722ec0a116b6d, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _Cull: 2
- _Energy: 1
- _Flicker: 0
- _Glow: 1.25
- _Metallic: 1
- _Mode: 0
- _NormalStrength: 1
- _ObjectSpace: 0
- _Quality: 1
- _Relief: 0.016
- _Rim: 0.35
- _Roughness: 1
- _Seed: 0
- _ShadowNormalScale: 0
- _StoneScale: 1
- _UvMaps: 1
- _VertexColor: 0
m_Colors:
- _AlbedoMean: {r: 1, g: 1, b: 1, a: 1}
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _OrmMean: {r: 1, g: 1, b: 1, a: 1}
- _RimColor: {r: 0.8, g: 0.86, b: 1, a: 1}
m_BuildTextureStacks: []
m_AllowLocking: 1

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 865f4661bd87d4a2898d8136100264bf
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,68 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: AI_SylvaraSichel_Blutmond
m_Shader: {fileID: 4800000, guid: 9809bd5750e264586bd30e14a6f1bd4e, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_LightmapFlags: 0
m_EnableInstancingVariants: 1
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _AlbedoMap:
m_Texture: {fileID: 2800000, guid: 5d8c0f56d849d484db5734f49a273a4b, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _NormalMap:
m_Texture: {fileID: 2800000, guid: a2ec696a4b29947e7bc1e9500caca183, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OrmMap:
m_Texture: {fileID: 2800000, guid: 19438d2ac4c6d4ca392685991f987ed5, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _StoneMap:
m_Texture: {fileID: 2800000, guid: 2e11a30a0df8143ab84722ec0a116b6d, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _Cull: 2
- _Energy: 1
- _Flicker: 0
- _Glow: 1.25
- _Metallic: 1
- _Mode: 0
- _NormalStrength: 1
- _ObjectSpace: 0
- _Quality: 1
- _Relief: 0.016
- _Rim: 0.35
- _Roughness: 1
- _Seed: 0
- _ShadowNormalScale: 0
- _StoneScale: 1
- _UvMaps: 1
- _VertexColor: 0
m_Colors:
- _AlbedoMean: {r: 1, g: 1, b: 1, a: 1}
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _OrmMean: {r: 1, g: 1, b: 1, a: 1}
- _RimColor: {r: 0.8, g: 0.86, b: 1, a: 1}
m_BuildTextureStacks: []
m_AllowLocking: 1

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: fda7007d8c5bb46db9bf32c4940caab8
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,68 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: AI_Sylvara_Blutmond
m_Shader: {fileID: 4800000, guid: 9809bd5750e264586bd30e14a6f1bd4e, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_LightmapFlags: 0
m_EnableInstancingVariants: 1
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _AlbedoMap:
m_Texture: {fileID: 2800000, guid: a6874598666524dfaa83369fe4e3bf2a, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _NormalMap:
m_Texture: {fileID: 2800000, guid: c8632afd5853d44d982ae859be8956e1, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OrmMap:
m_Texture: {fileID: 2800000, guid: d8311d476a8454de69778369b6523d29, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _StoneMap:
m_Texture: {fileID: 2800000, guid: 2e11a30a0df8143ab84722ec0a116b6d, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _Cull: 2
- _Energy: 1
- _Flicker: 0
- _Glow: 1.25
- _Metallic: 1
- _Mode: 0
- _NormalStrength: 1
- _ObjectSpace: 0
- _Quality: 1
- _Relief: 0.016
- _Rim: 0.35
- _Roughness: 1
- _Seed: 0
- _ShadowNormalScale: 0
- _StoneScale: 1
- _UvMaps: 1
- _VertexColor: 0
m_Colors:
- _AlbedoMean: {r: 1, g: 1, b: 1, a: 1}
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _OrmMean: {r: 1, g: 1, b: 1, a: 1}
- _RimColor: {r: 0.8, g: 0.86, b: 1, a: 1}
m_BuildTextureStacks: []
m_AllowLocking: 1

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: aa1c3bf7df6bd46ddbe3d0c8051d5b82
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

View file

@ -325,6 +325,7 @@ namespace Luneraria.Net
Str(text, hero.Talents != null ? string.Join("\x1d", hero.Talents) : "");
Str(text, hero.FreshItems != null ? string.Join("\x1d", hero.FreshItems) : "");
Str(text, hero.Ultimate ?? "");
Str(text, hero.Skin ?? "");
}
static void WriteUnit(StringBuilder text, NetUnitRecord unit)
@ -376,6 +377,7 @@ namespace Luneraria.Net
Str(text, def.Tier ?? "");
Str(text, def.Talents != null ? string.Join("\x1d", def.Talents) : "");
Str(text, def.UltimateRule ?? "");
Str(text, def.Skin ?? "");
}
static void Str(StringBuilder text, string value)
@ -759,6 +761,7 @@ namespace Luneraria.Net
AddSplit(hero.Talents, Text());
AddSplit(hero.FreshItems, Text());
hero.Ultimate = Text() ?? "";
hero.Skin = Text() ?? "";
return hero;
}
@ -828,6 +831,7 @@ namespace Luneraria.Net
};
AddSplit(unit.Def.Talents, Text());
unit.Def.UltimateRule = Text() ?? "";
unit.Def.Skin = Text() ?? "";
return unit;
}

File diff suppressed because it is too large Load diff

View file

@ -214,6 +214,9 @@ MonoBehaviour:
- Id: schlundkrone
Prefab: {fileID: 919132149155446097, guid: b2dd57798499c4b7b8698ee56e676c45, type: 3}
Controller: {fileID: 9100000, guid: 55d11e29be0134459bf261f2dad38f33, type: 2}
- Id: sylvara
Prefab: {fileID: 919132149155446097, guid: 6ec31d870bd7f4b71b9810cb0a14ba9a, type: 3}
Controller: {fileID: 9100000, guid: a9f7e924f692041b38fc5703d10e1cec, type: 2}
- Id: w01
Prefab: {fileID: 919132149155446097, guid: e5c065fe1a7de49d1896b96fa614df73, type: 3}
Controller: {fileID: 0}
@ -260,6 +263,7 @@ MonoBehaviour:
- {fileID: 2100000, guid: 42de21345916440af8d534f7a015a490, type: 2}
- {fileID: 2100000, guid: 77d940cdf3d6043cb93c647607c3e35e, type: 2}
HeroRing: {fileID: 2100000, guid: 862d58435f9824d969aecf8551257a64, type: 2}
MoonBurst: {fileID: 2100000, guid: c79261fd1aa5e42479782d3bac53f7ba, type: 2}
BarBack: {fileID: 2100000, guid: 8efe289a463614fee8dcb19e789f2bf8, type: 2}
BarFill:
- {fileID: 2100000, guid: 778bc4f74208340e38dc099b897f3db3, type: 2}

View file

@ -21,6 +21,29 @@ namespace Luneraria.Core.Tests
TestUltimate();
TestTalents();
TestBots();
TestSkins();
}
void TestSkins()
{
LuneMatch state = NewMatch(33);
state.Players[2].Draft.Gold += 1000;
Check(!state.Submit(2, Command.HeroSkin("blutmond")).Ok, "skin needs a hero");
state.Submit(2, Command.HeroBuy("held_sylvara"));
int gold = state.GoldOf(2);
Check(!state.Submit(2, Command.HeroSkin("sonnenwende")).Ok, "unknown skin rejected");
Check(state.Submit(2, Command.HeroSkin("blutmond")).Ok && state.GoldOf(2) == gold, "skin chosen for free in planning");
state.BeginCombat();
LuneUnit unit = state.Combat.Units.First(u => u.Kind == "hero" && u.OwnerSlot == 2);
Check(unit.Def.Skin == "blutmond", "the combat unit carries the skin for the view");
state.FinishCombat();
Check(state.Submit(2, Command.HeroSkin("")).Ok && state.Players[2].Draft.Hero.Skin == "", "back to the standard look");
// Cosmetic only: the same match with and without skin is identical.
Check(PlayWithSylvara(12, out LuneMatch _, "blutmond") == PlayWithSylvara(12, out LuneMatch _), "a skin never changes the match");
LuneMatch other = NewMatch(34);
other.Players[0].Draft.Gold += 1000;
other.Submit(0, Command.HeroBuy("held_funkenlanze"));
Check(!other.Submit(0, Command.HeroSkin("blutmond")).Ok, "skins belong to their hero");
}
static LuneMatch NewMatch(int seed = 31)
@ -211,7 +234,7 @@ namespace Luneraria.Core.Tests
Note("sylvara-bot match seed 12: " + first.Split('|')[0]);
}
static string PlayWithSylvara(int seed, out LuneMatch match)
static string PlayWithSylvara(int seed, out LuneMatch match, string skin = "")
{
match = new LuneMatch();
match.Setup(new MatchOptions { Seed = seed, HumanSlot = -1, Profiles = new List<string> { "assassine", "druck", "fernkampf", "ausgewogen", "druck", "fernkampf" } });
@ -220,6 +243,8 @@ namespace Luneraria.Core.Tests
{
for (int slot = 0; slot < 6; slot++)
LuneBot.Plan(match, slot);
if (skin.Length > 0 && match.Players[0].Draft.Hero != null)
match.Submit(0, Command.HeroSkin(skin));
match.BeginCombat();
int leaps = 0;
int ultimates = 0;

View file

@ -0,0 +1,180 @@
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>
/// H1: Sylvara in the real scene. SylvaraHud checks the HUD (four heroes to recruit, the tab
/// "Ultimate & Skin" with four rule cards and two skin cards, the command slot of the hero
/// card, commands from the cards) and that her figure, clips and skin material reach the
/// field. SylvaraBilder is the capture tool for the H1 evidence (1920×1080): recruiting,
/// the ultimate tab, the planning formation, the leap, the Mondsicheltanz and the Blutmond
/// skin; -testFilter "Luneraria.UI.Tests.H1HeroViewsTests.SylvaraBilder", LUNE_EVIDENCE
/// names the folder below docs/port/screenshots (default h1/spiel).
/// </summary>
public sealed class H1HeroViewsTests
{
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 LuneUnit Hero(HudSession s)
{
return s.Match.Combat?.Units.FirstOrDefault(u => u.Kind == "hero" && u.OwnerSlot == HudSession.Human);
}
static LuneUnitView ViewOf(LuneUnit unit)
{
return UnityEngine.Object.FindObjectsByType<LuneUnitView>(FindObjectsSortMode.None).FirstOrDefault(v => v.Unit == unit);
}
/// <summary>Steps the combat in single simulation steps until the condition holds (or the combat ends).</summary>
static IEnumerator Until(HudSession s, Func<bool> done, double limit = 60.0)
{
double time = 0.0;
while (!done() && time < limit && s.Runner.Current == LuneMatchRunner.Stage.Combat)
{
s.Runner.Advance(.05);
time += .05;
if ((int)(time / .05) % 10 == 0)
yield return null;
}
yield return HudSession.Frames(2);
s.Sync();
}
[UnityTest, Timeout(600000)]
public IEnumerator SylvaraHud()
{
var s = new HudSession();
yield return s.Open(1920, 1080, seed: 4, startRound: 6, extraGold: 1500);
s.Hud.OpenHero();
yield return HudSession.Frames(2);
s.Sync();
Assert.AreEqual(4, s.Hud.HeroDetail.RecruitButtons.Count, "four heroes to recruit");
Assert.IsTrue(s.Hud.HeroDetail.RecruitButtons.ContainsKey("held_sylvara"), "Sylvara can be recruited");
s.Click(s.Hud.HeroDetail.RecruitButtons["held_sylvara"]);
yield return HudSession.Frames(2);
s.Sync();
Assert.AreEqual("held_sylvara", s.Me.Draft.Hero?.HeroId, "the recruit button buys Sylvara");
s.Hud.OpenHero(LuneHeroDetail.TabUltimate);
yield return HudSession.Frames(2);
s.Sync();
Assert.AreEqual(4, s.Hud.HeroDetail.RuleCards.Count, "four trigger rules");
Assert.AreEqual(2, s.Hud.HeroDetail.SkinCards.Count, "standard look and Blutmond");
Assert.IsTrue(s.Hud.HeroDetail.RuleCards["gruppe"].On, "default rule Gruppe is marked");
s.Click(s.Hud.HeroDetail.RuleCards["zweite_reihe"]);
yield return HudSession.Frames(2);
s.Sync();
Assert.AreEqual("zweite_reihe", s.Me.Draft.Hero.Ultimate, "a rule card sets the rule");
s.Click(s.Hud.HeroDetail.SkinCards["blutmond"]);
yield return HudSession.Frames(2);
s.Sync();
Assert.AreEqual("blutmond", s.Me.Draft.Hero.Skin, "a skin card sets the skin");
Assert.IsTrue(HudSession.Visible(s.Hud.HeroCard.CommandSlot), "the hero card shows the ultimate");
StringAssert.Contains("ZWEITE REIHE", s.Hud.HeroCard.CommandSlot.Text, "the command slot names the rule");
s.Hud.CloseModal();
s.Game.Key(KeyCode.Space);
yield return HudSession.Frames(2);
LuneUnit hero = Hero(s);
Assert.IsNotNull(hero, "Sylvara fights");
Assert.AreEqual("blutmond", hero.Def.Skin);
yield return HudSession.Frames(3);
LuneUnitView view = ViewOf(hero);
Assert.IsNotNull(view, "Sylvara has a view");
Animator animator = view.GetComponentInChildren<Animator>();
Assert.IsNotNull(animator, "skinned figure");
Assert.IsTrue(animator.HasState(0, Animator.StringToHash("leap")) && animator.HasState(0, Animator.StringToHash("ultimate")), "leap and ultimate clips");
string[] materials = view.GetComponentsInChildren<Renderer>().SelectMany(r => r.sharedMaterials).Where(m => m != null).Select(m => m.name).Distinct().ToArray();
Assert.Contains("AI_Sylvara_Blutmond", materials, "the Blutmond material is dressed: " + string.Join(", ", materials));
Assert.Contains("AI_SylvaraSichel_Blutmond", materials, "both sickles in Blutmond");
yield return Until(s, () => hero.UltimateSerial > 0 || !hero.Alive);
Assert.IsTrue(hero.UltimateSerial > 0 || !hero.Alive, "the ultimate fires (or Sylvara fell first)");
if (hero.UltimateSerial > 0)
StringAssert.Contains("GENUTZT", s.Hud.HeroCard.CommandSlot.Text, "the card reports the fired ultimate");
s.Close();
}
[UnityTest, Timeout(900000), Explicit("Bildwerkzeug: nur gezielt per -testFilter")]
public IEnumerator SylvaraBilder()
{
string evidence = Environment.GetEnvironmentVariable("LUNE_EVIDENCE");
string folder = "docs/port/screenshots/" + (string.IsNullOrEmpty(evidence) ? "h1/spiel" : evidence) + "/";
var s = new HudSession();
yield return s.Open(1920, 1080, seed: 4, startRound: 6, extraGold: 1500);
yield return s.Starter();
s.Leave();
s.Hud.OpenHero();
yield return new WaitForSecondsRealtime(.6f);
yield return s.Shot(folder + "01-heldenwahl.png");
Send(s, Command.HeroBuy("held_sylvara"));
s.Hud.OpenHero(LuneHeroDetail.TabValues);
yield return new WaitForSecondsRealtime(.6f);
yield return s.Shot(folder + "02-heldenfenster.png");
s.Hud.OpenHero(LuneHeroDetail.TabUltimate);
yield return new WaitForSecondsRealtime(.8f);
yield return s.Shot(folder + "03-ultimate-und-skin.png");
s.Hud.CloseModal();
yield return new WaitForSecondsRealtime(.3f);
LuneUnit waiting = s.View.Preview?.Units.FirstOrDefault(u => u.Kind == "hero" && u.OwnerSlot == HudSession.Human);
Assert.IsNotNull(waiting, "Sylvara in the planning preview");
s.Rig.LookAt(waiting.Position, 9f, true);
yield return new WaitForSecondsRealtime(.6f);
yield return s.Shot(folder + "04-aufstellung.png");
s.Game.Key(KeyCode.Space);
yield return HudSession.Frames(2);
LuneUnit hero = Hero(s);
yield return Until(s, () => hero.LeapSerial > 0 || !hero.Alive);
s.Driver.Paused = true;
s.Rig.LookAt(hero.Position, 11f, true);
yield return new WaitForSecondsRealtime(.3f);
yield return s.Shot(folder + "05-mondsprung.png");
s.Driver.Paused = false;
yield return Until(s, () => hero.UltimateSerial > 0 || !hero.Alive);
s.Driver.Paused = true;
s.Rig.LookAt(hero.Position, 11f, true);
yield return new WaitForSecondsRealtime(.2f);
yield return s.Shot(folder + "06-mondsicheltanz.png");
yield return new WaitForSecondsRealtime(.6f);
yield return s.Shot(folder + "07-mondsicheltanz-wirbel.png");
s.Rig.LookAt(hero.Position, 20f, true);
yield return new WaitForSecondsRealtime(.4f);
yield return s.Shot(folder + "08-kampf-lane.png");
s.Driver.Paused = false;
yield return s.FinishCombat();
// Space is blocked for a moment after a combat (no accidental skip of the planning).
float waited = 0f;
while (s.Hud.ReadyBlocked() && waited < 5f)
{
waited += Time.unscaledDeltaTime;
yield return null;
}
Send(s, Command.HeroSkin("blutmond"));
s.Hud.OpenHero(LuneHeroDetail.TabUltimate);
yield return new WaitForSecondsRealtime(.8f);
yield return s.Shot(folder + "09-skin-blutmond-fenster.png");
s.Hud.CloseModal();
int round = s.Match.RoundNumber;
s.Game.Key(KeyCode.Space);
yield return HudSession.Frames(2);
Assert.AreEqual(LuneMatchRunner.Stage.Combat, s.Runner.Current, "combat of round " + round);
hero = Hero(s);
yield return s.Fight(9.0);
s.Driver.Paused = true;
s.Rig.LookAt(hero.Position, 9f, true);
yield return new WaitForSecondsRealtime(.5f);
yield return s.Shot(folder + "10-skin-blutmond-kampf.png");
s.Close();
}
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 98738af034f8454a9c352a05a8427bb6

View file

@ -188,7 +188,8 @@ namespace Luneraria.UI.Tests
yield return s.Open();
yield return s.Tap(() => s.Hud.HeroCard);
Check(s.Hud.ModalOpen, "hero card opens the hero window");
Check(s.Hud.HeroDetail.RecruitButtons.Count == 3, "three heroes to recruit");
// H1: every hero of the catalogue (G3: three; Sylvara is the fourth).
Check(s.Hud.HeroDetail.RecruitButtons.Count == LuneContent.Heroes.Count && LuneContent.Heroes.Count == 4, "all four heroes to recruit (H1)");
int heroCost = LuneContent.Heroes.Values[0].Cost;
bool unaffordable = s.Match.GoldOf(HudSession.Human) < heroCost;
Check(!unaffordable || s.Hud.HeroDetail.RecruitButtons.Values.All(b => b.Disabled), "recruiting blocked without gold");

View file

@ -11,8 +11,8 @@ namespace Luneraria.UI
/// The hero in the bottom bar (Godot LuneHeroCard): portrait, name, level, experience
/// progress, HP, role, the three item slots and the talent state. A click opens the hero window
/// (details, items, talents) or, without a hero, the recruiting window. No MOBA action bar:
/// heroes act alone. The command slot is reserved for the ultimates of the planned heroes
/// (PlannedHeroes, trigger Command); it stays hidden while no such hero is playable.
/// heroes act alone. H1: the command slot shows the ultimate of a hero that has one (its
/// planned trigger rule, in combat whether it fired) and opens the hero window on it.
/// </summary>
public sealed class LuneHeroCard : LuneButton
{
@ -39,6 +39,7 @@ namespace Luneraria.UI
/// <summary>Reserved: the ultimate of a planned hero (released through the command menu in combat).</summary>
public readonly LuneButton CommandSlot;
LuneHudModel _model;
LuneUnit _live;
HeroState _hero;
UnitDef _definition;
string _signature = "";
@ -132,6 +133,7 @@ namespace Luneraria.UI
public void Apply(HeroState hero, LuneHudModel model, LuneUnit live)
{
_model = model;
_live = live;
bool hasHero = hero != null;
if (live != null && hasHero)
{
@ -140,8 +142,8 @@ namespace Luneraria.UI
_hpBar.Fill = LuneHpBar.HealthColor(_hpBar.Fraction, LuneUiTheme.Good);
_portrait.Crossed = !live.Alive;
}
string signature = (hasHero ? hero.HeroId + ":" + hero.Xp + ":" + hero.Lane + ":" + string.Join(",", hero.Items) + ":" + string.Join(",", hero.Talents) : "-") + "|"
+ (live != null) + "|" + model.OwnGold + "|" + model.Planning;
string signature = (hasHero ? hero.HeroId + ":" + hero.Xp + ":" + hero.Lane + ":" + string.Join(",", hero.Items) + ":" + string.Join(",", hero.Talents) + ":" + hero.Ultimate + ":" + hero.Skin : "-") + "|"
+ (live != null) + "|" + (live != null ? live.UltimateSerial : 0) + "|" + model.OwnGold + "|" + model.Planning;
if (signature == _signature)
return;
_signature = signature;
@ -172,7 +174,7 @@ namespace Luneraria.UI
_definition = model.HeroDefinition(hero);
_portrait.Dimmed = false;
_portrait.Crossed = live != null && !live.Alive;
_portrait.ShowModel(heroSpec.Model);
_portrait.ShowModel(string.IsNullOrEmpty(hero.Skin) ? heroSpec.Model : heroSpec.Model + "#" + hero.Skin);
_name.text = heroSpec.Name;
int level = LuneContent.LevelFor(hero.Xp);
_level.text = "STUFE " + level;
@ -209,12 +211,18 @@ namespace Luneraria.UI
{
LuneUi.Show(_talent, false);
}
// The three reference heroes have no command ultimate; the planned heroes will.
PlannedHero planned = PlannedHeroes.All.FirstOrDefault(p => p.Active && p.Id == HeroId);
bool command = planned != null && planned.Ultimate.Trigger == PowerTrigger.Command;
// H1: heroes with an ultimate show it with its planned rule; the reference heroes have none.
bool command = LuneContent.HasUltimate(HeroId);
LuneUi.Show(CommandSlot, command);
if (command)
CommandSlot.Text = planned.Ultimate.Name.ToUpperInvariant();
{
string rule = LuneContent.UltimateRuleFor(hero);
string ruleName = LuneContent.UltimateRulesOf(HeroId).First(r => r.Id == rule).Name;
bool fired = _live != null && _live.UltimateSerial > 0;
// Short: the slot shares the row with the item slots and the talent badge.
CommandSlot.Text = fired ? "ULT GENUTZT" : "ULT · " + ruleName.ToUpperInvariant();
CommandSlot.On = fired;
}
}
LuneTip Tip()
@ -223,7 +231,7 @@ namespace Luneraria.UI
return new LuneTip
{
Title = "Held anwerben", Glyph = "crown", GlyphColor = LuneUiTheme.Hero,
Text = "Drei Helden stehen zur Wahl; jeder Spieler führt einen. Helden sammeln Erfahrung, steigen bis Stufe 10 auf, tragen drei Items und wählen zwei Talente.",
Text = LuneContent.Heroes.Count + " Helden stehen zur Wahl; jeder Spieler führt einen. Helden sammeln Erfahrung, steigen bis Stufe 10 auf, tragen drei Items und wählen zwei Talente.",
Note = "Klick: Heldenauswahl öffnen",
};
HeroSpec spec = LuneContent.Heroes[_hero.HeroId];
@ -250,6 +258,8 @@ namespace Luneraria.UI
public const int TabValues = 0;
public const int TabItems = 1;
public const int TabTalents = 2;
/// <summary>H1: ultimate rule and skin of heroes that have them.</summary>
public const int TabUltimate = 3;
public event Action<Command> CommandRequested;
public int Tab = TabValues;
@ -257,6 +267,8 @@ namespace Luneraria.UI
public readonly Dictionary<string, LuneButton> RecruitButtons = new Dictionary<string, LuneButton>();
public readonly Dictionary<string, LuneButton> LaneButtons = new Dictionary<string, LuneButton>();
public readonly List<LuneButton> TalentCards = new List<LuneButton>();
public readonly Dictionary<string, LuneButton> RuleCards = new Dictionary<string, LuneButton>();
public readonly Dictionary<string, LuneButton> SkinCards = new Dictionary<string, LuneButton>();
public LuneTabBar Tabs;
LuneHudModel _model;
string _signature = "";
@ -285,7 +297,7 @@ namespace Luneraria.UI
{
_model = model;
HeroState hero = model.OwnHero;
string signature = (hero != null ? hero.HeroId + ":" + hero.Xp + ":" + hero.Lane + ":" + hero.Fresh + ":" + string.Join(",", hero.Items) + ":" + string.Join(",", hero.Talents) + ":" + string.Join(",", hero.FreshItems) : "-")
string signature = (hero != null ? hero.HeroId + ":" + hero.Xp + ":" + hero.Lane + ":" + hero.Fresh + ":" + string.Join(",", hero.Items) + ":" + string.Join(",", hero.Talents) + ":" + string.Join(",", hero.FreshItems) + ":" + hero.Ultimate + ":" + hero.Skin : "-")
+ "|" + model.OwnGold + "|" + model.Planning + "|" + model.Locked + "|" + Tab + "|" + model.State.GrottoAvailable() + "|" + model.State.RoundNumber;
if (signature == _signature)
return;
@ -295,6 +307,8 @@ namespace Luneraria.UI
RecruitButtons.Clear();
LaneButtons.Clear();
TalentCards.Clear();
RuleCards.Clear();
SkinCards.Clear();
Tabs = null;
if (hero == null)
Recruit(model);
@ -360,7 +374,10 @@ namespace Luneraria.UI
RecruitButtons[heroId] = buy;
if (why.Length > 0)
LuneUi.SetColor(LuneUi.Wrap(LuneUi.Label(why, "HudMuted", column)), gold < cost ? LuneUiTheme.Danger : LuneUiTheme.Muted);
LuneUi.Label("Vorläufige Rolle des vorhandenen Modells.", "HudMuted", column);
if (spec.Provisional)
LuneUi.Wrap(LuneUi.Label("Vorläufige Rolle des vorhandenen Modells.", "HudMuted", column));
else if (spec.UltimateName.Length > 0)
LuneUi.SetColor(LuneUi.Label("Ultimate: " + spec.UltimateName, "HudText", column), LuneUiTheme.Hero);
}
}
@ -378,7 +395,7 @@ namespace Luneraria.UI
portrait.style.width = 290f;
portrait.style.height = 230f;
left.Add(portrait);
portrait.ShowModel(spec.Model, true);
portrait.ShowModel(string.IsNullOrEmpty(hero.Skin) ? spec.Model : spec.Model + "#" + hero.Skin, true);
LuneUi.Label(spec.Title, "HudMuted", left);
VisualElement role = LuneUi.Box(false, 6f, left);
LuneUi.Glyph(LuneStats.RoleGlyph(definition.Role), LuneUiTheme.BronzeLight, 16f, role);
@ -433,6 +450,11 @@ namespace Luneraria.UI
LuneButton talents = Tabs.AddTab("TALENTE");
if (talentReady)
LuneUi.Glyph("star", LuneUiTheme.Hero, 13f, talents).style.marginLeft = 5f;
bool special = LuneContent.HasUltimate(hero.HeroId) || LuneContent.SkinsOf(hero.HeroId).Length > 0;
if (special)
Tabs.AddTab("ULTIMATE & SKIN");
if (Tab == TabUltimate && !special)
Tab = TabValues;
Tabs.Select(Tab);
Tabs.TabChanged += ShowTab;
VisualElement page = LuneUi.Box(true, 8f, right);
@ -441,6 +463,8 @@ namespace Luneraria.UI
Items(model, hero, level, page);
else if (Tab == TabTalents)
Talents(model, hero, level, page);
else if (Tab == TabUltimate)
Ultimate(model, hero, spec, page);
else
Values(hero, definition, spec, page);
}
@ -461,7 +485,13 @@ namespace Luneraria.UI
LuneUi.Wrap(LuneUi.Label("Grundwerte " + LuneUiTheme.Number(baseDef.MaxHp) + " Leben, " + LuneUiTheme.Decimal(baseDef.Damage) + " Schaden; je Stufe +" + LuneUiTheme.Round(LuneContent.HpPerLevel * 100.0)
+ " % Leben und +" + LuneUiTheme.Round(LuneContent.DamagePerLevel * 100.0) + " % Schaden (jetzt Stufe " + definition.Level + ").", "HudMuted", page));
LuneUi.Label("FÄHIGKEIT", "HudCaps", page);
LuneUi.Wrap(LuneUi.Label(DataCatalog.GetUnit(spec.Model).AbilityDescription ?? "", "HudText", page));
// H1 heroes bring their own kit text; the reference heroes use their troop model's ability.
string ability = spec.AbilityText.Length > 0 ? spec.AbilityText : DataCatalog.GetUnit(spec.Model).AbilityDescription ?? "";
if (spec.PassiveText.Length > 0)
ability = spec.PassiveText + "\n" + ability;
if (spec.UltimateName.Length > 0)
ability += "\nUltimate " + spec.UltimateName + ": " + spec.UltimateText;
LuneUi.Wrap(LuneUi.Label(ability, "HudText", page));
var chosen = new List<string>();
TalentOption[][] options = LuneContent.TalentsOf(hero.HeroId);
for (int tier = 0; tier < hero.Talents.Count; tier++)
@ -605,5 +635,86 @@ namespace Luneraria.UI
}
LuneUi.Wrap(LuneUi.Label("Die Wahl ist endgültig; jede Stufe bietet zwei Richtungen (Einzelziel oder Fläche, Schutz oder Druck).", "HudMuted", page));
}
/// <summary>
/// H1: the ultimate and its trigger rule (one charge per combat, released automatically
/// when the rule holds; the rule can change in every planning), and the cosmetic skins.
/// </summary>
void Ultimate(LuneHudModel model, HeroState hero, HeroSpec spec, VisualElement page)
{
bool canAct = CanAct(model);
TalentOption[] rules = LuneContent.UltimateRulesOf(hero.HeroId);
if (rules.Length > 0)
{
LuneUi.Label("ULTIMATE · " + spec.UltimateName.ToUpperInvariant(), "HudCaps", page);
LuneUi.Wrap(LuneUi.Label(spec.UltimateText, "HudText", page));
LuneUi.Label("AUSLÖSER · jederzeit in der Planung änderbar, kostenlos", "HudCaps", page);
string current = LuneContent.UltimateRuleFor(hero);
VisualElement row = LuneUi.Box(false, 8f, page);
row.style.alignItems = Align.Stretch;
foreach (TalentOption rule in rules)
{
var card = new LuneButton(null, LuneButtons.HudCard, row);
card.style.flexGrow = 1f;
card.style.flexBasis = 0f;
card.style.minHeight = 84f;
card.style.flexDirection = FlexDirection.Column;
card.style.alignItems = Align.Stretch;
card.style.justifyContent = Justify.FlexStart;
card.style.paddingLeft = 8f;
card.style.paddingRight = 8f;
card.style.paddingTop = 6f;
card.style.paddingBottom = 6f;
LuneUi.Label(rule.Name + (rule == rules[0] ? " (Standard)" : ""), "HudValue", card);
LuneUi.Wrap(LuneUi.Label(rule.Text, "HudMuted", card));
bool on = rule.Id == current;
card.On = on;
card.Disabled = !canAct && !on;
string id = rule.Id;
card.Clicked += () =>
{
if (!on)
CommandRequested?.Invoke(Command.UltimateRule(id));
};
RuleCards[id] = card;
}
}
TalentOption[] skins = LuneContent.SkinsOf(hero.HeroId);
if (skins.Length == 0)
return;
LuneUi.Label("SKIN · nur das Aussehen, für alle sichtbar", "HudCaps", page);
VisualElement looks = LuneUi.Box(false, 8f, page);
looks.style.alignItems = Align.Stretch;
var options = new List<TalentOption> { new TalentOption("", "Mondsilber", "Standard-Aussehen.") };
options.AddRange(skins);
foreach (TalentOption skin in options)
{
var card = new LuneButton(null, LuneButtons.HudCard, looks);
card.style.width = 170f;
card.style.flexDirection = FlexDirection.Column;
card.style.alignItems = Align.Stretch;
card.style.paddingLeft = 6f;
card.style.paddingRight = 6f;
card.style.paddingTop = 6f;
card.style.paddingBottom = 6f;
var face = new LunePortraitElement();
face.style.height = 120f;
face.pickingMode = PickingMode.Ignore;
card.Add(face);
face.ShowModel(skin.Id.Length == 0 ? spec.Model : spec.Model + "#" + skin.Id, true);
LuneUi.Label(skin.Name, "HudValue", card);
bool on = (hero.Skin ?? "") == skin.Id;
card.On = on;
card.Disabled = !canAct && !on;
string id = skin.Id;
card.Clicked += () =>
{
if (!on)
CommandRequested?.Invoke(Command.HeroSkin(id));
};
LuneTooltip.Attach(card, () => new LuneTip { Title = skin.Name, Glyph = "crown", GlyphColor = LuneUiTheme.Hero, Text = skin.Text });
SkinCards[id] = card;
}
}
}
}

View file

@ -526,7 +526,11 @@ namespace Luneraria.UI
HeroCard = new LuneHeroCard();
row.Add(HeroCard);
HeroCard.Clicked += () => OpenHero();
HeroCard.CommandRequested += () => HeroCommandRequested?.Invoke();
HeroCard.CommandRequested += () =>
{
HeroCommandRequested?.Invoke();
OpenHero(LuneHeroDetail.TabUltimate);
};
}
void BuildReady()

View file

@ -192,6 +192,14 @@ namespace Luneraria.UI
{
if (Library == null)
return null;
// H1: "sylvara#blutmond" is the figure in a skin.
string skin = "";
int mark = modelId.IndexOf('#');
if (mark >= 0)
{
skin = modelId.Substring(mark + 1);
modelId = modelId.Substring(0, mark);
}
LuneUnitLibrary.UnitModel entry = Library.Find(modelId);
if (entry == null || entry.Prefab == null)
return null;
@ -199,7 +207,7 @@ namespace Luneraria.UI
model.SetActive(true);
foreach (Transform node in model.GetComponentsInChildren<Transform>(true))
node.gameObject.layer = Layer;
Library.Materials?.Dress(model, 2);
Library.Materials?.Dress(model, 2, skin);
ShowDetail(model);
// Skinned figures stand in their idle pose (Godot preview("idle", .4)).
if (entry.Controller != null)

View file

@ -19,7 +19,8 @@ namespace Luneraria.View
/// &lt;unit&gt;" is a figure stress test: every seat whose Bund owns the unit fields only that
/// unit up to the supply cap (a fixture like those of the HUD view tests: public match state
/// and planning commands; the other seats keep their bot plans). The report lists the moving
/// units by definition at the start of the first window.
/// units by definition at the start of the first window. H1: a hero id ("held_sylvara") gives
/// every seat without a committed hero that hero (start from round 2, before the bots recruit).
/// </summary>
[DefaultExecutionOrder(-100)]
public sealed class LuneBenchmark : MonoBehaviour
@ -175,6 +176,22 @@ namespace Luneraria.View
static int FieldArmy(LuneMatch match, string typeId)
{
int total = 0;
// H1: a hero id gives every seat that hero (on top of its planned army).
if (ContentData.Heroes.ContainsKey(typeId))
{
foreach (Player player in match.Players)
{
Draft draft = player.Draft;
if (draft.Hero != null && draft.Hero.Fresh)
match.Submit(player.Slot, Command.HeroCancel());
int gold = draft.Gold;
draft.Gold = 100000;
if (draft.Hero == null && match.Submit(player.Slot, Command.HeroBuy(typeId)).Ok)
total++;
draft.Gold = gold;
}
return total;
}
foreach (Player player in match.Players)
{
Draft draft = player.Draft;

View file

@ -47,8 +47,17 @@ namespace Luneraria.View
return cut < 0 ? name : name.Substring(0, cut);
}
/// <summary>Swaps every known surface below root for the shared material of the team.</summary>
public void Dress(GameObject root, int team)
/// <summary>H1: material key of a skin ("AI_Sylvara" + "blutmond" -> "AI_Sylvara_Blutmond").</summary>
public static string SkinKey(string key, string skin)
{
return key + "_" + char.ToUpperInvariant(skin[0]) + skin.Substring(1);
}
/// <summary>
/// Swaps every known surface below root for the shared material of the team; with a skin
/// (H1, heroes) its variant of a material is taken where one exists.
/// </summary>
public void Dress(GameObject root, int team, string skin = "")
{
foreach (Renderer renderer in root.GetComponentsInChildren<Renderer>(true))
{
@ -56,7 +65,9 @@ namespace Luneraria.View
bool changed = false;
for (int i = 0; i < materials.Length; i++)
{
Material shared = Get(KeyOf(materials[i]), team);
Material shared = !string.IsNullOrEmpty(skin) ? Get(SkinKey(KeyOf(materials[i]), skin), team) : null;
if (shared == null)
shared = Get(KeyOf(materials[i]), team);
if (shared != null && shared != materials[i])
{
materials[i] = shared;

View file

@ -36,6 +36,8 @@ namespace Luneraria.View
public Mesh Quad;
public Material[] TeamRing = new Material[3];
public Material HeroRing;
/// <summary>H1: expanding ring of a hero's ultimate (moon light).</summary>
public Material MoonBurst;
public Material BarBack;
public Material[] BarFill = new Material[3];
public Material[] Bolt = new Material[3];

View file

@ -25,6 +25,11 @@ namespace Luneraria.View
Transform _fill;
int _lastAttack;
int _lastAbility;
int _lastLeap;
int _lastUltimate;
/// <summary>H1: expanding moon ring of an ultimate (seconds left, 0 = none).</summary>
Transform _burst;
float _burstTime;
float _attackFlash;
float _time;
Vector3 _lastVisual;
@ -51,7 +56,7 @@ namespace Luneraria.View
_model.gameObject.SetActive(true);
float scale = (float)Math.Max(.1, unit.Def.ViewScale);
_model.localScale = Vector3.one * scale;
library.Materials.Dress(_model.gameObject, unit.Team);
library.Materials.Dress(_model.gameObject, unit.Team, unit.Def.Skin);
_renderers = _model.GetComponentsInChildren<Renderer>();
_baseColors = new Color[_renderers.Length][];
_emissions = new Color[_renderers.Length][];
@ -103,6 +108,14 @@ namespace Luneraria.View
_fill.localPosition = new Vector3(0f, 0f, -.001f);
_lastAttack = unit.AttackSerial;
_lastAbility = unit.AbilitySerial;
_lastLeap = unit.LeapSerial;
_lastUltimate = unit.UltimateSerial;
if (unit.Kind == "hero" && library.MoonBurst != null)
{
_burst = Marker("UltimateBurst", library.RingRound, library.MoonBurst);
_burst.localPosition = new Vector3(0f, .08f, 0f);
_burst.gameObject.SetActive(false);
}
transform.position = Ground(unit.Position);
transform.rotation = LuneSpace.Facing(unit.Facing);
_lastVisual = transform.position;
@ -142,14 +155,21 @@ namespace Luneraria.View
_lastVisual = transform.position;
bool attacked = Unit.AttackSerial != _lastAttack;
bool ability = Unit.AbilitySerial != _lastAbility;
bool leap = Unit.LeapSerial != _lastLeap;
bool ultimate = Unit.UltimateSerial != _lastUltimate;
_lastAttack = Unit.AttackSerial;
_lastAbility = Unit.AbilitySerial;
_lastLeap = Unit.LeapSerial;
_lastUltimate = Unit.UltimateSerial;
if (ultimate && _burst != null)
_burstTime = BurstSeconds;
Burst(dt);
if (attacked || ability)
_attackFlash = .28f;
_attackFlash = Mathf.Max(0f, _attackFlash - dt);
HitFlashGlow();
if (_skeletal)
AnimateSkeletal(moved, attacked, ability);
AnimateSkeletal(moved, attacked, ability, leap, ultimate);
else
AnimateRigid(moved);
float fraction = Mathf.Clamp01((float)(Unit.Hp / Math.Max(1.0, Unit.MaxHp)));
@ -227,7 +247,25 @@ namespace Luneraria.View
}
}
void AnimateSkeletal(float moved, bool attacked, bool ability)
/// <summary>H1: the moon ring of an ultimate grows to the 5 m reach of the dance in this time.</summary>
public const float BurstSeconds = .45f;
void Burst(float dt)
{
if (_burst == null)
return;
_burstTime = Mathf.Max(0f, _burstTime - dt);
bool on = _burstTime > 0f && Unit.Alive;
_burst.gameObject.SetActive(on);
if (!on)
return;
// Reach 5 m (ring outer radius .52 at scale 1); the view scale of the model is not applied.
float grown = 1f - _burstTime / BurstSeconds;
float radius = Mathf.Lerp(.6f, 5f / .52f, Mathf.Sqrt(grown));
_burst.localScale = new Vector3(radius, 1f, radius);
}
void AnimateSkeletal(float moved, bool attacked, bool ability, bool leap, bool ultimate)
{
if (!Unit.Alive)
{
@ -236,7 +274,14 @@ namespace Luneraria.View
_deathShown = true;
return;
}
if (ability)
// Hero clips (H1): figures without them keep their normal clips.
if (ultimate && HasClip("ultimate"))
Play("ultimate", true);
else if (leap && HasClip("leap"))
Play("leap", true);
else if (IsPlaying("ultimate") || IsPlaying("leap"))
return;
else if (ability)
Play("ability", true);
else if (attacked)
{
@ -249,6 +294,8 @@ namespace Luneraria.View
Play(moved > .002f ? "walk" : "idle");
}
bool HasClip(string state) { return _animator.HasState(0, Animator.StringToHash(state)); }
bool IsPlaying(string state)
{
AnimatorStateInfo info = _animator.GetCurrentAnimatorStateInfo(0);

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Binary file not shown.

View file

@ -104,3 +104,5 @@ Die Fähigkeiten setzen die **Ultimate-Bedingungen** aus [IDEEN.md](IDEEN.md) vo
## Pilot
**Sylvara mit einem Varianten-Skin (Blutmond).** Ziel: das Slot-System einmal vollständig prüfen (Körper, Waffen-Prop, Umhang, VFX-Palette, Teamfarbe, Variantenmaterial), bevor weitere Helden folgen.
**Umgesetzt in H1** (10. Oktober 2026): Sylvara als voller Held mit Ultimate-Auslöser und Blutmond-Skin, siehe [H1-SYLVARA.md](H1-SYLVARA.md). Werte nach der Balance-Abstimmung: 1.450 Leben, Sprung nur auf ungeschützte Ziele, Mondschleier, Tanz 220 %.

View file

@ -0,0 +1,145 @@
# H1 · Sylvara, die Mondklinge
Stand: 10. Oktober 2026 · Branch `luneraria/h1-sylvara` (von `luneraria/konzept-champions`, dieser von `luneraria/u5.5-g09` = `024937c`).
Grundlage: [CHAMPIONS-KONZEPT.md](CHAMPIONS-KONZEPT.md) und [IDEEN.md](IDEEN.md). Auftrag: „Variante 2“, also Sylvara als voller, spielbarer Held mit Figur, Ultimate und einem Skin.
![Mondsicheltanz im Kampf](../port/screenshots/h1/spiel/06-mondsicheltanz.jpg)
## Kurzfassung
- **Neue Heldin:** Sylvara ist der vierte kaufbare Held, Assassine in der Nahkampfreihe, 260 Gold wie alle Helden.
- **Kit:**
- Mondsprung (passiv, einmal pro Kampf)
- Sichelwurf (alle 6 s)
- Ultimate Mondsicheltanz (einmal pro Kampf)
- zwei Talentstufen
- **Ultimate-Auslöser in der Planung:** Der Spieler wählt, *wann* das Ultimate auslöst (Gruppe, Zweite Reihe, Notfall, Sofort). Der Kampf bleibt automatisch, das Netzwerk braucht keine Befehle während des Kampfes.
- **Skin-System:** Der erste Skin heißt „Blutmond“, Stufe „Variante“. Er ist für alle Spieler sichtbar, kostenlos in der Planung wählbar und ändert nie die Partie.
- **Figur:** Meshy-Figur mit zwei Sicheln als eigenen Modellen in beiden Händen, neun Clips inklusive Sprung und Doppelklingen-Wirbel. Verbrauch: 116 Credits.
- **Parität:** Die Referenzpartien bleiben unverändert: Golden 0 Abweichungen, Bot-Fingerabdrücke gleich. Sylvara ist eine reine Ergänzung.
## Arbeitsannahmen (anpassbar)
Die offenen Fragen aus `HELDEN-KONZEPT.md` sind für H1 so beantwortet:
| Frage | Annahme H1 |
| --- | --- |
| Helden pro Spieler | weiterhin einer |
| Bindung an Bünde | keine, frei wählbar wie bisher |
| Ersetzen die neuen Helden die vorläufigen? | nein; Ringborke, Quellgeflecht und Funkenlanze bleiben (Parität), Sylvara kommt dazu |
| Ultimate-Häufigkeit | eine Ladung pro Kampfphase, frühestens nach 2 s; ausgelöst durch die in der Planung gewählte Regel |
| Talente und Items | zwei eigene Talentstufen (3 und 6); die sechs Items gelten unverändert |
| Bots | Profil `assassine` mit Sylvara, aber **nicht** in der Seed-Rotation (sonst änderten sich alle Bot-Partien). Nutzbar als festes Profil (Balance-Läufe) |
## Regeln
| Teil | Wirkung |
| --- | --- |
| Grundwerte | 1.450 Leben, 42 Schaden, Klinge gegen Leicht, Reichweite 1,2 m, Tempo 2,8, Rolle Nahkampf |
| Mondsprung (passiv) | Einmal pro Kampf: Steht ein Fernkämpfer oder Unterstützer (Reichweite ≥ 3 m, kein Boss) in 8 m und hat er höchstens 2 Begleiter in 3 m, springt sie neben ihn und nimmt ihn als Ziel. Der erste Treffer macht 150 %. Mondschleier: Schild von 25 % ihrer Lebenspunkte für 4 s |
| Sichelwurf | Ab 4 s alle 6 s: 90 % Schaden an ihrem Ziel und bis zu 2 weiteren Gegnern in 2,5 m (Ziel in 6 m) |
| Mondsicheltanz (Ultimate) | Einmal pro Kampf, frühestens nach 2 s und nie im Sprungschritt: 220 % Schaden an bis zu 5 Gegnern in 5 m, 30 % Verlangsamung für 2 s, danach Mondschleier |
| Auslöser | **Gruppe** (Standard): mindestens 3 Gegner in 4 m · **Zweite Reihe:** ein Fernkämpfer/Unterstützer in 5 m · **Notfall:** unter 40 % Leben und ein Gegner in 4 m · **Sofort:** erster Gegner in 4 m |
| Talente Stufe 3 | **Mondsilber:** Sichelwurf nur aufs Ziel, 200 % · **Sichelsturm:** bis zu 5 Ziele in 3,5 m |
| Talente Stufe 6 | **Neumond:** +20 % Angriffstempo · **Vollmond:** Tanz trifft 7 Ziele mit 280 % |
| Gleichzeitigkeit | Sprung und Tanz entscheiden auf dem Zustand am Schrittbeginn; die Landung wird mit den Bewegungen angewendet, Schaden und Schilde mit den übrigen Ereignissen des Schritts. Damit gilt das Zwei-Phasen-Prinzip des Kerns unverändert |
Befehle: `ultimate_rule` (Regel-ID in `TypeId`) und `hero_skin` (Skin-ID in `TypeId`). Beide sind nur in der Planung möglich, kostenlos und rückgängig zu machen.
## Skin-System (technisch)
- **Kern:** `ContentData.HeroSkins` listet je Held die Skins; Standard ist `""`. `HeroState.Skin` und `UnitDef.Skin` werden übertragen (Wire), die Regeln lesen sie nie. Prüfung: dieselbe Partie mit und ohne Skin ist identisch.
- **Texturen:** `tools/meshy/skin_variant.py` mit `tools/meshy/sylvara/skins.json` färbt die Albedo-Karten um. Das Blau wird Karmesin, Metall wird abgedunkelt und leicht rot getönt, Haut, Haar und Leder bleiben. Normal- und ORM-Karten bleiben die des Standards.
- **Material:** `LuneMaterialFactory` macht aus `ai-<figur>_<skin>-albedo-2k.png` ein Surface-Material `AI_<Figur>_<Skin>`.
- **Darstellung:** `LuneMaterialSet.Dress(root, team, skin)` nimmt die Skin-Variante, wo es sie gibt. Porträts verstehen `sylvara#blutmond`.
- **Regeln aus dem Konzept:** Die Kern-Silhouette (Sicheln, Zopf, Körperbau) ist in jedem Skin gleich, die Teamfarbe bleibt am Ring.
## Figur
| Schritt | Ergebnis |
| --- | --- |
| Konzept | gpt-image-2 über Meshy, Funkenlanze-Konzept als Rahmenreferenz: `assets-source/meshy/sylvara/sylvara-konzept.png`; Sichel mit Sylvara als Stilreferenz |
| Modell | image-to-3d, 20.709 Dreiecke, Lane-Fassung 4.999; Sichel 2.039 / 498 Dreiecke, zweimal (rechte und linke Hand, gemeinsames Material) |
| Skelett und Clips | Auto-Rig 1,75 m; Clips idle, walk (Run 02), attack_a (Left Slash), attack_b (Right-hand Sword Slash), hit, ability (Over Shoulder Throw), death (Dying Backwards), **leap** (Run and Leap), **ultimate** (Double Blade Spin). Leap und Ultimate sind neue optionale Clips von `build_figure.py` |
| Export | `sh tools/blender/export_fbx.sh sylvara`: 23/23 Prüfungen, zwei Läufe byteidentisch |
| Credits | Konzept 12 + 12, Modelle 30 + 30, Skelett 5, Animationen 27 = **116** (Stand danach 291) |
Der Generator teilt das Material, wenn dieselbe Waffe in beiden Händen sitzt. Außerdem kann jedes Prop eine eigene Leuchtregel haben, hier die blaue Klingenkante.
## Oberfläche
- **Heldenwahl:** vier Helden. Der Hinweis „vorläufige Rolle“ steht nur bei den drei Referenzhelden, bei Sylvara steht stattdessen ihr Ultimate.
- **Heldenfenster:** neuer Reiter **„Ultimate & Skin“** mit Ultimate-Text, vier Auslöser-Karten und Skin-Karten mit Porträt. Die Fähigkeitsseite zeigt Passiv, Fähigkeit und Ultimate.
- **Heldenkarte:** Der lange reservierte Befehlsplatz zeigt „ULT · GRUPPE“, nach dem Auslösen „ULT GENUTZT“. Ein Klick öffnet das Heldenfenster auf dem Ultimate-Reiter.
- **Feld:**
- Clips `leap` und `ultimate` folgen den Zählern aus dem Kern. Im Netz reisen sie in den Flag-Bits des Kampfrahmens, die Rahmengröße bleibt bei 13 Werten je Einheit.
- Ein hellblauer Mondring wächst in 0,45 s auf die 5 m des Tanzes.
## Balance
Werkzeug: `dotnet run -c Release --project tools/dotnet/Luneraria.Balance 40`.
Aufbau: Jeder Held bekommt dasselbe Probeprofil (Truppenmix „ausgewogen“, gleiche Items, Held ab Runde 3) auf Platz 0 bzw. 3. Die anderen Plätze sind fest, gegenüber steht Ringborke. Gespielt werden 40 Seeds auf beiden Seiten.
| Held | Siegquote des Probesitzes | mittlere Rundenzahl |
| --- | ---: | ---: |
| Ringborke | 50 % | 15,0 |
| Quellgeflecht | 100 % | 13,5 |
| Funkenlanze | 50 % | 15,0 |
| **Sylvara** | **50 %** | 14,5 |
- **Werte vor der Abstimmung:** 1.150 Leben, Sprung auf jedes Ziel, kein Schild. Damit verlor Sylvara alle 80 Partien: Sie sprang nach etwa 9 s in die gegnerische Welle und fiel nach 3 bis 4 Treffern.
- **Abstimmung:** Mehr Leben, der gezielte Sprung (höchstens 2 Begleiter), Mondschleier und ein stärkerer Tanz brachten sie auf das Niveau von Ringborke und Funkenlanze.
- **Grenze der Messung:** Bot-Partien sind fast deterministisch, die Quote ist deshalb grob (je Seite gewinnen meist alle Seeds oder keiner).
- **Quellgeflecht bei 100 %:** Das ist ein bestehendes Ungleichgewicht der Referenz. Es bleibt wegen der Parität unverändert und ist als offener Punkt notiert.
## Tests
| Prüfung | Ergebnis |
| --- | --- |
| Kern (.NET 8) | content 76, core 91, m2 73, golden 157, determinism 6, net 43, net_rounds 12, **h1 42** = 500/500 |
| Golden-Parität | 51.221 Werte, 0 Abweichungen (Sylvara wird in keinem Referenzszenario gekauft) |
| h1 | Kauf, Regel- und Skin-Befehl samt Rückgängig, Sprung (Ziel, Landung, nur einmal, nicht auf Bosse und Nahkämpfer), Sprungtreffer 150 %, Sichelwurf (Zeitpunkte, drei Ziele), alle vier Auslöser, Talente, Rotation ohne `assassine`, Determinismus, Skin ohne Einfluss |
| Unity EditMode | 30/30 (29 + Kernsuite h1) |
| Unity PlayMode | 15/15, 7 Bildwerkzeuge übersprungen; neu `H1HeroViewsTests.SylvaraHud` (Heldenwahl mit vier Helden, Regel- und Skin-Karten, Befehlsplatz, Figur mit Clips `leap`/`ultimate`, Blutmond-Material an Körper und beiden Sicheln, Ultimate im Kampf) |
| Verify A–I | 718/0; eine G3-Prüfung angepasst: „three heroes to recruit“ → „all four heroes to recruit (H1)“ |
| Fingerabdrücke | `DCE95C96556F3A1A` (Seed 2, bei 30/60/120 fps und unbegrenzt) und `7B8E43AEFC0D60C5` (Seed 9 ab Welle 21) unverändert |
| Asset-Prüfung | Export 23/23, byteidentisch in zwei Läufen; Unity-Verifier ohne Fehler |
| Player-Selbsttest | macOS-Player 30/30 (`logs/h1/player-smoke.json`) |
## Leistung
Benchmark im selben macOS-Player, je drei Läufe abwechselnd, Seed 9 ab Welle 2. `-luneBenchmarkArmy <held>` gibt allen sechs Plätzen diesen Helden, als Vergleich dient die Funkenlanze-Heldin (ebenfalls Meshy-Figur mit Waffe):
| Held auf allen Plätzen | Karte (fps) | Mid nah (fps) |
| --- | --- | --- |
| Funkenlanze | 137,7 · 133,5 · 136,6 | 162,4 · 132,6 · 161,1 |
| Sylvara | 136,3 · 137,2 · 134,9 | 158,1 · 160,5 · 159,2 |
Die Mittelwerte liegen auf der Karte gleichauf (135,9 zu 136,1). Mid nah liegt Sylvara im Median 1,1 % darunter (159,2 zu 161,1). Der Lauf mit 132,6 fps ist ein Lastausreißer, der Mac arbeitete nebenbei. Ergebnis: Sylvara kostet nicht messbar mehr als eine vorhandene Heldenfigur. Rohdaten liegen in `docs/port/logs/h1/`.
## Bilder
- `docs/port/screenshots/h1/spiel/`:
1. Heldenwahl
2. Heldenfenster
3. Ultimate & Skin
4. Aufstellung
5. Sprung und Tanz
6. Mondsicheltanz mit Mondring
7. Mondsicheltanz, Wirbel
8. Lane
9. Blutmond im Fenster
10. Blutmond im Kampf
Alle Bilder in 1920×1080, aufgenommen mit `H1HeroViewsTests.SylvaraBilder`.
- `docs/port/screenshots/h1/figur/`: Figurenblatt.
- `docs/port/screenshots/h1/ablauf/`: die 14 Momente des Vertical Function Test.
## Offene Punkte
- **Bots in der Rotation:** Sie sollen Sylvara im normalen Spiel wählen. Das ändert die Bot-Fingerabdrücke und braucht deine Entscheidung.
- **Manuelles Ultimate per Klick im Kampf (🔴):** wartet auf Befehle während des Kampfes im Netzwerk.
- **Quellgeflecht-Dominanz:** Balance der Referenz, eigene Entscheidung.
- **Weitere Helden des Konzepts:** Thalion, Ilyra, Brunhild, Isolde, Aurelian und Rowan folgen dem Muster von H1. Kosten nach H1-Erfahrung etwa 110 bis 120 Credits je Held mit Waffe; Restguthaben 291.
- **Git LFS:** H1 fügt etwa 60 MB hinzu (Quellen, Texturen, FBX).

View file

@ -218,6 +218,19 @@ Hinweis: Die Projektdateien des .NET-Harness (`tools/dotnet/*/*.csproj`) fehlten
| Bild | `screenshots/u5.5-g09/` |
| Commits | `luneraria/u5.5-g09` |
## H1 · Sylvara (erste Heldin des Champions-Konzepts)
| Punkt | Ergebnis |
| --- | --- |
| Tests | Kern .NET 500/500 (neu `h1` 42), EditMode 30/30, PlayMode 15/15 (neu `SylvaraHud`), Verify A–I 718/0 (eine G3-Prüfung auf vier Helden angepasst), Player-Selbsttest 30/30, Export 23/23 |
| Parität | Golden 51.221 Werte, 0 Abweichungen; Fingerabdrücke unverändert (`DCE95C96556F3A1A`, `7B8E43AEFC0D60C5`). Sylvara ist eine Ergänzung: kein Referenzszenario und kein Bot der Rotation kauft sie |
| Inhalt | Heldin mit Mondsprung, Sichelwurf, Mondsicheltanz; Ultimate-Auslöser in der Planung (`ultimate_rule`); Skin-System mit Blutmond (`hero_skin`, für alle sichtbar, ohne Regelwirkung); Meshy-Figur mit zwei Sicheln, Clips `leap`/`ultimate`, 116 Credits |
| Balance | Probesitz-Quote 50 % wie Ringborke und Funkenlanze (`logs/h1/balance-h1.txt`); Quellgeflecht 100 % ist Referenzbefund |
| Leistung | sechs Heldinnen auf dem Feld: Karte 136,1 zu 135,9 fps, Mid nah 159,2 zu 161,1 fps (Median) gegen die Funkenlanze-Heldin; kein messbarer Unterschied |
| Bild | `screenshots/h1/spiel/` (10 Motive 1920×1080), `figur/`, `ablauf/` |
| Bekannte Unterschiede | gewollte Erweiterung über die Referenz hinaus ([../luneraria/H1-SYLVARA.md](../luneraria/H1-SYLVARA.md)) |
| Commits | `luneraria/h1-sylvara` |
## 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.

View file

@ -1,6 +1,6 @@
# Port-Status · Champions of Luneraria in Unity
Stand: 10. Oktober 2026 (U5.5, achte Figur).
Stand: 10. Oktober 2026 (H1, Sylvara).
Referenz ist der Godot-Stand `luneraria/g3` (`1b540f2`) in `../saumwacht-godot`; er wird nicht mehr verändert. Engine: Unity 6.3 LTS (6000.3.20f1), Renderer URP. HDRP ist ausgeschlossen, bis ein Vergleich mit einer echten Szene etwas anderes nahelegt.
@ -14,6 +14,7 @@ Zielplattformen sind Fedora 44 und Windows 11; macOS ist die Entwicklungsplattfo
| U3 · G3-HUD portieren | **fertig** (`luneraria/u3`): UI Toolkit, Sichtmodell mit Privatsphäre, menschlicher Sitz, alle HUD-Bereiche, Eingabe und Befehle, Prüfung 718/0, 14 G3-Motive, Spieltest, Leistung mit HUD | [U3-UI.md](U3-UI.md) |
| U4 · Netzwerk | **fertig** (`luneraria/u4` = `769e622`): LuneSession (Protokoll 4), TCP-Transport, Startbildschirm Host/Join, 43+12 Prüfungen, Mindestumfang M4. Nachtrag (`luneraria/u4-nachtrag`, in U5.3 zusammengeführt): Startbildschirm in der Szene, „Menü“ führt dorthin zurück | [U4-NETWORK.md](U4-NETWORK.md) |
| U5 · Visuelle Neuausrichtung (Vertical Slice Mid-Lane) | **fertig** (`luneraria/u5` = `2c1686b`, Stufen `luneraria/u5.2`): 6 PBR-Sätze, Surface-Shader mit Albedo/Normal/ORM, Stufen Lane/Rand, Hit- und Turm-VFX, 133/180 fps. **U5.3** (`luneraria/u5.3` = `07fa457`): Gebäude, Boss und Ringborkes Rinde auf PBR (11 Sätze); Bildfehler aus U5 behoben (doppelte Einfärbung, Datenkarten als sRGB, Streifen, bleichender Treffer-Flash, Nebel), Helligkeit und Grün wieder auf U3-Niveau **U5.4** (`luneraria/u5.4` = `4883d95`): Surface-Materialien für alle 146 Figurenmaterialien (Metalle metallisch, Randlicht, Struktur in den Porträts), SSAO (abschaltbar), Leistung −13 % Karte / −16 % Mid **U5.5-pilot** (`luneraria/u5.5-pilot` = `c386206`): Meshy-Figur für den Kohlenbeißer `g01` (Pipeline `tools/meshy/`, UV-Material mit Lava-Glut, Schatten ohne Normalen-Versatz), GPU-Batched-Skinning, Figuren-Stress −21 % Mid / −13 % Karte gegenüber Phase-4; **Lane-Fassung** (`luneraria/u5.5-lod`): 5.000-Dreiecke-LOD, Abstand −10 % Mid / −2 % Karte; **Schlackenklaue** `g02` (`luneraria/u5.5-g02`) als zweite Meshy-Figur, −11 % Mid / −1 % Karte; **Schlackenwacht** `g03` (`luneraria/u5.5-g03`), −8 % Mid / 0 % Karte; **Funkenlanze** `g05` mit Lanze als eigenem Modell (`luneraria/u5.5-g05`), +15 % gegenüber der Phase-18-Figur; **Glasballiste** `g06` als Maschine mit übernommenem Skelett (`luneraria/u5.5-g06`); **Aschenwerfer** `g07` (`luneraria/u5.5-g07`), −11 % Mid / +2 % Karte; **Kraterrufer** `g08` (`luneraria/u5.5-g08`), −9 % Mid / +10 % Karte; **Herdhüter** `g09` (`luneraria/u5.5-g09`), −4 % Mid / +6 % Karte | [U5-VISUAL.md](U5-VISUAL.md) |
| H1 · Sylvara | **fertig** (`luneraria/h1-sylvara`): erste spielbare Heldin nach dem Port mit Ultimate-Auslöser in der Planung und Skin-System (Blutmond); Referenzpartien unverändert | [../luneraria/H1-SYLVARA.md](../luneraria/H1-SYLVARA.md) |
QA je Meilenstein: [PORT-QA.md](PORT-QA.md).
@ -32,6 +33,7 @@ Bekannte Verhaltensunterschiede, auch die bewusst übernommenen Referenzfehler:
- **Tabellen** einmal aus Godot erzeugt (`tools/port/gen_content.py`); danach ist `ContentData.cs` die gepflegte Quelle.
- **Referenzfehler R1** im Bot-Gedächtnis ist bewusst übernommen (Parität) und für eine spätere Bot-Phase vorgemerkt.
- **Geplante Helden** (Lucy, Ghaliga, Siegfried, Feena) stehen im Datenmodell, sind aber inaktiv, bis eine Heldenphase ihre Regeln umsetzt.
- **Neue Helden ergänzen, statt zu ersetzen (H1):** Die drei Referenzhelden bleiben, neue Helden folgen ihnen in `ContentData.Heroes` (`ReferenceHeroes` hält die Godot-Liste für den Inhaltsvergleich). Ultimates lösen über eine in der Planung gewählte Regel aus, Skins sind kosmetische Planungswahl. Bot-Profile neuer Helden stehen außerhalb der Seed-Rotation.
- **Assets:** Blender-Quellen und Generatoren sind die Quelle. Ein zentraler, reproduzierbarer Blender-Export erzeugt FBX für Unity; GLB nur, wo keine bessere Quelle existiert (U2A).
- **Prozedurale Welt gebacken (U2B):** Gelände und Vegetation der G1-Karte hängen an Godots Rauschen und Zufallsgenerator; ein Godot-Werkzeug backt die Welt aus dem Referenzgenerator, Unity baut daraus die Szene. U5 bekommt eine neue Weltquelle.
- **Koordinaten:** Unity = (−x, Höhe, y) der Kartenpunkte; FBX-Pipeline, Welt und Kamera nutzen dieselbe Umrechnung, das Bild entspricht Godots.

View file

@ -0,0 +1,5 @@
hero; seat wins; losses; draws; open; win rate; mean rounds; leaps/combat; ultimates/combat
held_ringborke; 40; 40; 0; 0; 50 %; 15.0; 0.00; 0.00
held_quellgeflecht; 80; 0; 0; 0; 100 %; 13.5; 0.00; 0.00
held_funkenlanze; 40; 40; 0; 0; 50 %; 15.0; 0.00; 0.00
held_sylvara; 40; 40; 0; 0; 50 %; 14.5; 0.28; 0.31

View file

@ -0,0 +1,15 @@
{
"suites": [
{"suite": "content", "checks": 76, "failures": 0, "seconds": 0.03, "failed": [], "notes": ["map geometry: largest deviation lanes 0.00E+000 m, buildings 0.00E+000 m"]},
{"suite": "core", "checks": 91, "failures": 0, "seconds": 2.22, "failed": [], "notes": ["full match seed 2 -> Rot after 9 rounds"]},
{"suite": "m2", "checks": 73, "failures": 0, "seconds": 0.56, "failed": [], "notes": []},
{"suite": "golden", "checks": 157, "failures": 0, "seconds": 2.21, "failed": [], "notes": ["golden values compared: 51221", "largest deviation angle: 0.00E+000 over 1140 values (tolerance 1E-004)", "largest deviation effect: 0.00E+000 over 264 values (tolerance 1E-006)", "largest deviation hp: 0.00E+000 over 5679 values (tolerance 1E-002)", "largest deviation other: 0.00E+000 over 34 values (tolerance 1E-006)", "largest deviation position: 0.00E+000 over 3420 values (tolerance 1E-003)", "largest deviation time: 0.00E+000 over 780 values (tolerance 1E-006)", "domain ancients: 246 values, 0 differences, largest numeric deviation 0.00E+000", "domain announcements: 44 values, 0 differences, largest numeric deviation 0.00E+000", "domain boss: 1559 values, 0 differences, largest numeric deviation 0.00E+000", "domain combat: 676 values, 0 differences, largest numeric deviation 0.00E+000", "domain commands: 410 values, 0 differences, largest numeric deviation 0.00E+000", "domain events: 6937 values, 0 differences, largest numeric deviation 0.00E+000", "domain facing: 1140 values, 0 differences, largest numeric deviation 0.00E+000", "domain gold: 3584 values, 0 differences, largest numeric deviation 0.00E+000", "domain heroes: 1512 values, 0 differences, largest numeric deviation 0.00E+000", "domain hp: 3420 values, 0 differences, largest numeric deviation 0.00E+000", "domain other: 119 values, 0 differences, largest numeric deviation 0.00E+000", "domain positions: 3420 values, 0 differences, largest numeric deviation 0.00E+000", "domain purchases: 9311 values, 0 differences, largest numeric deviation 0.00E+000", "domain rounds: 119 values, 0 differences, largest numeric deviation 0.00E+000", "domain targets: 1140 values, 0 differences, largest numeric deviation 0.00E+000", "domain towers: 1994 values, 0 differences, largest numeric deviation 0.00E+000", "domain units: 14164 values, 0 differences, largest numeric deviation 0.00E+000", "domain waves: 731 values, 0 differences, largest numeric deviation 0.00E+000", "domain winner: 695 values, 0 differences, largest numeric deviation 0.00E+000"]},
{"suite": "determinism", "checks": 6, "failures": 0, "seconds": 2.02, "failed": [], "notes": []},
{"suite": "net", "checks": 43, "failures": 0, "seconds": 0.01, "failed": [], "notes": []},
{"suite": "net_rounds", "checks": 12, "failures": 0, "seconds": 0.10, "failed": [], "notes": []},
{"suite": "h1", "checks": 42, "failures": 0, "seconds": 1.36, "failed": [], "notes": ["sylvara-bot match seed 12: 13/1"]}
],
"runtime": ".NET 8.0.27",
"label": ".NET 8.0.27, Release",
"os": "Darwin 27.0.0 Darwin Kernel Version 27.0.0: Tue Aug 11 21:02:59 PDT 2026; root:xnu-13432.1.9~1/RELEASE_ARM64_T8142 Arm64"
}

View file

@ -0,0 +1,337 @@
<?xml version="1.0" encoding="utf-8"?>
<test-run id="2" testcasecount="30" result="Passed" total="30" passed="30" failed="0" inconclusive="0" skipped="0" asserts="0" engine-version="3.5.0.0" clr-version="4.0.30319.42000" start-time="2026-10-10 15:37:07Z" end-time="2026-10-10 15:38:20Z" duration="73.276881">
<test-suite type="TestSuite" id="1000" name="luneraria-unity" fullname="luneraria-unity" runstate="Runnable" testcasecount="30" result="Passed" start-time="2026-10-10 15:37:07Z" end-time="2026-10-10 15:38:20Z" duration="73.276881" total="30" passed="30" failed="0" inconclusive="0" skipped="0" asserts="0">
<properties>
<property name="platform" value="EditMode" />
</properties>
<test-suite type="Assembly" id="1013" name="Luneraria.Core.Tests.dll" fullname="/private/tmp/lune-konzept/Library/ScriptAssemblies/Luneraria.Core.Tests.dll" runstate="Runnable" testcasecount="10" result="Passed" start-time="2026-10-10 15:37:07Z" end-time="2026-10-10 15:37:57Z" duration="49.426745" total="10" passed="10" failed="0" inconclusive="0" skipped="0" asserts="0">
<properties>
<property name="_PID" value="1214" />
<property name="_APPDOMAIN" value="Unity Child Domain" />
<property name="platform" value="EditMode" />
<property name="EditorOnly" value="True" />
</properties>
<test-suite type="TestSuite" id="1014" name="Luneraria" fullname="Luneraria" runstate="Runnable" testcasecount="10" result="Passed" start-time="2026-10-10 15:37:07Z" end-time="2026-10-10 15:37:57Z" duration="49.426502" total="10" passed="10" failed="0" inconclusive="0" skipped="0" asserts="0">
<properties />
<test-suite type="TestSuite" id="1015" name="Core" fullname="Luneraria.Core" runstate="Runnable" testcasecount="10" result="Passed" start-time="2026-10-10 15:37:07Z" end-time="2026-10-10 15:37:57Z" duration="49.426299" total="10" passed="10" failed="0" inconclusive="0" skipped="0" asserts="0">
<properties />
<test-suite type="TestSuite" id="1016" name="Tests" fullname="Luneraria.Core.Tests" runstate="Runnable" testcasecount="10" result="Passed" start-time="2026-10-10 15:37:07Z" end-time="2026-10-10 15:37:57Z" duration="49.426140" total="10" passed="10" failed="0" inconclusive="0" skipped="0" asserts="0">
<properties />
<test-suite type="TestFixture" id="1001" name="CoreIntegrationTests" fullname="Luneraria.Core.Tests.CoreIntegrationTests" classname="Luneraria.Core.Tests.CoreIntegrationTests" runstate="Runnable" testcasecount="2" result="Passed" start-time="2026-10-10 15:37:07Z" end-time="2026-10-10 15:37:07Z" duration="0.054420" total="2" passed="2" failed="0" inconclusive="0" skipped="0" asserts="0">
<properties />
<test-case id="1003" name="CoreFloatArithmeticMatchesGodot" fullname="Luneraria.Core.Tests.CoreIntegrationTests.CoreFloatArithmeticMatchesGodot" methodname="CoreFloatArithmeticMatchesGodot" classname="Luneraria.Core.Tests.CoreIntegrationTests" runstate="Runnable" seed="1947739012" result="Passed" start-time="2026-10-10 15:37:07Z" end-time="2026-10-10 15:37:07Z" duration="0.049481" asserts="0">
<properties>
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
<output><![CDATA[float probe: length 4000/4000, length_squared 4000/4000, distance_to 4000/4000, distance_squared_to 4000/4000, dot 4000/4000, normalized 4000/4000, lerp 4000/4000, limit_length 4000/4000, multiply 4000/4000, divide 4000/4000, sub_normalized 4000/4000, atan2 4000/4000
]]></output>
</test-case>
<test-case id="1002" name="CoreHasNoEngineReferences" fullname="Luneraria.Core.Tests.CoreIntegrationTests.CoreHasNoEngineReferences" methodname="CoreHasNoEngineReferences" classname="Luneraria.Core.Tests.CoreIntegrationTests" runstate="Runnable" seed="506113659" result="Passed" start-time="2026-10-10 15:37:07Z" end-time="2026-10-10 15:37:07Z" duration="0.000328" asserts="0">
<properties>
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
</test-case>
</test-suite>
<test-suite type="TestFixture" id="1004" name="CoreSuiteTests" fullname="Luneraria.Core.Tests.CoreSuiteTests" classname="Luneraria.Core.Tests.CoreSuiteTests" runstate="Runnable" testcasecount="8" result="Passed" start-time="2026-10-10 15:37:07Z" end-time="2026-10-10 15:37:57Z" duration="49.371118" total="8" passed="8" failed="0" inconclusive="0" skipped="0" asserts="0">
<properties />
<test-case id="1005" name="Content" fullname="Luneraria.Core.Tests.CoreSuiteTests.Content" methodname="Content" classname="Luneraria.Core.Tests.CoreSuiteTests" runstate="Runnable" seed="376060218" result="Passed" start-time="2026-10-10 15:37:07Z" end-time="2026-10-10 15:37:07Z" duration="0.012018" asserts="0">
<properties>
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
<output><![CDATA[content: map geometry: largest deviation lanes 0.00E+000 m, buildings 0.00E+000 m
LUNE_U1_PASS content: 76 checks
]]></output>
</test-case>
<test-case id="1006" name="CoreRules" fullname="Luneraria.Core.Tests.CoreSuiteTests.CoreRules" methodname="CoreRules" classname="Luneraria.Core.Tests.CoreSuiteTests" runstate="Runnable" seed="739851858" result="Passed" start-time="2026-10-10 15:37:07Z" end-time="2026-10-10 15:37:13Z" duration="5.709836" asserts="0">
<properties>
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
<output><![CDATA[core: full match seed 2 -> Rot after 9 rounds
LUNE_U1_PASS core: 91 checks
]]></output>
</test-case>
<test-case id="1009" name="Determinism" fullname="Luneraria.Core.Tests.CoreSuiteTests.Determinism" methodname="Determinism" classname="Luneraria.Core.Tests.CoreSuiteTests" runstate="Runnable" seed="232832264" result="Passed" start-time="2026-10-10 15:37:13Z" end-time="2026-10-10 15:37:28Z" duration="14.714001" asserts="0">
<properties>
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
<output><![CDATA[LUNE_U1_PASS determinism: 6 checks
]]></output>
</test-case>
<test-case id="1008" name="GoldenReplays" fullname="Luneraria.Core.Tests.CoreSuiteTests.GoldenReplays" methodname="GoldenReplays" classname="Luneraria.Core.Tests.CoreSuiteTests" runstate="Runnable" seed="512407771" result="Passed" start-time="2026-10-10 15:37:28Z" end-time="2026-10-10 15:37:42Z" duration="14.584194" asserts="0">
<properties>
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
<output><![CDATA[golden: golden values compared: 51221
golden: largest deviation angle: 0.00E+000 over 1140 values (tolerance 1E-004)
golden: largest deviation effect: 0.00E+000 over 264 values (tolerance 1E-006)
golden: largest deviation hp: 0.00E+000 over 5679 values (tolerance 1E-002)
golden: largest deviation other: 0.00E+000 over 34 values (tolerance 1E-006)
golden: largest deviation position: 0.00E+000 over 3420 values (tolerance 1E-003)
golden: largest deviation time: 0.00E+000 over 780 values (tolerance 1E-006)
golden: domain ancients: 246 values, 0 differences, largest numeric deviation 0.00E+000
golden: domain announcements: 44 values, 0 differences, largest numeric deviation 0.00E+000
golden: domain boss: 1559 values, 0 differences, largest numeric deviation 0.00E+000
golden: domain combat: 676 values, 0 differences, largest numeric deviation 0.00E+000
golden: domain commands: 410 values, 0 differences, largest numeric deviation 0.00E+000
golden: domain events: 6937 values, 0 differences, largest numeric deviation 0.00E+000
golden: domain facing: 1140 values, 0 differences, largest numeric deviation 0.00E+000
golden: domain gold: 3584 values, 0 differences, largest numeric deviation 0.00E+000
golden: domain heroes: 1512 values, 0 differences, largest numeric deviation 0.00E+000
golden: domain hp: 3420 values, 0 differences, largest numeric deviation 0.00E+000
golden: domain other: 119 values, 0 differences, largest numeric deviation 0.00E+000
golden: domain positions: 3420 values, 0 differences, largest numeric deviation 0.00E+000
golden: domain purchases: 9311 values, 0 differences, largest numeric deviation 0.00E+000
golden: domain rounds: 119 values, 0 differences, largest numeric deviation 0.00E+000
golden: domain targets: 1140 values, 0 differences, largest numeric deviation 0.00E+000
golden: domain towers: 1994 values, 0 differences, largest numeric deviation 0.00E+000
golden: domain units: 14164 values, 0 differences, largest numeric deviation 0.00E+000
golden: domain waves: 731 values, 0 differences, largest numeric deviation 0.00E+000
golden: domain winner: 695 values, 0 differences, largest numeric deviation 0.00E+000
LUNE_U1_PASS golden: 157 checks
]]></output>
</test-case>
<test-case id="1012" name="H1Heroes" fullname="Luneraria.Core.Tests.CoreSuiteTests.H1Heroes" methodname="H1Heroes" classname="Luneraria.Core.Tests.CoreSuiteTests" runstate="Runnable" seed="13106569" result="Passed" start-time="2026-10-10 15:37:42Z" end-time="2026-10-10 15:37:52Z" duration="9.710053" asserts="0">
<properties>
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
<output><![CDATA[h1: sylvara-bot match seed 12: 13/1
LUNE_U1_PASS h1: 42 checks
]]></output>
</test-case>
<test-case id="1007" name="M2Rules" fullname="Luneraria.Core.Tests.CoreSuiteTests.M2Rules" methodname="M2Rules" classname="Luneraria.Core.Tests.CoreSuiteTests" runstate="Runnable" seed="632454483" result="Passed" start-time="2026-10-10 15:37:52Z" end-time="2026-10-10 15:37:56Z" duration="3.817677" asserts="0">
<properties>
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
<output><![CDATA[LUNE_U1_PASS m2: 73 checks
]]></output>
</test-case>
<test-case id="1010" name="NetProtocol" fullname="Luneraria.Core.Tests.CoreSuiteTests.NetProtocol" methodname="NetProtocol" classname="Luneraria.Core.Tests.CoreSuiteTests" runstate="Runnable" seed="630092697" result="Passed" start-time="2026-10-10 15:37:56Z" end-time="2026-10-10 15:37:56Z" duration="0.084087" asserts="0">
<properties>
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
<output><![CDATA[LUNE_U1_PASS net: 43 checks
]]></output>
</test-case>
<test-case id="1011" name="NetRounds" fullname="Luneraria.Core.Tests.CoreSuiteTests.NetRounds" methodname="NetRounds" classname="Luneraria.Core.Tests.CoreSuiteTests" runstate="Runnable" seed="930426082" result="Passed" start-time="2026-10-10 15:37:56Z" end-time="2026-10-10 15:37:57Z" duration="0.736250" asserts="0">
<properties>
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
<output><![CDATA[LUNE_U1_PASS net_rounds: 12 checks
]]></output>
</test-case>
</test-suite>
</test-suite>
</test-suite>
</test-suite>
</test-suite>
<test-suite type="Assembly" id="1022" name="Luneraria.Net.Tests.dll" fullname="/private/tmp/lune-konzept/Library/ScriptAssemblies/Luneraria.Net.Tests.dll" runstate="Runnable" testcasecount="4" result="Passed" start-time="2026-10-10 15:37:57Z" end-time="2026-10-10 15:37:57Z" duration="0.012485" total="4" passed="4" failed="0" inconclusive="0" skipped="0" asserts="0">
<properties>
<property name="_PID" value="1214" />
<property name="_APPDOMAIN" value="Unity Child Domain" />
<property name="platform" value="EditMode" />
<property name="EditorOnly" value="True" />
</properties>
<test-suite type="TestSuite" id="1023" name="Luneraria" fullname="Luneraria" runstate="Runnable" testcasecount="4" result="Passed" start-time="2026-10-10 15:37:57Z" end-time="2026-10-10 15:37:57Z" duration="0.008963" total="4" passed="4" failed="0" inconclusive="0" skipped="0" asserts="0">
<properties />
<test-suite type="TestSuite" id="1024" name="Net" fullname="Luneraria.Net" runstate="Runnable" testcasecount="4" result="Passed" start-time="2026-10-10 15:37:57Z" end-time="2026-10-10 15:37:57Z" duration="0.008762" total="4" passed="4" failed="0" inconclusive="0" skipped="0" asserts="0">
<properties />
<test-suite type="TestSuite" id="1025" name="Tests" fullname="Luneraria.Net.Tests" runstate="Runnable" testcasecount="4" result="Passed" start-time="2026-10-10 15:37:57Z" end-time="2026-10-10 15:37:57Z" duration="0.008544" total="4" passed="4" failed="0" inconclusive="0" skipped="0" asserts="0">
<properties />
<test-suite type="TestFixture" id="1017" name="LuneWireTests" fullname="Luneraria.Net.Tests.LuneWireTests" classname="Luneraria.Net.Tests.LuneWireTests" runstate="Runnable" testcasecount="4" result="Passed" start-time="2026-10-10 15:37:57Z" end-time="2026-10-10 15:37:57Z" duration="0.008263" total="4" passed="4" failed="0" inconclusive="0" skipped="0" asserts="0">
<properties />
<test-case id="1018" name="CommandRoundTrips" fullname="Luneraria.Net.Tests.LuneWireTests.CommandRoundTrips" methodname="CommandRoundTrips" classname="Luneraria.Net.Tests.LuneWireTests" runstate="Runnable" seed="1872664228" result="Passed" start-time="2026-10-10 15:37:57Z" end-time="2026-10-10 15:37:57Z" duration="0.002185" asserts="0">
<properties>
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
</test-case>
<test-case id="1021" name="LobbyAndOptionsRoundTrip" fullname="Luneraria.Net.Tests.LuneWireTests.LobbyAndOptionsRoundTrip" methodname="LobbyAndOptionsRoundTrip" classname="Luneraria.Net.Tests.LuneWireTests" runstate="Runnable" seed="206070263" result="Passed" start-time="2026-10-10 15:37:57Z" end-time="2026-10-10 15:37:57Z" duration="0.000822" asserts="0">
<properties>
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
</test-case>
<test-case id="1019" name="StateRoundTrips" fullname="Luneraria.Net.Tests.LuneWireTests.StateRoundTrips" methodname="StateRoundTrips" classname="Luneraria.Net.Tests.LuneWireTests" runstate="Runnable" seed="1028346710" result="Passed" start-time="2026-10-10 15:37:57Z" end-time="2026-10-10 15:37:57Z" duration="0.002758" asserts="0">
<properties>
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
</test-case>
<test-case id="1020" name="UnitsAndFrameRoundTrip" fullname="Luneraria.Net.Tests.LuneWireTests.UnitsAndFrameRoundTrip" methodname="UnitsAndFrameRoundTrip" classname="Luneraria.Net.Tests.LuneWireTests" runstate="Runnable" seed="2026846229" result="Passed" start-time="2026-10-10 15:37:57Z" end-time="2026-10-10 15:37:57Z" duration="0.001666" asserts="0">
<properties>
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
</test-case>
</test-suite>
</test-suite>
</test-suite>
</test-suite>
</test-suite>
<test-suite type="Assembly" id="1039" name="Luneraria.UI.Tests.EditMode.dll" fullname="/private/tmp/lune-konzept/Library/ScriptAssemblies/Luneraria.UI.Tests.EditMode.dll" runstate="Runnable" testcasecount="12" result="Passed" start-time="2026-10-10 15:37:57Z" end-time="2026-10-10 15:37:57Z" duration="0.213056" total="12" passed="12" failed="0" inconclusive="0" skipped="0" asserts="0">
<properties>
<property name="_PID" value="1214" />
<property name="_APPDOMAIN" value="Unity Child Domain" />
<property name="platform" value="EditMode" />
<property name="EditorOnly" value="True" />
</properties>
<test-suite type="TestSuite" id="1040" name="Luneraria" fullname="Luneraria" runstate="Runnable" testcasecount="12" result="Passed" start-time="2026-10-10 15:37:57Z" end-time="2026-10-10 15:37:57Z" duration="0.212682" total="12" passed="12" failed="0" inconclusive="0" skipped="0" asserts="0">
<properties />
<test-suite type="TestSuite" id="1041" name="UI" fullname="Luneraria.UI" runstate="Runnable" testcasecount="12" result="Passed" start-time="2026-10-10 15:37:57Z" end-time="2026-10-10 15:37:57Z" duration="0.212505" total="12" passed="12" failed="0" inconclusive="0" skipped="0" asserts="0">
<properties />
<test-suite type="TestSuite" id="1042" name="Tests" fullname="Luneraria.UI.Tests" runstate="Runnable" testcasecount="12" result="Passed" start-time="2026-10-10 15:37:57Z" end-time="2026-10-10 15:37:57Z" duration="0.212258" total="12" passed="12" failed="0" inconclusive="0" skipped="0" asserts="0">
<properties />
<test-suite type="TestFixture" id="1026" name="HudModelTests" fullname="Luneraria.UI.Tests.HudModelTests" classname="Luneraria.UI.Tests.HudModelTests" runstate="Runnable" testcasecount="12" result="Passed" start-time="2026-10-10 15:37:57Z" end-time="2026-10-10 15:37:57Z" duration="0.212003" total="12" passed="12" failed="0" inconclusive="0" skipped="0" asserts="0">
<properties />
<test-case id="1031" name="AnnouncedDangersRaiseTheThreat" fullname="Luneraria.UI.Tests.HudModelTests.AnnouncedDangersRaiseTheThreat" methodname="AnnouncedDangersRaiseTheThreat" classname="Luneraria.UI.Tests.HudModelTests" runstate="Runnable" seed="1588076510" result="Passed" start-time="2026-10-10 15:37:57Z" end-time="2026-10-10 15:37:57Z" duration="0.003857" asserts="0">
<properties>
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
</test-case>
<test-case id="1032" name="BattlefieldCountsTheLaneUnits" fullname="Luneraria.UI.Tests.HudModelTests.BattlefieldCountsTheLaneUnits" methodname="BattlefieldCountsTheLaneUnits" classname="Luneraria.UI.Tests.HudModelTests" runstate="Runnable" seed="1036583609" result="Passed" start-time="2026-10-10 15:37:57Z" end-time="2026-10-10 15:37:57Z" duration="0.032987" asserts="0">
<properties>
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
</test-case>
<test-case id="1029" name="BossLaneChoiceIsPrivateToTheChooser" fullname="Luneraria.UI.Tests.HudModelTests.BossLaneChoiceIsPrivateToTheChooser" methodname="BossLaneChoiceIsPrivateToTheChooser" classname="Luneraria.UI.Tests.HudModelTests" runstate="Runnable" seed="1149423740" result="Passed" start-time="2026-10-10 15:37:57Z" end-time="2026-10-10 15:37:57Z" duration="0.002735" asserts="0">
<properties>
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
</test-case>
<test-case id="1033" name="BossStatesFromPublicState" fullname="Luneraria.UI.Tests.HudModelTests.BossStatesFromPublicState" methodname="BossStatesFromPublicState" classname="Luneraria.UI.Tests.HudModelTests" runstate="Runnable" seed="1410270439" result="Passed" start-time="2026-10-10 15:37:57Z" end-time="2026-10-10 15:37:57Z" duration="0.000674" asserts="0">
<properties>
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
</test-case>
<test-case id="1038" name="BotMatchStillStartsByItself" fullname="Luneraria.UI.Tests.HudModelTests.BotMatchStillStartsByItself" methodname="BotMatchStillStartsByItself" classname="Luneraria.UI.Tests.HudModelTests" runstate="Runnable" seed="1100587855" result="Passed" start-time="2026-10-10 15:37:57Z" end-time="2026-10-10 15:37:57Z" duration="0.001287" asserts="0">
<properties>
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
</test-case>
<test-case id="1027" name="EverySeatSeesTheSamePublicPicture" fullname="Luneraria.UI.Tests.HudModelTests.EverySeatSeesTheSamePublicPicture" methodname="EverySeatSeesTheSamePublicPicture" classname="Luneraria.UI.Tests.HudModelTests" runstate="Runnable" seed="1428547189" result="Passed" start-time="2026-10-10 15:37:57Z" end-time="2026-10-10 15:37:57Z" duration="0.044443" asserts="0">
<properties>
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
</test-case>
<test-case id="1037" name="HumanSeatPlanningWaitsForReady" fullname="Luneraria.UI.Tests.HudModelTests.HumanSeatPlanningWaitsForReady" methodname="HumanSeatPlanningWaitsForReady" classname="Luneraria.UI.Tests.HudModelTests" runstate="Runnable" seed="972937890" result="Passed" start-time="2026-10-10 15:37:57Z" end-time="2026-10-10 15:37:57Z" duration="0.060155" asserts="0">
<properties>
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
</test-case>
<test-case id="1030" name="LaneThreatFollowsTowerHealth" fullname="Luneraria.UI.Tests.HudModelTests.LaneThreatFollowsTowerHealth" methodname="LaneThreatFollowsTowerHealth" classname="Luneraria.UI.Tests.HudModelTests" runstate="Runnable" seed="737893124" result="Passed" start-time="2026-10-10 15:37:57Z" end-time="2026-10-10 15:37:57Z" duration="0.000993" asserts="0">
<properties>
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
</test-case>
<test-case id="1034" name="NextWaveIsTheRulesWave" fullname="Luneraria.UI.Tests.HudModelTests.NextWaveIsTheRulesWave" methodname="NextWaveIsTheRulesWave" classname="Luneraria.UI.Tests.HudModelTests" runstate="Runnable" seed="696380445" result="Passed" start-time="2026-10-10 15:37:57Z" end-time="2026-10-10 15:37:57Z" duration="0.001462" asserts="0">
<properties>
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
</test-case>
<test-case id="1036" name="NumbersAreFormattedAsInGodot" fullname="Luneraria.UI.Tests.HudModelTests.NumbersAreFormattedAsInGodot" methodname="NumbersAreFormattedAsInGodot" classname="Luneraria.UI.Tests.HudModelTests" runstate="Runnable" seed="583622533" result="Passed" start-time="2026-10-10 15:37:57Z" end-time="2026-10-10 15:37:57Z" duration="0.000529" asserts="0">
<properties>
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
</test-case>
<test-case id="1028" name="OtherSeatsPlansStayPrivateUntilCombat" fullname="Luneraria.UI.Tests.HudModelTests.OtherSeatsPlansStayPrivateUntilCombat" methodname="OtherSeatsPlansStayPrivateUntilCombat" classname="Luneraria.UI.Tests.HudModelTests" runstate="Runnable" seed="622660681" result="Passed" start-time="2026-10-10 15:37:57Z" end-time="2026-10-10 15:37:57Z" duration="0.060713" asserts="0">
<properties>
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
</test-case>
<test-case id="1035" name="ReadyLocksThePlan" fullname="Luneraria.UI.Tests.HudModelTests.ReadyLocksThePlan" methodname="ReadyLocksThePlan" classname="Luneraria.UI.Tests.HudModelTests" runstate="Runnable" seed="1685189601" result="Passed" start-time="2026-10-10 15:37:57Z" end-time="2026-10-10 15:37:57Z" duration="0.000825" asserts="0">
<properties>
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
</test-case>
</test-suite>
</test-suite>
</test-suite>
</test-suite>
</test-suite>
<test-suite type="Assembly" id="1048" name="Luneraria.View.Tests.EditMode.dll" fullname="/private/tmp/lune-konzept/Library/ScriptAssemblies/Luneraria.View.Tests.EditMode.dll" runstate="Runnable" testcasecount="4" result="Passed" start-time="2026-10-10 15:37:57Z" end-time="2026-10-10 15:38:20Z" duration="23.621599" total="4" passed="4" failed="0" inconclusive="0" skipped="0" asserts="0">
<properties>
<property name="_PID" value="1214" />
<property name="_APPDOMAIN" value="Unity Child Domain" />
<property name="platform" value="EditMode" />
<property name="EditorOnly" value="True" />
</properties>
<test-suite type="TestSuite" id="1049" name="Luneraria" fullname="Luneraria" runstate="Runnable" testcasecount="4" result="Passed" start-time="2026-10-10 15:37:57Z" end-time="2026-10-10 15:38:20Z" duration="23.621162" total="4" passed="4" failed="0" inconclusive="0" skipped="0" asserts="0">
<properties />
<test-suite type="TestSuite" id="1050" name="View" fullname="Luneraria.View" runstate="Runnable" testcasecount="4" result="Passed" start-time="2026-10-10 15:37:57Z" end-time="2026-10-10 15:38:20Z" duration="23.621026" total="4" passed="4" failed="0" inconclusive="0" skipped="0" asserts="0">
<properties />
<test-suite type="TestSuite" id="1051" name="Tests" fullname="Luneraria.View.Tests" runstate="Runnable" testcasecount="4" result="Passed" start-time="2026-10-10 15:37:57Z" end-time="2026-10-10 15:38:20Z" duration="23.620908" total="4" passed="4" failed="0" inconclusive="0" skipped="0" asserts="0">
<properties />
<test-suite type="TestFixture" id="1043" name="FrameRateIndependenceTests" fullname="Luneraria.View.Tests.FrameRateIndependenceTests" classname="Luneraria.View.Tests.FrameRateIndependenceTests" runstate="Runnable" testcasecount="4" result="Passed" start-time="2026-10-10 15:37:57Z" end-time="2026-10-10 15:38:20Z" duration="23.620703" total="4" passed="4" failed="0" inconclusive="0" skipped="0" asserts="0">
<properties />
<test-case id="1047" name="ClockRunsWholeStepsOnly" fullname="Luneraria.View.Tests.FrameRateIndependenceTests.ClockRunsWholeStepsOnly" methodname="ClockRunsWholeStepsOnly" classname="Luneraria.View.Tests.FrameRateIndependenceTests" runstate="Runnable" seed="1583043447" result="Passed" start-time="2026-10-10 15:37:57Z" end-time="2026-10-10 15:37:57Z" duration="0.000740" asserts="0">
<properties>
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
</test-case>
<test-case id="1044" name="FullBotMatchSeed2IsTheSameAtEveryFrameRate" fullname="Luneraria.View.Tests.FrameRateIndependenceTests.FullBotMatchSeed2IsTheSameAtEveryFrameRate" methodname="FullBotMatchSeed2IsTheSameAtEveryFrameRate" classname="Luneraria.View.Tests.FrameRateIndependenceTests" runstate="Runnable" seed="1444775013" result="Passed" start-time="2026-10-10 15:37:57Z" end-time="2026-10-10 15:38:06Z" duration="9.619393" asserts="0">
<properties>
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
<output><![CDATA[LUNE_FPS seed 2 30 fps: 19315 frames, 12690 steps, hash DCE95C96556F3A1A (core DCE95C96556F3A1A)
LUNE_FPS seed 2 60 fps: 38597 frames, 12690 steps, hash DCE95C96556F3A1A (core DCE95C96556F3A1A)
LUNE_FPS seed 2 120 fps: 77169 frames, 12690 steps, hash DCE95C96556F3A1A (core DCE95C96556F3A1A)
LUNE_FPS seed 2 unlimited (0.4-3.9 ms jitter): 569627 frames, 12690 steps, hash DCE95C96556F3A1A (core DCE95C96556F3A1A)
LUNE_FPS seed 2 stutter (stalls up to 0.4 s): 26845 frames, 12690 steps, hash DCE95C96556F3A1A (core DCE95C96556F3A1A)
]]></output>
</test-case>
<test-case id="1045" name="HighWaveMatchFromRound21IsTheSameAtEveryFrameRate" fullname="Luneraria.View.Tests.FrameRateIndependenceTests.HighWaveMatchFromRound21IsTheSameAtEveryFrameRate" methodname="HighWaveMatchFromRound21IsTheSameAtEveryFrameRate" classname="Luneraria.View.Tests.FrameRateIndependenceTests" runstate="Runnable" seed="299858285" result="Passed" start-time="2026-10-10 15:38:06Z" end-time="2026-10-10 15:38:11Z" duration="5.074635" asserts="0">
<properties>
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
<output><![CDATA[LUNE_FPS seed 9 30 fps: 6342 frames, 4195 steps, hash 7B8E43AEFC0D60C5 (core 7B8E43AEFC0D60C5)
LUNE_FPS seed 9 60 fps: 12678 frames, 4195 steps, hash 7B8E43AEFC0D60C5 (core 7B8E43AEFC0D60C5)
LUNE_FPS seed 9 120 fps: 25352 frames, 4195 steps, hash 7B8E43AEFC0D60C5 (core 7B8E43AEFC0D60C5)
LUNE_FPS seed 9 unlimited (0.4-3.9 ms jitter): 99090 frames, 4195 steps, hash 7B8E43AEFC0D60C5 (core 7B8E43AEFC0D60C5)
LUNE_FPS seed 9 stutter (stalls up to 0.4 s): 8796 frames, 4195 steps, hash 7B8E43AEFC0D60C5 (core 7B8E43AEFC0D60C5)
]]></output>
</test-case>
<test-case id="1046" name="MatchSpeedDoesNotChangeTheMatch" fullname="Luneraria.View.Tests.FrameRateIndependenceTests.MatchSpeedDoesNotChangeTheMatch" methodname="MatchSpeedDoesNotChangeTheMatch" classname="Luneraria.View.Tests.FrameRateIndependenceTests" runstate="Runnable" seed="2104716873" result="Passed" start-time="2026-10-10 15:38:11Z" end-time="2026-10-10 15:38:20Z" duration="8.924810" asserts="0">
<properties>
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
<output><![CDATA[LUNE_FPS seed 2 30 fps: 2418 frames, 12690 steps, hash DCE95C96556F3A1A (core DCE95C96556F3A1A)
LUNE_FPS seed 2 60 fps: 4831 frames, 12690 steps, hash DCE95C96556F3A1A (core DCE95C96556F3A1A)
LUNE_FPS seed 2 120 fps: 9658 frames, 12690 steps, hash DCE95C96556F3A1A (core DCE95C96556F3A1A)
LUNE_FPS seed 2 unlimited (0.4-3.9 ms jitter): 37713 frames, 12690 steps, hash DCE95C96556F3A1A (core DCE95C96556F3A1A)
LUNE_FPS seed 2 stutter (stalls up to 0.4 s): 3428 frames, 12690 steps, hash DCE95C96556F3A1A (core DCE95C96556F3A1A)
Saving results to: /Users/martin/Library/Application Support/DefaultCompany/luneraria-unity/TestResults.xml
]]></output>
</test-case>
</test-suite>
</test-suite>
</test-suite>
</test-suite>
</test-suite>
</test-suite>
</test-run>

View file

@ -0,0 +1,6 @@
{"endpoint": "v1/image-to-image", "task": "01a12660-8426-77ce-9832-5a332fd436a3", "status": "SUCCEEDED", "credits": 12, "error": null, "time": "2026-10-10T17:14:26"}
{"endpoint": "v1/image-to-image", "task": "01a12661-63ed-7373-b83d-b3dc2c94bcac", "status": "SUCCEEDED", "credits": 12, "error": null, "time": "2026-10-10T17:15:23"}
{"endpoint": "v1/image-to-3d", "task": "01a12662-40fd-7342-ae86-311bcb6c1961", "status": "SUCCEEDED", "credits": 30, "error": null, "time": "2026-10-10T17:18:59"}
{"endpoint": "v1/image-to-3d", "task": "01a12662-4701-75d1-86fd-c9b339de6946", "status": "SUCCEEDED", "credits": 30, "error": null, "time": "2026-10-10T17:19:00"}
{"endpoint": "v1/rigging", "task": "01a12665-d337-7562-aa9e-819e870a07f2", "status": "SUCCEEDED", "credits": 5, "error": null, "time": "2026-10-10T17:19:55"}
{"endpoint": "v1/animations", "task": "01a12666-6509-76fb-9fc8-f9f771e76751", "status": "SUCCEEDED", "credits": 27, "error": null, "time": "2026-10-10T17:20:39"}

View file

@ -0,0 +1,15 @@
{
"build": "OSXPlayer player, 6000.3.20f1, release",
"device": "Mac17,2; Apple M5; Apple M5",
"graphics_api": "Metal",
"resolution": "1920x1080",
"vsync": 0,
"match": "seed 9 from round 2, army held_funkenlanze x6, speed 1x, measured after 10 s of combat",
// moving units at the start of the first window: e01 12, w04 11, w06 11, g04 10, g02 9, g06 9, w02 7, g05 6, g08 4, g10 4, w08 4, w10 3
"windows": [
{"view": "overview (zoom 64)", "frames": 2755, "fps": 137.7, "frame_ms_avg": 7.26, "frame_ms_median": 3.69, "frame_ms_p95": 20.80, "frame_ms_p99": 25.00, "frame_ms_max": 51.16, "frames_over_16_7_ms": 310, "of_them_with_simulation_step": 32, "gc_collections": 20, "simulation_ms_per_frame": 0.080, "views_ms_per_frame": 0.248, "ui_ms_per_frame": 0.084, "units_alive_max": 90},
// timings overview (zoom 64): main thread avg 3.06 / median 2.90 / p95 4.50 ms, render thread avg 2.23 / median 2.20 / p95 2.87 ms, gpu avg 0.00 / median 0.00 / p95 0.00 ms, present wait avg 4.20 / median 0.24 / p95 17.55 ms
{"view": "mid lane close (zoom 22)", "frames": 1624, "fps": 162.4, "frame_ms_avg": 6.16, "frame_ms_median": 2.91, "frame_ms_p95": 20.19, "frame_ms_p99": 27.00, "frame_ms_max": 34.61, "frames_over_16_7_ms": 143, "of_them_with_simulation_step": 14, "gc_collections": 8, "simulation_ms_per_frame": 0.035, "views_ms_per_frame": 0.190, "ui_ms_per_frame": 0.060, "units_alive_max": 37}
// timings mid lane close (zoom 22): main thread avg 2.16 / median 2.04 / p95 3.19 ms, render thread avg 1.52 / median 1.46 / p95 1.99 ms, gpu avg 0.00 / median 0.00 / p95 0.00 ms, present wait avg 4.00 / median 0.20 / p95 17.97 ms
]
}

View file

@ -0,0 +1,15 @@
{
"build": "OSXPlayer player, 6000.3.20f1, release",
"device": "Mac17,2; Apple M5; Apple M5",
"graphics_api": "Metal",
"resolution": "1920x1080",
"vsync": 0,
"match": "seed 9 from round 2, army held_funkenlanze x6, speed 1x, measured after 10 s of combat",
// moving units at the start of the first window: e01 12, w04 11, w06 11, g04 10, g02 9, g06 9, w02 7, g05 6, g08 4, g10 4, w08 4, w10 3
"windows": [
{"view": "overview (zoom 64)", "frames": 2672, "fps": 133.5, "frame_ms_avg": 7.49, "frame_ms_median": 3.50, "frame_ms_p95": 21.61, "frame_ms_p99": 28.60, "frame_ms_max": 50.21, "frames_over_16_7_ms": 339, "of_them_with_simulation_step": 30, "gc_collections": 20, "simulation_ms_per_frame": 0.077, "views_ms_per_frame": 0.249, "ui_ms_per_frame": 0.084, "units_alive_max": 90},
// timings overview (zoom 64): main thread avg 3.07 / median 2.90 / p95 4.60 ms, render thread avg 2.09 / median 2.06 / p95 2.58 ms, gpu avg 0.00 / median 0.00 / p95 0.00 ms, present wait avg 4.42 / median 0.12 / p95 18.66 ms
{"view": "mid lane close (zoom 22)", "frames": 1327, "fps": 132.6, "frame_ms_avg": 7.54, "frame_ms_median": 3.53, "frame_ms_p95": 24.89, "frame_ms_p99": 34.00, "frame_ms_max": 61.50, "frames_over_16_7_ms": 169, "of_them_with_simulation_step": 18, "gc_collections": 8, "simulation_ms_per_frame": 0.051, "views_ms_per_frame": 0.233, "ui_ms_per_frame": 0.077, "units_alive_max": 37}
// timings mid lane close (zoom 22): main thread avg 2.69 / median 2.48 / p95 4.64 ms, render thread avg 1.60 / median 1.56 / p95 2.11 ms, gpu avg 0.00 / median 0.00 / p95 0.00 ms, present wait avg 4.83 / median 0.00 / p95 22.17 ms
]
}

View file

@ -0,0 +1,15 @@
{
"build": "OSXPlayer player, 6000.3.20f1, release",
"device": "Mac17,2; Apple M5; Apple M5",
"graphics_api": "Metal",
"resolution": "1920x1080",
"vsync": 0,
"match": "seed 9 from round 2, army held_funkenlanze x6, speed 1x, measured after 10 s of combat",
// moving units at the start of the first window: e01 12, w04 11, w06 11, g04 10, g02 9, g06 9, w02 7, g05 6, g08 4, g10 4, w08 4, w10 3
"windows": [
{"view": "overview (zoom 64)", "frames": 2734, "fps": 136.6, "frame_ms_avg": 7.32, "frame_ms_median": 3.33, "frame_ms_p95": 22.40, "frame_ms_p99": 27.30, "frame_ms_max": 34.91, "frames_over_16_7_ms": 365, "of_them_with_simulation_step": 38, "gc_collections": 21, "simulation_ms_per_frame": 0.071, "views_ms_per_frame": 0.235, "ui_ms_per_frame": 0.081, "units_alive_max": 90},
// timings overview (zoom 64): main thread avg 2.87 / median 2.70 / p95 4.13 ms, render thread avg 1.94 / median 1.91 / p95 2.39 ms, gpu avg 0.00 / median 0.00 / p95 0.00 ms, present wait avg 4.44 / median 0.11 / p95 19.66 ms
{"view": "mid lane close (zoom 22)", "frames": 1612, "fps": 161.1, "frame_ms_avg": 6.21, "frame_ms_median": 2.72, "frame_ms_p95": 21.59, "frame_ms_p99": 27.36, "frame_ms_max": 34.94, "frames_over_16_7_ms": 153, "of_them_with_simulation_step": 18, "gc_collections": 7, "simulation_ms_per_frame": 0.033, "views_ms_per_frame": 0.190, "ui_ms_per_frame": 0.060, "units_alive_max": 37}
// timings mid lane close (zoom 22): main thread avg 2.15 / median 2.08 / p95 3.00 ms, render thread avg 1.39 / median 1.37 / p95 1.67 ms, gpu avg 0.00 / median 0.00 / p95 0.00 ms, present wait avg 4.06 / median 0.08 / p95 19.11 ms
]
}

View file

@ -0,0 +1,15 @@
{
"build": "OSXPlayer player, 6000.3.20f1, release",
"device": "Mac17,2; Apple M5; Apple M5",
"graphics_api": "Metal",
"resolution": "1920x1080",
"vsync": 0,
"match": "seed 9 from round 2, army held_sylvara x6, speed 1x, measured after 10 s of combat",
// moving units at the start of the first window: w04 11, w06 11, g04 10, g02 9, g06 9, w02 7, sylvara 5, g08 4, g10 4, w08 4, w10 3
"windows": [
{"view": "overview (zoom 64)", "frames": 2727, "fps": 136.3, "frame_ms_avg": 7.34, "frame_ms_median": 3.40, "frame_ms_p95": 21.80, "frame_ms_p99": 27.00, "frame_ms_max": 48.39, "frames_over_16_7_ms": 347, "of_them_with_simulation_step": 44, "gc_collections": 21, "simulation_ms_per_frame": 0.076, "views_ms_per_frame": 0.241, "ui_ms_per_frame": 0.068, "units_alive_max": 77},
// timings overview (zoom 64): main thread avg 2.93 / median 2.76 / p95 4.35 ms, render thread avg 2.09 / median 2.04 / p95 2.69 ms, gpu avg 0.00 / median 0.00 / p95 0.00 ms, present wait avg 4.39 / median 0.19 / p95 18.74 ms
{"view": "mid lane close (zoom 22)", "frames": 1582, "fps": 158.1, "frame_ms_avg": 6.33, "frame_ms_median": 3.03, "frame_ms_p95": 20.36, "frame_ms_p99": 27.61, "frame_ms_max": 36.90, "frames_over_16_7_ms": 135, "of_them_with_simulation_step": 15, "gc_collections": 7, "simulation_ms_per_frame": 0.042, "views_ms_per_frame": 0.213, "ui_ms_per_frame": 0.051, "units_alive_max": 37}
// timings mid lane close (zoom 22): main thread avg 2.36 / median 2.26 / p95 3.53 ms, render thread avg 1.59 / median 1.57 / p95 2.00 ms, gpu avg 0.00 / median 0.00 / p95 0.00 ms, present wait avg 3.95 / median 0.14 / p95 17.89 ms
]
}

View file

@ -0,0 +1,15 @@
{
"build": "OSXPlayer player, 6000.3.20f1, release",
"device": "Mac17,2; Apple M5; Apple M5",
"graphics_api": "Metal",
"resolution": "1920x1080",
"vsync": 0,
"match": "seed 9 from round 2, army held_sylvara x6, speed 1x, measured after 10 s of combat",
// moving units at the start of the first window: w04 11, w06 11, g04 10, g02 9, g06 9, w02 7, sylvara 5, g08 4, g10 4, w08 4, w10 3
"windows": [
{"view": "overview (zoom 64)", "frames": 2744, "fps": 137.2, "frame_ms_avg": 7.29, "frame_ms_median": 3.41, "frame_ms_p95": 21.00, "frame_ms_p99": 27.19, "frame_ms_max": 40.74, "frames_over_16_7_ms": 319, "of_them_with_simulation_step": 51, "gc_collections": 21, "simulation_ms_per_frame": 0.072, "views_ms_per_frame": 0.246, "ui_ms_per_frame": 0.068, "units_alive_max": 77},
// timings overview (zoom 64): main thread avg 2.92 / median 2.79 / p95 4.13 ms, render thread avg 2.03 / median 2.00 / p95 2.54 ms, gpu avg 0.00 / median 0.00 / p95 0.00 ms, present wait avg 4.37 / median 0.16 / p95 18.04 ms
{"view": "mid lane close (zoom 22)", "frames": 1605, "fps": 160.5, "frame_ms_avg": 6.23, "frame_ms_median": 2.70, "frame_ms_p95": 20.51, "frame_ms_p99": 27.88, "frame_ms_max": 34.10, "frames_over_16_7_ms": 142, "of_them_with_simulation_step": 13, "gc_collections": 7, "simulation_ms_per_frame": 0.037, "views_ms_per_frame": 0.195, "ui_ms_per_frame": 0.047, "units_alive_max": 37}
// timings mid lane close (zoom 22): main thread avg 2.12 / median 2.05 / p95 2.90 ms, render thread avg 1.44 / median 1.42 / p95 1.75 ms, gpu avg 0.00 / median 0.00 / p95 0.00 ms, present wait avg 4.11 / median 0.12 / p95 18.49 ms
]
}

View file

@ -0,0 +1,15 @@
{
"build": "OSXPlayer player, 6000.3.20f1, release",
"device": "Mac17,2; Apple M5; Apple M5",
"graphics_api": "Metal",
"resolution": "1920x1080",
"vsync": 0,
"match": "seed 9 from round 2, army held_sylvara x6, speed 1x, measured after 10 s of combat",
// moving units at the start of the first window: w04 11, w06 11, g04 10, g02 9, g06 9, w02 7, sylvara 5, g08 4, g10 4, w08 4, w10 3
"windows": [
{"view": "overview (zoom 64)", "frames": 2699, "fps": 134.9, "frame_ms_avg": 7.41, "frame_ms_median": 3.37, "frame_ms_p95": 21.65, "frame_ms_p99": 26.81, "frame_ms_max": 32.50, "frames_over_16_7_ms": 339, "of_them_with_simulation_step": 26, "gc_collections": 20, "simulation_ms_per_frame": 0.069, "views_ms_per_frame": 0.244, "ui_ms_per_frame": 0.066, "units_alive_max": 77},
// timings overview (zoom 64): main thread avg 2.94 / median 2.83 / p95 3.92 ms, render thread avg 1.99 / median 1.98 / p95 2.38 ms, gpu avg 0.00 / median 0.00 / p95 0.00 ms, present wait avg 4.47 / median 0.08 / p95 18.69 ms
{"view": "mid lane close (zoom 22)", "frames": 1593, "fps": 159.2, "frame_ms_avg": 6.28, "frame_ms_median": 3.14, "frame_ms_p95": 20.80, "frame_ms_p99": 27.71, "frame_ms_max": 35.20, "frames_over_16_7_ms": 152, "of_them_with_simulation_step": 6, "gc_collections": 7, "simulation_ms_per_frame": 0.036, "views_ms_per_frame": 0.196, "ui_ms_per_frame": 0.049, "units_alive_max": 37}
// timings mid lane close (zoom 22): main thread avg 2.24 / median 2.03 / p95 3.68 ms, render thread avg 1.40 / median 1.35 / p95 1.79 ms, gpu avg 0.00 / median 0.00 / p95 0.00 ms, present wait avg 4.04 / median 0.10 / p95 18.22 ms
]
}

View file

@ -0,0 +1,11 @@
{
"build": "OSXPlayer player, 6000.3.20f1, release",
"device": "Mac17,2; Apple M5; Apple M5",
"graphics_api": "Metal",
"resolution": "1920x1080",
"seconds": 11.6,
"passed": ["Startbildschirm sichtbar", "Partie wartet: Spielcontroller und Treiber aus", "vor dem Start kein HUD", "„Allein spielen“ bedienbar", "Offline: Startbildschirm verborgen", "Offline: Spielcontroller und Treiber laufen", "Offline: HUD sichtbar", "Offline: neue Partie, Sitz 1 (Mid)", "Offline: Planung", "Offline: lokale Sitzung", "„Startaufstellung“ bedienbar", "Startaufstellung gekauft (3 Einheiten)", "„Bereit“ bedienbar", "Bereit: Kampf beginnt", "Kampf: Figuren im Feld", "„Menü“ bedienbar", "Verlassen-Dialog mit „Zum Menü“", "Zurück: Startbildschirm sichtbar", "Zurück: HUD verborgen", "Zurück: Spielcontroller und Treiber aus", "Zurück: Sitzung beendet", "Zurück: keine Figuren im Feld", "Zurück: Kamera ruht", "Zurück: „Allein spielen“ bedienbar", "Zweite Partie: Startbildschirm verborgen, HUD sichtbar", "Zweite Partie: neue Partie in der Planung", "SSAO folgt der Einstellung", "Option „Umgebungsverdeckung“ sichtbar", "Option schaltet SSAO um", "Option stellt SSAO zurück"],
"failed": [],
"photos": ["00-startbildschirm.jpg", "01-planung.jpg", "02-kampf.jpg", "03-verlassen.jpg", "04-zurueck-im-startbildschirm.jpg", "05-zweite-partie.jpg", "06-optionen.jpg"],
"result": "PASS"
}

View file

@ -0,0 +1,349 @@
<?xml version="1.0" encoding="utf-8"?>
<test-run id="2" testcasecount="22" result="Passed" total="22" passed="15" failed="0" inconclusive="0" skipped="7" asserts="0" engine-version="3.5.0.0" clr-version="4.0.30319.42000" start-time="2026-10-10 15:47:45Z" end-time="2026-10-10 15:52:53Z" duration="308.0706649">
<test-suite type="TestSuite" id="1044" name="luneraria-unity" fullname="luneraria-unity" runstate="Runnable" testcasecount="22" result="Passed" start-time="2026-10-10 15:47:45Z" end-time="2026-10-10 15:52:53Z" duration="308.070665" total="22" passed="15" failed="0" inconclusive="0" skipped="7" asserts="0">
<properties>
<property name="platform" value="PlayMode" />
</properties>
<test-suite type="Assembly" id="1029" name="Luneraria.UI.Tests.PlayMode.dll" fullname="/private/tmp/lune-konzept/Library/ScriptAssemblies/Luneraria.UI.Tests.PlayMode.dll" runstate="Runnable" testcasecount="20" result="Passed" start-time="2026-10-10 15:47:45Z" end-time="2026-10-10 15:48:11Z" duration="25.097900" total="20" passed="13" failed="0" inconclusive="0" skipped="7" asserts="0">
<properties>
<property name="_PID" value="2778" />
<property name="_APPDOMAIN" value="Unity Child Domain" />
<property name="platform" value="PlayMode" />
<property name="EditorOnly" value="False" />
</properties>
<test-suite type="TestSuite" id="1030" name="Luneraria" fullname="Luneraria" runstate="Runnable" testcasecount="20" result="Passed" start-time="2026-10-10 15:47:45Z" end-time="2026-10-10 15:48:11Z" duration="25.097585" total="20" passed="13" failed="0" inconclusive="0" skipped="7" asserts="0">
<properties />
<test-suite type="TestSuite" id="1031" name="UI" fullname="Luneraria.UI" runstate="Runnable" testcasecount="20" result="Passed" start-time="2026-10-10 15:47:45Z" end-time="2026-10-10 15:48:11Z" duration="25.097368" total="20" passed="13" failed="0" inconclusive="0" skipped="7" asserts="0">
<properties />
<test-suite type="TestSuite" id="1032" name="Tests" fullname="Luneraria.UI.Tests" runstate="Runnable" testcasecount="20" result="Passed" start-time="2026-10-10 15:47:45Z" end-time="2026-10-10 15:48:11Z" duration="25.097031" total="20" passed="13" failed="0" inconclusive="0" skipped="7" asserts="0">
<properties />
<test-suite type="TestFixture" id="1001" name="FigureViewsTests" fullname="Luneraria.UI.Tests.FigureViewsTests" classname="Luneraria.UI.Tests.FigureViewsTests" runstate="Explicit" testcasecount="1" result="Skipped" label="Explicit" site="SetUp" start-time="2026-10-10 15:47:45Z" end-time="2026-10-10 15:47:45Z" duration="0.002649" total="1" passed="0" failed="0" inconclusive="0" skipped="1" asserts="0">
<properties>
<property name="_SKIPREASON" value="Bildwerkzeug: nur gezielt per -testFilter" />
</properties>
<reason>
<message><![CDATA[Bildwerkzeug: nur gezielt per -testFilter]]></message>
</reason>
<test-case id="1002" name="Kohlenbeisser" fullname="Luneraria.UI.Tests.FigureViewsTests.Kohlenbeisser" methodname="Kohlenbeisser" classname="Luneraria.UI.Tests.FigureViewsTests" runstate="Runnable" seed="1437142582" result="Skipped" label="Explicit" site="Parent" start-time="0001-01-01 00:00:00Z" end-time="0001-01-01 00:00:00Z" duration="0.000000" asserts="0">
<properties>
<property name="_JOINTYPE" value="UnityCombinatorial" />
<property name="Timeout" value="900000" />
</properties>
<reason>
<message><![CDATA[Bildwerkzeug: nur gezielt per -testFilter]]></message>
</reason>
</test-case>
</test-suite>
<test-suite type="TestFixture" id="1003" name="H1HeroViewsTests" fullname="Luneraria.UI.Tests.H1HeroViewsTests" classname="Luneraria.UI.Tests.H1HeroViewsTests" runstate="Runnable" testcasecount="2" result="Passed" start-time="2026-10-10 15:47:45Z" end-time="2026-10-10 15:47:48Z" duration="2.350747" total="2" passed="1" failed="0" inconclusive="0" skipped="1" asserts="0">
<properties />
<test-case id="1005" name="SylvaraBilder" fullname="Luneraria.UI.Tests.H1HeroViewsTests.SylvaraBilder" methodname="SylvaraBilder" classname="Luneraria.UI.Tests.H1HeroViewsTests" runstate="Explicit" seed="1295471033" result="Skipped" label="Explicit" start-time="2026-10-10 15:47:45Z" end-time="2026-10-10 15:47:45Z" duration="0.000159" asserts="0">
<properties>
<property name="_JOINTYPE" value="UnityCombinatorial" />
<property name="Timeout" value="900000" />
<property name="_SKIPREASON" value="Bildwerkzeug: nur gezielt per -testFilter" />
</properties>
<reason>
<message><![CDATA[Bildwerkzeug: nur gezielt per -testFilter]]></message>
</reason>
</test-case>
<test-case id="1004" name="SylvaraHud" fullname="Luneraria.UI.Tests.H1HeroViewsTests.SylvaraHud" methodname="SylvaraHud" classname="Luneraria.UI.Tests.H1HeroViewsTests" runstate="Runnable" seed="860687101" result="Passed" start-time="2026-10-10 15:47:45Z" end-time="2026-10-10 15:47:48Z" duration="2.348293" asserts="0">
<properties>
<property name="_JOINTYPE" value="UnityCombinatorial" />
<property name="Timeout" value="600000" />
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
</test-case>
</test-suite>
<test-suite type="TestFixture" id="1006" name="HudCaptureTests" fullname="Luneraria.UI.Tests.HudCaptureTests" classname="Luneraria.UI.Tests.HudCaptureTests" runstate="Runnable" testcasecount="1" result="Passed" start-time="2026-10-10 15:47:48Z" end-time="2026-10-10 15:47:48Z" duration="0.444573" total="1" passed="1" failed="0" inconclusive="0" skipped="0" asserts="0">
<properties />
<test-case id="1007" name="PlanningHudOverTheScene" fullname="Luneraria.UI.Tests.HudCaptureTests.PlanningHudOverTheScene" methodname="PlanningHudOverTheScene" classname="Luneraria.UI.Tests.HudCaptureTests" runstate="Runnable" seed="2061754256" result="Passed" start-time="2026-10-10 15:47:48Z" end-time="2026-10-10 15:47:48Z" duration="0.441429" asserts="0">
<properties>
<property name="_JOINTYPE" value="UnityCombinatorial" />
<property name="Timeout" value="600000" />
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
<output><![CDATA[LUNE_HUD syncs 1 sync ms 0.147 portraits 14 scale 1 size (1706.67, 960.00)
LUNE_HUD region top (x:425.78, y:12.44, width:855.11, height:83.56)
LUNE_HUD region system (x:1559.11, y:12.44, width:136.00, height:35.56)
LUNE_HUD region left (x:12.44, y:12.44, width:312.00, height:466.67)
LUNE_HUD region right (x:1372.44, y:56.00, width:322.67, height:248.00)
LUNE_HUD region bottom (x:12.44, y:761.78, width:1432.00, height:186.67)
LUNE_HUD region ready (x:1455.11, y:616.00, width:240.00, height:84.44)
LUNE_HUD region minimap (x:1455.11, y:708.44, width:240.00, height:240.00)
]]></output>
</test-case>
</test-suite>
<test-suite type="TestFixture" id="1008" name="HudPlaytest" fullname="Luneraria.UI.Tests.HudPlaytest" classname="Luneraria.UI.Tests.HudPlaytest" runstate="Explicit" testcasecount="1" result="Skipped" label="Explicit" site="SetUp" start-time="2026-10-10 15:47:48Z" end-time="2026-10-10 15:47:48Z" duration="0.000120" total="1" passed="0" failed="0" inconclusive="0" skipped="1" asserts="0">
<properties>
<property name="_SKIPREASON" value="Spieltest: wartet auf Befehlsdateien" />
</properties>
<reason>
<message><![CDATA[Spieltest: wartet auf Befehlsdateien]]></message>
</reason>
<test-case id="1009" name="Play" fullname="Luneraria.UI.Tests.HudPlaytest.Play" methodname="Play" classname="Luneraria.UI.Tests.HudPlaytest" runstate="Runnable" seed="765093496" result="Skipped" label="Explicit" site="Parent" start-time="0001-01-01 00:00:00Z" end-time="0001-01-01 00:00:00Z" duration="0.000000" asserts="0">
<properties>
<property name="_JOINTYPE" value="UnityCombinatorial" />
<property name="Timeout" value="2147483647" />
</properties>
<reason>
<message><![CDATA[Spieltest: wartet auf Befehlsdateien]]></message>
</reason>
</test-case>
</test-suite>
<test-suite type="TestFixture" id="1010" name="HudVerifyTests" fullname="Luneraria.UI.Tests.HudVerifyTests" classname="Luneraria.UI.Tests.HudVerifyTests" runstate="Runnable" testcasecount="9" result="Passed" start-time="2026-10-10 15:47:48Z" end-time="2026-10-10 15:48:00Z" duration="11.503575" total="9" passed="9" failed="0" inconclusive="0" skipped="0" asserts="0">
<properties />
<test-case id="1011" name="A_Layout" fullname="Luneraria.UI.Tests.HudVerifyTests.A_Layout" methodname="A_Layout" classname="Luneraria.UI.Tests.HudVerifyTests" runstate="Runnable" seed="69155108" result="Passed" start-time="2026-10-10 15:47:48Z" end-time="2026-10-10 15:47:52Z" duration="4.109364" asserts="0">
<properties>
<property name="_JOINTYPE" value="UnityCombinatorial" />
<property name="Timeout" value="1800000" />
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
<output><![CDATA[LUNE_VERIFY A: 585 checks, 0 failed
]]></output>
</test-case>
<test-case id="1012" name="B_Status" fullname="Luneraria.UI.Tests.HudVerifyTests.B_Status" methodname="B_Status" classname="Luneraria.UI.Tests.HudVerifyTests" runstate="Runnable" seed="252383894" result="Passed" start-time="2026-10-10 15:47:52Z" end-time="2026-10-10 15:47:53Z" duration="0.353989" asserts="0">
<properties>
<property name="_JOINTYPE" value="UnityCombinatorial" />
<property name="Timeout" value="900000" />
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
<output><![CDATA[LUNE_VERIFY B: 21 checks, 0 failed
]]></output>
</test-case>
<test-case id="1013" name="C_HeroItemsUnits" fullname="Luneraria.UI.Tests.HudVerifyTests.C_HeroItemsUnits" methodname="C_HeroItemsUnits" classname="Luneraria.UI.Tests.HudVerifyTests" runstate="Runnable" seed="2072496130" result="Passed" start-time="2026-10-10 15:47:53Z" end-time="2026-10-10 15:47:53Z" duration="0.671604" asserts="0">
<properties>
<property name="_JOINTYPE" value="UnityCombinatorial" />
<property name="Timeout" value="900000" />
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
<output><![CDATA[LUNE_VERIFY C: 23 checks, 0 failed
]]></output>
</test-case>
<test-case id="1014" name="D_ChampionsAndBoss" fullname="Luneraria.UI.Tests.HudVerifyTests.D_ChampionsAndBoss" methodname="D_ChampionsAndBoss" classname="Luneraria.UI.Tests.HudVerifyTests" runstate="Runnable" seed="885539175" result="Passed" start-time="2026-10-10 15:47:53Z" end-time="2026-10-10 15:47:54Z" duration="0.493105" asserts="0">
<properties>
<property name="_JOINTYPE" value="UnityCombinatorial" />
<property name="Timeout" value="900000" />
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
<output><![CDATA[LUNE_VERIFY D: 16 checks, 0 failed
]]></output>
</test-case>
<test-case id="1015" name="E_ReadyBotsPrivacy" fullname="Luneraria.UI.Tests.HudVerifyTests.E_ReadyBotsPrivacy" methodname="E_ReadyBotsPrivacy" classname="Luneraria.UI.Tests.HudVerifyTests" runstate="Runnable" seed="1851023791" result="Passed" start-time="2026-10-10 15:47:54Z" end-time="2026-10-10 15:47:55Z" duration="1.386051" asserts="0">
<properties>
<property name="_JOINTYPE" value="UnityCombinatorial" />
<property name="Timeout" value="900000" />
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
<output><![CDATA[LUNE_VERIFY E: 17 checks, 0 failed
]]></output>
</test-case>
<test-case id="1016" name="F_Input" fullname="Luneraria.UI.Tests.HudVerifyTests.F_Input" methodname="F_Input" classname="Luneraria.UI.Tests.HudVerifyTests" runstate="Runnable" seed="945800995" result="Passed" start-time="2026-10-10 15:47:55Z" end-time="2026-10-10 15:47:59Z" duration="3.416656" asserts="0">
<properties>
<property name="_JOINTYPE" value="UnityCombinatorial" />
<property name="Timeout" value="900000" />
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
<output><![CDATA[LUNE_VERIFY F: 18 checks, 0 failed
]]></output>
</test-case>
<test-case id="1017" name="G_EventsAndMotion" fullname="Luneraria.UI.Tests.HudVerifyTests.G_EventsAndMotion" methodname="G_EventsAndMotion" classname="Luneraria.UI.Tests.HudVerifyTests" runstate="Runnable" seed="866811812" result="Passed" start-time="2026-10-10 15:47:59Z" end-time="2026-10-10 15:47:59Z" duration="0.535323" asserts="0">
<properties>
<property name="_JOINTYPE" value="UnityCombinatorial" />
<property name="Timeout" value="900000" />
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
<output><![CDATA[LUNE_VERIFY G: 14 checks, 0 failed
]]></output>
</test-case>
<test-case id="1018" name="H_RatesAndPortraits" fullname="Luneraria.UI.Tests.HudVerifyTests.H_RatesAndPortraits" methodname="H_RatesAndPortraits" classname="Luneraria.UI.Tests.HudVerifyTests" runstate="Runnable" seed="1119729067" result="Passed" start-time="2026-10-10 15:47:59Z" end-time="2026-10-10 15:47:59Z" duration="0.205526" asserts="0">
<properties>
<property name="_JOINTYPE" value="UnityCombinatorial" />
<property name="Timeout" value="900000" />
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
<output><![CDATA[LUNE_VERIFY rates planning 18/2s combat 10/2s sync 0.216 ms portraits 15
LUNE_VERIFY H: 5 checks, 0 failed
]]></output>
</test-case>
<test-case id="1019" name="I_Field" fullname="Luneraria.UI.Tests.HudVerifyTests.I_Field" methodname="I_Field" classname="Luneraria.UI.Tests.HudVerifyTests" runstate="Runnable" seed="1558274577" result="Passed" start-time="2026-10-10 15:47:59Z" end-time="2026-10-10 15:48:00Z" duration="0.327592" asserts="0">
<properties>
<property name="_JOINTYPE" value="UnityCombinatorial" />
<property name="Timeout" value="900000" />
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
<output><![CDATA[LUNE_VERIFY I: 19 checks, 0 failed
]]></output>
</test-case>
</test-suite>
<test-suite type="TestFixture" id="1020" name="HudViewsTests" fullname="Luneraria.UI.Tests.HudViewsTests" classname="Luneraria.UI.Tests.HudViewsTests" runstate="Explicit" testcasecount="4" result="Skipped" label="Explicit" site="SetUp" start-time="2026-10-10 15:48:00Z" end-time="2026-10-10 15:48:00Z" duration="0.000261" total="4" passed="0" failed="0" inconclusive="0" skipped="4" asserts="0">
<properties>
<property name="_SKIPREASON" value="Bildwerkzeug: nur gezielt per -testFilter" />
</properties>
<reason>
<message><![CDATA[Bildwerkzeug: nur gezielt per -testFilter]]></message>
</reason>
<test-case id="1023" name="Motifs_1280x720" fullname="Luneraria.UI.Tests.HudViewsTests.Motifs_1280x720" methodname="Motifs_1280x720" classname="Luneraria.UI.Tests.HudViewsTests" runstate="Runnable" seed="982760305" result="Skipped" label="Explicit" site="Parent" start-time="0001-01-01 00:00:00Z" end-time="0001-01-01 00:00:00Z" duration="0.000000" asserts="0">
<properties>
<property name="_JOINTYPE" value="UnityCombinatorial" />
<property name="Timeout" value="1800000" />
</properties>
<reason>
<message><![CDATA[Bildwerkzeug: nur gezielt per -testFilter]]></message>
</reason>
</test-case>
<test-case id="1021" name="Motifs_1920x1080" fullname="Luneraria.UI.Tests.HudViewsTests.Motifs_1920x1080" methodname="Motifs_1920x1080" classname="Luneraria.UI.Tests.HudViewsTests" runstate="Runnable" seed="462963487" result="Skipped" label="Explicit" site="Parent" start-time="0001-01-01 00:00:00Z" end-time="0001-01-01 00:00:00Z" duration="0.000000" asserts="0">
<properties>
<property name="_JOINTYPE" value="UnityCombinatorial" />
<property name="Timeout" value="1800000" />
</properties>
<reason>
<message><![CDATA[Bildwerkzeug: nur gezielt per -testFilter]]></message>
</reason>
</test-case>
<test-case id="1024" name="Motifs_2560x1080" fullname="Luneraria.UI.Tests.HudViewsTests.Motifs_2560x1080" methodname="Motifs_2560x1080" classname="Luneraria.UI.Tests.HudViewsTests" runstate="Runnable" seed="447798494" result="Skipped" label="Explicit" site="Parent" start-time="0001-01-01 00:00:00Z" end-time="0001-01-01 00:00:00Z" duration="0.000000" asserts="0">
<properties>
<property name="_JOINTYPE" value="UnityCombinatorial" />
<property name="Timeout" value="1800000" />
</properties>
<reason>
<message><![CDATA[Bildwerkzeug: nur gezielt per -testFilter]]></message>
</reason>
</test-case>
<test-case id="1022" name="Motifs_2560x1440" fullname="Luneraria.UI.Tests.HudViewsTests.Motifs_2560x1440" methodname="Motifs_2560x1440" classname="Luneraria.UI.Tests.HudViewsTests" runstate="Runnable" seed="1634160471" result="Skipped" label="Explicit" site="Parent" start-time="0001-01-01 00:00:00Z" end-time="0001-01-01 00:00:00Z" duration="0.000000" asserts="0">
<properties>
<property name="_JOINTYPE" value="UnityCombinatorial" />
<property name="Timeout" value="1800000" />
</properties>
<reason>
<message><![CDATA[Bildwerkzeug: nur gezielt per -testFilter]]></message>
</reason>
</test-case>
</test-suite>
<test-suite type="TestFixture" id="1025" name="StartScreenTests" fullname="Luneraria.UI.Tests.StartScreenTests" classname="Luneraria.UI.Tests.StartScreenTests" runstate="Runnable" testcasecount="1" result="Passed" start-time="2026-10-10 15:48:00Z" end-time="2026-10-10 15:48:10Z" duration="10.694453" total="1" passed="1" failed="0" inconclusive="0" skipped="0" asserts="0">
<properties />
<test-case id="1026" name="StartScreenLeadsIntoTheMatchAndBack" fullname="Luneraria.UI.Tests.StartScreenTests.StartScreenLeadsIntoTheMatchAndBack" methodname="StartScreenLeadsIntoTheMatchAndBack" classname="Luneraria.UI.Tests.StartScreenTests" runstate="Runnable" seed="326579306" result="Passed" start-time="2026-10-10 15:48:00Z" end-time="2026-10-10 15:48:10Z" duration="10.692463" asserts="0">
<properties>
<property name="_JOINTYPE" value="UnityCombinatorial" />
<property name="Timeout" value="300000" />
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
<output><![CDATA[LUNE_SMOKE ok Startbildschirm sichtbar
LUNE_SMOKE ok Partie wartet: Spielcontroller und Treiber aus
LUNE_SMOKE ok vor dem Start kein HUD
LUNE_SMOKE ok „Allein spielen“ bedienbar
LUNE_SMOKE ok Offline: Startbildschirm verborgen
LUNE_SMOKE ok Offline: Spielcontroller und Treiber laufen
LUNE_SMOKE ok Offline: HUD sichtbar
LUNE_SMOKE ok Offline: neue Partie, Sitz 1 (Mid)
LUNE_SMOKE ok Offline: Planung
LUNE_SMOKE ok Offline: lokale Sitzung
LUNE_SMOKE ok „Startaufstellung“ bedienbar
LUNE_SMOKE ok Startaufstellung gekauft (3 Einheiten)
LUNE_SMOKE ok „Bereit“ bedienbar
LUNE_SMOKE ok Bereit: Kampf beginnt
LUNE_SMOKE ok Kampf: Figuren im Feld
LUNE_SMOKE ok „Menü“ bedienbar
LUNE_SMOKE ok Verlassen-Dialog mit „Zum Menü“
LUNE_SMOKE ok Zurück: Startbildschirm sichtbar
LUNE_SMOKE ok Zurück: HUD verborgen
LUNE_SMOKE ok Zurück: Spielcontroller und Treiber aus
LUNE_SMOKE ok Zurück: Sitzung beendet
LUNE_SMOKE ok Zurück: keine Figuren im Feld
LUNE_SMOKE ok Zurück: Kamera ruht
LUNE_SMOKE ok Zurück: „Allein spielen“ bedienbar
LUNE_SMOKE ok Zweite Partie: Startbildschirm verborgen, HUD sichtbar
LUNE_SMOKE ok Zweite Partie: neue Partie in der Planung
LUNE_SMOKE_PASS 26 ok, 0 Fehler
LUNE_START_SCREEN 26 checks passed
]]></output>
</test-case>
</test-suite>
<test-suite type="TestFixture" id="1027" name="UiToolkitProbeTests" fullname="Luneraria.UI.Tests.UiToolkitProbeTests" classname="Luneraria.UI.Tests.UiToolkitProbeTests" runstate="Runnable" testcasecount="1" result="Passed" start-time="2026-10-10 15:48:10Z" end-time="2026-10-10 15:48:11Z" duration="0.099695" total="1" passed="1" failed="0" inconclusive="0" skipped="0" asserts="0">
<properties />
<test-case id="1028" name="PanelRendersIntoTexture" fullname="Luneraria.UI.Tests.UiToolkitProbeTests.PanelRendersIntoTexture" methodname="PanelRendersIntoTexture" classname="Luneraria.UI.Tests.UiToolkitProbeTests" runstate="Runnable" seed="1089315124" result="Passed" start-time="2026-10-10 15:48:10Z" end-time="2026-10-10 15:48:11Z" duration="0.098794" asserts="0">
<properties>
<property name="_JOINTYPE" value="UnityCombinatorial" />
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
<output><![CDATA[LUNE_SPIKE corner RGBA(0.565, 0.635, 0.506, 1.000) panel RGBA(0.196, 0.227, 0.204, 1.000) layout (x:12.44, y:12.44, width:760.00, height:530.67)
]]></output>
</test-case>
</test-suite>
</test-suite>
</test-suite>
</test-suite>
</test-suite>
<test-suite type="Assembly" id="1037" name="Luneraria.View.Tests.PlayMode.dll" fullname="/private/tmp/lune-konzept/Library/ScriptAssemblies/Luneraria.View.Tests.PlayMode.dll" runstate="Runnable" testcasecount="2" result="Passed" start-time="2026-10-10 15:48:11Z" end-time="2026-10-10 15:52:53Z" duration="282.969746" total="2" passed="2" failed="0" inconclusive="0" skipped="0" asserts="0">
<properties>
<property name="_PID" value="2778" />
<property name="_APPDOMAIN" value="Unity Child Domain" />
<property name="platform" value="PlayMode" />
<property name="EditorOnly" value="False" />
</properties>
<test-suite type="TestSuite" id="1038" name="Luneraria" fullname="Luneraria" runstate="Runnable" testcasecount="2" result="Passed" start-time="2026-10-10 15:48:11Z" end-time="2026-10-10 15:52:53Z" duration="282.968503" total="2" passed="2" failed="0" inconclusive="0" skipped="0" asserts="0">
<properties />
<test-suite type="TestSuite" id="1039" name="View" fullname="Luneraria.View" runstate="Runnable" testcasecount="2" result="Passed" start-time="2026-10-10 15:48:11Z" end-time="2026-10-10 15:52:53Z" duration="282.967857" total="2" passed="2" failed="0" inconclusive="0" skipped="0" asserts="0">
<properties />
<test-suite type="TestSuite" id="1040" name="Tests" fullname="Luneraria.View.Tests" runstate="Runnable" testcasecount="2" result="Passed" start-time="2026-10-10 15:48:11Z" end-time="2026-10-10 15:52:53Z" duration="282.967414" total="2" passed="2" failed="0" inconclusive="0" skipped="0" asserts="0">
<properties />
<test-suite type="TestFixture" id="1033" name="SceneFrameRateTests" fullname="Luneraria.View.Tests.SceneFrameRateTests" classname="Luneraria.View.Tests.SceneFrameRateTests" runstate="Runnable" testcasecount="1" result="Passed" start-time="2026-10-10 15:48:11Z" end-time="2026-10-10 15:50:01Z" duration="110.402578" total="1" passed="1" failed="0" inconclusive="0" skipped="0" asserts="0">
<properties />
<test-case id="1034" name="SceneMatchIsTheSameAtRealFrameRates" fullname="Luneraria.View.Tests.SceneFrameRateTests.SceneMatchIsTheSameAtRealFrameRates" methodname="SceneMatchIsTheSameAtRealFrameRates" classname="Luneraria.View.Tests.SceneFrameRateTests" runstate="Runnable" seed="568181117" result="Passed" start-time="2026-10-10 15:48:11Z" end-time="2026-10-10 15:50:01Z" duration="110.400504" asserts="0">
<properties>
<property name="_JOINTYPE" value="UnityCombinatorial" />
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
<output><![CDATA[LUNE_SCENE_FPS 30 fps: 815 frames in 27.2 s = 30.0 fps, up to 19 steps per frame, hash DCE95C96556F3A1A, same=True
LUNE_SCENE_FPS 60 fps: 1626 frames in 27.1 s = 60.0 fps, up to 10 steps per frame, hash DCE95C96556F3A1A, same=True
LUNE_SCENE_FPS 120 fps: 3222 frames in 26.9 s = 119.8 fps, up to 7 steps per frame, hash DCE95C96556F3A1A, same=True
LUNE_SCENE_FPS unlimited: 83284 frames in 26.8 s = 3102.5 fps, up to 6 steps per frame, hash DCE95C96556F3A1A, same=True
]]></output>
</test-case>
</test-suite>
<test-suite type="TestFixture" id="1035" name="VerticalFunctionTests" fullname="Luneraria.View.Tests.VerticalFunctionTests" classname="Luneraria.View.Tests.VerticalFunctionTests" runstate="Runnable" testcasecount="1" result="Passed" start-time="2026-10-10 15:50:01Z" end-time="2026-10-10 15:52:53Z" duration="172.564413" total="1" passed="1" failed="0" inconclusive="0" skipped="0" asserts="0">
<properties />
<test-case id="1036" name="BotMatchesRunVisiblyAndMatchTheCore" fullname="Luneraria.View.Tests.VerticalFunctionTests.BotMatchesRunVisiblyAndMatchTheCore" methodname="BotMatchesRunVisiblyAndMatchTheCore" classname="Luneraria.View.Tests.VerticalFunctionTests" runstate="Runnable" seed="262074730" result="Passed" start-time="2026-10-10 15:50:01Z" end-time="2026-10-10 15:52:53Z" duration="172.559732" asserts="0">
<properties>
<property name="_JOINTYPE" value="UnityCombinatorial" />
<property name="Timeout" value="3600000" />
<property name="retryIteration" value="0" />
<property name="repeatIteration" value="0" />
</properties>
<output><![CDATA[LUNE_U2D shot 01-runde1-aufmarsch round 1 Combat
LUNE_U2D shot 02-runde1-mid-kampf round 1 Combat
LUNE_U2D shot 03-turm-faellt round 7 Combat
LUNE_U2D shot 04-turm-ruine round 7 Combat
LUNE_U2D shot 05-grotte-bosskampf round 8 Combat
LUNE_U2D shot 06-held-kaempft round 9 Combat
LUNE_U2D shot 07-boss-auf-der-lane round 9 Combat
LUNE_U2D shot 08-ancient-faellt round 9 Over
LUNE_U2D shot 09-ancient-ruine round 9 Over
LUNE_U2D shot 10-ende-uebersicht round 9 Over
LUNE_U2D shot 11-welle21-uebersicht round 21 Combat
LUNE_U2D shot 12-welle21-kampf round 21 Combat
LUNE_U2D shot 13-ancient-rot-faellt round 22 Over
LUNE_U2D shot 14-welle-ende round 22 Over
Saving results to: /Users/martin/Library/Application Support/DefaultCompany/luneraria-unity/TestResults.xml
]]></output>
</test-case>
</test-suite>
</test-suite>
</test-suite>
</test-suite>
</test-suite>
</test-suite>
</test-run>

View file

@ -0,0 +1,11 @@
{
"match": "seed 2, bots, speed 24x",
"core_hash": "DCE95C96556F3A1A",
"core_steps": 12690,
"runs": [
{"target": "30 fps", "frames": 815, "seconds": 27.152, "measured_fps": 30.016, "max_steps_per_frame": 19, "steps": 12690, "hash": "DCE95C96556F3A1A", "winner": 1, "same_as_core": true},
{"target": "60 fps", "frames": 1626, "seconds": 27.092, "measured_fps": 60.019, "max_steps_per_frame": 10, "steps": 12690, "hash": "DCE95C96556F3A1A", "winner": 1, "same_as_core": true},
{"target": "120 fps", "frames": 3222, "seconds": 26.888, "measured_fps": 119.829, "max_steps_per_frame": 7, "steps": 12690, "hash": "DCE95C96556F3A1A", "winner": 1, "same_as_core": true},
{"target": "unlimited", "frames": 83284, "seconds": 26.844, "measured_fps": 3102.53, "max_steps_per_frame": 6, "steps": 12690, "hash": "DCE95C96556F3A1A", "winner": 1, "same_as_core": true}
]
}

View file

@ -0,0 +1,16 @@
{
"runs": [
{"label": "match-seed2", "seed": 2, "start_round": 1, "extra_gold": 0, "speed": 6, "winner": 1, "end_note": "Ancient von Blau zerstört.", "steps": 12690, "hash": "DCE95C96556F3A1A", "core_hash": "DCE95C96556F3A1A", "same_as_core": true,
"units_alive_max": 84, "heroes_alive_max": 4, "boss_log": ["round 8: won team 1 ", "round 9: deployed team 1 bot"],
"rounds": [{"round": 1, "combat_seconds": 44.9, "lost": [], "boss": "none", "end": "cleared"}, {"round": 2, "combat_seconds": 57.1, "lost": [], "boss": "none", "end": "cleared"}, {"round": 3, "combat_seconds": 54.1, "lost": [], "boss": "none", "end": "cleared"}, {"round": 4, "combat_seconds": 62.9, "lost": [], "boss": "none", "end": "cleared"}, {"round": 5, "combat_seconds": 60.7, "lost": [], "boss": "none", "end": "cleared"}, {"round": 6, "combat_seconds": 62.1, "lost": [], "boss": "none", "end": "cleared"}, {"round": 7, "combat_seconds": 66.5, "lost": ["blau_bot_outer"], "boss": "none", "end": "cleared"}, {"round": 8, "combat_seconds": 89.65, "lost": ["rot_top_outer", "rot_top_inner"], "boss": "won", "end": "cleared"}, {"round": 9, "combat_seconds": 136.55, "lost": ["blau_bot_inner", "blau_base_2", "blau_base_1", "blau_ancient"], "boss": "deployed", "end": "core"}],
"events": ["round 7: blau_bot_outer destroyed", "round 8: rot_top_outer destroyed", "round 8: rot_top_inner destroyed", "round 8: grotto boss won", "round 9: blau_bot_inner destroyed", "round 9: blau_base_2 destroyed", "round 9: blau_base_1 destroyed", "round 9: blau_ancient destroyed", "round 9: grotto boss deployed"],
"shots": ["01-runde1-aufmarsch", "02-runde1-mid-kampf", "03-turm-faellt", "04-turm-ruine", "05-grotte-bosskampf", "06-held-kaempft", "07-boss-auf-der-lane", "08-ancient-faellt", "09-ancient-ruine", "10-ende-uebersicht"],
"performance": null},
{"label": "match-seed9-round21", "seed": 9, "start_round": 21, "extra_gold": 4000, "speed": 6, "winner": 0, "end_note": "Ancient von Rot zerstört.", "steps": 4195, "hash": "7B8E43AEFC0D60C5", "core_hash": "7B8E43AEFC0D60C5", "same_as_core": true,
"units_alive_max": 125, "heroes_alive_max": 6, "boss_log": [],
"rounds": [{"round": 21, "combat_seconds": 121.8, "lost": ["rot_mid_outer", "rot_top_outer", "rot_mid_inner"], "boss": "none", "end": "cleared"}, {"round": 22, "combat_seconds": 87.95, "lost": ["rot_top_inner", "rot_base_1", "blau_bot_outer", "rot_base_2", "rot_ancient"], "boss": "none", "end": "core"}],
"events": ["round 21: rot_mid_outer destroyed", "round 21: rot_top_outer destroyed", "round 21: rot_mid_inner destroyed", "round 22: rot_top_inner destroyed", "round 22: rot_base_1 destroyed", "round 22: blau_bot_outer destroyed", "round 22: rot_base_2 destroyed", "round 22: rot_ancient destroyed"],
"shots": ["11-welle21-uebersicht", "12-welle21-kampf", "13-ancient-rot-faellt", "14-welle-ende"],
"performance": {"window": "20 s real time at 1x speed, unlimited frame rate, round 21", "frames": 44261, "fps": 2213.026, "frame_ms_avg": 0.452, "frame_ms_p95": 0.642, "simulation_ms_per_frame": 0.006, "views_ms_per_frame": 0.144, "units_alive_max": 116}}
]
}

View file

@ -3175,6 +3175,225 @@
]
}
},
{
"id": "sylvara",
"kind": "skinned",
"ok": true,
"checks": [
{
"check": "blender_checks_passed",
"ok": true,
"detail": ""
},
{
"check": "imported",
"ok": true,
"detail": "\"Assets/Luneraria/Art/Characters/sylvara.fbx\""
},
{
"check": "import_rules_applied",
"ok": true,
"detail": ""
},
{
"check": "root_transform_identity",
"ok": true,
"detail": "\"sylvara pos (0.0000, 0.0000, 0.0000) rot (0.00, 0.00, 0.00) scale (1.0000, 1.0000, 1.0000)\""
},
{
"check": "node_transforms_axis_clean",
"ok": true,
"detail": "[]"
},
{
"check": "mesh_names",
"ok": true,
"detail": "[]"
},
{
"check": "triangles",
"ok": true,
"detail": "\"30782 unity / 30782 blender \""
},
{
"check": "material_slots",
"ok": true,
"detail": "[]"
},
{
"check": "normals_unit_length",
"ok": true,
"detail": "[]"
},
{
"check": "tangents_where_uv",
"ok": true,
"detail": "[]"
},
{
"check": "uvs_where_blender_has_uv",
"ok": true,
"detail": "[]"
},
{
"check": "vertex_colors",
"ok": true,
"detail": "[]"
},
{
"check": "bounds_axes_scale",
"ok": true,
"detail": "\"largest difference 0.00003 m; unity (-0.503, 0.000, -0.205) (0.744, 1.750, 0.602)\""
},
{
"check": "skinned_mesh",
"ok": true,
"detail": "6"
},
{
"check": "bone_names SylvaraBody_LOD0",
"ok": true,
"detail": "[]"
},
{
"check": "root_bone SylvaraBody_LOD0",
"ok": true,
"detail": "\"Root\""
},
{
"check": "bone_names SylvaraBody_LOD1",
"ok": true,
"detail": "[]"
},
{
"check": "root_bone SylvaraBody_LOD1",
"ok": true,
"detail": "\"Root\""
},
{
"check": "bone_names SylvaraSichelL_LOD0",
"ok": true,
"detail": "[]"
},
{
"check": "root_bone SylvaraSichelL_LOD0",
"ok": true,
"detail": "\"Root\""
},
{
"check": "bone_names SylvaraSichelL_LOD1",
"ok": true,
"detail": "[]"
},
{
"check": "root_bone SylvaraSichelL_LOD1",
"ok": true,
"detail": "\"Root\""
},
{
"check": "bone_names SylvaraSichelR_LOD0",
"ok": true,
"detail": "[]"
},
{
"check": "root_bone SylvaraSichelR_LOD0",
"ok": true,
"detail": "\"Root\""
},
{
"check": "bone_names SylvaraSichelR_LOD1",
"ok": true,
"detail": "[]"
},
{
"check": "root_bone SylvaraSichelR_LOD1",
"ok": true,
"detail": "\"Root\""
},
{
"check": "generic_avatar",
"ok": true,
"detail": "\"sylvaraAvatar\""
},
{
"check": "clips",
"ok": true,
"detail": "[]"
}
],
"facts": {
"triangles": 30782,
"renderers": 6,
"meshes_without_uv_and_tangents": 0,
"degenerate_triangles_dropped": 0,
"bounds_min": [
-0.50298053,
-0.000126670973,
-0.204599217
],
"bounds_max": [
0.7444107,
1.75022984,
0.6024977
],
"clips": [
{
"name": "ability",
"length": 1.0,
"loop": false,
"events": 1
},
{
"name": "attack_a",
"length": 0.9166667,
"loop": false,
"events": 1
},
{
"name": "attack_b",
"length": 0.9166667,
"loop": false,
"events": 1
},
{
"name": "death",
"length": 2.20833325,
"loop": false,
"events": 0
},
{
"name": "hit",
"length": 0.5,
"loop": false,
"events": 0
},
{
"name": "idle",
"length": 4.0,
"loop": true,
"events": 0
},
{
"name": "leap",
"length": 0.7083333,
"loop": false,
"events": 0
},
{
"name": "ultimate",
"length": 1.41666663,
"loop": false,
"events": 1
},
{
"name": "walk",
"length": 0.75,
"loop": true,
"events": 0
}
]
}
},
{
"id": "e01",
"kind": "rigid",

Binary file not shown.

After

Width:  |  Height:  |  Size: 584 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 598 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 598 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 614 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 567 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 612 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 612 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 580 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 637 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 591 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 570 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 337 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 633 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 571 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 553 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 688 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 736 KiB

Some files were not shown because too many files have changed in this diff Show more