Compare commits
6 commits
main
...
luneraria/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
faf0fbdef0 | ||
|
|
d7c3a03e23 | ||
|
|
f53859a298 | ||
|
|
c27a0097c3 | ||
|
|
b565546c37 | ||
|
|
4b6a4f530e |
236 changed files with 29934 additions and 12 deletions
158
assets-source/luneraria/build_grotto.py
Normal file
158
assets-source/luneraria/build_grotto.py
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
"""Boss grotto for Champions of Luneraria: a rock island in the river with a crescent of
|
||||
cliffs, a cave mouth and violet crystals. Symmetric across the map diagonal, so both
|
||||
entrances (towards Blau and towards Rot) are equal. Stone uses ENV_* material names.
|
||||
|
||||
Run: ALSOFT_DRIVERS=null blender -b --python-exit-code 1 --python assets-source/luneraria/build_grotto.py
|
||||
Local Godot frame: +x/+z are the map axes; the map diagonal (x = z) is the mirror line.
|
||||
"""
|
||||
from pathlib import Path
|
||||
import bpy, bmesh, json, hashlib, struct
|
||||
from math import sin, cos, pi, sqrt
|
||||
from mathutils import Vector, noise
|
||||
|
||||
P = Path(__file__).resolve().parents[2]
|
||||
SRC = Path(__file__).resolve().parent
|
||||
OUT = P / 'assets/luneraria'
|
||||
OUT.mkdir(parents=True, exist_ok=True)
|
||||
bpy.ops.wm.read_factory_settings(use_empty=True)
|
||||
bpy.context.preferences.filepaths.save_version = 0
|
||||
parts = []
|
||||
|
||||
|
||||
def G(x, y, z):
|
||||
return Vector((x, -z, y))
|
||||
|
||||
|
||||
def material(name, color, rough=.9, metal=0.0, emission=0.0):
|
||||
m = bpy.data.materials.new(name)
|
||||
m.diffuse_color = (*color, 1)
|
||||
m.use_nodes = True
|
||||
bs = m.node_tree.nodes.get('Principled BSDF')
|
||||
bs.inputs['Base Color'].default_value = (*color, 1)
|
||||
bs.inputs['Roughness'].default_value = rough
|
||||
bs.inputs['Metallic'].default_value = metal
|
||||
if emission:
|
||||
bs.inputs['Emission Color'].default_value = (*color, 1)
|
||||
bs.inputs['Emission Strength'].default_value = emission
|
||||
return m
|
||||
|
||||
|
||||
M = {
|
||||
'cliff': material('ENV_cliff', (.133, .153, .138)),
|
||||
'soil': material('ENV_soil', (.10, .15, .065), .97),
|
||||
'limestone': material('ENV_limestone', (.283, .246, .178)),
|
||||
'dark': material('GR_Shadow', (.02, .02, .03), 1.0),
|
||||
'crystal': material('GR_Crystal', (.62, .38, 1.0), .15, 0, 3.0),
|
||||
}
|
||||
|
||||
|
||||
def obj(name, vs, fs, kind, smooth=False):
|
||||
me = bpy.data.meshes.new(name)
|
||||
me.from_pydata([tuple(v) for v in vs], [], fs)
|
||||
me.update()
|
||||
me.materials.append(M[kind])
|
||||
for p in me.polygons:
|
||||
p.use_smooth = smooth
|
||||
ob = bpy.data.objects.new(name, me)
|
||||
bpy.context.collection.objects.link(ob)
|
||||
parts.append(ob)
|
||||
return ob
|
||||
|
||||
|
||||
def island(name, radius, top, bottom, seed, kind='soil'):
|
||||
sides, levels = 64, 6
|
||||
vs, fs = [], []
|
||||
for li in range(levels):
|
||||
y = top - (top - bottom) * li / (levels - 1)
|
||||
for k in range(sides):
|
||||
a = 2 * pi * k / sides
|
||||
# Radius depends on |angle - 45 deg| so the island is symmetric across x = z.
|
||||
m = abs(((a - pi / 4) + pi) % (2 * pi) - pi)
|
||||
r = radius * (1 + .08 * noise.noise(Vector((cos(m) * 2, li * .5, seed)))) * (1 - .06 * li / levels)
|
||||
vs.append(G(cos(a) * r, y, sin(a) * r))
|
||||
for li in range(levels - 1):
|
||||
for k in range(sides):
|
||||
a, b = li * sides + k, li * sides + (k + 1) % sides
|
||||
fs.append((a, a + sides, b + sides, b))
|
||||
fs += [tuple(range(sides)), tuple(reversed(range((levels - 1) * sides, levels * sides)))]
|
||||
return obj(name, vs, fs, kind)
|
||||
|
||||
|
||||
def boulder(name, center, size, seed, kind='cliff'):
|
||||
bm = bmesh.new()
|
||||
bmesh.ops.create_icosphere(bm, subdivisions=2, radius=1.0)
|
||||
c = G(*center)
|
||||
for v in bm.verts:
|
||||
d = v.co.normalized()
|
||||
r = 1 + .32 * noise.noise(d * 1.8 + Vector((seed, seed * .5, seed * .3)))
|
||||
gx, gy, gz = d.x * r * size[0], d.z * r * size[1], -d.y * r * size[2]
|
||||
if gy < -.25 * size[1]:
|
||||
gy = -.25 * size[1]
|
||||
v.co = c + Vector((gx, -gz, gy))
|
||||
me = bpy.data.meshes.new(name)
|
||||
bm.to_mesh(me)
|
||||
bm.free()
|
||||
me.materials.append(M[kind])
|
||||
ob = bpy.data.objects.new(name, me)
|
||||
bpy.context.collection.objects.link(ob)
|
||||
parts.append(ob)
|
||||
return ob
|
||||
|
||||
|
||||
def gem(name, center, height, radius, tilt, kind='crystal'):
|
||||
cx, cy, cz = center
|
||||
tip = G(cx + tilt[0], cy + height, cz + tilt[1])
|
||||
base = [G(cx + cos(2 * pi * k / 6) * radius, cy + height * .25, cz + sin(2 * pi * k / 6) * radius) for k in range(6)]
|
||||
root = G(cx, cy - .1, cz)
|
||||
vs = [tip] + base + [root]
|
||||
fs = [(0, 1 + (k + 1) % 6, 1 + k) for k in range(6)] + [(7, 1 + k, 1 + (k + 1) % 6) for k in range(6)]
|
||||
return obj(name, vs, fs, kind)
|
||||
|
||||
|
||||
def mirror(p):
|
||||
return (p[2], p[1], p[0])
|
||||
|
||||
|
||||
island('Island', 7.2, .35, -1.2, 3)
|
||||
# Crescent of cliffs on the far side from Mid (towards -x-z), open towards both entrances.
|
||||
ring = []
|
||||
for k in range(9):
|
||||
a = pi + pi / 4 + (k - 4) * .30
|
||||
ring.append((cos(a) * 5.6, 0.0, sin(a) * 5.6, 1.5 + (1.2 if abs(k - 4) <= 1 else .5 * (4 - abs(k - 4)) / 4)))
|
||||
for i, (x, y, z, h) in enumerate(ring):
|
||||
boulder('Cliff_%d' % i, (x, y + h * .45, z), (1.6, h, 1.4), 10 + min(i, 8 - i))
|
||||
# Cave mouth: dark recess under an arch in the middle of the crescent.
|
||||
a = pi + pi / 4
|
||||
boulder('Cave_Shadow', (cos(a) * 4.6, .8, sin(a) * 4.6), (1.4, 1.1, .7), 31, 'dark')
|
||||
boulder('Arch_Top', (cos(a) * 4.8, 3.1, sin(a) * 4.8), (2.2, .8, 1.3), 32)
|
||||
# Violet crystals, mirrored pairs so neither entrance looks different.
|
||||
for i, (x, z, h, r) in enumerate([(-2.2, -3.6, 1.8, .32), (-3.9, -1.2, 1.4, .28), (-1.0, -4.3, 1.1, .22), (-3.2, -3.2, 2.3, .4)]):
|
||||
for p in {(x, 0.3, z), mirror((x, 0.3, z))}:
|
||||
gem('Crystal_%d_%d' % (i, int(p[0] * 10)), p, h, r, (.12 * (1 if p[0] < p[2] else -1), .08))
|
||||
# Entrance stones: symmetric pair of limestone steps facing Blau (+x) and Rot (+z)... see manifest.
|
||||
for p in [(4.6, .18, 1.2), mirror((4.6, .18, 1.2))]:
|
||||
boulder('Step_%d' % int(p[0] * 10), p, (1.1, .25, .8), 40, 'limestone')
|
||||
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
for ob in parts:
|
||||
ob.select_set(True)
|
||||
bpy.context.view_layer.objects.active = parts[0]
|
||||
bpy.ops.object.join()
|
||||
grotto = bpy.context.object
|
||||
grotto.name = 'BossGrotto'
|
||||
bm = bmesh.new()
|
||||
bm.from_mesh(grotto.data)
|
||||
bmesh.ops.triangulate(bm, faces=list(bm.faces))
|
||||
bm.to_mesh(grotto.data)
|
||||
bm.free()
|
||||
bpy.ops.wm.save_as_mainfile(filepath=str(SRC / 'grotto.blend'))
|
||||
bpy.ops.export_scene.gltf(filepath=str(OUT / 'grotto.glb'), export_format='GLB', use_selection=True,
|
||||
export_materials='EXPORT', export_yup=True, export_animations=False)
|
||||
raw = (OUT / 'grotto.glb').read_bytes()
|
||||
doc = json.loads(raw[20:20 + struct.unpack_from('<I', raw, 12)[0]])
|
||||
triangles = sum(doc['accessors'][q['indices']]['count'] // 3 for m in doc['meshes'] for q in m['primitives'])
|
||||
(OUT / 'grotto_manifest.json').write_text(json.dumps({'assets': [{
|
||||
'id': 'boss_grotto', 'resource_path': 'res://assets/luneraria/grotto.glb', 'source': 'assets-source/luneraria/grotto.blend',
|
||||
'triangles': triangles, 'sha256': hashlib.sha256(raw).hexdigest(),
|
||||
'materials': [m['name'] for m in doc['materials']]}]}, indent=2) + '\n')
|
||||
print('GROTTO_BUILD', triangles, 'triangles', flush=True)
|
||||
248
assets-source/luneraria/build_map_props.py
Normal file
248
assets-source/luneraria/build_map_props.py
Normal file
|
|
@ -0,0 +1,248 @@
|
|||
"""Map dressing for Champions of Luneraria: river bridge, curb stone, trees, rocks, banner
|
||||
and edge cliffs, exported as separate named meshes in one GLB. Godot instances them with
|
||||
MultiMeshes. Stone, bark and leaves use ENV_* names so the Kluft shaders (with wind on
|
||||
foliage) apply at runtime.
|
||||
|
||||
Run: ALSOFT_DRIVERS=null blender -b --python-exit-code 1 --python assets-source/luneraria/build_map_props.py
|
||||
Godot frame per prop: y up, prop origin at ground level; the bridge spans local +x.
|
||||
"""
|
||||
from pathlib import Path
|
||||
import bpy, bmesh, json, hashlib, struct
|
||||
from math import sin, cos, pi
|
||||
from mathutils import Vector, noise
|
||||
|
||||
P = Path(__file__).resolve().parents[2]
|
||||
SRC = Path(__file__).resolve().parent
|
||||
OUT = P / 'assets/luneraria'
|
||||
bpy.ops.wm.read_factory_settings(use_empty=True)
|
||||
bpy.context.preferences.filepaths.save_version = 0
|
||||
|
||||
|
||||
def G(x, y, z):
|
||||
return Vector((x, -z, y))
|
||||
|
||||
|
||||
def material(name, color, rough=.9, metal=0.0, emission=0.0):
|
||||
m = bpy.data.materials.new(name)
|
||||
m.diffuse_color = (*color, 1)
|
||||
m.use_nodes = True
|
||||
bs = m.node_tree.nodes.get('Principled BSDF')
|
||||
bs.inputs['Base Color'].default_value = (*color, 1)
|
||||
bs.inputs['Roughness'].default_value = rough
|
||||
bs.inputs['Metallic'].default_value = metal
|
||||
if emission:
|
||||
bs.inputs['Emission Color'].default_value = (*color, 1)
|
||||
bs.inputs['Emission Strength'].default_value = emission
|
||||
return m
|
||||
|
||||
|
||||
M = {
|
||||
'limestone': material('ENV_limestone', (.283, .246, .178)),
|
||||
'paving': material('ENV_paving', (.19, .185, .15), .92),
|
||||
'cliff': material('ENV_cliff', (.133, .153, .138)),
|
||||
'bark': material('ENV_bark', (.087, .056, .032), .93),
|
||||
'leaf_dark': material('ENV_leaf_dark', (.031, .07, .04), .89),
|
||||
'leaf_mid': material('ENV_leaf_mid', (.084, .144, .054), .85),
|
||||
'leaf_light': material('ENV_leaf_light', (.258, .305, .091), .79),
|
||||
'soil': material('ENV_soil', (.10, .15, .065), .97),
|
||||
'brass': material('ENV_brass', (.515, .366, .153), .45, .7),
|
||||
'cloth': material('PR_Banner', (.9, .9, .9), .8),
|
||||
}
|
||||
groups = {}
|
||||
|
||||
|
||||
def add(group, name, vs, fs, kind, smooth=False):
|
||||
me = bpy.data.meshes.new(name)
|
||||
me.from_pydata([tuple(v) for v in vs], [], fs)
|
||||
me.update()
|
||||
me.materials.append(M[kind])
|
||||
for p in me.polygons:
|
||||
p.use_smooth = smooth
|
||||
ob = bpy.data.objects.new(name, me)
|
||||
bpy.context.collection.objects.link(ob)
|
||||
groups.setdefault(group, []).append(ob)
|
||||
return ob
|
||||
|
||||
|
||||
def box(group, name, c, size, kind, yaw=0.0):
|
||||
cx, cy, cz = c
|
||||
hx, hy, hz = size[0] / 2, size[1] / 2, size[2] / 2
|
||||
vs = []
|
||||
for dy in (-1, 1):
|
||||
for dz in (-1, 1):
|
||||
for dx in (-1, 1):
|
||||
x, z = dx * hx, dz * hz
|
||||
vs.append(G(cx + x * cos(yaw) - z * sin(yaw), cy + dy * hy, cz + x * sin(yaw) + z * cos(yaw)))
|
||||
return add(group, name, vs, [(0, 1, 3, 2), (4, 6, 7, 5), (0, 4, 5, 1), (2, 3, 7, 6), (0, 2, 6, 4), (1, 5, 7, 3)], kind)
|
||||
|
||||
|
||||
def lathe(group, name, profile, sides, kind, c=(0, 0, 0), jitter=0.0, seed=0.0, smooth=False):
|
||||
cx, cy, cz = c
|
||||
vs, fs = [], []
|
||||
for r, y in profile:
|
||||
for k in range(sides):
|
||||
a = 2 * pi * k / sides
|
||||
rr = r * (1 + jitter * noise.noise(Vector((cos(a) * 2, y * 1.3, sin(a) * 2 + seed))))
|
||||
vs.append(G(cx + cos(a) * rr, cy + y, cz + sin(a) * rr))
|
||||
n = len(profile)
|
||||
for j in range(n - 1):
|
||||
for k in range(sides):
|
||||
a, b = j * sides + k, j * sides + (k + 1) % sides
|
||||
fs.append((a, b, b + sides, a + sides))
|
||||
fs += [tuple(reversed(range(sides))), tuple(range((n - 1) * sides, n * sides))]
|
||||
return add(group, name, vs, fs, kind, smooth)
|
||||
|
||||
|
||||
def blob(group, name, c, size, kind, seed, subdiv=2, amp=.3, floor=None, smooth=False):
|
||||
bm = bmesh.new()
|
||||
bmesh.ops.create_icosphere(bm, subdivisions=subdiv, radius=1.0)
|
||||
cc = G(*c)
|
||||
for v in bm.verts:
|
||||
d = v.co.normalized()
|
||||
r = 1 + amp * noise.noise(d * 1.7 + Vector((seed, seed * .7, seed * .3)))
|
||||
gx, gy, gz = d.x * r * size[0], d.z * r * size[1], -d.y * r * size[2]
|
||||
if floor is not None and gy < floor * size[1]:
|
||||
gy = floor * size[1]
|
||||
v.co = cc + Vector((gx, -gz, gy))
|
||||
me = bpy.data.meshes.new(name)
|
||||
bm.to_mesh(me)
|
||||
bm.free()
|
||||
me.materials.append(M[kind])
|
||||
for p in me.polygons:
|
||||
p.use_smooth = smooth
|
||||
ob = bpy.data.objects.new(name, me)
|
||||
bpy.context.collection.objects.link(ob)
|
||||
groups.setdefault(group, []).append(ob)
|
||||
return ob
|
||||
|
||||
|
||||
def tube(group, name, points, radii, kind, sides=8, steps=10, seed=0.0, gnarl=0.0):
|
||||
pts = [G(*p) for p in points]
|
||||
vs, fs = [], []
|
||||
for j in range(steps + 1):
|
||||
t = j / steps
|
||||
seg = min(len(pts) - 2, int(t * (len(pts) - 1)))
|
||||
u = t * (len(pts) - 1) - seg
|
||||
p = pts[seg].lerp(pts[seg + 1], u)
|
||||
tangent = (pts[seg + 1] - pts[seg]).normalized()
|
||||
ref = Vector((0, 0, 1)) if abs(tangent.z) < .9 else Vector((1, 0, 0))
|
||||
a1 = tangent.cross(ref).normalized()
|
||||
a2 = tangent.cross(a1)
|
||||
rs = min(len(radii) - 2, int(t * (len(radii) - 1)))
|
||||
ru = t * (len(radii) - 1) - rs
|
||||
radius = radii[rs] * (1 - ru) + radii[rs + 1] * ru
|
||||
for k in range(sides):
|
||||
ang = 2 * pi * k / sides
|
||||
w = 1 + gnarl * noise.noise(Vector((cos(ang), t * 5, sin(ang) + seed)))
|
||||
vs.append(p + (a1 * cos(ang) + a2 * sin(ang)) * radius * w)
|
||||
for j in range(steps):
|
||||
for k in range(sides):
|
||||
a, b = j * sides + k, j * sides + (k + 1) % sides
|
||||
fs.append((a, b, b + sides, a + sides))
|
||||
fs += [tuple(reversed(range(sides))), tuple(range(steps * sides, (steps + 1) * sides))]
|
||||
return add(group, name, vs, fs, kind, True)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- bridge (spans local x, 11 m long, 7 m wide)
|
||||
# The simulation is flat: the deck sits at ground level so units walk on it, not inside it.
|
||||
L, Wd = 11.0, 7.0
|
||||
for i in range(12):
|
||||
x = -L / 2 + (i + .5) * L / 12
|
||||
box('Bridge', 'Deck_%d' % i, (x, .05, 0), (L / 12 + .02, .1, Wd), 'paving')
|
||||
for s_ in (-1, 1):
|
||||
box('Bridge', 'Parapet_%d_%d' % (i, s_), (x, .42, s_ * (Wd / 2 - .22)), (L / 12 + .03, .62, .38), 'limestone')
|
||||
for x in (-L / 2 + .4, -1.8, 1.8, L / 2 - .4):
|
||||
for s_ in (-1, 1):
|
||||
lathe('Bridge', 'Post_%d_%d' % (int(x * 10), s_), [(.32, 0), (.32, 1.05), (.26, 1.15), (.2, 1.3)], 6, 'limestone', (x, 0, s_ * (Wd / 2 - .22)))
|
||||
lathe('Bridge', 'Cap_%d_%d' % (int(x * 10), s_), [(.22, 0), (.22, .1), (.14, .16)], 6, 'brass', (x, 1.3, s_ * (Wd / 2 - .22)))
|
||||
for x in (-2.6, 2.6):
|
||||
for s_ in (-1, 1):
|
||||
box('Bridge', 'Pier_%d_%d' % (int(x), s_), (x, -.6, s_ * (Wd / 2 + .15)), (1.1, 1.4, .5), 'limestone')
|
||||
|
||||
# ---------------------------------------------------------------- curb stone (placed along lane edges)
|
||||
box('Curb', 'Curb', (0, .12, 0), (1.3, .26, .42), 'limestone')
|
||||
|
||||
# ---------------------------------------------------------------- trees
|
||||
for v, (h, seed) in enumerate([(3.8, 1.0), (4.6, 2.0), (3.2, 3.0)]):
|
||||
group = 'Pine_%d' % v
|
||||
tube(group, 'Trunk', [(0, 0, 0), (0, h * .55, 0), (0, h, 0)], [.24, .17, .08], 'bark', 8, 6, seed, .1)
|
||||
for k in range(5):
|
||||
y = h * (.28 + k * .15)
|
||||
r = (1.35 - k * .22) * (1 + .08 * v)
|
||||
lathe(group, 'Cone_%d' % k, [(r, y), (r * .75, y + .35), (.05, y + h * .26)], 9, ('leaf_dark', 'leaf_mid')[k % 2], (0, 0, 0), .12, seed + k)
|
||||
for v, (h, seed) in enumerate([(3.4, 4.0), (4.0, 5.0), (2.8, 6.0)]):
|
||||
group = 'Oak_%d' % v
|
||||
tube(group, 'Trunk', [(0, 0, 0), (.15, h * .5, .05), (-.1, h * .85, 0)], [.34, .24, .15], 'bark', 9, 8, seed, .15)
|
||||
for k in range(3):
|
||||
ang = k * 2.1 + seed
|
||||
tube(group, 'Branch_%d' % k, [(0, h * .55, 0), (cos(ang) * .9, h * .78, sin(ang) * .9)], [.13, .06], 'bark', 6, 4, seed + k, .1)
|
||||
for k in range(9):
|
||||
ang = k * 2.4 + seed
|
||||
rr = .55 + .5 * ((k * .618) % 1.0)
|
||||
s = .95 - .2 * ((k * .37) % 1.0)
|
||||
blob(group, 'Leaves_%d' % k, (cos(ang) * rr, h * .88 + .5 * ((k * .53) % 1.0), sin(ang) * rr), (s, s * .78, s),
|
||||
('leaf_mid', 'leaf_light', 'leaf_dark')[k % 3], seed * 10 + k, 2, .28)
|
||||
for k in range(4):
|
||||
ang = k * 1.57 + seed
|
||||
tube(group, 'Root_%d' % k, [(0, .25, 0), (cos(ang) * .7, .05, sin(ang) * .7)], [.14, .05], 'bark', 6, 4, seed + k)
|
||||
|
||||
# ---------------------------------------------------------------- rocks and shrubs
|
||||
for v, (size, seed) in enumerate([((1.2, .8, 1.0), 7.0), ((1.8, 1.1, 1.3), 8.0), ((.8, .5, .7), 9.0)]):
|
||||
group = 'Rock_%d' % v
|
||||
blob(group, 'Rock', (0, size[1] * .3, 0), size, 'cliff', seed, 2, .34, -.35)
|
||||
blob(group, 'Moss', (size[0] * .15, size[1] * .82, 0), (size[0] * .55, size[1] * .25, size[2] * .5), 'leaf_dark', seed + 1, 1, .3, -.2)
|
||||
for k in range(2):
|
||||
blob(group, 'Pebble_%d' % k, (size[0] * (.9 + .3 * k), .1, size[2] * (.5 - k)), (.28, .18, .24), 'limestone', seed + 3 + k, 1, .3, -.3)
|
||||
for v in range(2):
|
||||
blob('Shrub_%d' % v, 'Shrub', (0, .3, 0), (.8 + .3 * v, .55, .7 + .2 * v), ('leaf_mid', 'leaf_dark')[v], 11 + v, 2, .35, -.3)
|
||||
|
||||
# ---------------------------------------------------------------- banner (team colour at runtime via PR_Banner)
|
||||
lathe('Banner', 'Pole', [(.07, 0), (.07, 4.2), (.1, 4.3), (.02, 4.5)], 6, 'brass')
|
||||
vs, fs = [], []
|
||||
for j in range(6):
|
||||
for i in range(4):
|
||||
x = .08 + i * .35
|
||||
y = 4.1 - j * .45
|
||||
z = .08 * sin(i * 1.3 + j * .6)
|
||||
vs.append(G(x, y - (.25 * (i / 3) if j == 5 else 0), z))
|
||||
for j in range(5):
|
||||
for i in range(3):
|
||||
a = j * 4 + i
|
||||
fs.append((a, a + 1, a + 5, a + 4))
|
||||
add('Banner', 'Cloth', vs, fs, 'cloth', True)
|
||||
|
||||
# ---------------------------------------------------------------- edge cliffs (a 12 m wall segment, local x)
|
||||
for i in range(7):
|
||||
x = -6 + i * 2
|
||||
h = 3.4 + 1.6 * noise.noise(Vector((i * .7, 3.1, 0)))
|
||||
blob('EdgeCliff', 'Block_%d' % i, (x, h * .45, 0), (1.6, h * .6, 1.8), 'cliff', 20 + i, 2, .3, -.5)
|
||||
blob('EdgeCliff', 'Grass_%d' % i, (x, h * .85, -.3), (1.2, .35, 1.3), 'leaf_mid', 30 + i, 1, .3, -.2)
|
||||
|
||||
# Join each group into one mesh object per prop and triangulate.
|
||||
exported = []
|
||||
for group, objects in groups.items():
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
for ob in objects:
|
||||
ob.select_set(True)
|
||||
bpy.context.view_layer.objects.active = objects[0]
|
||||
bpy.ops.object.join()
|
||||
joined = bpy.context.object
|
||||
joined.name = group
|
||||
bm = bmesh.new()
|
||||
bm.from_mesh(joined.data)
|
||||
bmesh.ops.triangulate(bm, faces=list(bm.faces))
|
||||
bm.to_mesh(joined.data)
|
||||
bm.free()
|
||||
exported.append(joined)
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
for ob in exported:
|
||||
ob.select_set(True)
|
||||
bpy.ops.wm.save_as_mainfile(filepath=str(SRC / 'map_props.blend'))
|
||||
bpy.ops.export_scene.gltf(filepath=str(OUT / 'map_props.glb'), export_format='GLB', use_selection=True,
|
||||
export_materials='EXPORT', export_yup=True, export_animations=False)
|
||||
raw = (OUT / 'map_props.glb').read_bytes()
|
||||
doc = json.loads(raw[20:20 + struct.unpack_from('<I', raw, 12)[0]])
|
||||
counts = {m['name']: sum(doc['accessors'][q['indices']]['count'] // 3 for q in m['primitives']) for m in doc['meshes']}
|
||||
(OUT / 'map_props_manifest.json').write_text(json.dumps({'assets': [{'id': 'map_props', 'resource_path': 'res://assets/luneraria/map_props.glb',
|
||||
'source': 'assets-source/luneraria/map_props.blend', 'props': counts, 'sha256': hashlib.sha256(raw).hexdigest()}]}, indent=2) + '\n')
|
||||
print('MAP_PROPS_BUILD', counts, flush=True)
|
||||
1457
assets-source/luneraria/build_peoples.py
Normal file
1457
assets-source/luneraria/build_peoples.py
Normal file
File diff suppressed because it is too large
Load diff
144
assets-source/luneraria/build_tower.py
Normal file
144
assets-source/luneraria/build_tower.py
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
"""Lane tower for Champions of Luneraria: stone plinth, tapered shaft with brass bands,
|
||||
crenellated platform and a hovering crystal. The crystal material (TW_Crystal) is tinted
|
||||
per team at runtime; stone surfaces use the Kluft material names (ENV_*).
|
||||
|
||||
Run: ALSOFT_DRIVERS=null blender -b --python-exit-code 1 --python assets-source/luneraria/build_tower.py
|
||||
Godot coordinates are written through G(x, y, z) (x right, y up, z towards the viewer).
|
||||
"""
|
||||
from pathlib import Path
|
||||
import bpy, bmesh, json, hashlib, struct
|
||||
from math import sin, cos, pi
|
||||
from mathutils import Vector, noise
|
||||
|
||||
P = Path(__file__).resolve().parents[2]
|
||||
SRC = Path(__file__).resolve().parent
|
||||
OUT = P / 'assets/luneraria'
|
||||
OUT.mkdir(parents=True, exist_ok=True)
|
||||
bpy.ops.wm.read_factory_settings(use_empty=True)
|
||||
bpy.context.preferences.filepaths.save_version = 0
|
||||
parts = []
|
||||
|
||||
|
||||
def G(x, y, z):
|
||||
return Vector((x, -z, y))
|
||||
|
||||
|
||||
def material(name, color, rough=.9, metal=0.0, emission=0.0):
|
||||
m = bpy.data.materials.new(name)
|
||||
m.diffuse_color = (*color, 1)
|
||||
m.use_nodes = True
|
||||
bs = m.node_tree.nodes.get('Principled BSDF')
|
||||
bs.inputs['Base Color'].default_value = (*color, 1)
|
||||
bs.inputs['Roughness'].default_value = rough
|
||||
bs.inputs['Metallic'].default_value = metal
|
||||
if emission:
|
||||
bs.inputs['Emission Color'].default_value = (*color, 1)
|
||||
bs.inputs['Emission Strength'].default_value = emission
|
||||
return m
|
||||
|
||||
|
||||
M = {
|
||||
'stone': material('ENV_limestone', (.283, .246, .178)),
|
||||
'dark': material('ENV_cliff', (.133, .153, .138)),
|
||||
'paving': material('ENV_paving', (.162, .171, .136), .92),
|
||||
'brass': material('ENV_brass', (.515, .366, .153), .45, .7),
|
||||
'crystal': material('TW_Crystal', (.55, .8, 1.0), .15, 0, 2.5),
|
||||
}
|
||||
|
||||
|
||||
def obj(name, vs, fs, kind, smooth=False):
|
||||
me = bpy.data.meshes.new(name)
|
||||
me.from_pydata([tuple(v) for v in vs], [], fs)
|
||||
me.update()
|
||||
me.materials.append(M[kind])
|
||||
for p in me.polygons:
|
||||
p.use_smooth = smooth
|
||||
ob = bpy.data.objects.new(name, me)
|
||||
bpy.context.collection.objects.link(ob)
|
||||
parts.append(ob)
|
||||
return ob
|
||||
|
||||
|
||||
def lathe(name, profile, sides, kind, center=(0, 0, 0), rotation=0.0, jitter=0.0, seed=0):
|
||||
cx, cy, cz = center
|
||||
vs, fs = [], []
|
||||
for j, (r, y) in enumerate(profile):
|
||||
for k in range(sides):
|
||||
a = 2 * pi * k / sides + rotation
|
||||
rr = r * (1 + jitter * noise.noise(Vector((cos(a) * 3, y * 2, sin(a) * 3 + seed))))
|
||||
vs.append(G(cx + cos(a) * rr, cy + y, cz + sin(a) * rr))
|
||||
n = len(profile)
|
||||
for j in range(n - 1):
|
||||
for k in range(sides):
|
||||
a, b = j * sides + k, j * sides + (k + 1) % sides
|
||||
fs.append((a, b, b + sides, a + sides))
|
||||
fs += [tuple(reversed(range(sides))), tuple(range((n - 1) * sides, n * sides))]
|
||||
return obj(name, vs, fs, kind)
|
||||
|
||||
|
||||
def box(name, center, size, yaw, kind):
|
||||
cx, cy, cz = center
|
||||
hx, hy, hz = size[0] / 2, size[1] / 2, size[2] / 2
|
||||
vs = []
|
||||
for dy in (-1, 1):
|
||||
for dz in (-1, 1):
|
||||
for dx in (-1, 1):
|
||||
x, z = dx * hx, dz * hz
|
||||
vs.append(G(cx + x * cos(yaw) - z * sin(yaw), cy + dy * hy, cz + x * sin(yaw) + z * cos(yaw)))
|
||||
return obj(name, vs, [(0, 1, 3, 2), (4, 6, 7, 5), (0, 4, 5, 1), (2, 3, 7, 6), (0, 2, 6, 4), (1, 5, 7, 3)], kind)
|
||||
|
||||
|
||||
# Plinth: two stepped octagons of dark stone with a paving top.
|
||||
lathe('Plinth', [(1.65, 0.0), (1.65, .28), (1.45, .34), (1.45, .52), (1.3, .58)], 8, 'dark', rotation=pi / 8, jitter=.03, seed=1)
|
||||
lathe('Plinth_Top', [(1.28, .57), (1.28, .62)], 8, 'paving', rotation=pi / 8)
|
||||
# Shaft: tapered, slightly irregular limestone blocks.
|
||||
shaft = [(1.02, .6), (.98, 1.4), (.9, 2.4), (.84, 3.2), (.9, 3.4)]
|
||||
lathe('Shaft', shaft, 10, 'stone', rotation=pi / 10, jitter=.025, seed=2)
|
||||
for h in (1.05, 2.25, 3.25):
|
||||
r = .99 - (h - .6) * .05
|
||||
lathe('Band_%d' % int(h * 10), [(r + .06, h - .07), (r + .06, h + .07)], 10, 'brass', rotation=pi / 10)
|
||||
# Platform with crenellations.
|
||||
lathe('Platform', [(.95, 3.35), (1.25, 3.6), (1.25, 3.85), (1.1, 3.9)], 10, 'stone', rotation=pi / 10, jitter=.02, seed=3)
|
||||
for k in range(10):
|
||||
a = 2 * pi * (k + .5) / 10
|
||||
box('Merlon_%d' % k, (cos(a) * 1.08, 4.08, sin(a) * 1.08), (.42, .42, .26), -a + pi / 2, 'stone')
|
||||
# Crystal cradle: four brass prongs and a hovering bipyramid crystal.
|
||||
for k in range(4):
|
||||
a = pi / 4 + k * pi / 2
|
||||
pts = [(cos(a) * .55, 3.9, sin(a) * .55), (cos(a) * .42, 4.55, sin(a) * .42), (cos(a) * .22, 5.0, sin(a) * .22)]
|
||||
for i in range(2):
|
||||
p0, p1 = Vector(pts[i]), Vector(pts[i + 1])
|
||||
mid = (p0 + p1) / 2
|
||||
d = p1 - p0
|
||||
box('Prong_%d_%d' % (k, i), tuple(mid), (.09, d.length + .05, .09), 0, 'brass')
|
||||
crystal = [G(0, 5.95, 0)] + [G(cos(2 * pi * k / 6) * .36, 5.05, sin(2 * pi * k / 6) * .36) for k in range(6)] + [G(0, 4.45, 0)]
|
||||
cf = [(0, 1 + k, 1 + (k + 1) % 6) for k in range(6)] + [(7, 1 + (k + 1) % 6, 1 + k) for k in range(6)]
|
||||
obj('Crystal', crystal, cf, 'crystal')
|
||||
# A small door and window slits keep the scale readable from the game camera.
|
||||
box('Door', (0, .95, 1.0), (.5, .75, .12), 0, 'dark')
|
||||
for k, h in enumerate((1.7, 2.7)):
|
||||
box('Slit_%d' % k, (0, h, .93 - (h - 1.7) * .05), (.14, .42, .1), 0, 'dark')
|
||||
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
for ob in parts:
|
||||
ob.select_set(True)
|
||||
bpy.context.view_layer.objects.active = parts[0]
|
||||
bpy.ops.object.join()
|
||||
tower = bpy.context.object
|
||||
tower.name = 'LaneTower'
|
||||
bm = bmesh.new()
|
||||
bm.from_mesh(tower.data)
|
||||
bmesh.ops.triangulate(bm, faces=list(bm.faces))
|
||||
bm.to_mesh(tower.data)
|
||||
bm.free()
|
||||
bpy.ops.wm.save_as_mainfile(filepath=str(SRC / 'tower.blend'))
|
||||
bpy.ops.export_scene.gltf(filepath=str(OUT / 'tower.glb'), export_format='GLB', use_selection=True,
|
||||
export_materials='EXPORT', export_yup=True, export_animations=False)
|
||||
raw = (OUT / 'tower.glb').read_bytes()
|
||||
doc = json.loads(raw[20:20 + struct.unpack_from('<I', raw, 12)[0]])
|
||||
triangles = sum(doc['accessors'][q['indices']]['count'] // 3 for m in doc['meshes'] for q in m['primitives'])
|
||||
(P / 'assets/luneraria/tower_manifest.json').write_text(json.dumps({'assets': [{
|
||||
'id': 'lane_tower', 'resource_path': 'res://assets/luneraria/tower.glb', 'source': 'assets-source/luneraria/tower.blend',
|
||||
'triangles': triangles, 'height': 5.95, 'sha256': hashlib.sha256(raw).hexdigest(),
|
||||
'materials': [m['name'] for m in doc['materials']]}]}, indent=2) + '\n')
|
||||
print('TOWER_BUILD', triangles, 'triangles', flush=True)
|
||||
BIN
assets-source/luneraria/grotto.blend
Normal file
BIN
assets-source/luneraria/grotto.blend
Normal file
Binary file not shown.
BIN
assets-source/luneraria/map_props.blend
Normal file
BIN
assets-source/luneraria/map_props.blend
Normal file
Binary file not shown.
245
assets-source/luneraria/peoples-audit.json
Normal file
245
assets-source/luneraria/peoples-audit.json
Normal file
|
|
@ -0,0 +1,245 @@
|
|||
{
|
||||
"figures": [
|
||||
{
|
||||
"id": "p_mensch",
|
||||
"source_parts": 84,
|
||||
"exported_clips": [
|
||||
"ability",
|
||||
"attack_a",
|
||||
"attack_b",
|
||||
"death",
|
||||
"hit",
|
||||
"idle",
|
||||
"start",
|
||||
"stop",
|
||||
"walk"
|
||||
],
|
||||
"skins": 1,
|
||||
"materials": [
|
||||
"LP_Mensch_Cloth",
|
||||
"LP_Mensch_Skin",
|
||||
"LP_Mensch_Metal",
|
||||
"LP_Mensch_TrimMetal",
|
||||
"LP_Mensch_Leather",
|
||||
"LP_Mensch_Dark",
|
||||
"LP_Mensch_ClothAccent"
|
||||
],
|
||||
"max_wrist_contact_error_m": 0.0,
|
||||
"worst_sample": [
|
||||
"walk",
|
||||
1.1,
|
||||
"R"
|
||||
],
|
||||
"samples": 696,
|
||||
"contact_validation": "Analytic two-bone arm IK against the grip bones, baked at 30 Hz for all nine clips."
|
||||
},
|
||||
{
|
||||
"id": "p_elf",
|
||||
"source_parts": 89,
|
||||
"exported_clips": [
|
||||
"ability",
|
||||
"attack_a",
|
||||
"attack_b",
|
||||
"death",
|
||||
"hit",
|
||||
"idle",
|
||||
"start",
|
||||
"stop",
|
||||
"walk"
|
||||
],
|
||||
"skins": 1,
|
||||
"materials": [
|
||||
"LP_Elf_Leather",
|
||||
"LP_Elf_Skin",
|
||||
"LP_Elf_Cloth",
|
||||
"LP_Elf_ClothAccent",
|
||||
"LP_Elf_TrimMetal",
|
||||
"LP_Elf_Dark",
|
||||
"LP_Elf_Hair",
|
||||
"LP_Elf_Glow",
|
||||
"LP_Elf_Wood"
|
||||
],
|
||||
"max_wrist_contact_error_m": 0.0,
|
||||
"worst_sample": [
|
||||
"walk",
|
||||
1.1,
|
||||
"R"
|
||||
],
|
||||
"samples": 696,
|
||||
"contact_validation": "Analytic two-bone arm IK against the grip bones, baked at 30 Hz for all nine clips."
|
||||
},
|
||||
{
|
||||
"id": "p_zwerg",
|
||||
"source_parts": 91,
|
||||
"exported_clips": [
|
||||
"ability",
|
||||
"attack_a",
|
||||
"attack_b",
|
||||
"death",
|
||||
"hit",
|
||||
"idle",
|
||||
"start",
|
||||
"stop",
|
||||
"walk"
|
||||
],
|
||||
"skins": 1,
|
||||
"materials": [
|
||||
"LP_Zwerg_Cloth",
|
||||
"LP_Zwerg_Skin",
|
||||
"LP_Zwerg_Leather",
|
||||
"LP_Zwerg_Metal",
|
||||
"LP_Zwerg_TrimMetal",
|
||||
"LP_Zwerg_Dark",
|
||||
"LP_Zwerg_Hair",
|
||||
"LP_Zwerg_Bone",
|
||||
"LP_Zwerg_Wood",
|
||||
"LP_Zwerg_Glow"
|
||||
],
|
||||
"max_wrist_contact_error_m": 0.0,
|
||||
"worst_sample": [
|
||||
"walk",
|
||||
1.1,
|
||||
"R"
|
||||
],
|
||||
"samples": 696,
|
||||
"contact_validation": "Analytic two-bone arm IK against the grip bones, baked at 30 Hz for all nine clips."
|
||||
},
|
||||
{
|
||||
"id": "p_troll",
|
||||
"source_parts": 72,
|
||||
"exported_clips": [
|
||||
"ability",
|
||||
"attack_a",
|
||||
"attack_b",
|
||||
"death",
|
||||
"hit",
|
||||
"idle",
|
||||
"start",
|
||||
"stop",
|
||||
"walk"
|
||||
],
|
||||
"skins": 1,
|
||||
"materials": [
|
||||
"LP_Troll_Skin",
|
||||
"LP_Troll_Leather",
|
||||
"LP_Troll_Bone",
|
||||
"LP_Troll_Stone",
|
||||
"LP_Troll_EyeGlow",
|
||||
"LP_Troll_Hair",
|
||||
"LP_Troll_Wood"
|
||||
],
|
||||
"max_wrist_contact_error_m": 0.06613055871718698,
|
||||
"worst_sample": [
|
||||
"ability",
|
||||
1.1,
|
||||
"L"
|
||||
],
|
||||
"samples": 696,
|
||||
"contact_validation": "Analytic two-bone arm IK against the grip bones, baked at 30 Hz for all nine clips."
|
||||
},
|
||||
{
|
||||
"id": "p_fee",
|
||||
"source_parts": 72,
|
||||
"exported_clips": [
|
||||
"ability",
|
||||
"attack_a",
|
||||
"attack_b",
|
||||
"death",
|
||||
"hit",
|
||||
"idle",
|
||||
"start",
|
||||
"stop",
|
||||
"walk"
|
||||
],
|
||||
"skins": 1,
|
||||
"materials": [
|
||||
"LP_Fee_ClothAccent",
|
||||
"LP_Fee_Skin",
|
||||
"LP_Fee_Cloth",
|
||||
"LP_Fee_TrimMetal",
|
||||
"LP_Fee_Dark",
|
||||
"LP_Fee_Hair",
|
||||
"LP_Fee_Glow",
|
||||
"LP_Fee_Wood"
|
||||
],
|
||||
"max_wrist_contact_error_m": 0.0,
|
||||
"worst_sample": [
|
||||
"walk",
|
||||
1.1,
|
||||
"R"
|
||||
],
|
||||
"samples": 696,
|
||||
"contact_validation": "Analytic two-bone arm IK against the grip bones, baked at 30 Hz for all nine clips."
|
||||
},
|
||||
{
|
||||
"id": "p_ork",
|
||||
"source_parts": 84,
|
||||
"exported_clips": [
|
||||
"ability",
|
||||
"attack_a",
|
||||
"attack_b",
|
||||
"death",
|
||||
"hit",
|
||||
"idle",
|
||||
"start",
|
||||
"stop",
|
||||
"walk"
|
||||
],
|
||||
"skins": 1,
|
||||
"materials": [
|
||||
"LP_Ork_Skin",
|
||||
"LP_Ork_Leather",
|
||||
"LP_Ork_Metal",
|
||||
"LP_Ork_TrimMetal",
|
||||
"LP_Ork_Bone",
|
||||
"LP_Ork_Fur",
|
||||
"LP_Ork_Dark",
|
||||
"LP_Ork_Hair",
|
||||
"LP_Ork_Wood"
|
||||
],
|
||||
"max_wrist_contact_error_m": 0.0,
|
||||
"worst_sample": [
|
||||
"walk",
|
||||
1.1,
|
||||
"R"
|
||||
],
|
||||
"samples": 696,
|
||||
"contact_validation": "Analytic two-bone arm IK against the grip bones, baked at 30 Hz for all nine clips."
|
||||
},
|
||||
{
|
||||
"id": "p_biest",
|
||||
"source_parts": 82,
|
||||
"exported_clips": [
|
||||
"ability",
|
||||
"attack_a",
|
||||
"attack_b",
|
||||
"death",
|
||||
"hit",
|
||||
"idle",
|
||||
"start",
|
||||
"stop",
|
||||
"walk"
|
||||
],
|
||||
"skins": 1,
|
||||
"materials": [
|
||||
"LP_Biest_Fur",
|
||||
"LP_Biest_FurLight",
|
||||
"LP_Biest_Leather",
|
||||
"LP_Biest_Metal",
|
||||
"LP_Biest_Cloth",
|
||||
"LP_Biest_Bone",
|
||||
"LP_Biest_Dark",
|
||||
"LP_Biest_EyeGlow",
|
||||
"LP_Biest_Skin"
|
||||
],
|
||||
"max_wrist_contact_error_m": 0.0,
|
||||
"worst_sample": [
|
||||
"walk",
|
||||
1.1,
|
||||
"R"
|
||||
],
|
||||
"samples": 696,
|
||||
"contact_validation": "Analytic two-bone arm IK against the grip bones, baked at 30 Hz for all nine clips."
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
assets-source/luneraria/peoples/p_biest.blend
Normal file
BIN
assets-source/luneraria/peoples/p_biest.blend
Normal file
Binary file not shown.
BIN
assets-source/luneraria/peoples/p_elf.blend
Normal file
BIN
assets-source/luneraria/peoples/p_elf.blend
Normal file
Binary file not shown.
BIN
assets-source/luneraria/peoples/p_fee.blend
Normal file
BIN
assets-source/luneraria/peoples/p_fee.blend
Normal file
Binary file not shown.
BIN
assets-source/luneraria/peoples/p_mensch.blend
Normal file
BIN
assets-source/luneraria/peoples/p_mensch.blend
Normal file
Binary file not shown.
BIN
assets-source/luneraria/peoples/p_ork.blend
Normal file
BIN
assets-source/luneraria/peoples/p_ork.blend
Normal file
Binary file not shown.
BIN
assets-source/luneraria/peoples/p_troll.blend
Normal file
BIN
assets-source/luneraria/peoples/p_troll.blend
Normal file
Binary file not shown.
BIN
assets-source/luneraria/peoples/p_zwerg.blend
Normal file
BIN
assets-source/luneraria/peoples/p_zwerg.blend
Normal file
Binary file not shown.
BIN
assets-source/luneraria/tower.blend
Normal file
BIN
assets-source/luneraria/tower.blend
Normal file
Binary file not shown.
40
assets/ChatGPT-Bild 27. Sept. 2026, 19_46_52-1.png.import
Normal file
40
assets/ChatGPT-Bild 27. Sept. 2026, 19_46_52-1.png.import
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://cdyqe8uxp766t"
|
||||
path="res://.godot/imported/ChatGPT-Bild 27. Sept. 2026, 19_46_52-1.png-2d037606185a25aabd1841674c9a8676.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/ChatGPT-Bild 27. Sept. 2026, 19_46_52-1.png"
|
||||
dest_files=["res://.godot/imported/ChatGPT-Bild 27. Sept. 2026, 19_46_52-1.png-2d037606185a25aabd1841674c9a8676.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
40
assets/ChatGPT-Bild 27. Sept. 2026, 19_46_52-2.png.import
Normal file
40
assets/ChatGPT-Bild 27. Sept. 2026, 19_46_52-2.png.import
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://cm5ok6wwo5k4c"
|
||||
path="res://.godot/imported/ChatGPT-Bild 27. Sept. 2026, 19_46_52-2.png-ad15328ef82598f8d29650086961c8e2.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/ChatGPT-Bild 27. Sept. 2026, 19_46_52-2.png"
|
||||
dest_files=["res://.godot/imported/ChatGPT-Bild 27. Sept. 2026, 19_46_52-2.png-ad15328ef82598f8d29650086961c8e2.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
40
assets/ChatGPT-Bild 27. Sept. 2026, 19_46_53-3.png.import
Normal file
40
assets/ChatGPT-Bild 27. Sept. 2026, 19_46_53-3.png.import
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bjtulyxjl22dy"
|
||||
path="res://.godot/imported/ChatGPT-Bild 27. Sept. 2026, 19_46_53-3.png-7e556551f7b3efde4bca6a6f73eb8860.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/ChatGPT-Bild 27. Sept. 2026, 19_46_53-3.png"
|
||||
dest_files=["res://.godot/imported/ChatGPT-Bild 27. Sept. 2026, 19_46_53-3.png-7e556551f7b3efde4bca6a6f73eb8860.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
assets/luneraria/grotto.glb
Normal file
BIN
assets/luneraria/grotto.glb
Normal file
Binary file not shown.
45
assets/luneraria/grotto.glb.import
Normal file
45
assets/luneraria/grotto.glb.import
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
[remap]
|
||||
|
||||
importer="scene"
|
||||
importer_version=1
|
||||
type="PackedScene"
|
||||
uid="uid://g2wd2l3wkvb7"
|
||||
path="res://.godot/imported/grotto.glb-415ef169549c859f990847e218fcf14a.scn"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/luneraria/grotto.glb"
|
||||
dest_files=["res://.godot/imported/grotto.glb-415ef169549c859f990847e218fcf14a.scn"]
|
||||
|
||||
[params]
|
||||
|
||||
nodes/root_type=""
|
||||
nodes/root_name=""
|
||||
nodes/root_script=null
|
||||
mesh_library/use_node_names_as_mesh_names=false
|
||||
array_mesh/deduplicate_surfaces=true
|
||||
nodes/apply_root_scale=true
|
||||
nodes/root_scale=1.0
|
||||
nodes/import_as_skeleton_bones=false
|
||||
nodes/use_name_suffixes=true
|
||||
nodes/use_node_type_suffixes=true
|
||||
meshes/ensure_tangents=true
|
||||
meshes/generate_lods=true
|
||||
meshes/create_shadow_meshes=true
|
||||
meshes/light_baking=1
|
||||
meshes/lightmap_texel_size=0.2
|
||||
meshes/force_disable_compression=false
|
||||
skins/use_named_skins=true
|
||||
animation/import=true
|
||||
animation/fps=30
|
||||
animation/trimming=false
|
||||
animation/remove_immutable_tracks=true
|
||||
animation/import_rest_as_RESET=false
|
||||
import_script/path=""
|
||||
materials/extract=0
|
||||
materials/extract_format=0
|
||||
materials/extract_path=""
|
||||
_subresources={}
|
||||
gltf/naming_version=2
|
||||
gltf/embedded_image_handling=1
|
||||
gltf/texture_map_mode=1
|
||||
18
assets/luneraria/grotto_manifest.json
Normal file
18
assets/luneraria/grotto_manifest.json
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"assets": [
|
||||
{
|
||||
"id": "boss_grotto",
|
||||
"resource_path": "res://assets/luneraria/grotto.glb",
|
||||
"source": "assets-source/luneraria/grotto.blend",
|
||||
"triangles": 1888,
|
||||
"sha256": "92e7a4b4c98ebafb167523fb2816d91e997add201bf223ab6e9c8326bf77daf9",
|
||||
"materials": [
|
||||
"ENV_soil",
|
||||
"ENV_cliff",
|
||||
"GR_Shadow",
|
||||
"GR_Crystal",
|
||||
"ENV_limestone"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
assets/luneraria/map_props.glb
Normal file
BIN
assets/luneraria/map_props.glb
Normal file
Binary file not shown.
45
assets/luneraria/map_props.glb.import
Normal file
45
assets/luneraria/map_props.glb.import
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
[remap]
|
||||
|
||||
importer="scene"
|
||||
importer_version=1
|
||||
type="PackedScene"
|
||||
uid="uid://bdygvqh1lru4a"
|
||||
path="res://.godot/imported/map_props.glb-ee8d7dcb8819cf2777bc63c68f327e1d.scn"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/luneraria/map_props.glb"
|
||||
dest_files=["res://.godot/imported/map_props.glb-ee8d7dcb8819cf2777bc63c68f327e1d.scn"]
|
||||
|
||||
[params]
|
||||
|
||||
nodes/root_type=""
|
||||
nodes/root_name=""
|
||||
nodes/root_script=null
|
||||
mesh_library/use_node_names_as_mesh_names=false
|
||||
array_mesh/deduplicate_surfaces=true
|
||||
nodes/apply_root_scale=true
|
||||
nodes/root_scale=1.0
|
||||
nodes/import_as_skeleton_bones=false
|
||||
nodes/use_name_suffixes=true
|
||||
nodes/use_node_type_suffixes=true
|
||||
meshes/ensure_tangents=true
|
||||
meshes/generate_lods=true
|
||||
meshes/create_shadow_meshes=true
|
||||
meshes/light_baking=1
|
||||
meshes/lightmap_texel_size=0.2
|
||||
meshes/force_disable_compression=false
|
||||
skins/use_named_skins=true
|
||||
animation/import=true
|
||||
animation/fps=30
|
||||
animation/trimming=false
|
||||
animation/remove_immutable_tracks=true
|
||||
animation/import_rest_as_RESET=false
|
||||
import_script/path=""
|
||||
materials/extract=0
|
||||
materials/extract_format=0
|
||||
materials/extract_path=""
|
||||
_subresources={}
|
||||
gltf/naming_version=2
|
||||
gltf/embedded_image_handling=1
|
||||
gltf/texture_map_mode=1
|
||||
27
assets/luneraria/map_props_manifest.json
Normal file
27
assets/luneraria/map_props_manifest.json
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"assets": [
|
||||
{
|
||||
"id": "map_props",
|
||||
"resource_path": "res://assets/luneraria/map_props.glb",
|
||||
"source": "assets-source/luneraria/map_props.blend",
|
||||
"props": {
|
||||
"Pole": 74,
|
||||
"Deck_0": 1088,
|
||||
"Curb": 12,
|
||||
"Block_0": 700,
|
||||
"Trunk.003": 1270,
|
||||
"Trunk.004": 1270,
|
||||
"Trunk.005": 1270,
|
||||
"Trunk": 358,
|
||||
"Trunk.001": 358,
|
||||
"Trunk.002": 358,
|
||||
"Rock": 140,
|
||||
"Rock.001": 140,
|
||||
"Rock.002": 140,
|
||||
"Shrub": 80,
|
||||
"Shrub.001": 80
|
||||
},
|
||||
"sha256": "d997546df3d537dae03ff5d8925f0af9457c3cc5ee63b6f20018baa994e8ff9d"
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
assets/luneraria/peoples/p_biest.glb
Normal file
BIN
assets/luneraria/peoples/p_biest.glb
Normal file
Binary file not shown.
45
assets/luneraria/peoples/p_biest.glb.import
Normal file
45
assets/luneraria/peoples/p_biest.glb.import
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
[remap]
|
||||
|
||||
importer="scene"
|
||||
importer_version=1
|
||||
type="PackedScene"
|
||||
uid="uid://vlty7tphfgnx"
|
||||
path="res://.godot/imported/p_biest.glb-8e5e6e1fa11c916fb2bef94a33cda329.scn"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/luneraria/peoples/p_biest.glb"
|
||||
dest_files=["res://.godot/imported/p_biest.glb-8e5e6e1fa11c916fb2bef94a33cda329.scn"]
|
||||
|
||||
[params]
|
||||
|
||||
nodes/root_type=""
|
||||
nodes/root_name=""
|
||||
nodes/root_script=null
|
||||
mesh_library/use_node_names_as_mesh_names=false
|
||||
array_mesh/deduplicate_surfaces=true
|
||||
nodes/apply_root_scale=true
|
||||
nodes/root_scale=1.0
|
||||
nodes/import_as_skeleton_bones=false
|
||||
nodes/use_name_suffixes=true
|
||||
nodes/use_node_type_suffixes=true
|
||||
meshes/ensure_tangents=true
|
||||
meshes/generate_lods=true
|
||||
meshes/create_shadow_meshes=true
|
||||
meshes/light_baking=1
|
||||
meshes/lightmap_texel_size=0.2
|
||||
meshes/force_disable_compression=false
|
||||
skins/use_named_skins=true
|
||||
animation/import=true
|
||||
animation/fps=30
|
||||
animation/trimming=false
|
||||
animation/remove_immutable_tracks=true
|
||||
animation/import_rest_as_RESET=false
|
||||
import_script/path=""
|
||||
materials/extract=0
|
||||
materials/extract_format=0
|
||||
materials/extract_path=""
|
||||
_subresources={}
|
||||
gltf/naming_version=2
|
||||
gltf/embedded_image_handling=1
|
||||
gltf/texture_map_mode=1
|
||||
BIN
assets/luneraria/peoples/p_elf.glb
Normal file
BIN
assets/luneraria/peoples/p_elf.glb
Normal file
Binary file not shown.
45
assets/luneraria/peoples/p_elf.glb.import
Normal file
45
assets/luneraria/peoples/p_elf.glb.import
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
[remap]
|
||||
|
||||
importer="scene"
|
||||
importer_version=1
|
||||
type="PackedScene"
|
||||
uid="uid://pw4ristm1wtt"
|
||||
path="res://.godot/imported/p_elf.glb-d890d18acc6c79e79d4b8598982a53f2.scn"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/luneraria/peoples/p_elf.glb"
|
||||
dest_files=["res://.godot/imported/p_elf.glb-d890d18acc6c79e79d4b8598982a53f2.scn"]
|
||||
|
||||
[params]
|
||||
|
||||
nodes/root_type=""
|
||||
nodes/root_name=""
|
||||
nodes/root_script=null
|
||||
mesh_library/use_node_names_as_mesh_names=false
|
||||
array_mesh/deduplicate_surfaces=true
|
||||
nodes/apply_root_scale=true
|
||||
nodes/root_scale=1.0
|
||||
nodes/import_as_skeleton_bones=false
|
||||
nodes/use_name_suffixes=true
|
||||
nodes/use_node_type_suffixes=true
|
||||
meshes/ensure_tangents=true
|
||||
meshes/generate_lods=true
|
||||
meshes/create_shadow_meshes=true
|
||||
meshes/light_baking=1
|
||||
meshes/lightmap_texel_size=0.2
|
||||
meshes/force_disable_compression=false
|
||||
skins/use_named_skins=true
|
||||
animation/import=true
|
||||
animation/fps=30
|
||||
animation/trimming=false
|
||||
animation/remove_immutable_tracks=true
|
||||
animation/import_rest_as_RESET=false
|
||||
import_script/path=""
|
||||
materials/extract=0
|
||||
materials/extract_format=0
|
||||
materials/extract_path=""
|
||||
_subresources={}
|
||||
gltf/naming_version=2
|
||||
gltf/embedded_image_handling=1
|
||||
gltf/texture_map_mode=1
|
||||
BIN
assets/luneraria/peoples/p_fee.glb
Normal file
BIN
assets/luneraria/peoples/p_fee.glb
Normal file
Binary file not shown.
45
assets/luneraria/peoples/p_fee.glb.import
Normal file
45
assets/luneraria/peoples/p_fee.glb.import
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
[remap]
|
||||
|
||||
importer="scene"
|
||||
importer_version=1
|
||||
type="PackedScene"
|
||||
uid="uid://biourdwo5b8lq"
|
||||
path="res://.godot/imported/p_fee.glb-84ebd920f33b8ac4eaaa887665f7685d.scn"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/luneraria/peoples/p_fee.glb"
|
||||
dest_files=["res://.godot/imported/p_fee.glb-84ebd920f33b8ac4eaaa887665f7685d.scn"]
|
||||
|
||||
[params]
|
||||
|
||||
nodes/root_type=""
|
||||
nodes/root_name=""
|
||||
nodes/root_script=null
|
||||
mesh_library/use_node_names_as_mesh_names=false
|
||||
array_mesh/deduplicate_surfaces=true
|
||||
nodes/apply_root_scale=true
|
||||
nodes/root_scale=1.0
|
||||
nodes/import_as_skeleton_bones=false
|
||||
nodes/use_name_suffixes=true
|
||||
nodes/use_node_type_suffixes=true
|
||||
meshes/ensure_tangents=true
|
||||
meshes/generate_lods=true
|
||||
meshes/create_shadow_meshes=true
|
||||
meshes/light_baking=1
|
||||
meshes/lightmap_texel_size=0.2
|
||||
meshes/force_disable_compression=false
|
||||
skins/use_named_skins=true
|
||||
animation/import=true
|
||||
animation/fps=30
|
||||
animation/trimming=false
|
||||
animation/remove_immutable_tracks=true
|
||||
animation/import_rest_as_RESET=false
|
||||
import_script/path=""
|
||||
materials/extract=0
|
||||
materials/extract_format=0
|
||||
materials/extract_path=""
|
||||
_subresources={}
|
||||
gltf/naming_version=2
|
||||
gltf/embedded_image_handling=1
|
||||
gltf/texture_map_mode=1
|
||||
BIN
assets/luneraria/peoples/p_mensch.glb
Normal file
BIN
assets/luneraria/peoples/p_mensch.glb
Normal file
Binary file not shown.
45
assets/luneraria/peoples/p_mensch.glb.import
Normal file
45
assets/luneraria/peoples/p_mensch.glb.import
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
[remap]
|
||||
|
||||
importer="scene"
|
||||
importer_version=1
|
||||
type="PackedScene"
|
||||
uid="uid://irnp3eyfc180"
|
||||
path="res://.godot/imported/p_mensch.glb-39d67a910d0ef6afd640de8d0f7f2922.scn"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/luneraria/peoples/p_mensch.glb"
|
||||
dest_files=["res://.godot/imported/p_mensch.glb-39d67a910d0ef6afd640de8d0f7f2922.scn"]
|
||||
|
||||
[params]
|
||||
|
||||
nodes/root_type=""
|
||||
nodes/root_name=""
|
||||
nodes/root_script=null
|
||||
mesh_library/use_node_names_as_mesh_names=false
|
||||
array_mesh/deduplicate_surfaces=true
|
||||
nodes/apply_root_scale=true
|
||||
nodes/root_scale=1.0
|
||||
nodes/import_as_skeleton_bones=false
|
||||
nodes/use_name_suffixes=true
|
||||
nodes/use_node_type_suffixes=true
|
||||
meshes/ensure_tangents=true
|
||||
meshes/generate_lods=true
|
||||
meshes/create_shadow_meshes=true
|
||||
meshes/light_baking=1
|
||||
meshes/lightmap_texel_size=0.2
|
||||
meshes/force_disable_compression=false
|
||||
skins/use_named_skins=true
|
||||
animation/import=true
|
||||
animation/fps=30
|
||||
animation/trimming=false
|
||||
animation/remove_immutable_tracks=true
|
||||
animation/import_rest_as_RESET=false
|
||||
import_script/path=""
|
||||
materials/extract=0
|
||||
materials/extract_format=0
|
||||
materials/extract_path=""
|
||||
_subresources={}
|
||||
gltf/naming_version=2
|
||||
gltf/embedded_image_handling=1
|
||||
gltf/texture_map_mode=1
|
||||
BIN
assets/luneraria/peoples/p_ork.glb
Normal file
BIN
assets/luneraria/peoples/p_ork.glb
Normal file
Binary file not shown.
45
assets/luneraria/peoples/p_ork.glb.import
Normal file
45
assets/luneraria/peoples/p_ork.glb.import
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
[remap]
|
||||
|
||||
importer="scene"
|
||||
importer_version=1
|
||||
type="PackedScene"
|
||||
uid="uid://ch346bo30gv7u"
|
||||
path="res://.godot/imported/p_ork.glb-2fc1770fe3cbd6425271bd6ed96455c7.scn"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/luneraria/peoples/p_ork.glb"
|
||||
dest_files=["res://.godot/imported/p_ork.glb-2fc1770fe3cbd6425271bd6ed96455c7.scn"]
|
||||
|
||||
[params]
|
||||
|
||||
nodes/root_type=""
|
||||
nodes/root_name=""
|
||||
nodes/root_script=null
|
||||
mesh_library/use_node_names_as_mesh_names=false
|
||||
array_mesh/deduplicate_surfaces=true
|
||||
nodes/apply_root_scale=true
|
||||
nodes/root_scale=1.0
|
||||
nodes/import_as_skeleton_bones=false
|
||||
nodes/use_name_suffixes=true
|
||||
nodes/use_node_type_suffixes=true
|
||||
meshes/ensure_tangents=true
|
||||
meshes/generate_lods=true
|
||||
meshes/create_shadow_meshes=true
|
||||
meshes/light_baking=1
|
||||
meshes/lightmap_texel_size=0.2
|
||||
meshes/force_disable_compression=false
|
||||
skins/use_named_skins=true
|
||||
animation/import=true
|
||||
animation/fps=30
|
||||
animation/trimming=false
|
||||
animation/remove_immutable_tracks=true
|
||||
animation/import_rest_as_RESET=false
|
||||
import_script/path=""
|
||||
materials/extract=0
|
||||
materials/extract_format=0
|
||||
materials/extract_path=""
|
||||
_subresources={}
|
||||
gltf/naming_version=2
|
||||
gltf/embedded_image_handling=1
|
||||
gltf/texture_map_mode=1
|
||||
BIN
assets/luneraria/peoples/p_troll.glb
Normal file
BIN
assets/luneraria/peoples/p_troll.glb
Normal file
Binary file not shown.
45
assets/luneraria/peoples/p_troll.glb.import
Normal file
45
assets/luneraria/peoples/p_troll.glb.import
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
[remap]
|
||||
|
||||
importer="scene"
|
||||
importer_version=1
|
||||
type="PackedScene"
|
||||
uid="uid://cgmg6jsstbn0w"
|
||||
path="res://.godot/imported/p_troll.glb-1e8b28d4cdbb22a6f14981dad1c5577b.scn"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/luneraria/peoples/p_troll.glb"
|
||||
dest_files=["res://.godot/imported/p_troll.glb-1e8b28d4cdbb22a6f14981dad1c5577b.scn"]
|
||||
|
||||
[params]
|
||||
|
||||
nodes/root_type=""
|
||||
nodes/root_name=""
|
||||
nodes/root_script=null
|
||||
mesh_library/use_node_names_as_mesh_names=false
|
||||
array_mesh/deduplicate_surfaces=true
|
||||
nodes/apply_root_scale=true
|
||||
nodes/root_scale=1.0
|
||||
nodes/import_as_skeleton_bones=false
|
||||
nodes/use_name_suffixes=true
|
||||
nodes/use_node_type_suffixes=true
|
||||
meshes/ensure_tangents=true
|
||||
meshes/generate_lods=true
|
||||
meshes/create_shadow_meshes=true
|
||||
meshes/light_baking=1
|
||||
meshes/lightmap_texel_size=0.2
|
||||
meshes/force_disable_compression=false
|
||||
skins/use_named_skins=true
|
||||
animation/import=true
|
||||
animation/fps=30
|
||||
animation/trimming=false
|
||||
animation/remove_immutable_tracks=true
|
||||
animation/import_rest_as_RESET=false
|
||||
import_script/path=""
|
||||
materials/extract=0
|
||||
materials/extract_format=0
|
||||
materials/extract_path=""
|
||||
_subresources={}
|
||||
gltf/naming_version=2
|
||||
gltf/embedded_image_handling=1
|
||||
gltf/texture_map_mode=1
|
||||
BIN
assets/luneraria/peoples/p_zwerg.glb
Normal file
BIN
assets/luneraria/peoples/p_zwerg.glb
Normal file
Binary file not shown.
45
assets/luneraria/peoples/p_zwerg.glb.import
Normal file
45
assets/luneraria/peoples/p_zwerg.glb.import
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
[remap]
|
||||
|
||||
importer="scene"
|
||||
importer_version=1
|
||||
type="PackedScene"
|
||||
uid="uid://cl7r1ec10jtmg"
|
||||
path="res://.godot/imported/p_zwerg.glb-e90f71dd7991679fd78ec39f4df7c5be.scn"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/luneraria/peoples/p_zwerg.glb"
|
||||
dest_files=["res://.godot/imported/p_zwerg.glb-e90f71dd7991679fd78ec39f4df7c5be.scn"]
|
||||
|
||||
[params]
|
||||
|
||||
nodes/root_type=""
|
||||
nodes/root_name=""
|
||||
nodes/root_script=null
|
||||
mesh_library/use_node_names_as_mesh_names=false
|
||||
array_mesh/deduplicate_surfaces=true
|
||||
nodes/apply_root_scale=true
|
||||
nodes/root_scale=1.0
|
||||
nodes/import_as_skeleton_bones=false
|
||||
nodes/use_name_suffixes=true
|
||||
nodes/use_node_type_suffixes=true
|
||||
meshes/ensure_tangents=true
|
||||
meshes/generate_lods=true
|
||||
meshes/create_shadow_meshes=true
|
||||
meshes/light_baking=1
|
||||
meshes/lightmap_texel_size=0.2
|
||||
meshes/force_disable_compression=false
|
||||
skins/use_named_skins=true
|
||||
animation/import=true
|
||||
animation/fps=30
|
||||
animation/trimming=false
|
||||
animation/remove_immutable_tracks=true
|
||||
animation/import_rest_as_RESET=false
|
||||
import_script/path=""
|
||||
materials/extract=0
|
||||
materials/extract_format=0
|
||||
materials/extract_path=""
|
||||
_subresources={}
|
||||
gltf/naming_version=2
|
||||
gltf/embedded_image_handling=1
|
||||
gltf/texture_map_mode=1
|
||||
333
assets/luneraria/peoples_manifest.json
Normal file
333
assets/luneraria/peoples_manifest.json
Normal file
|
|
@ -0,0 +1,333 @@
|
|||
{
|
||||
"assets": [
|
||||
{
|
||||
"id": "p_mensch",
|
||||
"name": "Ritter",
|
||||
"people": "Menschen",
|
||||
"klasse": "Ritter",
|
||||
"rolle": "front",
|
||||
"resource_path": "res://assets/luneraria/peoples/p_mensch.glb",
|
||||
"triangles": 17480,
|
||||
"mesh_parts": 1,
|
||||
"parts": [
|
||||
"MenschBody"
|
||||
],
|
||||
"skeletal": true,
|
||||
"bones": 22,
|
||||
"clips": [
|
||||
"idle",
|
||||
"start",
|
||||
"walk",
|
||||
"stop",
|
||||
"attack_a",
|
||||
"attack_b",
|
||||
"hit",
|
||||
"ability",
|
||||
"death"
|
||||
],
|
||||
"attack_cycle": [
|
||||
"attack_a",
|
||||
"attack_b",
|
||||
"attack_a",
|
||||
"ability"
|
||||
],
|
||||
"contact_seconds": 0.9,
|
||||
"bounds_godot": {
|
||||
"min": [
|
||||
-0.40699902176856995,
|
||||
-0.01069701835513115,
|
||||
-0.27477124333381653
|
||||
],
|
||||
"max": [
|
||||
0.42016029357910156,
|
||||
1.9657350778579712,
|
||||
0.6130658388137817
|
||||
]
|
||||
},
|
||||
"sha256": "218b6d020a0d70e6693e6b61c9eb2d3090e8365b23afe675268a9d0084bacd73",
|
||||
"source": "assets-source/luneraria/peoples/p_mensch.blend"
|
||||
},
|
||||
{
|
||||
"id": "p_elf",
|
||||
"name": "Waldl\u00e4uferin",
|
||||
"people": "Elfen",
|
||||
"klasse": "Waldl\u00e4uferin",
|
||||
"rolle": "ranged",
|
||||
"resource_path": "res://assets/luneraria/peoples/p_elf.glb",
|
||||
"triangles": 18502,
|
||||
"mesh_parts": 1,
|
||||
"parts": [
|
||||
"ElfBody"
|
||||
],
|
||||
"skeletal": true,
|
||||
"bones": 24,
|
||||
"clips": [
|
||||
"idle",
|
||||
"start",
|
||||
"walk",
|
||||
"stop",
|
||||
"attack_a",
|
||||
"attack_b",
|
||||
"hit",
|
||||
"ability",
|
||||
"death"
|
||||
],
|
||||
"attack_cycle": [
|
||||
"attack_a",
|
||||
"attack_b",
|
||||
"attack_a",
|
||||
"ability"
|
||||
],
|
||||
"contact_seconds": 0.9,
|
||||
"bounds_godot": {
|
||||
"min": [
|
||||
-0.274183988571167,
|
||||
0.00043252474279142916,
|
||||
-0.5287083387374878
|
||||
],
|
||||
"max": [
|
||||
0.29548221826553345,
|
||||
2.230403423309326,
|
||||
1.1226369142532349
|
||||
]
|
||||
},
|
||||
"sha256": "9c155a1cf3868185cbabdc4ee26fd23e53006d4a093c2f2d623eb42317da02a6",
|
||||
"source": "assets-source/luneraria/peoples/p_elf.blend"
|
||||
},
|
||||
{
|
||||
"id": "p_zwerg",
|
||||
"name": "Schildtr\u00e4ger",
|
||||
"people": "Zwerge",
|
||||
"klasse": "Schildtr\u00e4ger",
|
||||
"rolle": "front",
|
||||
"resource_path": "res://assets/luneraria/peoples/p_zwerg.glb",
|
||||
"triangles": 20214,
|
||||
"mesh_parts": 1,
|
||||
"parts": [
|
||||
"ZwergBody"
|
||||
],
|
||||
"skeletal": true,
|
||||
"bones": 22,
|
||||
"clips": [
|
||||
"idle",
|
||||
"start",
|
||||
"walk",
|
||||
"stop",
|
||||
"attack_a",
|
||||
"attack_b",
|
||||
"hit",
|
||||
"ability",
|
||||
"death"
|
||||
],
|
||||
"attack_cycle": [
|
||||
"attack_a",
|
||||
"attack_b",
|
||||
"attack_a",
|
||||
"ability"
|
||||
],
|
||||
"contact_seconds": 0.9,
|
||||
"bounds_godot": {
|
||||
"min": [
|
||||
-0.3604458272457123,
|
||||
-0.018512045964598656,
|
||||
-0.17344079911708832
|
||||
],
|
||||
"max": [
|
||||
0.4053660035133362,
|
||||
1.3439915180206299,
|
||||
0.4210769236087799
|
||||
]
|
||||
},
|
||||
"sha256": "bb6706d13f8cf28d3142a919f66d69192167577d769a5de781a4ee7ac0b42559",
|
||||
"source": "assets-source/luneraria/peoples/p_zwerg.blend"
|
||||
},
|
||||
{
|
||||
"id": "p_troll",
|
||||
"name": "Steinhauer",
|
||||
"people": "Trolle",
|
||||
"klasse": "Steinhauer",
|
||||
"rolle": "splash",
|
||||
"resource_path": "res://assets/luneraria/peoples/p_troll.glb",
|
||||
"triangles": 14686,
|
||||
"mesh_parts": 1,
|
||||
"parts": [
|
||||
"TrollBody"
|
||||
],
|
||||
"skeletal": true,
|
||||
"bones": 22,
|
||||
"clips": [
|
||||
"idle",
|
||||
"start",
|
||||
"walk",
|
||||
"stop",
|
||||
"attack_a",
|
||||
"attack_b",
|
||||
"hit",
|
||||
"ability",
|
||||
"death"
|
||||
],
|
||||
"attack_cycle": [
|
||||
"attack_a",
|
||||
"attack_b",
|
||||
"attack_a",
|
||||
"ability"
|
||||
],
|
||||
"contact_seconds": 0.9,
|
||||
"bounds_godot": {
|
||||
"min": [
|
||||
-0.5339592695236206,
|
||||
-0.03151940554380417,
|
||||
-0.2999359965324402
|
||||
],
|
||||
"max": [
|
||||
0.49503999948501587,
|
||||
2.198559045791626,
|
||||
1.255454421043396
|
||||
]
|
||||
},
|
||||
"sha256": "1c250068745bd7305569fd7b4db2848b86fea486dc5af139798939141597c259",
|
||||
"source": "assets-source/luneraria/peoples/p_troll.blend"
|
||||
},
|
||||
{
|
||||
"id": "p_fee",
|
||||
"name": "Lichtheilerin",
|
||||
"people": "Feen",
|
||||
"klasse": "Lichtheilerin",
|
||||
"rolle": "support",
|
||||
"resource_path": "res://assets/luneraria/peoples/p_fee.glb",
|
||||
"triangles": 16744,
|
||||
"mesh_parts": 1,
|
||||
"parts": [
|
||||
"FeeBody"
|
||||
],
|
||||
"skeletal": true,
|
||||
"bones": 24,
|
||||
"clips": [
|
||||
"idle",
|
||||
"start",
|
||||
"walk",
|
||||
"stop",
|
||||
"attack_a",
|
||||
"attack_b",
|
||||
"hit",
|
||||
"ability",
|
||||
"death"
|
||||
],
|
||||
"attack_cycle": [
|
||||
"attack_a",
|
||||
"attack_b",
|
||||
"attack_a",
|
||||
"ability"
|
||||
],
|
||||
"contact_seconds": 0.9,
|
||||
"bounds_godot": {
|
||||
"min": [
|
||||
-0.35030224919319153,
|
||||
0.31140172481536865,
|
||||
-0.1565617471933365
|
||||
],
|
||||
"max": [
|
||||
0.35030224919319153,
|
||||
1.6979674100875854,
|
||||
0.2717953622341156
|
||||
]
|
||||
},
|
||||
"sha256": "f084d1f922d1a19d421b38e8ed68e944582dd0a1c4768e310773eca084f3b236",
|
||||
"source": "assets-source/luneraria/peoples/p_fee.blend"
|
||||
},
|
||||
{
|
||||
"id": "p_ork",
|
||||
"name": "Kriegsh\u00e4uptling",
|
||||
"people": "Orks",
|
||||
"klasse": "Kriegsh\u00e4uptling",
|
||||
"rolle": "melee",
|
||||
"resource_path": "res://assets/luneraria/peoples/p_ork.glb",
|
||||
"triangles": 15890,
|
||||
"mesh_parts": 1,
|
||||
"parts": [
|
||||
"OrkBody"
|
||||
],
|
||||
"skeletal": true,
|
||||
"bones": 22,
|
||||
"clips": [
|
||||
"idle",
|
||||
"start",
|
||||
"walk",
|
||||
"stop",
|
||||
"attack_a",
|
||||
"attack_b",
|
||||
"hit",
|
||||
"ability",
|
||||
"death"
|
||||
],
|
||||
"attack_cycle": [
|
||||
"attack_a",
|
||||
"attack_b",
|
||||
"attack_a",
|
||||
"ability"
|
||||
],
|
||||
"contact_seconds": 0.9,
|
||||
"bounds_godot": {
|
||||
"min": [
|
||||
-0.5301840901374817,
|
||||
-0.0254998579621315,
|
||||
-0.18939527869224548
|
||||
],
|
||||
"max": [
|
||||
0.5364153385162354,
|
||||
2.0665111541748047,
|
||||
0.760603666305542
|
||||
]
|
||||
},
|
||||
"sha256": "6d9552f8c4e5fdfbba2a9a933a861c4a59b7dc3ab406e7070a7e2553e7b39bff",
|
||||
"source": "assets-source/luneraria/peoples/p_ork.blend"
|
||||
},
|
||||
{
|
||||
"id": "p_biest",
|
||||
"name": "Klauenj\u00e4ger",
|
||||
"people": "Biestmenschen",
|
||||
"klasse": "Klauenj\u00e4ger",
|
||||
"rolle": "melee",
|
||||
"resource_path": "res://assets/luneraria/peoples/p_biest.glb",
|
||||
"triangles": 16858,
|
||||
"mesh_parts": 1,
|
||||
"parts": [
|
||||
"BiestBody"
|
||||
],
|
||||
"skeletal": true,
|
||||
"bones": 24,
|
||||
"clips": [
|
||||
"idle",
|
||||
"start",
|
||||
"walk",
|
||||
"stop",
|
||||
"attack_a",
|
||||
"attack_b",
|
||||
"hit",
|
||||
"ability",
|
||||
"death"
|
||||
],
|
||||
"attack_cycle": [
|
||||
"attack_a",
|
||||
"attack_b",
|
||||
"attack_a",
|
||||
"ability"
|
||||
],
|
||||
"contact_seconds": 0.9,
|
||||
"bounds_godot": {
|
||||
"min": [
|
||||
-0.4814721643924713,
|
||||
0.009468089789152145,
|
||||
-0.5130493640899658
|
||||
],
|
||||
"max": [
|
||||
0.4814721643924713,
|
||||
2.072967052459717,
|
||||
0.6682941913604736
|
||||
]
|
||||
},
|
||||
"sha256": "d990197e3030d34455f8ad070a1f047cccea03d1dcccc81950a4b4b692a5f2d1",
|
||||
"source": "assets-source/luneraria/peoples/p_biest.blend"
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
assets/luneraria/tower.glb
Normal file
BIN
assets/luneraria/tower.glb
Normal file
Binary file not shown.
45
assets/luneraria/tower.glb.import
Normal file
45
assets/luneraria/tower.glb.import
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
[remap]
|
||||
|
||||
importer="scene"
|
||||
importer_version=1
|
||||
type="PackedScene"
|
||||
uid="uid://fqj2uftgmgig"
|
||||
path="res://.godot/imported/tower.glb-367b5fb07a0c6d34829755c1c6ffa2f0.scn"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/luneraria/tower.glb"
|
||||
dest_files=["res://.godot/imported/tower.glb-367b5fb07a0c6d34829755c1c6ffa2f0.scn"]
|
||||
|
||||
[params]
|
||||
|
||||
nodes/root_type=""
|
||||
nodes/root_name=""
|
||||
nodes/root_script=null
|
||||
mesh_library/use_node_names_as_mesh_names=false
|
||||
array_mesh/deduplicate_surfaces=true
|
||||
nodes/apply_root_scale=true
|
||||
nodes/root_scale=1.0
|
||||
nodes/import_as_skeleton_bones=false
|
||||
nodes/use_name_suffixes=true
|
||||
nodes/use_node_type_suffixes=true
|
||||
meshes/ensure_tangents=true
|
||||
meshes/generate_lods=true
|
||||
meshes/create_shadow_meshes=true
|
||||
meshes/light_baking=1
|
||||
meshes/lightmap_texel_size=0.2
|
||||
meshes/force_disable_compression=false
|
||||
skins/use_named_skins=true
|
||||
animation/import=true
|
||||
animation/fps=30
|
||||
animation/trimming=false
|
||||
animation/remove_immutable_tracks=true
|
||||
animation/import_rest_as_RESET=false
|
||||
import_script/path=""
|
||||
materials/extract=0
|
||||
materials/extract_format=0
|
||||
materials/extract_path=""
|
||||
_subresources={}
|
||||
gltf/naming_version=2
|
||||
gltf/embedded_image_handling=1
|
||||
gltf/texture_map_mode=1
|
||||
19
assets/luneraria/tower_manifest.json
Normal file
19
assets/luneraria/tower_manifest.json
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"assets": [
|
||||
{
|
||||
"id": "lane_tower",
|
||||
"resource_path": "res://assets/luneraria/tower.glb",
|
||||
"source": "assets-source/luneraria/tower.blend",
|
||||
"triangles": 648,
|
||||
"height": 5.95,
|
||||
"sha256": "52de81cafa3712efb78413d28d16fe112330d27af0e66a8c9b31fde7d6dd1442",
|
||||
"materials": [
|
||||
"ENV_cliff",
|
||||
"ENV_paving",
|
||||
"ENV_limestone",
|
||||
"ENV_brass",
|
||||
"TW_Crystal"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
17
assets/ui/emblems/luneraria.svg
Normal file
17
assets/ui/emblems/luneraria.svg
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="512" height="512">
|
||||
<defs>
|
||||
<linearGradient id="stone" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#1f2733"/><stop offset="1" stop-color="#0c1016"/></linearGradient>
|
||||
<linearGradient id="moon" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stop-color="#fbf1d4"/><stop offset="1" stop-color="#c9a562"/></linearGradient>
|
||||
<linearGradient id="gem" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#d8f0ff"/><stop offset=".55" stop-color="#5aa8ff"/><stop offset="1" stop-color="#27508a"/></linearGradient>
|
||||
<radialGradient id="halo" cx=".5" cy=".46" r=".5"><stop offset="0" stop-color="#9fd0ff" stop-opacity=".45"/><stop offset="1" stop-color="#9fd0ff" stop-opacity="0"/></radialGradient>
|
||||
</defs>
|
||||
<circle cx="256" cy="256" r="232" fill="url(#stone)" stroke="#c99a58" stroke-width="12"/>
|
||||
<circle cx="256" cy="256" r="204" fill="none" stroke="#6b4f2e" stroke-width="4"/>
|
||||
<circle cx="256" cy="236" r="160" fill="url(#halo)"/>
|
||||
<path d="M300 70 A186 186 0 1 0 300 442 A214 214 0 0 1 300 70 Z" fill="url(#moon)" stroke="#fff4d8" stroke-width="4"/>
|
||||
<path d="M256 150 L300 236 L256 360 L212 236 Z" fill="url(#gem)" stroke="#eaf6ff" stroke-width="5" stroke-linejoin="round"/>
|
||||
<path d="M212 236 L256 262 L300 236 M256 150 L256 360" fill="none" stroke="#eaf6ff" stroke-width="2.5" opacity=".8"/>
|
||||
<path d="M256 70 l10 22 l22 10 l-22 10 l-10 22 l-10 -22 l-22 -10 l22 -10 Z" fill="#f6e2b0"/>
|
||||
<path d="M120 400 Q190 372 256 400 T392 400" fill="none" stroke="#6fd3b4" stroke-width="7" stroke-linecap="round" opacity=".85"/>
|
||||
<path d="M150 432 L178 404 M362 432 L334 404" stroke="#c99a58" stroke-width="6" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
43
assets/ui/emblems/luneraria.svg.import
Normal file
43
assets/ui/emblems/luneraria.svg.import
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dq03newjr6neo"
|
||||
path="res://.godot/imported/luneraria.svg-12b34911b283c50c0fc77d4b9fb43e87.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/ui/emblems/luneraria.svg"
|
||||
dest_files=["res://.godot/imported/luneraria.svg-12b34911b283c50c0fc77d4b9fb43e87.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
svg/scale=1.0
|
||||
editor/scale_with_editor_scale=false
|
||||
editor/convert_colors_with_editor_theme=false
|
||||
6
data/luneraria/balance_default.tres
Normal file
6
data/luneraria/balance_default.tres
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
[gd_resource type="Resource" script_class="LuneBalance" load_steps=2 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://scripts/luneraria/core/lune_balance.gd" id="1"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1")
|
||||
77
docs/luneraria/ANLEITUNG.md
Normal file
77
docs/luneraria/ANLEITUNG.md
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
# Installation, Start, Steuerung und Export
|
||||
|
||||
## Start aus dem Quellprojekt (Fedora 44)
|
||||
|
||||
```bash
|
||||
cd saumwacht-godot
|
||||
godot --path . # Champions of Luneraria (Hauptszene scenes/luneraria.tscn)
|
||||
godot --path . -- --legacy # archivierter Saumwacht-Modus (scenes/main.tscn)
|
||||
```
|
||||
|
||||
Voraussetzung ist Godot 4.7.2. Blender wird nur zum Neuerzeugen von Assets gebraucht, nicht zum Spielen.
|
||||
|
||||
## Eine Partie
|
||||
|
||||
1. **Neue Partie** → Bund (Glutpakt oder Wurzelbund) und deine Lane (Top, Mid, Bottom) wählen → **Partie beginnen**. Du spielst in Team Blau (Südwest) mit zwei Bot-Verbündeten gegen drei Bots in Team Rot.
|
||||
2. **Planung:** Truppen kaufen (Knöpfe oder 1–5), mit T/M/B einer Lane zuweisen, mit ↑ aufwerten, mit × zurückgeben. Käufe aus derselben Planung werden voll erstattet, ältere mit 75 %. **Startaufstellung** kauft Front, Nahkampf und Fernkampf. **Bereit** (Leertaste) übernimmt alle Befehle verbindlich.
|
||||
3. **Kampf:** Er läuft automatisch. Deine Truppen rücken mit der eigenen Monsterwelle über ihre Lane vor. Leertaste oder P pausiert, Tempo 1×/2×/4×.
|
||||
4. **Abrechnung:** Getötete Monster und Gebäude bringen Gold, dazu kommt das Rundeneinkommen. Deine Truppen kehren geheilt zurück. Türme und Kerne behalten ihren Schaden.
|
||||
5. Die Partie endet erst, wenn ein Ancient fällt. Es gibt kein Rundenlimit.
|
||||
|
||||
## Steuerung
|
||||
|
||||
| Eingabe | Wirkung |
|
||||
| --- | --- |
|
||||
| 1–5 | Truppe kaufen (Planung) |
|
||||
| Leertaste | Bereit / im Kampf Pause |
|
||||
| P | Pause |
|
||||
| WASD, Pfeiltasten, mittlere Maustaste ziehen | Kamera verschieben |
|
||||
| Mausrad | Zoom |
|
||||
| Tab / Lane-Knöpfe links | Kamera auf die nächste Lane |
|
||||
| O | Kartenübersicht |
|
||||
| Minimap klicken/ziehen | Kamera springt dorthin |
|
||||
| F1 | Optionen und Steuerung |
|
||||
| M / F11 | Ton / Vollbild |
|
||||
|
||||
## Prüfungen
|
||||
|
||||
```bash
|
||||
godot --headless --path . res://tests/luneraria/test_lune_core.tscn # Regeln M1 (91, inkl. Spiegeltest)
|
||||
godot --headless --path . res://tests/luneraria/test_lune_m2.tscn # Regeln M2 (73)
|
||||
godot --path . --resolution 1280x720 res://tools/luneraria/verify_m1.tscn # echte Bedienung, volle Partie (38)
|
||||
godot --path . --resolution 1920x1080 res://tools/luneraria/verify_m2.tscn # Helden, Items, Grotte, Boss (15)
|
||||
godot --headless --path . res://tools/luneraria/sim_match.tscn -- --seeds=1,2,3 --limit=80
|
||||
godot --headless --path . res://tools/luneraria/balance_run.tscn -- --compositions=20 --limit=60 --out=res://docs/luneraria/logs/m3/balance.json
|
||||
godot --headless --path . res://tools/luneraria/balance_run.tscn -- --matchups --limit=60 --out=res://docs/luneraria/logs/m3/matchups.json
|
||||
python3 tools/luneraria/analyze_balance.py docs/luneraria/logs/m3/balance.json
|
||||
godot --headless --path . res://tools/luneraria/stress_run.tscn # Wellen bis 10^6, Langlauf
|
||||
godot --path . res://tools/luneraria/people_lineup.tscn -- --out=res://docs/luneraria/screenshots
|
||||
godot --path . --resolution 1920x1080 res://tools/luneraria/lune_benchmark.tscn
|
||||
godot --path . --resolution 1920x1080 res://tools/luneraria/lune_review.tscn # Aufnahmen
|
||||
# Legacy (Saumwacht) unverändert:
|
||||
godot --headless --path . res://tests/test_runner.tscn
|
||||
godot --headless --path . -- --smoke-test
|
||||
godot --headless --path . -- --faction-test
|
||||
godot --headless --path . -- --expedition-test
|
||||
```
|
||||
|
||||
`verify_m1` und `verify_m2` brauchen ein Fenster (echte Maus-/Tastaturereignisse), nicht `--headless`.
|
||||
|
||||
## Assets neu erzeugen
|
||||
|
||||
```bash
|
||||
ALSOFT_DRIVERS=null blender -b --python-exit-code 1 --python assets-source/luneraria/build_tower.py
|
||||
ALSOFT_DRIVERS=null blender -b --python-exit-code 1 --python assets-source/luneraria/build_grotto.py
|
||||
ALSOFT_DRIVERS=null blender -b --python-exit-code 1 --python assets-source/luneraria/build_map_props.py
|
||||
ALSOFT_DRIVERS=null blender -b --python-exit-code 1 --python assets-source/luneraria/build_peoples.py
|
||||
python3 tools/luneraria/build_asset_matrix.py
|
||||
godot --headless --editor --import --path .
|
||||
```
|
||||
|
||||
## Export
|
||||
|
||||
Die Pakete für Champions of Luneraria kommen mit M4. Bis dahin baut `tools/build_demo.py` weiterhin die Saumwacht-Demo 0.15.0.
|
||||
|
||||
## Benutzereinstellungen
|
||||
|
||||
Der neue Projektname legt einen neuen Benutzerordner an (`~/.local/share/godot/app_userdata/Champions of Luneraria`). Beim ersten Start übernimmt `Preferences` einmalig die `preferences.cfg` aus „Saumwacht · Glutpakt“. Die alte Datei bleibt unverändert; fehlt sie, gelten die Standardwerte.
|
||||
27
docs/luneraria/ARCHITEKTUR.md
Normal file
27
docs/luneraria/ARCHITEKTUR.md
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# Architektur- und Migrationsentscheidungen
|
||||
|
||||
Stand: 27. September 2026 (M0).
|
||||
|
||||
## Bestand (geprüft)
|
||||
|
||||
- **Werkzeuge:** Godot 4.7.2 (Fedora-Build; offizielle 4.7.2-Exportvorlagen unter `assets-source/phase6/export-templates`), Blender 5.2.2 LTS, Forward+ mit OpenGL-Kompatibilitätsmodus. Kein Engine-Update.
|
||||
- **Repository:** Es gab kein Git. Angelegt wurde ein lokales Repository mit dem Baseline-Commit `c2b4476` auf `main` (unveränderter Stand 0.15.0, Phase 20A); die Arbeit läuft auf `luneraria/m1`. Screenshots und die Projekt-Doku außerhalb des Projektordners sind in `../backups/vor-luneraria-2026-09-27-docs-und-screenshots.tar.gz` gesichert. Keine uncommitteten fremden Änderungen; `../.mimocode` gehört zu einem fremden Werkzeug und bleibt unberührt. Ein Stand 20B existiert nicht. Keine CLAUDE.md.
|
||||
- **Spiel:** eine Szene `scenes/main.tscn`, sieben Autoloads (`AssetLibrary`, `DataCatalog`, `GameState`, `EconomyManager`, `WaveManager`, `Preferences`, `Soundscape`), alle Oberflächen im Code. Kampf in `scripts/combat/`: Verteidiger gegen Angreifer je Lane, die Feindschaft hängt an `is_attacker`, die Lane an `team_id`.
|
||||
- **Baseline-Tests** (`logs/m0-baseline/`): 209 · 33 · 463 · 206 · 1.665 bestanden.
|
||||
|
||||
## Entscheidungen
|
||||
|
||||
1. **Neuer Modus neben dem Legacy-Modus.** Die Saumwacht-Regeln (zwei Bretter, 8/20 Wellen, Kern-HP-Entscheid, Arbeiter/Funken) widersprechen den neuen Produktregeln. Sie werden nicht umgeschrieben, sondern als **Legacy-Modus** archiviert: `scenes/main.tscn` und die zugehörigen Tests bleiben lauffähig. Die neue Hauptszene `scenes/luneraria.tscn` startet Champions of Luneraria. Die bisherigen QA-Schalter (`--smoke-test`, `--faction-test`, `--expedition-test`) leitet sie in die Legacy-Szene um. So vermischen sich die Wirtschaftsmodelle nicht (Arbeitsannahme E), und die technischen Regressionen bleiben erhalten.
|
||||
2. **Neue autoritative Simulation** in `scripts/luneraria/core/` als reine Datenklassen (`RefCounted`) ohne Szenenbaum. Der alte Kampf ist an zwei Bretter und `is_attacker` gebunden. Übernommen werden Einheitenwerte (`DataCatalog`), Schadensmatrix, Fähigkeitsregeln (auf Teamfeindschaft umgeschrieben), Modelle und die Animationsanbindung (`SkeletalFigure.update_combat`, `AnimatedFigure.pose`).
|
||||
- `LuneBalance` (Resource) enthält alle Zahlen.
|
||||
- `LuneMap` enthält Lane-Polylinien, 16 Türme und 2 Kerne, Aufmarschflächen, Sperrlogik und die Grotte. Die Karte entsteht per Konstruktion spiegelsymmetrisch zur Diagonale x = z: Team 1 ist das Spiegelbild von Team 0.
|
||||
- `LuneCombat` rechnet einen festen Schritt in zwei Phasen, die Ergebnisse sind reihenfolgeunabhängig.
|
||||
- `LuneMatch` verwaltet Teams, Spieler, Gold, Besitz mit eindeutigen IDs, Befehle, Runden, Abrechnung, Sieg und Ereignisprotokoll.
|
||||
- `LuneWaves` erzeugt datengetriebene, unbegrenzte Wellen mit Mengengrenze.
|
||||
- `LuneBot` nutzt dieselbe Befehlsschnittstelle wie der Mensch.
|
||||
3. **Autoritative Matchinstanz von Anfang an.** Oberfläche und Bots senden nur Befehle (`LuneMatch.submit`), die beim Phasenwechsel atomar geprüft werden. Darstellung und Tests lesen denselben Zustand. Zufall kommt nur aus einer `RandomNumberGenerator`-Instanz mit Seed (Wellenrotation, Bots). Das ist die Grundlage für M4 (Host/Join), ohne Bit-Identität über Plattformen zu behaupten.
|
||||
4. **Darstellung** in `scripts/luneraria/view/`: Kartenaufbau aus Bestandsmaterialien (Kluft-Shader, Kerne, Felsen, Bäume), neu erzeugte Türme (Blender-Generator), eine Einheitenansicht pro Kampfinstanz mit Positionsinterpolation zwischen den Simulationsschritten. Sichtbarkeit und Kamera beeinflussen die Simulation nicht.
|
||||
5. **Oberfläche** in `scripts/luneraria/ui/` mit dem gemeinsamen `SaumwachtTheme` und seinen Bauteilen. Titel und Menü werden auf Champions of Luneraria umgestellt. Die Eingabeabschirmung aus 20A bleibt.
|
||||
6. **Benutzereinstellungen:** Der Projektname wird zu „Champions of Luneraria“, dadurch ändert sich der `user://`-Pfad. `Preferences` übernimmt beim ersten Start einmalig die alte `preferences.cfg` aus „Saumwacht · Glutpakt“ und protokolliert das. Fehlt sie, gelten die Standardwerte.
|
||||
7. **Tests:** Neue Tests liegen unter `tests/luneraria/` und `tools/luneraria/`, die Legacy-Tests bleiben unverändert und werden als „Legacy“ geführt. Neue Referenzen werden erst nach fachlicher Prüfung festgeschrieben.
|
||||
8. **M3-Nachtrag:** Bots planen Items/Champions vor der Armee und helfen deterministisch (kein geteilter `rng`), damit Spiegelmatches bit-symmetrisch bleiben. Kartenprops stammen aus `map_props.glb` (MultiMesh, ENV_*-Kluftshader). Volksrepräsentanten `p_*` sind Asset- und Datenziele ohne Matcheinbindung; siehe [VOELKER.md](VOELKER.md). Balance- und Stresswerkzeuge liegen unter `tools/luneraria/`.
|
||||
80
docs/luneraria/ASSETMATRIX.md
Normal file
80
docs/luneraria/ASSETMATRIX.md
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
# Asset-Wiederverwendungsmatrix
|
||||
|
||||
Erzeugt mit `python3 tools/luneraria/build_asset_matrix.py` aus den Laufzeitmanifesten. „Volk/Bund“ ist die Datenzuordnung. Die sieben Zielvölker haben ab M3 **eigene Repräsentantenmodelle** (`p_*`); sie sind noch nicht als spielbare Fraktionen eingebunden. Bestehende Wesen bleiben als eigene Bünde Teil der Welt. Als „vorläufig“ markierte Rollen sind Zuordnungen vorhandener Modelle, keine neu erstellten Völker.
|
||||
|
||||
| ID | Name | Pfad | Quelle | Rig / Clips | Dreiecke | bisherige Rolle | neue Rolle | Volk / Bund | Materialzustand | Eingriff |
|
||||
| --- | --- | --- | --- | --- | ---: | --- | --- | --- | --- | --- |
|
||||
| core_team0 | Saumkern · Team 0 | res://assets/models/core_team0.glb | assets-source/phase4/blend/core_team0.blend | starre Gelenkgruppen | 36652 | Saumkern Team 0 | Ancient Blau (SW) | — | HD, starre Teile | keiner |
|
||||
| core_team1 | Saumkern · Team 1 | res://assets/models/core_team1.glb | assets-source/phase4/blend/core_team1.blend | starre Gelenkgruppen | 36848 | Saumkern Team 1 | Ancient Rot (NO) | — | HD, starre Teile | keiner |
|
||||
| e01 | Splitterling | res://assets/models/enemy_e01.glb | assets-source/phase4/blend/e01.blend | starre Gelenkgruppen | 19228 | Wellengegner | Monsterwelle (teamgebunden, rotierend) | Riftbrut (neutral, pro Team eingefärbt) | HD, starre Teile | Teamkennzeichnung |
|
||||
| e02 | Schalenläufer | res://assets/models/enemy_e02.glb | assets-source/phase4/blend/e02.blend | starre Gelenkgruppen | 20180 | Wellengegner | Monsterwelle | Riftbrut | HD, starre Teile | Teamkennzeichnung |
|
||||
| e03 | Nebelrest | res://assets/models/enemy_e03.glb | assets-source/phase4/blend/e03.blend | starre Gelenkgruppen | 35898 | Wellengegner | Monsterwelle | Riftbrut | HD, starre Teile | Teamkennzeichnung |
|
||||
| e04 | Fadenschütze | res://assets/models/enemy_e04.glb | assets-source/phase4/blend/e04.blend | starre Gelenkgruppen | 51050 | Wellengegner | Monsterwelle | Riftbrut | HD, starre Teile | Teamkennzeichnung |
|
||||
| e05 | Bruchstampfer | res://assets/models/enemy_e05.glb | assets-source/phase4/blend/e05.blend | starre Gelenkgruppen | 62798 | Wellengegner | Monsterwelle (späte Variante) | Riftbrut | HD, starre Teile | Teamkennzeichnung |
|
||||
| e06 | Knotenrufer | res://assets/models/enemy_e06.glb | assets-source/phase4/blend/e06.blend | starre Gelenkgruppen | 48336 | Wellengegner | Monsterwelle (Unterstützer) | Riftbrut | HD, starre Teile | Teamkennzeichnung |
|
||||
| e07 | Bruchhirsch | res://assets/models/enemy_e07.glb | assets-source/phase4/blend/e07.blend | starre Gelenkgruppen | 33800 | Boss Welle 5 | Reserve (Wellen-Elite ab höheren Indizes) | Riftbrut | HD, starre Teile | offen |
|
||||
| e08 | Riegelkoloss | res://assets/models/enemy_e08.glb | assets-source/phase4/blend/e08.blend | starre Gelenkgruppen | 81240 | Boss Welle 8 | Reserve (Wellen-Elite) | Riftbrut | HD, starre Teile | offen |
|
||||
| e09 | Maskenrichter | res://assets/models/enemy_e09.glb | assets-source/phase4/blend/e09.blend | starre Gelenkgruppen | 57310 | Boss Welle 15 | Reserve | Riftbrut | HD, starre Teile | offen |
|
||||
| e10 | Schlundkrone | res://assets/models/enemy_e10.glb | assets-source/phase4/blend/e10.blend | starre Gelenkgruppen | 64694 | Boss Welle 20 | neutraler Grottenboss und entsandter Boss (×1,7) | Riftbrut / Grotte | HD, starre Teile | umgesetzt (M2) |
|
||||
| g01 | Kohlenbeißer | res://assets/models/unit_g01.glb | assets-source/phase4/blend/g01.blend | starre Gelenkgruppen | 79780 | Glutpakt Nahkampf | Truppe Nahkampf | Glutkonstrukt / Glutpakt | HD, starre Teile | keiner |
|
||||
| g02 | Schlackenklaue | res://assets/models/unit_g02.glb | assets-source/phase4/blend/g02.blend | starre Gelenkgruppen | 75624 | Glutpakt Nahkampf+ | Truppenaufwertung | Glutkonstrukt / Glutpakt | HD, starre Teile | keiner |
|
||||
| g03 | Schlackenwacht | res://assets/models/unit_g03.glb | assets-source/phase4/blend/g03.blend | starre Gelenkgruppen | 67232 | Glutpakt Tank | Truppe Front | Glutkonstrukt / Glutpakt | HD, starre Teile | keiner |
|
||||
| g04 | Basaltbastion | res://assets/characters/basaltbastion.glb | assets-source/phase15/basaltbastion.blend | 17 Knochen · 9 Clips | 17824 | Glutpakt Tank+ | Truppenaufwertung | Glutkonstrukt / Glutpakt | gewichtetes Skelett (phase15) | keiner |
|
||||
| g05 | Funkenlanze | res://assets/characters/funkenlanze.glb | assets-source/phase18/funkenlanze.blend | 26 Knochen · 9 Clips | 24036 | Glutpakt Fernkampf | Truppe Fernkampf; zusätzlich Held „Funkenlanze“ (vorläufig; Goldring, Namensschild, ×1,25) | Glutkonstrukt / Glutpakt | gewichtetes Skelett (phase18) | umgesetzt (M2) |
|
||||
| g06 | Glasballiste | res://assets/characters/glasballiste.glb | assets-source/phase19/glasballiste.blend | 20 Knochen · 9 Clips | 15784 | Glutpakt Fernkampf+ | Truppenaufwertung (Belagerung) | Glutkonstrukt / Glutpakt | gewichtetes Skelett (phase19) | keiner |
|
||||
| g07 | Aschenwerfer | res://assets/models/unit_g07.glb | assets-source/phase4/blend/g07.blend | starre Gelenkgruppen | 81492 | Glutpakt Fläche | Truppe Fläche | Glutkonstrukt / Glutpakt | HD, starre Teile | keiner |
|
||||
| g08 | Kraterrufer | res://assets/models/unit_g08.glb | assets-source/phase4/blend/g08.blend | starre Gelenkgruppen | 77130 | Glutpakt Fläche+ | Truppenaufwertung | Glutkonstrukt / Glutpakt | HD, starre Teile | keiner |
|
||||
| g09 | Herdhüter | res://assets/models/unit_g09.glb | assets-source/phase4/blend/g09.blend | starre Gelenkgruppen | 84568 | Glutpakt Unterstützung | Truppe Unterstützung | Glutkonstrukt / Glutpakt | HD, starre Teile | keiner |
|
||||
| g10 | Sonnenesse | res://assets/models/unit_g10.glb | assets-source/phase4/blend/g10.blend | starre Gelenkgruppen | 96706 | Glutpakt Unterstützung+ | Truppenaufwertung | Glutkonstrukt / Glutpakt | HD, starre Teile | keiner |
|
||||
| m01 | Kesselwicht | res://assets/models/unit_m01.glb | assets-source/phase4/blend/m01.blend | starre Gelenkgruppen | 1284 | nicht spielbar, niedrige Detailstufe | Reserve für spätere Völker | Nietenkonvent (nicht spielbar) | niedrige Detailstufe | Neuaufbau nötig vor Nutzung |
|
||||
| m02 | Druckhüter | res://assets/models/unit_m02.glb | assets-source/phase4/blend/m02.blend | starre Gelenkgruppen | 1360 | nicht spielbar, niedrige Detailstufe | Reserve für spätere Völker | Nietenkonvent (nicht spielbar) | niedrige Detailstufe | Neuaufbau nötig vor Nutzung |
|
||||
| m03 | Scherschreiter | res://assets/models/unit_m03.glb | assets-source/phase4/blend/m03.blend | starre Gelenkgruppen | 932 | nicht spielbar, niedrige Detailstufe | Reserve für spätere Völker | Nietenkonvent (nicht spielbar) | niedrige Detailstufe | Neuaufbau nötig vor Nutzung |
|
||||
| m04 | Sechsklingler | res://assets/models/unit_m04.glb | assets-source/phase4/blend/m04.blend | starre Gelenkgruppen | 1398 | nicht spielbar, niedrige Detailstufe | Reserve für spätere Völker | Nietenkonvent (nicht spielbar) | niedrige Detailstufe | Neuaufbau nötig vor Nutzung |
|
||||
| m05 | Bolzenknecht | res://assets/models/unit_m05.glb | assets-source/phase4/blend/m05.blend | starre Gelenkgruppen | 1148 | nicht spielbar, niedrige Detailstufe | Reserve für spätere Völker | Nietenkonvent (nicht spielbar) | niedrige Detailstufe | Neuaufbau nötig vor Nutzung |
|
||||
| m06 | Linienmeister | res://assets/models/unit_m06.glb | assets-source/phase4/blend/m06.blend | starre Gelenkgruppen | 1432 | nicht spielbar, niedrige Detailstufe | Reserve für spätere Völker | Nietenkonvent (nicht spielbar) | niedrige Detailstufe | Neuaufbau nötig vor Nutzung |
|
||||
| m07 | Klangkolben | res://assets/models/unit_m07.glb | assets-source/phase4/blend/m07.blend | starre Gelenkgruppen | 740 | nicht spielbar, niedrige Detailstufe | Reserve für spätere Völker | Nietenkonvent (nicht spielbar) | niedrige Detailstufe | Neuaufbau nötig vor Nutzung |
|
||||
| m08 | Resonanzramme | res://assets/models/unit_m08.glb | assets-source/phase4/blend/m08.blend | starre Gelenkgruppen | 1316 | nicht spielbar, niedrige Detailstufe | Reserve für spätere Völker | Nietenkonvent (nicht spielbar) | niedrige Detailstufe | Neuaufbau nötig vor Nutzung |
|
||||
| m09 | Taktspindel | res://assets/models/unit_m09.glb | assets-source/phase4/blend/m09.blend | starre Gelenkgruppen | 1160 | nicht spielbar, niedrige Detailstufe | Reserve für spätere Völker | Nietenkonvent (nicht spielbar) | niedrige Detailstufe | Neuaufbau nötig vor Nutzung |
|
||||
| m10 | Taktprälat | res://assets/models/unit_m10.glb | assets-source/phase4/blend/m10.blend | starre Gelenkgruppen | 946 | nicht spielbar, niedrige Detailstufe | Reserve für spätere Völker | Nietenkonvent (nicht spielbar) | niedrige Detailstufe | Neuaufbau nötig vor Nutzung |
|
||||
| map_lane_segment | Lane-Segment | res://assets/models/map_lane_segment.glb | assets-source/phase4/blend/map_lane_segment.blend | starre Gelenkgruppen | 10700 | Lane-Kachel alt | nicht verwendet; Lanes neu erzeugt | — | HD, starre Teile | keiner |
|
||||
| n01 | Saummaske | res://assets/models/unit_n01.glb | assets-source/phase4/blend/n01.blend | starre Gelenkgruppen | 1132 | nicht spielbar, niedrige Detailstufe | Reserve für spätere Völker | Nebelchor (nicht spielbar) | niedrige Detailstufe | Neuaufbau nötig vor Nutzung |
|
||||
| n02 | Grenzmaske | res://assets/models/unit_n02.glb | assets-source/phase4/blend/n02.blend | starre Gelenkgruppen | 1156 | nicht spielbar, niedrige Detailstufe | Reserve für spätere Völker | Nebelchor (nicht spielbar) | niedrige Detailstufe | Neuaufbau nötig vor Nutzung |
|
||||
| n03 | Fadentänzer | res://assets/models/unit_n03.glb | assets-source/phase4/blend/n03.blend | starre Gelenkgruppen | 934 | nicht spielbar, niedrige Detailstufe | Reserve für spätere Völker | Nebelchor (nicht spielbar) | niedrige Detailstufe | Neuaufbau nötig vor Nutzung |
|
||||
| n04 | Saumzertrenner | res://assets/models/unit_n04.glb | assets-source/phase4/blend/n04.blend | starre Gelenkgruppen | 1360 | nicht spielbar, niedrige Detailstufe | Reserve für spätere Völker | Nebelchor (nicht spielbar) | niedrige Detailstufe | Neuaufbau nötig vor Nutzung |
|
||||
| n05 | Fernflüsterer | res://assets/models/unit_n05.glb | assets-source/phase4/blend/n05.blend | starre Gelenkgruppen | 1118 | nicht spielbar, niedrige Detailstufe | Reserve für spätere Völker | Nebelchor (nicht spielbar) | niedrige Detailstufe | Neuaufbau nötig vor Nutzung |
|
||||
| n06 | Fernrufer | res://assets/models/unit_n06.glb | assets-source/phase4/blend/n06.blend | starre Gelenkgruppen | 1498 | nicht spielbar, niedrige Detailstufe | Reserve für spätere Völker | Nebelchor (nicht spielbar) | niedrige Detailstufe | Neuaufbau nötig vor Nutzung |
|
||||
| n07 | Glockenschlepper | res://assets/models/unit_n07.glb | assets-source/phase4/blend/n07.blend | starre Gelenkgruppen | 1274 | nicht spielbar, niedrige Detailstufe | Reserve für spätere Völker | Nebelchor (nicht spielbar) | niedrige Detailstufe | Neuaufbau nötig vor Nutzung |
|
||||
| n08 | Hohlgeläut | res://assets/models/unit_n08.glb | assets-source/phase4/blend/n08.blend | starre Gelenkgruppen | 1482 | nicht spielbar, niedrige Detailstufe | Reserve für spätere Völker | Nebelchor (nicht spielbar) | niedrige Detailstufe | Neuaufbau nötig vor Nutzung |
|
||||
| n09 | Maskenkantor | res://assets/models/unit_n09.glb | assets-source/phase4/blend/n09.blend | starre Gelenkgruppen | 1314 | nicht spielbar, niedrige Detailstufe | Reserve für spätere Völker | Nebelchor (nicht spielbar) | niedrige Detailstufe | Neuaufbau nötig vor Nutzung |
|
||||
| n10 | Vielstimmenkantor | res://assets/models/unit_n10.glb | assets-source/phase4/blend/n10.blend | starre Gelenkgruppen | 1734 | nicht spielbar, niedrige Detailstufe | Reserve für spätere Völker | Nebelchor (nicht spielbar) | niedrige Detailstufe | Neuaufbau nötig vor Nutzung |
|
||||
| s01 | Nadelspäher | res://assets/models/unit_s01.glb | assets-source/phase4/blend/s01.blend | starre Gelenkgruppen | 10340 | Söldner | Reserve Angriffschampion | Söldner | HD, starre Teile | offen |
|
||||
| s02 | Rostschieber | res://assets/models/unit_s02.glb | assets-source/phase4/blend/s02.blend | starre Gelenkgruppen | 12040 | Söldner | Angriffschampion Schutz (Rostschieber) | Söldner | HD, starre Teile | umgesetzt (M2) |
|
||||
| s03 | Dunstsänger | res://assets/models/unit_s03.glb | assets-source/phase4/blend/s03.blend | starre Gelenkgruppen | 7832 | Söldner | Angriffschampion Druck auf Unterstützer (Dunstsänger) | Söldner | HD, starre Teile | umgesetzt (M2) |
|
||||
| s04 | Keilbrecher | res://assets/models/unit_s04.glb | assets-source/phase4/blend/s04.blend | starre Gelenkgruppen | 10458 | Söldner | Angriffschampion Belagerung (Keilbrecher) | Söldner | HD, starre Teile | umgesetzt (M2) |
|
||||
| s05 | Risszehrer | res://assets/models/unit_s05.glb | assets-source/phase4/blend/s05.blend | starre Gelenkgruppen | 10440 | Söldner | Reserve Angriffschampion | Söldner | HD, starre Teile | offen |
|
||||
| w01 | Dornhopser | res://assets/models/unit_w01.glb | assets-source/phase4/blend/w01.blend | starre Gelenkgruppen | 61376 | Wurzelbund Nahkampf | Truppe Nahkampf | Wurzelwesen / Wurzelbund | HD, starre Teile | keiner |
|
||||
| w02 | Rankenschnapper | res://assets/models/unit_w02.glb | assets-source/phase4/blend/w02.blend | starre Gelenkgruppen | 78020 | Wurzelbund Nahkampf+ | Truppenaufwertung | Wurzelwesen / Wurzelbund | HD, starre Teile | keiner |
|
||||
| w03 | Korkrücken | res://assets/models/unit_w03.glb | assets-source/phase4/blend/w03.blend | starre Gelenkgruppen | 84786 | Wurzelbund Tank | Truppe Front | Wurzelwesen / Wurzelbund | HD, starre Teile | keiner |
|
||||
| w04 | Ringborke | res://assets/characters/ringborke.glb | assets-source/phase11/ringborke.blend | 27 Knochen · 9 Clips | 118064 | Wurzelbund Tank+ | Truppenaufwertung; zusätzlich Held „Ringborke“ (vorläufig) | Wurzelwesen / Wurzelbund | gewichtetes Skelett (phase11) | umgesetzt (M2) |
|
||||
| w05 | Samenschleuder | res://assets/models/unit_w05.glb | assets-source/phase4/blend/w05.blend | starre Gelenkgruppen | 50536 | Wurzelbund Fernkampf | Truppe Fernkampf | Wurzelwesen / Wurzelbund | HD, starre Teile | keiner |
|
||||
| w06 | Zapfenkrone | res://assets/models/unit_w06.glb | assets-source/phase4/blend/w06.blend | starre Gelenkgruppen | 62588 | Wurzelbund Fernkampf+ | Truppenaufwertung | Wurzelwesen / Wurzelbund | HD, starre Teile | keiner |
|
||||
| w07 | Sporenkelch | res://assets/models/unit_w07.glb | assets-source/phase4/blend/w07.blend | starre Gelenkgruppen | 69164 | Wurzelbund Fläche | Truppe Fläche | Wurzelwesen / Wurzelbund | HD, starre Teile | keiner |
|
||||
| w08 | Pilzkathedrale | res://assets/models/unit_w08.glb | assets-source/phase4/blend/w08.blend | starre Gelenkgruppen | 103748 | Wurzelbund Fläche+ | Truppenaufwertung | Wurzelwesen / Wurzelbund | HD, starre Teile | keiner |
|
||||
| w09 | Tauhüter | res://assets/models/unit_w09.glb | assets-source/phase4/blend/w09.blend | starre Gelenkgruppen | 52040 | Wurzelbund Heiler | Truppe Unterstützung | Wurzelwesen / Wurzelbund | HD, starre Teile | keiner |
|
||||
| w10 | Quellgeflecht | res://assets/characters/quellgeflecht.glb | assets-source/phase16/quellgeflecht.blend | 17 Knochen · 9 Clips | 14276 | Wurzelbund Heiler+ | Truppenaufwertung; zusätzlich Held „Quellgeflecht“ (vorläufig) | Wurzelwesen / Wurzelbund | gewichtetes Skelett (phase16) | umgesetzt (M2) |
|
||||
| worker | Funkenleser | res://assets/characters/arbeiter.glb | assets-source/phase12/arbeiter.blend | 27 Knochen · 10 Clips | 7184 | Arbeiter/Funken | nicht im neuen Modus (Arbeitsannahme E); Modell bleibt erhalten | — | gewichtetes Skelett (phase12) | keiner |
|
||||
| p_biest | Klauenjäger | res://assets/luneraria/peoples/p_biest.glb | assets-source/luneraria/peoples/p_biest.blend | 24 Knochen · 9 Clips | 16858 | — | Volksrepräsentant Nahkampf (Klauenjäger) | Biestmenschen | gewichtetes Skelett (peoples, LP_*-Materialien) | neu (M3) |
|
||||
| p_elf | Waldläuferin | res://assets/luneraria/peoples/p_elf.glb | assets-source/luneraria/peoples/p_elf.blend | 24 Knochen · 9 Clips | 18502 | — | Volksrepräsentant Fernkampf (Waldläuferin) | Elfen | gewichtetes Skelett (peoples, LP_*-Materialien) | neu (M3) |
|
||||
| p_fee | Lichtheilerin | res://assets/luneraria/peoples/p_fee.glb | assets-source/luneraria/peoples/p_fee.blend | 24 Knochen · 9 Clips | 16744 | — | Volksrepräsentant Unterstützung (Lichtheilerin) | Feen | gewichtetes Skelett (peoples, LP_*-Materialien) | neu (M3) |
|
||||
| p_mensch | Ritter | res://assets/luneraria/peoples/p_mensch.glb | assets-source/luneraria/peoples/p_mensch.blend | 22 Knochen · 9 Clips | 17480 | — | Volksrepräsentant Front (Ritter) | Menschen | gewichtetes Skelett (peoples, LP_*-Materialien) | neu (M3) |
|
||||
| p_ork | Kriegshäuptling | res://assets/luneraria/peoples/p_ork.glb | assets-source/luneraria/peoples/p_ork.blend | 22 Knochen · 9 Clips | 15890 | — | Volksrepräsentant Nahkampf (Kriegshäuptling) | Orks | gewichtetes Skelett (peoples, LP_*-Materialien) | neu (M3) |
|
||||
| p_troll | Steinhauer | res://assets/luneraria/peoples/p_troll.glb | assets-source/luneraria/peoples/p_troll.blend | 22 Knochen · 9 Clips | 14686 | — | Volksrepräsentant Fläche (Steinhauer) | Trolle | gewichtetes Skelett (peoples, LP_*-Materialien) | neu (M3) |
|
||||
| p_zwerg | Schildträger | res://assets/luneraria/peoples/p_zwerg.glb | assets-source/luneraria/peoples/p_zwerg.blend | 22 Knochen · 9 Clips | 20214 | — | Volksrepräsentant Front (Schildträger) | Zwerge | gewichtetes Skelett (peoples, LP_*-Materialien) | neu (M3) |
|
||||
| menu-stage | Menü-Diorama | res://assets/environment/menu-stage.glb | assets-source/phase20/build_menu_stage.py | statisch | 48660 | Hauptmenü Phase 20A | Hauptmenü (Titel angepasst) | — | Kluft-Shader | keiner |
|
||||
| verdant-rift | Grüne Kluft (2-Bretter-Arena) | res://assets/environment/verdant-rift.glb | assets-source/phase10/verdant-rift.blend | statisch | — | Spielfeld Saumwacht | Legacy-Modus; Materialien/Shader für die neue Karte wiederverwendet | — | triplanare Kluft-Shader | keine neue Nutzung als Karte |
|
||||
| lane_tower | Laneturm | res://assets/luneraria/tower.glb | assets-source/luneraria/build_tower.py | statisch | 648 | — | 16 Lanetürme und Basistürme, Kristall zur Laufzeit in Teamfarbe | — | ENV_*-Kluftshader, Kristall emissiv | neu (M1) |
|
||||
| boss_grotto | Bossgrotte | res://assets/luneraria/grotto.glb | assets-source/luneraria/build_grotto.py | statisch | 1888 | — | Felsinsel mit Höhle auf der Symmetrieachse, zwei gespiegelte Zugänge | — | ENV_*-Kluftshader, violette Kristalle | neu (M2) |
|
||||
| map_props | Kartenprops (Bäume, Felsen, Büsche, Brücken, Bordsteine, Klippen, Banner) | res://assets/luneraria/map_props.glb | assets-source/luneraria/build_map_props.py | statisch | MultiMesh | — | 3D-Kartendekoration der drei Lanes, Brücken über die Kluft, Klampterrahmen | — | ENV_*-Kluftshader | neu (M3) |
|
||||
| luneraria-emblem | Emblem Luneraria | res://assets/ui/emblems/luneraria.svg | SVG | — | — | — | Titel und Menü | — | Vektor | neu (M1) |
|
||||
| Emblem/Theme | Saumwacht-Theme | scripts/ui/theme/, assets/ui/ | Code / SVG | — | — | Menü 20A | Theme weiterverwendet, Titel/Emblem Luneraria | — | Vektor | Titelschrift/Emblem ergänzen |
|
||||
| compare-rock / compare-tree | Fels, Baum (Alt) | res://assets/compare/ | assets-source/phase14/build_compare_props.py | statisch | 360 / 852 | Vergleichsszene | ab M3 durch map_props ersetzt | — | einfach | abgelöst (M3) |
|
||||
119
docs/luneraria/BALANCE.md
Normal file
119
docs/luneraria/BALANCE.md
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
# Balancekonfiguration und Auswertung
|
||||
|
||||
Alle Werte stehen in `scripts/luneraria/core/lune_balance.gd`. Die aktive Standardinstanz ist `data/luneraria/balance_default.tres`, die derzeit alle Klassenwerte übernimmt.
|
||||
|
||||
## Startwerte (M1) und Begründung
|
||||
|
||||
| Wert | Stand | Begründung |
|
||||
| --- | ---: | --- |
|
||||
| Startgold | 220 | Wie im Saumwacht-Einstieg; reicht für die Startaufstellung (180/185) plus Rest. |
|
||||
| Grundeinkommen | 70 + 4 je Runde, Obergrenze +80 | Etwa eine Truppe pro Runde; der Zuwachs hält mit den Wellen mit, ohne endlos zu steigen. |
|
||||
| Versorgungsgrenze | 12 Truppen je Spieler | Begrenzt aktive Einheiten; später investiert man in Aufwertungen statt in Masse. |
|
||||
| Verkauf | 75 % (in derselben Planung 100 %) | Aus Saumwacht übernommen; die Rücknahme im selben Planungsschritt ist ein Bedienkomfort. |
|
||||
| Wellen | 3 Monster je Lane und Team, +1 alle 3 Runden, max. 7 | Pro Runde höchstens 42 Monster auf der Karte. |
|
||||
| Wellenstärke | HP ×(1 + 0,11·r + 0,0015·r²), Schaden ×(1 + 0,07·r + 0,0015·r²) | Stetig und quadratisch leicht zunehmend, ohne Obergrenze; bei r = 10⁶ endlich (Test). |
|
||||
| Monsterkopfgeld | Katalogwert ×2 ×(1 + 0,04·r) | Monster sind die Hauptgoldquelle; wächst langsamer als die Stärke. |
|
||||
| Türme | außen 6.000 / innen 7.500 / Basis 9.000 HP, 90 / 120 Schaden, Reichweite 8,6 m | Eine Welle allein kommt nicht durch. Die Reichweite liegt über der größten Einheitenreichweite (6,5 m + Gebäuderadius), sonst wären Türme ungestraft auszuschießen. |
|
||||
| Ancient | 12.000 HP | Braucht eine voll durchbrochene Basis und mehrere Runden Druck. |
|
||||
| Gebäudekopfgeld | 150 / 210 / 270 | Belohnt Durchbrüche gleichmäßig im Team. |
|
||||
| Kampffenster | 180 s | In 91 Bot-Kampfphasen (8 Seeds) dauerte die längste 130 s, im Mittel 68 s; keine erreichte das Fenster. Es greift nur bei festgefahrenen Kämpfen. |
|
||||
| Marschtempo | Katalogtempo ×1,6 | Eine Lane (~95 m) ist in ~30 s durchquerbar, damit Angriffe die Basis innerhalb eines Kampfes erreichen. |
|
||||
|
||||
## Auswertung M1 (reine Bot-Partien, 1 Mensch = Bot)
|
||||
|
||||
[sim-8-seeds.json](logs/m1/sim-8-seeds.json): acht Seeds mit gemischten Bünden und fünf Bot-Profilen (ausgewogen, verteidigung, druck, fernkampf, teamhilfe). Die Ergebnisse stehen in [STATUS.md](STATUS.md).
|
||||
|
||||
- Alle acht Partien enden regulär durch einen Ancient-Fall, nach 8–15 Wellen (Blau 5, Rot 3). 83 Kampfphasen enden, weil alle beweglichen Einheiten gefallen sind, 8 durch einen Kernfall, keine durch das Zeitfenster.
|
||||
- **Exakter Spiegel** (sechsmal derselbe Bund, dasselbe deterministische Profil): Die Partie bleibt über 60 Runden Bit für Bit symmetrisch. Sie wird aber nicht entschieden, weil sich gleich starke Armeen und Wellen gegenseitig aufheben. Das ist der erwartbare Grenzfall identischen Spiels. Kein Timer oder Gebäudeverfall erzwingt ein Ende. Heldenwachstum, Angriffschampions und Boss (M2) liefern die beabsichtigten Asymmetrien.
|
||||
- Kleine Botstichproben belegen keine ausgewogene Spielerfahrung. Die Bünde und Profile sind noch nicht getrennt ausgewertet (M3).
|
||||
|
||||
## M2 · Helden, Items, Champions, Boss
|
||||
|
||||
Werte in `scripts/luneraria/core/lune_content.gd`, Begründungen im [Regelwerk](REGELWERK.md) §4.
|
||||
|
||||
| Wert | Stand | Begründung |
|
||||
| --- | ---: | --- |
|
||||
| Heldenpreis | 260 | Mehr als das Startgold: Ein Held kommt frühestens in Runde 2 und ersetzt keine frühe Armee. |
|
||||
| Heldenwerte | Ringborke 2.200 HP / 34, Quellgeflecht 1.300 / 28, Funkenlanze 950 / 46 | Aus den Truppenwerten der Aufwertungsstufe mit etwa 1,4-fachem Leben abgeleitet. |
|
||||
| Stufen | 10; +9 % Leben, +7 % Schaden je Stufe | In 12 Bot-Partien erreichen Helden bis Partieende Stufe 3–6, Talentstufe 2 also erst spät. |
|
||||
| Items | 180–260 | Ein Item kostet etwa eine aufgewertete Truppe. |
|
||||
| Champions | 150/150/180, Leben ×2,2, Schaden ×1,6 der Söldnerwerte, Kopfgeld 70 + 6·r | Einmalige Welle etwa zum Preis von zwei Truppen. |
|
||||
| Grottenboss | 4.200 HP × Wellenstärke, 55 Schaden | Nur mit großer Expedition schaffbar (Szenarien unten). |
|
||||
| Entsandter Boss | 5.200 HP × Wellenstärke, 70 Schaden, Kopfgeld 520 + 60·r | Das Kopfgeld liegt deutlich über einem Turm (150–270) und über einem Monster (~10–30). |
|
||||
|
||||
### Bot-Serie (12 Seeds, [sim-12-seeds.json](logs/m2/sim-12-seeds.json))
|
||||
|
||||
- Alle 12 Partien enden regulär nach 7–10 Wellen (Blau 7, Rot 5), keine Kampfphase im Zeitfenster; die längste dauerte 128 s.
|
||||
- Bossversuche: 36 gescheitert, 11 erobert, 7 entsandt (die übrigen Partien endeten vorher).
|
||||
- **Befund:** Der Bossjäger-Bot versucht es in jeder Partie ab Runde 5, scheitert bis Runde 7 und siegt in Runde 8. Das Muster ist zu gleichförmig; der Bot schätzt seine Stärke nicht ein (M3).
|
||||
- Siegquote des Teams mit dem jeweiligen Profil: fernkampf 11/12, druck 9/12, teamhilfe 7/12, verteidigung 5/12, bossjagd 3/12, ausgewogen 1/12. **Vorsicht:** Jede Partie enthält jedes Profil genau einmal, und die Paare fernkampf/ausgewogen, druck/bossjagd und verteidigung/teamhilfe stehen immer in verschiedenen Teams. Die Zahlen sind daher nicht unabhängig; eine saubere Auswertung mit variierter Teamzusammensetzung folgt in M3.
|
||||
|
||||
### Bossstrategie im direkten Vergleich ([boss_scenarios.gd](../../tools/luneraria/boss_scenarios.gd))
|
||||
|
||||
Identischer Stand nach Runde 7, danach vier Runden mit gewöhnlichen Bots ohne Bossjagd. Wert = eingesetzter Armeewert (Blau / Rot). ΔHP und ΔGold jeweils Blau / Rot über die vier Runden.
|
||||
|
||||
| Seed | Szenario | Wert | Grotte | Mid-Türme Blau verloren | Bossrunde | Gebäudeschaden Rot durch Boss | Kopfgeld für Rot | ΔHP Gebäude | ΔGold | Sieger |
|
||||
| --- | --- | ---: | --- | ---: | ---: | ---: | ---: | ---: | ---: | --- |
|
||||
| 3 | kein_versuch | 0 | none | 0 | — | 0 | — | -1.436 / -50.521 | 284 / -235 | Blau |
|
||||
| 3 | gescheitert | 210 | failed | 0 | — | 0 | — | -1.754 / -50.257 | 284 / -235 | Blau |
|
||||
| 3 | erfolgreich | 1000 | won | 2 | 9 | 33.219 | 1060 | -15.023 / -35.384 | 543 / 794 | Blau |
|
||||
| 3 | umkaempft | 1000 / 995 | failed | 0 | — | 0 | — | -1.435 / -51.276 | 494 / -185 | Blau |
|
||||
| 3 | ueberinvestition | 2495 | won | 2 | 9 | 25.392 | 1060 | -68.295 / -25.392 | -250 / 437 | Rot |
|
||||
| 7 | kein_versuch | 0 | none | 0 | — | 0 | — | -9.222 / -5.573 | 174 / 139 | offen |
|
||||
| 7 | gescheitert | 180 | failed | 0 | — | 0 | — | -9.548 / -4.660 | 174 / 139 | offen |
|
||||
| 7 | erfolgreich | 930 | won | 2 | 9 | 22.793 | 1060 | -67.737 / -22.793 | -302 / 319 | Rot |
|
||||
| 7 | umkaempft | 930 / 865 | failed | 0 | — | 0 | — | -9.855 / -4.660 | 174 / 139 | offen |
|
||||
| 7 | ueberinvestition | 2580 | won | 2 | 9 | 20.685 | 1060 | -67.737 / -20.685 | -320 / 277 | Rot |
|
||||
|
||||
**Deutung:**
|
||||
- Eine gescheiterte kleine Expedition kostet wenig.
|
||||
- In der umkämpften Grotte reiben sich beide Expeditionen auf; kein Team erhält den Anspruch.
|
||||
- Eine erfolgreiche Eroberung zieht die Mid-Lane so weit ab, dass Blau dort beide Türme verliert. Der Boss richtet danach 20.000–33.000 HP Gebäudeschaden an, stirbt und bringt Rot 1.060 Gold.
|
||||
- Überinvestition kippt die Partie in beiden Seeds zu Rot, und auch die normale Eroberung verliert bei Seed 7.
|
||||
- Die Bossstrategie ist damit riskant und nicht dominant. Nach diesen Stichproben wiegt der Boss die geschwächte Lane eher zu wenig auf: ein Balancepunkt für M3 (z. B. mehr Bosswirkung oder schwächerer Grottenboss). Es gibt weder eine kostenlose Sofortrückkehr noch eine Doppelbelohnung (Tests); das Goldrisiko steht im Kopfgeld offen angekündigt.
|
||||
|
||||
## M3 · Qualität und Balance
|
||||
|
||||
### Geänderte Werte und Bot-Regeln
|
||||
|
||||
| Thema | Vorher | Nachher | Begründung |
|
||||
| --- | --- | --- | --- |
|
||||
| Keilbrecher Belagerungsfaktor | ×2,5 | ×1,8 | Belagerungs-Champion dominierte Gebäude zu stark. |
|
||||
| Grottenboss HP | 4.200 | 3.600 | Expeditionen scheiterten zu oft vor Runde 8. |
|
||||
| Entsandter Boss | 5.200 HP / 70 Schaden | 6.800 HP / 88 Schaden | Die Belohnung wiegt die geschwächte Lane nun besser auf. |
|
||||
| Bot Item-/Championkauf | nach der Armee | **vor** der Armee (Reserve 110 bzw. 40 Gold) | Die Roster-Schleife verzehrte die gesamte Reserve; Helden blieben ohne Items, Champions wurden nie gebucht (`test_lune_m2` bots_m2). |
|
||||
| Bot Lane-Hilfe | geteilter Zufall (`rng`) | deterministisch `(Runde + Laneindex) % Periode` | Der geteilte Zufall brach die Spiegelsymmetrie (`test_lune_core` mirror_fairness). |
|
||||
| Bossjagd-Schwelle | Lanchester 2,0 | 1,35 (+1,25 je Fehlversuch) | Frühere Versuche erst ab Runde 8; Ziel: sinnvolle Risikoabschätzung. |
|
||||
| Expeditionstärke | 6 Truppen + Held | 5 Truppen + Held | Weniger Lane-Abzug bei der Jagd. |
|
||||
| Ausgewogen-Held | ab Runde 3 | ab Runde 4 | Reines „ausgewogen“ schlug in Spiegel-Duellen alle Spezialprofile. |
|
||||
| Verteidigung | kein Champion, 40 % Front | Champion Schutz, 15 % Lane-Hilfe | Reines Verteidigen gewann zu selten (14 %). |
|
||||
|
||||
### Bot-Serie (20 Zusammensetzungen × Seitentausch, [balance-step4.json](logs/m3/balance-step4.json))
|
||||
|
||||
- 40 Partien, alle regulär durch Ancient-Fall nach 9–14 Wellen (Median 11). Kein Testlimit, kein Zeitfenster-Kampf.
|
||||
- **Seitentausch 20/20:** dieselbe Zusammensetzung gewinnt beide Male. Keine Seitenbevorzugung.
|
||||
- Profile (Siege/Einsätze): verteidigung 64 %, ausgewogen 58 %, fernkampf 54 %, druck 53 %, teamhilfe 46 %, bossjagd 24 %.
|
||||
- Bünde: Glutpakt 55 % / Wurzelbund 45 %.
|
||||
- Boss: 20 Erfolge, 8 Entsendungen. Heldenstufe am Ende (Median) 4.
|
||||
|
||||
### Reine Profil-Duelle ([matchups-step4.json](logs/m3/matchups-step4.json))
|
||||
|
||||
15 Paare × 2 Seiten = 30 Partien. Seitentausch 15/15 konsistent.
|
||||
|
||||
| Profil | Siege | Duellkette |
|
||||
| --- | ---: | --- |
|
||||
| ausgewogen | 10/10 | schlägt alle Spezialprofile |
|
||||
| verteidigung | 8/10 | verliert nur gegen ausgewogen |
|
||||
| teamhilfe | 6/10 | schlägt druck, fernkampf, bossjagd |
|
||||
| fernkampf | 4/10 | schlägt druck, bossjagd |
|
||||
| druck | 2/10 | schlägt bossjagd |
|
||||
| bossjagd | 0/10 | verliert gegen jedes Spezialprofil |
|
||||
|
||||
**Befund:** In reinen 3-gleichen Spiegeln ergibt sich eine lineare Kette, kein Zyklus. In gemischten Sechser-Aufstellungen (die eigentliche Partie) liegen alle Profile im Band 24–64 %. Kleine Botstichproben beweisen keine ausgewogene Spielerfahrung; menschliche Spieltests bleiben offen. Bossjagd ist als reines Teamprofil schwach, in Mischteams aber spielbar (24 %).
|
||||
|
||||
### Belastungstests ([stress.json](logs/m3/stress.json))
|
||||
|
||||
- 17/17 Prüfungen, keine Fehler.
|
||||
- Wellenindizes 10², 10³, 10⁴, 10⁶ enden regulär über Kernfall; Monster-HP endlich (bei 10⁶ ≈ 7,2·10¹¹), kein NaN, kein Arrayfehler, mobile Einheiten gedeckelt (120).
|
||||
- Langlauf 200 Runden: „Testlimit erreicht / Partie nicht abgeschlossen“ (korrekt, kein Unentschieden). Objektzahl stabil (1706 → 1853), Speicher 52 → 53 MB. Rundenzeit 1,05 s → 2,01 s (wachsende Wellenmenge, kein Leck).
|
||||
|
||||
68
docs/luneraria/QA-MATRIX.md
Normal file
68
docs/luneraria/QA-MATRIX.md
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
# QA-Matrix
|
||||
|
||||
Testumgebung aller Läufe: Fedora Linux 44 (KDE Plasma, XWayland), AMD Ryzen 5 5600X, NVIDIA GeForce RTX 5060 Ti (Vulkan 1.4.351), Godot 4.7.2 (Fedora-Build), Forward+. **Windows 11 ist nicht geprüft:** Es gibt keine Windows-Hardware in dieser Umgebung.
|
||||
|
||||
Legende: ✅ automatisiert geprüft · 👁 in echten Aufnahmen visuell geprüft · ⏳ offen (Meilenstein) · — nicht zutreffend.
|
||||
|
||||
## Abnahmepunkte aus dem Masterauftrag (§15)
|
||||
|
||||
| # | Anforderung | Stand | Beleg |
|
||||
| --- | --- | --- | --- |
|
||||
| 1 | Zwei Teams, sechs Eigentümerrollen, drei Lanes, 16 Türme, 2 Kerne | ✅ M1 | `test_lune_core` · structure |
|
||||
| 2 | Turmreihenfolge, Basisschutz, Kernsieg; gleichzeitige Kernzerstörung ohne Reihenfolgevorteil | ✅ M1 | `test_lune_core` · gates, victory_and_draw, mirror_fairness |
|
||||
| 3 | Fortsetzung nach Welle 20, hohe Indizes ohne Final-Wave-Logik, Fehler oder Objektwachstum | ✅ M1 (Wellen bis 10⁶, Runde 21; Menge ≤ 7 je Lane) | `test_lune_core` · endless_waves |
|
||||
| 4 | Gold exakt einmal, Besitzprüfung, keine Reset-/Despawn-/Beschwörungsfarmen | ✅ M1 (Monster, Gebäude, Truppentod ohne Kopfgeld); Beschwörungen gibt es noch nicht | `test_lune_core` · rewards, commands |
|
||||
| 5 | Heilung und Persistenz nach der Runde; neue Partie ohne übernommene Werte | ✅ M1 Truppen · ✅ M2 Helden (XP, Stufe, Talente, Items bleiben; Rückkehr geheilt, auch nach dem Tod; neue Partie ohne Held) | `test_lune_core` · persistence; `test_lune_m2` · xp_and_persistence |
|
||||
| 6 | Truppen ohne Heldeninventar; Talente, drei Itemplätze, Stapeln | ✅ M2 | `test_lune_m2` · heroes_and_items |
|
||||
| 7 | Verstärkungskauf n → Einsatz n+1, richtige Lane und richtiges Team | ✅ M2 (öffentliche Ankündigung, keine Verschiebung nach Übernahme, Verbrauch nach n+1, Kopfgeld, Belagerungsziel) | `test_lune_m2` · champions |
|
||||
| 8 | Grottenabzug schwächt die Lane für die ganze Kampfphase | ✅ M2 | `test_lune_m2` · grotto_withdrawal_and_contest |
|
||||
| 9 | Beide Expeditionen, Scheitern, Erfolg, genau eine Entsendung, Kopfgeld, Verfügbarkeit ab Runde 10 | ✅ M2 (Sieg in Runde 6 → Einsatz 7 → gesperrt 7–9 → frei ab 10; wiederholtes Signal ohne Wirkung) | `test_lune_m2` · boss_*; Szenarien `boss_scenarios` |
|
||||
| 10 | Laneverlust, Phasenende, Pause, Neustart, Rückkehr ins Menü | ✅ M1/M2 | `verify_m1`, `test_lune_core` · victory (timeout), `test_lune_m2` · lane_loss |
|
||||
| 11 | Bots ohne Sonderressourcen und ohne Sicht auf private Befehle | ✅ Bots nutzen dieselben Befehle ohne Sondergold; sie lesen nur den eigenen Entwurf, veröffentlichte Gebäudestände, den öffentlichen Bosszustand und Ankündigungen (Code-Durchsicht, `LuneBot`) | `test_lune_core` · commands; `test_lune_m2` · bots_m2 |
|
||||
| 12 | Netzwerk: doppelte, veraltete und fremde Befehle; synchroner Phasenwechsel, Disconnect | ⏳ M4 | — |
|
||||
|
||||
## M3 · Qualität und Balance
|
||||
|
||||
| Nachweis | Stand | Beleg |
|
||||
| --- | --- | --- |
|
||||
| Mehrere Seeds und gemischte Teamzusammensetzungen, Seitentausch | ✅ 20 Zusammensetzungen × 2 Seiten, 20/20 konsistent | `balance_run` · `logs/m3/balance-step4.json` |
|
||||
| Gegenstrategien / Profil-Duelle | ✅ 15 Paare, 15/15 Seitenfair; lineare Kette (Befund) | `balance_run --matchups` · `matchups-step4.json` |
|
||||
| Hohe Wellenindizes und Langlauf | ✅ 10²–10⁶ ohne Fehler; 200 Runden = Testlimit, keine Objektflut | `stress_run` · `logs/m3/stress.json` |
|
||||
| Bot kauft Items und Angriffschampions | ✅ Regression `test_lune_m2` bots_m2 (war 0 Buchungen) | `test_lune_m2` 73/73 |
|
||||
| Spiegelsymmetrie mit erweiterten Bots | ✅ glutpakt/wurzelbund je 12 Runden bit-symmetrisch | `test_lune_core` mirror_fairness |
|
||||
| Karte mit echten Props (Bäume, Felsen, Brücken, Bordsteine, Banner) | 👁 Übersicht, Kampf Top/Mid, Planung | `screenshots/overview-*.png`, `combat-*.png` |
|
||||
| Sieben Volksrepräsentanten (Modelle + Clips) | 👁 Ruhe, Kontakt, Laufen, Fähigkeit, Tod, Nahaufnahme | `screenshots/peoples-*.png`, `people_lineup` |
|
||||
| Assetmatrix mit `p_*` und map_props | ✅ 74 Zeilen | `python3 tools/luneraria/build_asset_matrix.py` |
|
||||
|
||||
## Echte Anwendung (M1)
|
||||
|
||||
`tools/luneraria/verify_m1.tscn`, 38 Prüfungen mit echten Maus- und Tastaturereignissen:
|
||||
|
||||
- Titel und Projektname, Lane- und Bundwahl per Klick, Start.
|
||||
- Eingabeschutz während der Überblendung: Mausrad, 1 und Leertaste erreichen das Spiel nicht.
|
||||
- Kauf, Startaufstellung, Rückgängig, Laneeinteilung und die Leertaste übernehmen die Planung; im Kampf wird nichts gekauft.
|
||||
- Truppen kämpfen auf ihrer Lane; Pause hält die Kampfuhr an; Tempo schaltet um.
|
||||
- Abrechnung und Rückkehr der Truppen.
|
||||
- HUD innerhalb des Fensters bei 1280 × 720 und 1920 × 1080.
|
||||
- Menü, neue Partie ohne Altlasten, eine vollständige Partie bis zum Ancient-Fall mit Live-Aufnahme der Belagerung, Ergebnisbildschirm, Rematch.
|
||||
- Vier Menü-/Partiewechsel ohne wachsende Objektzahl.
|
||||
|
||||
Nur die Kampfuhr wird dabei beschleunigt (mehr feste Schritte pro Bild), die Regeln bleiben unverändert.
|
||||
|
||||
## Echte Anwendung (M2)
|
||||
|
||||
`tools/luneraria/verify_m2.tscn`, 15 Prüfungen. Teil 1 bedient das HUD mit echten Klicks: Reiter, Held anwerben, Held-Lane, Truppe kaufen und in die Grotte schicken, Verstärkungsseite, Rückgängig. Teil 2 spielt eine gewöhnliche Partie ohne Sondergold bis zum Ancient-Fall; der menschliche Platz wird vom Bot-Planer über dieselben Befehle gespielt. Aufgenommen: Held mit Items, Held im Feld, Grottenkampf, Ankündigung, Bossentsendung.
|
||||
|
||||
Weitere M2-Belege: `test_lune_m2` 73/73, darunter der Nachweis, dass die alte Arbeiter- und Funkenökonomie nicht mitläuft (Arbeitsannahme E). M2-App nach M3-Botfix erneut 15/15 (bzw. 14/14, wenn die Partie vor einer Bossentsendung endet).
|
||||
|
||||
## Legacy-Regressionen (Saumwacht)
|
||||
|
||||
Unverändert über die Umleitung der alten QA-Schalter: 209 · 33 · 463 · 206 · 1.665 · Menü 20A 68. Logs: `logs/m0-baseline/`, `logs/m1/legacy-*.log`.
|
||||
|
||||
## Plattformen
|
||||
|
||||
| Plattform | Stand |
|
||||
| --- | --- |
|
||||
| Fedora 44, Forward+ | ✅ Quellprojekt (Tests, Aufnahmen, Leistung, Balance, Stress) |
|
||||
| Fedora 44, Kompatibilitätsmodus (OpenGL) | ⏳ M4 (für Saumwacht 0.15.0 geprüft, für Luneraria noch nicht) |
|
||||
| Windows 11 | ⏳ nicht geprüft (keine Hardware). Ein exportiertes Paket oder ein Wine-Lauf wäre kein nativer Test. |
|
||||
72
docs/luneraria/REGELWERK.md
Normal file
72
docs/luneraria/REGELWERK.md
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
# Champions of Luneraria · Regelwerk
|
||||
|
||||
Stand: 27. September 2026. Drei Ebenen, getrennt gehalten:
|
||||
|
||||
1. **Verbindliche Produktregeln** aus dem Masterauftrag. Änderungen nur per ausdrücklicher Entscheidung des Auftraggebers.
|
||||
2. **Arbeitsannahmen A–F** aus dem Masterauftrag, als anpassbare Designentscheidungen formuliert. Es sind keine Nutzerzitate.
|
||||
3. **Eigene Detailentscheidungen** dieser Umsetzung, anpassbar und mit Konfigurationsort.
|
||||
|
||||
## 1 · Verbindliche Produktregeln
|
||||
|
||||
- Titel: **Champions of Luneraria**.
|
||||
- Zwei Teams mit je drei eigenständigen Spielerrollen.
|
||||
- Drei zusammenhängende Lanes: Top, Mid, Bottom.
|
||||
- Kämpfe laufen automatisch. Es gibt weder direkte Heldensteuerung noch manuelles Last-Hitting.
|
||||
- Die Partie endet ausschließlich durch Zerstörung eines Ancient-Kerns. Es gibt keine maximale Rundenzahl, keinen Sieg nach einer Wellengrenze, keine Entscheidung nach Kern-HP und keinen Sieger per Zeitlimit.
|
||||
- Werden beide Kerne im selben Simulationsschritt zerstört, ist das ein Unentschieden, unabhängig von Array-, Render- oder Netzwerkreihenfolge. Ein manueller Testabbruch oder technischer Abbruch ist kein Kern-Sieg.
|
||||
- Monsterwellen werden mit jeder Welle stärker.
|
||||
- Je Team und Lane zwei Lanetürme; zusätzliche Türme schützen den Ancient.
|
||||
- Normale Truppen werden dauerhaft gekauft und aufgewertet; sie haben kein Levelsystem und keine Items.
|
||||
- Helden werden gekauft, sammeln in der Partie Erfahrung und entwickeln sich über Items und Talente.
|
||||
- Angriffschampions werden mit Gold als einmalige Verstärkung einer Angriffswelle gekauft.
|
||||
- Besiegte Monster und Angriffschampions geben Gold.
|
||||
- Eine gemeinsame Bossgrotte bindet Einheiten, die dafür ihre Lane verlassen.
|
||||
- Nach erfolgreicher Eroberung verstärkt der Boss einmalig den Angriff des **siegreichen** Teams in der folgenden Runde, gegen das **gegnerische** Team. Er läuft zum gegnerischen Ancient.
|
||||
- Der entsandte Boss gibt dem verteidigenden Team bei seinem Tod deutlich mehr Gold als ein normaler Gegner.
|
||||
- Nach einem Bosssieg ist die Grotte drei vollständige Runden gesperrt. Beispiel: Sieg in Runde 6, Einsatz in Runde 7, Sperre 7–9, wieder bekämpfbar ab 10.
|
||||
- Vorhandene Assets werden bevorzugt erhalten. Inhaltsziel: Elfen, Trolle, Zwerge, Menschen, Feen, Orks, Biestmenschen; bestehende Wesen und Bünde bleiben Teil der Welt.
|
||||
- Ziel ist taktische Wiederspielbarkeit.
|
||||
|
||||
## 2 · Arbeitsannahmen (Masterauftrag, anpassbar)
|
||||
|
||||
- **A** Dauerhafte Truppen und Helden rücken mit den eigenen Monsterwellen über ihre Lane vor und greifen danach zulässige gegnerische Gebäude an.
|
||||
- **B** Jeder Spieler hat eigenes Gold und eine eigene Armee. Seine Lane ist die anfängliche Zuständigkeit; Unterstützung anderer Lanes ist möglich. Das Team ist unabhängig von Volk und Bund.
|
||||
- **C** Ein aktiver Held pro Spieler mit drei Itemplätzen; mehrere Helden zur Wahl. Normale Truppen bleiben relevant.
|
||||
- **D** Genau zwei gemeinsame Basistürme pro Team: acht Türme je Team, sechzehn auf der Karte, plus zwei Ancients.
|
||||
- **E** Die alte Arbeiter- und Funkenökonomie läuft im neuen Modus nicht. Gold finanziert Armee, Aufwertungen, Helden, Items und Angriffschampions.
|
||||
- **F** Erster Modus: echte Sechs-Spieler-Simulation mit einem Menschen und fünf Bots. Netzwerk folgt als eigener Meilenstein.
|
||||
|
||||
## 3 · Detailentscheidungen dieser Umsetzung
|
||||
|
||||
Alle Zahlen stehen zentral in `data/luneraria/balance_default.tres` (Klasse `LuneBalance`).
|
||||
|
||||
| Thema | Entscheidung |
|
||||
| --- | --- |
|
||||
| Runde | Planung → Befehle werden atomar übernommen → automatischer Kampf → Abrechnung → nächste Planung. Die Wellennummer steigt unbegrenzt. |
|
||||
| Simulation | Feste Schrittweite 1/20 s. Jeder Schritt läuft in zwei Phasen: erst werden alle Treffer, Heilungen und Effekte aus dem Zustand zu Schrittbeginn berechnet, dann gleichzeitig angewendet. Todesfälle eines Schritts gelten gemeinsam. So entsteht kein Vorteil aus der Verarbeitungsreihenfolge. |
|
||||
| Aufmarsch | Armeen und Wellen starten jede Runde an festen, symmetrischen Aufmarschflächen ihrer Lane. Formationsplätze sind Offsets vor/quer zur Laufrichtung. Keine Front-Teleports. |
|
||||
| Vormarsch | Ohne Ziel folgen Einheiten ihrer Lane. Sie kommen nicht an einem lebenden gegnerischen Turm ihrer Lane vorbei. Am Laneende greifen sie das nächste zulässige Basisgebäude an. |
|
||||
| Gebäudesperren | Der innere Turm ist erst nach dem äußeren verwundbar. Die Basistürme sind verwundbar, sobald eine Lane des Teams ganz durchbrochen ist. Der Ancient ist erst verwundbar, wenn beide Basistürme gefallen sind. Die Sperre gilt für jeden Schaden (Fernkampf, Fläche, Fähigkeiten, Boss). Gesperrte Gebäude schießen weiter. |
|
||||
| Kampfende | Eine Kampfphase endet, wenn keine beweglichen Einheiten mehr leben, wenn ein Kern fällt oder wenn das Zeitfenster abläuft (Standard 180 s). Das Zeitfenster beendet nur die Kampfphase, nie die Partie. Übrige temporäre Einheiten verschwinden ohne Belohnung, dauerhafte kehren zurück. Es gibt keinen Kernschaden durch den Abbruch. |
|
||||
| Rückkehr | Dauerhafte Truppen und Helden kehren nach jeder Kampfphase vollständig geheilt zurück, auch wenn sie im Kampf gefallen sind. Schilde, Brand, Verlangsamungen, Stärkungen und Abklingzeiten werden auf Startwerte zurückgesetzt. Aufwertungen, Erfahrung, Items und Talente bleiben. |
|
||||
| Gebäude | Türme und Kerne behalten Schaden; zerstörte Gebäude kehren nicht zurück. Gebäude skalieren nicht mit der Welle. |
|
||||
| Belohnung | Pro gegnerischem Todesereignis genau eine Belohnung, egal wer tötet. Lane-Killgold geht zur Hälfte an den zuständigen Lane-Spieler des tötenden Teams und zur Hälfte gleichmäßig an alle drei. Der Rest der Ganzzahlteilung geht in stabiler Slotreihenfolge. Gebäude- und Boss-Kopfgelder werden gleichmäßig im Team verteilt. Dauerhafte Truppen und Helden geben kein Kopfgeld. |
|
||||
| Laneverlust | Kein Spieler scheidet aus. Er baut weiter auf, verteidigt und unterstützt. |
|
||||
| Pause | Offline darf die Planung auf den Menschen warten; Pause und Tempo 1×/2×/4× gelten nur lokal. |
|
||||
| QA-Grenze | Testläufe dürfen eine Rundenobergrenze haben. Eine dort nicht beendete Partie wird als „Testlimit erreicht / Partie nicht abgeschlossen“ protokolliert, nie als Sieg oder Unentschieden. |
|
||||
|
||||
## 4 · Detailentscheidungen M2 (anpassbar, Werte in `scripts/luneraria/core/lune_content.gd`)
|
||||
|
||||
| Thema | Entscheidung |
|
||||
| --- | --- |
|
||||
| Helden | Drei Helden aus vorhandenen Skelettmodellen, als **vorläufige Rollenzuordnung**: Ringborke (Front/Schutz), Quellgeflecht (Heilung), Funkenlanze (Fernkampf). Jeder Spieler kann einen aktiven Helden anwerben, unabhängig vom Bund, für 260 Gold. Damit ist ein Held frühestens ab Runde 2 erschwinglich. Ein Held aus derselben Planung lässt sich voll erstatten, danach bleibt er bis Partieende. |
|
||||
| Erfahrung | Nicht an den letzten Treffer gebunden. Jeder Held, der an einer Kampfphase teilnimmt, erhält 40 + 6 × Runde. Jeder gegnerische Tod im Umkreis von 12 m (Gebäude 14 m) wird zu gleichen Teilen auf alle Helden in der Nähe verteilt: Monster 12 + Runde, Champion 30 + 2 × Runde, Boss 220, Truppe/Held 15, Gebäude 60. So erhalten auch Heiler in der zweiten Reihe Erfahrung. Stufen 1–10, je Stufe +9 % Leben und +7 % Schaden. |
|
||||
| Talente | Auf Stufe 3 und 6 je eine endgültige Wahl zwischen zwei Richtungen: Eigen- gegen Gruppenschutz oder Einzelziel gegen Fläche, je Held eigene Optionen. |
|
||||
| Items | Sechs dauerhafte Items, drei Plätze. Jedes Item höchstens einmal pro Held. Kristallsplitter setzt Heldenstufe 3 voraus. Verkauf bringt 50 %, ein Kauf aus derselben Planung wird voll erstattet. Boni verschiedener Items addieren sich; die Schadensminderung ist auf 35 %, das Angriffstempo auf +50 % begrenzt. |
|
||||
| Reihenfolge im Kampf | Primärtreffer → Grundfähigkeit → Talent → Item-Effekt. Item- und Talenteffekte lösen keine weiteren Treffer-Effekte aus, Heilungen lösen nichts aus; dadurch sind Schleifen ausgeschlossen. Normale Truppen haben kein Inventar. |
|
||||
| Angriffschampions | Rostschieber (Schutz, 150 Gold), Dunstsänger (Druck auf Unterstützer, 150), Keilbrecher (Belagerung, ×1,8 gegen Gebäude, 180). Ein Kauf in Runde n wird für Runde n+1 auf eine Lane gebucht, höchstens zwei Buchungen pro Runde. Bis zum Ende der Planung lässt sich eine Buchung voll erstatten, danach ist sie weder verschiebbar noch erstattbar. Buchungen werden zu Beginn von n+1 öffentlich angekündigt. Der Champion kämpft einmal und verschwindet. Die Stärke skaliert mit der Einsatzrunde, das Kopfgeld beträgt 70 + 6 × Runde und wird wie Monstergold verteilt. |
|
||||
| Grotte · Zuweisung | Die Zuweisung „G“ gilt für genau eine Runde. Die Einheiten fehlen ihrer Lane die ganze Kampfphase, starten an festen, gespiegelten Grotteneingängen und kehren bei der Abrechnung auf die Lane ihres Besitzers zurück. In Sperrrunden ist die Zuweisung abgelehnt. |
|
||||
| Grotte · Kampf | Der neutrale Boss ruht, solange Expeditionen beider Teams leben; die Expeditionen kämpfen zuerst gegeneinander. Erst wenn höchstens ein Team übrig ist, erwacht der Boss mit vollen Lebenspunkten. Tod aller Expeditionen oder Ablauf des Zeitfensters: kein Anspruch. Der nächste Versuch trifft einen vollständig neuen Boss. Todesfälle in der Grotte bringen kein Gold. |
|
||||
| Anspruch | Genau ein Anspruch pro Sieg; ein wiederholtes Abrechnungssignal ändert nichts. Ziel-Lane: die Lane des beitragenden Spielers mit dem höchsten eingesetzten Armeewert in der Grotte (Held einschließlich Items); bei Gleichstand der niedrigere Slot. Dieser Spieler kann die Lane in der folgenden Planung ändern; ohne Eingabe gilt seine eigene Lane. |
|
||||
| Entsendung | Automatisch in der folgenden Runde, für das siegreiche Team, gegen den gegnerischen Ancient. Gebäudesperren gelten unverändert. Stärke und Kopfgeld (520 + 60 × Runde) richten sich nach der Einsatzrunde. Das Kopfgeld geht bei seinem Tod gleichmäßig an das verteidigende Team. Überlebt er, verschwindet er ohne Belohnung. |
|
||||
| Sperre | `next_available_round = Siegrunde + 4`. Beispiel: Sieg in Runde 6, Einsatz in Runde 7, gesperrt in 7–9, bekämpfbar ab Runde 10. Die Sperre hängt am Grottensieg, nicht am Tod des entsandten Bosses. |
|
||||
97
docs/luneraria/STATUS.md
Normal file
97
docs/luneraria/STATUS.md
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
# STATUS · Champions of Luneraria
|
||||
|
||||
Stand: 28. September 2026 · Branches `luneraria/m1` (M0/M1), `luneraria/m2`, `luneraria/m3` · Version im Projekt 0.15.0 (Saumwacht-Demo), Luneraria-Paket erst mit M4.
|
||||
|
||||
| Meilenstein | Zustand |
|
||||
| --- | --- |
|
||||
| M0 · Migration vorbereiten | **abgeschlossen** |
|
||||
| M1 · Spielbarer Drei-Lane-Kern | **abgeschlossen** |
|
||||
| M2 · Mechanikdurchlauf | **abgeschlossen** |
|
||||
| M3 · Qualität und Balance | **abgeschlossen** (siehe unten) |
|
||||
| M4 · Netzwerk und Pakete | offen |
|
||||
|
||||
## M1 · abgeschlossen
|
||||
|
||||
**Implementiert**
|
||||
- Autoritative Partie mit sechs Spielerrollen (ein Mensch, fünf Bots), drei spiegelsymmetrischen Lanes, 16 Türmen und zwei Ancients.
|
||||
- Gebäudesperren für jede Schadensquelle.
|
||||
- Vorrückende Armeen mit eigenen, unbegrenzt wachsenden Monsterwellen.
|
||||
- Planung mit atomarer Übernahme, Besitz-IDs, Einmal-Belohnung mit verlustfreier Restverteilung, Rückkehr und Heilung der Truppen, persistenter Gebäudeschaden.
|
||||
- Partieende nur durch Kernfall; bei gleichzeitigem Kernfall Unentschieden.
|
||||
- Bots über dieselbe Befehlsschnittstelle.
|
||||
- 3D-Karte aus Bestandsassets plus neuem Turm (Blender), Einheiten mit den vorhandenen Modellen und Animationen.
|
||||
- HUD mit Planung, Laneübersicht, Minimap, Ergebnis; Titelmenü auf Champions of Luneraria umgestellt.
|
||||
- Übernahme der alten Benutzereinstellungen. Legacy-Modus bleibt unter `--legacy` und den alten QA-Schaltern erreichbar.
|
||||
|
||||
**Automatisiert geprüft**
|
||||
- Regeln 91/91, darunter der exakte Spiegeltest über 12 Runden.
|
||||
- Echte Anwendung 38/38, mit einer vollständigen Partie bis zum Ancient-Fall.
|
||||
- Acht Bot-Seeds enden regulär nach 8–15 Wellen.
|
||||
- Legacy 209 · 33 · 463 · 206 · 1.665 · 68 unverändert.
|
||||
|
||||
**Visuell geprüft:** Menü, Planung (720p/1080p), Kampf Mid/Top, Übersicht, Belagerung eines Ancients, Ergebnis (`screenshots/`).
|
||||
|
||||
**Leistung** (RTX 5060 Ti, Ryzen 5 5600X, Forward+, VSync aus, 2×): 114 bewegliche Einheiten und 18 Gebäude. 1080p: 7,6 ms/Bild (p95 10,5 ms), GPU 3,1 ms, ~3.170 Draw Calls, Simulationsschritt 2,4 ms (vor der Optimierung 15,8 ms). Es gibt keine allgemeine FPS-Zusage.
|
||||
|
||||
**Ungetestet:** Windows 11, Kompatibilitätsmodus für Luneraria, menschliche Spieltests.
|
||||
|
||||
## M2 · abgeschlossen
|
||||
|
||||
**Implementiert**
|
||||
- Drei Helden (vorläufige Rollen der vorhandenen Skelettmodelle Ringborke, Quellgeflecht, Funkenlanze) mit Erfahrung aus Gefechtsnähe und Rundenteilnahme, Stufen, je zwei Talentstufen mit echten Aufgabenwechseln und drei Itemplätzen für sechs Items.
|
||||
- Drei Angriffschampions (Schutz, Druck auf Unterstützer, Belagerung) mit Buchung n → n+1 und öffentlicher Ankündigung.
|
||||
- Bossgrotte mit ruhendem Boss bei zwei Expeditionen, Scheitern, Eroberung, genau einer Entsendung für das siegreiche Team gegen den gegnerischen Ancient, hohem Kopfgeld für die Verteidiger und Sperre ab `Sieg + 4`.
|
||||
- Wahl der Ziel-Lane durch den beitragenden Spieler; Grottenaufträge gelten für genau eine Runde.
|
||||
- HUD mit Reitern Truppen / Held / Verstärkung, Heldenporträt aus dem echten Modell, Grottenstatus, Ankündigungen und Minimap-Grotte.
|
||||
- Neues Grotten-Asset (Blender). Bots mit Helden, Items, Talenten, Champions und Bossjagd.
|
||||
|
||||
**Automatisiert geprüft**
|
||||
- Regeln M2 73/73 und M1 91/91 (mit Spiegeltest).
|
||||
- Echte Anwendung M2 15/15 und M1 38/38.
|
||||
- 12 Bot-Seeds enden regulär nach 7–10 Wellen.
|
||||
- Szenariovergleich der Bossstrategie (2 Seeds × 5 Varianten).
|
||||
|
||||
**Visuell geprüft:** Held mit Items im HUD, Held im Feld, Grottenkampf, Ankündigung, Bossentsendung (`screenshots/m2-*`).
|
||||
|
||||
**Ungetestet:** menschliche Spieltests der neuen Systeme, Windows 11.
|
||||
|
||||
## M3 · abgeschlossen
|
||||
|
||||
**Implementiert**
|
||||
- Bot-Priorisierung: Items und Angriffschampions werden **vor** der Armee geplant (Reserve), damit Helden Ausrüstung erhalten und Champions überhaupt gebucht werden. Regression `bots_m2` gefixt.
|
||||
- Deterministische Lane-Hilfe der Bots statt geteiltem Zufall — erhält die exakte Spiegelsymmetrie.
|
||||
- Bossbalance: Grottenboss 3.600 HP, entsandter Boss 6.800 HP / 88 Schaden, Belagerungsfaktor 1,8. Bossjäger senden 5 Truppen + Held und bewerten Expeditionen per öffentlicher Lanchester-Schätzung.
|
||||
- Profilbalance: verteidigung erhält Champion und Teamhilfe; ausgewogen startet den Held eine Runde später; teamhilfe hilft seltener.
|
||||
- 3D-Kartenvisuals: `map_props.glb` (Blender-Generator) mit Kiefern, Eichen, Felsen, Büschen, Brücken über die Kluft, Bordsteinen, Klamprahmen und Team-Bannern an den Ancients. Alte Compare-Props abgelöst.
|
||||
- Sieben Volksrepräsentanten (`p_mensch` … `p_biest`) mit gewichtetem Skelett, 9 Clips, LP_*-Materialien, Audit und Sichtprüfung. Entwicklungsplan in [VOELKER.md](VOELKER.md). Noch nicht spielbar im Match.
|
||||
- Balancewerkzeuge: `balance_run` (Zusammensetzungen, Seitentausch, reine Duelle), `analyze_balance.py`, `stress_run`, `people_lineup`.
|
||||
|
||||
**Automatisiert geprüft**
|
||||
- Regeln: Core 91/91 (inkl. Spiegel) und M2 73/73 nach den Bot-Änderungen.
|
||||
- Echte Anwendung: M1 38/38 und M2 15/15 (nach Fix der Item-Ausrüstung).
|
||||
- Balance 40 Partien: Seitentausch 20/20, Profile 24–64 %, Bünde 55/45, alle regulär nach 9–14 Wellen.
|
||||
- Profil-Duelle 30 Partien: Seitentausch 15/15.
|
||||
- Stress 17/17: Wellen bis 10⁶, Langlauf 200 Runden als „Testlimit erreicht“.
|
||||
- Legacy unverändert.
|
||||
|
||||
**Visuell geprüft:** Kartenübersicht mit Props und Brücken, Kampf Top/Mid, Planung mit Helden-Items (Funkenlanze Stufe 3, Glutklinge), sieben Völker in Ruhe/Kontakt/Laufen/Fähigkeit/Tod und Nahaufnahme (`screenshots/peoples-*`).
|
||||
|
||||
**Bekannte Befunde**
|
||||
- Reine 3-gleichen Profil-Duelle ergeben eine lineare Kette (ausgewogen > verteidigung > teamhilfe > fernkampf > druck > bossjagd), keinen Zyklus. In gemischten Teams sind alle Profile im Band 24–64 %.
|
||||
- Bossjagd als reines Teamprofil 0/10, in Mischteams 24 %. Die Risikoabschätzung ist besser geworden, die Jagd bleibt teuer.
|
||||
|
||||
## Bekannt
|
||||
|
||||
- Ein exakt gespiegeltes Match bleibt unentschieden, wird also nicht beendet (Testlimit). Das ist der erwartbare Grenzfall identischen Spiels; Asymmetrie kommt aus Helden, Champions und Boss.
|
||||
- Die Monsterwellen sind nur über Teamring und Lichtfarbe dem Team zugeordnet.
|
||||
- Beim Beenden meldet Godot eine noch belegte Ressource (Hintergrundladen der Menübühne); ohne Folgen im Spiel.
|
||||
- Die sieben Volksrepräsentanten sind noch nicht spielbar (Daten und Modelle liegen vor, Plan in VOELKER.md).
|
||||
|
||||
## Blockiert
|
||||
|
||||
- Nativer Windows-11-Test: keine Windows-Hardware.
|
||||
- Kompatibilitätsmodus (OpenGL) für Luneraria: erst mit M4-Exporten gezielt prüfen.
|
||||
|
||||
## Nächster Schritt
|
||||
|
||||
M4: autoritatives Host/Join für sechs Slots (Direktverbindung, Bots für freie Slots), synchronisierte Phasen und Zustandsabgleich, reale Mehrprozessprüfungen (Loopback), reproduzierbare Linux-/Windows-Exports, entpackbare Demo, klare Testmatrix. Öffentliches Matchmaking bleibt außerhalb des Umfangs.
|
||||
40
docs/luneraria/VOELKER.md
Normal file
40
docs/luneraria/VOELKER.md
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
# Völker und Repräsentanten
|
||||
|
||||
Stand: 28. September 2026 (M3). Trennung der Daten: **Volk** · **Bund** · **Klasse** · **Kampfrolle**. Ein Volk ist kein eigener Kampfmechanismus; Rollen kommen aus dem gemeinsamen Truppen-/Heldenkatalog.
|
||||
|
||||
## Repräsentanten M3
|
||||
|
||||
Jedes der sieben Zielvölker besitzt genau ein eigenständiges Blender-Modell mit gewichtetem Skelett (22–24 Knochen, 9 Clips: idle, start, walk, stop, attack_a, attack_b, hit, ability, death). Erzeugt mit `assets-source/luneraria/build_peoples.py`, exportiert nach `assets/luneraria/peoples/p_*.glb`, Manifest `assets/luneraria/peoples_manifest.json`, Prüfbefund `assets-source/luneraria/peoples-audit.json`.
|
||||
|
||||
| Volk | ID | Name | Klasse | Kampfrolle | Besonderheit |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| Menschen | `p_mensch` | Ritter | Ritter | Front | Schild + Schwert, Plattenrüstung |
|
||||
| Elfen | `p_elf` | Waldläuferin | Waldläuferin | Fernkampf | Bogen, leichte Rüstung, spitze Ohren |
|
||||
| Zwerge | `p_zwerg` | Schildträger | Schildträger | Front | Vollbart, Hornhelm, Rundschild |
|
||||
| Trolle | `p_troll` | Steinhauer | Steinhauer | Fläche | massive Keule, Felsplatten |
|
||||
| Feen | `p_fee` | Lichtheilerin | Lichtheilerin | Unterstützung | Flügel, Glüheffekte |
|
||||
| Orks | `p_ork` | Kriegshäuptling | Kriegshäuptling | Nahkampf | Krallenwaffe, Fell |
|
||||
| Biestmenschen | `p_biest` | Klauenjäger | Klauenjäger | Nahkampf | Bestienanatomie, Klauen |
|
||||
|
||||
Sichtprüfung: `screenshots/peoples-ruhe.png`, `-kontakt`, `-laufen`, `-faehigkeit`, `-tod`, `-detail-a/b`. Werkzeug: `tools/luneraria/people_lineup.tscn`.
|
||||
|
||||
## Was noch nicht implementiert ist
|
||||
|
||||
- Keine der sieben Figuren ist derzeit **spielbar**. Die laufenden Bünde Glutpakt und Wurzelbund behalten ihre vorhandenen Modelle (Glutkonstrukte, Wurzelwesen).
|
||||
- Es gibt **keine** Volkswahl im Menü und **keine** volksspezifischen Boni oder Fähigkeiten.
|
||||
- Die Repräsentanten sind Bestandteil der Assetmatrix und der Entwicklungsplanung, nicht des Matchrosters.
|
||||
|
||||
## Entwicklungsplan (nach M4)
|
||||
|
||||
1. **Volksdaten in den Katalog:** `people`, `bund`, `klasse`, `rolle` als getrennte Felder in `DataCatalog` / `LuneContent`. Einheitentypen verweisen auf ein Volk, ein Bund bleibt eine spielbare Fraktion mit eigener Aufwertungslinie.
|
||||
2. **Spielbare Vertretung pro Volk:** je ein normaler Truppentyp und ein Aufwertungsschritt aus den Repräsentanten-Animationen, übernommen in die bestehenden Rollen Front / Nahkampf / Fernkampf / Fläche / Unterstützung. Kein eigenes Kampfsystem pro Volk.
|
||||
3. **Bündekopplung:** Jeder Bund öffnet eine Teilmenge der Völker (z. B. Wurzelbund: Elfen, Feen, Biestmenschen; Glutpakt: Menschen, Orks, Zwerge, Trolle). Volk formt Startboni und Heldenauswahl, nicht die Grundregeln.
|
||||
4. **Helden pro Volk:** je ein Held aus dem Repräsentantenmodell mit zwei Talentrichtungen, analog zu Ringborke / Quellgeflecht / Funkenlanze. Vorläufige Bestandshelden bleiben erhalten.
|
||||
5. **Balancierung über Rollen, nicht Sammelboni:** Volkssynergien sind höchstens eine kleine, sichtbare Verstärkung (z. B. Formationsschild), nie der einzige Hebel.
|
||||
6. **Inhaltliche Ausweitung:** weitere Klassen pro Volk (Aufwertungen, Champion-Varianten) erst nach stabilen sechs Rollen und laufendem Netzwerkmodus.
|
||||
|
||||
## Bestandsschutz
|
||||
|
||||
- Ausgearbeitete Modelle (Ringborke, Funkenleser, Basaltbastion, Quellgeflecht, Funkenlanze, Glasballiste, Kernkristalle) bleiben unverändert erhalten.
|
||||
- Nietenkonvent (`m*`) und Nebelchor (`n*`) bleiben als Reserve in der Assetmatrix und werden nicht als Völker ausgegeben.
|
||||
- Die LP_*-Materialien der Völkermodelle laufen über denselben Kluft-/Sanctuary-Pfad wie die übrigen Figuren (`asset_library.gd`).
|
||||
4
docs/luneraria/logs/core-tests.json
Normal file
4
docs/luneraria/logs/core-tests.json
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"checks": 91,
|
||||
"failures": []
|
||||
}
|
||||
4
docs/luneraria/logs/m0-baseline/ability-events.log
Normal file
4
docs/luneraria/logs/m0-baseline/ability-events.log
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
Godot Engine v4.7.2.stable.fedora.ed1daf0bf - https://godotengine.org
|
||||
|
||||
ABILITY_EVENT_PASS: 33 checks; 0 failures
|
||||
EXIT 0
|
||||
250
docs/luneraria/logs/m0-baseline/expedition-test.log
Normal file
250
docs/luneraria/logs/m0-baseline/expedition-test.log
Normal file
|
|
@ -0,0 +1,250 @@
|
|||
Godot Engine v4.7.2.stable.fedora.ed1daf0bf - https://godotengine.org
|
||||
|
||||
ERROR: Attempting to initialize the wrong RID
|
||||
at: get_or_null (./core/templates/rid_owner.h:240)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:90)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:62)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Parameter "mem" is null.
|
||||
at: initialize_rid (./core/templates/rid_owner.h:284)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:90)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:62)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Attempting to use an uninitialized RID
|
||||
at: get_or_null (./core/templates/rid_owner.h:247)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:90)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:62)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Parameter "m" is null.
|
||||
at: mesh_set_blend_shape_count (servers/rendering/dummy/storage/mesh_storage.h:74)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:90)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:62)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Attempting to use an uninitialized RID
|
||||
at: get_or_null (./core/templates/rid_owner.h:247)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:90)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:62)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Parameter "m" is null.
|
||||
at: mesh_add_surface (servers/rendering/dummy/storage/mesh_storage.h:81)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:90)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:62)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Attempting to use an uninitialized RID
|
||||
at: get_or_null (./core/templates/rid_owner.h:247)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:90)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:62)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Parameter "m" is null.
|
||||
at: mesh_add_surface (servers/rendering/dummy/storage/mesh_storage.h:81)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:90)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:62)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Attempting to use an uninitialized RID
|
||||
at: get_or_null (./core/templates/rid_owner.h:247)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:90)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:62)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Parameter "m" is null.
|
||||
at: mesh_add_surface (servers/rendering/dummy/storage/mesh_storage.h:81)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:90)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:62)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Attempting to use an uninitialized RID
|
||||
at: get_or_null (./core/templates/rid_owner.h:247)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:90)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:62)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Parameter "m" is null.
|
||||
at: mesh_add_surface (servers/rendering/dummy/storage/mesh_storage.h:81)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:90)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:62)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Attempting to use an uninitialized RID
|
||||
at: get_or_null (./core/templates/rid_owner.h:247)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:90)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:62)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Parameter "m" is null.
|
||||
at: mesh_add_surface (servers/rendering/dummy/storage/mesh_storage.h:81)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:90)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:62)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Attempting to use an uninitialized RID
|
||||
at: get_or_null (./core/templates/rid_owner.h:247)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:90)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:62)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Parameter "m" is null.
|
||||
at: mesh_add_surface (servers/rendering/dummy/storage/mesh_storage.h:81)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:90)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:62)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Attempting to use an uninitialized RID
|
||||
at: get_or_null (./core/templates/rid_owner.h:247)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:90)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:62)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Parameter "m" is null.
|
||||
at: mesh_add_surface (servers/rendering/dummy/storage/mesh_storage.h:81)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:90)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:62)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Attempting to use an uninitialized RID
|
||||
at: get_or_null (./core/templates/rid_owner.h:247)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:90)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:62)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Parameter "m" is null.
|
||||
at: mesh_add_surface (servers/rendering/dummy/storage/mesh_storage.h:81)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:90)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:62)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Attempting to use an uninitialized RID
|
||||
at: get_or_null (./core/templates/rid_owner.h:247)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:90)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:62)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Parameter "m" is null.
|
||||
at: mesh_set_blend_shape_mode (servers/rendering/dummy/storage/mesh_storage.h:110)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:90)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:62)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Attempting to use an uninitialized RID
|
||||
at: get_or_null (./core/templates/rid_owner.h:247)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:90)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:62)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Parameter "m" is null.
|
||||
at: mesh_set_blend_shape_mode (servers/rendering/dummy/storage/mesh_storage.h:110)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:90)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:62)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
EXPEDITION_MATCH: Standard gegen Standard; wave 20; cores [669, 669]; outcome -1
|
||||
EXPEDITION_MATCH: Standard gegen Lernmodus; wave 10; cores [2038, 0]; outcome 0
|
||||
EXPEDITION_MATCH: Leeres Baufeld gegen Standard; wave 7; cores [0, 3000]; outcome 1
|
||||
EXPEDITION_PASS: 206 checks; 0 failures; report /home/martin/.local/share/godot/app_userdata/Saumwacht · Glutpakt/phase8-verification.json
|
||||
WARNING: 6 ObjectDB instances were leaked at exit (run with `--verbose` for details).
|
||||
at: cleanup (core/object/object.cpp:2536)
|
||||
ERROR: 1 RID allocations of type 'N13RendererDummy9DummyMeshE' were leaked at exit.
|
||||
EXIT 0
|
||||
8
docs/luneraria/logs/m0-baseline/faction-test.log
Normal file
8
docs/luneraria/logs/m0-baseline/faction-test.log
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
Godot Engine v4.7.2.stable.fedora.ed1daf0bf - https://godotengine.org
|
||||
|
||||
FACTION_MATCH: Wurzelbund gegen Glutpakt wave 20 cores [1244, 1709]
|
||||
FACTION_MATCH: Glutpakt gegen Wurzelbund wave 20 cores [1709, 1244]
|
||||
FACTION_MATCH: Wurzelbund Spiegel wave 20 cores [1244, 1244]
|
||||
FACTION_MATCH: Wurzelbund Kurzpartie wave 8 cores [3000, 3000]
|
||||
FACTION_PASS: 1665 checks; 0 failures; /home/martin/.local/share/godot/app_userdata/Saumwacht · Glutpakt/phase10-verification.json
|
||||
EXIT 0
|
||||
5
docs/luneraria/logs/m0-baseline/smoke-test.log
Normal file
5
docs/luneraria/logs/m0-baseline/smoke-test.log
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Godot Engine v4.7.2.stable.fedora.ed1daf0bf - https://godotengine.org
|
||||
|
||||
EXPORT_SMOKE_PASS: 463 checks; 0 failures; engine 4.7.2-stable (fedora); cores [3000, 1035]
|
||||
SMOKE_CAPTURES: /home/martin/.local/share/godot/app_userdata/Saumwacht · Glutpakt/phase8-smoke
|
||||
EXIT 0
|
||||
4
docs/luneraria/logs/m0-baseline/test-runner.log
Normal file
4
docs/luneraria/logs/m0-baseline/test-runner.log
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
Godot Engine v4.7.2.stable.fedora.ed1daf0bf - https://godotengine.org
|
||||
|
||||
PASS: 209 checks across economy, combat and the full match lifecycle.
|
||||
EXIT 0
|
||||
10
docs/luneraria/logs/m1-acceptance.json
Normal file
10
docs/luneraria/logs/m1-acceptance.json
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"checks": 38,
|
||||
"failures": [],
|
||||
"object_counts": [
|
||||
3363.0,
|
||||
3363.0,
|
||||
3363.0,
|
||||
3363.0
|
||||
]
|
||||
}
|
||||
8
docs/luneraria/logs/m1/bench-1280x720.log
Normal file
8
docs/luneraria/logs/m1/bench-1280x720.log
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
Godot Engine v4.7.2.stable.fedora.ed1daf0bf - https://godotengine.org
|
||||
Vulkan 1.4.351 - Forward+ - Using Device #0: NVIDIA - NVIDIA GeForce RTX 5060 Ti
|
||||
|
||||
LUNE_BENCH {"buildings":18,"cpu":"AMD Ryzen 5 5600X 6-Core Processor","draw_calls_mean":3175.86281588448,"engine":"4.7.2-stable (fedora)","frame_ms_mean":7.22646841155234,"frame_ms_p95":10.294,"frames":1108,"gpu":"NVIDIA GeForce RTX 5060 Ti","gpu_ms_mean":2.09521750809914,"mobile_units_at_start":114,"mobile_units_mean_measured":108.60559566787,"renderer":"forward_plus","scene_build_ms":198.002,"sim_speed":"2x (40 steps/s)","sim_step_ms":2.37125,"static_mem_mb":120.703545570374,"video_mem_mb":658.710235595703,"window":"(1280, 720)"}
|
||||
WARNING: 24 ObjectDB instances were leaked at exit (run with `--verbose` for details).
|
||||
at: cleanup (core/object/object.cpp:2536)
|
||||
ERROR: 1 resources still in use at exit (run with --verbose for details).
|
||||
at: clear (core/io/resource.cpp:822)
|
||||
8
docs/luneraria/logs/m1/bench-1920x1080.log
Normal file
8
docs/luneraria/logs/m1/bench-1920x1080.log
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
Godot Engine v4.7.2.stable.fedora.ed1daf0bf - https://godotengine.org
|
||||
Vulkan 1.4.351 - Forward+ - Using Device #0: NVIDIA - NVIDIA GeForce RTX 5060 Ti
|
||||
|
||||
LUNE_BENCH {"buildings":18,"cpu":"AMD Ryzen 5 5600X 6-Core Processor","draw_calls_mean":3172.21948912015,"engine":"4.7.2-stable (fedora)","frame_ms_mean":7.56970955534533,"frame_ms_p95":10.505,"frames":1057,"gpu":"NVIDIA GeForce RTX 5060 Ti","gpu_ms_mean":3.06410596431599,"mobile_units_at_start":114,"mobile_units_mean_measured":108.593188268685,"renderer":"forward_plus","scene_build_ms":221.213,"sim_speed":"2x (40 steps/s)","sim_step_ms":2.403405,"static_mem_mb":120.915734291077,"video_mem_mb":765.283081054688,"window":"(1920, 1080)"}
|
||||
WARNING: 24 ObjectDB instances were leaked at exit (run with `--verbose` for details).
|
||||
at: cleanup (core/object/object.cpp:2536)
|
||||
ERROR: 1 resources still in use at exit (run with --verbose for details).
|
||||
at: clear (core/io/resource.cpp:822)
|
||||
4
docs/luneraria/logs/m1/legacy-ability.log
Normal file
4
docs/luneraria/logs/m1/legacy-ability.log
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
Godot Engine v4.7.2.stable.fedora.ed1daf0bf - https://godotengine.org
|
||||
|
||||
ABILITY_EVENT_PASS: 33 checks; 0 failures
|
||||
EXIT 0
|
||||
250
docs/luneraria/logs/m1/legacy-expedition.log
Normal file
250
docs/luneraria/logs/m1/legacy-expedition.log
Normal file
|
|
@ -0,0 +1,250 @@
|
|||
Godot Engine v4.7.2.stable.fedora.ed1daf0bf - https://godotengine.org
|
||||
|
||||
ERROR: Attempting to initialize the wrong RID
|
||||
at: get_or_null (./core/templates/rid_owner.h:240)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:97)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:69)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Parameter "mem" is null.
|
||||
at: initialize_rid (./core/templates/rid_owner.h:284)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:97)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:69)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Attempting to use an uninitialized RID
|
||||
at: get_or_null (./core/templates/rid_owner.h:247)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:97)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:69)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Parameter "m" is null.
|
||||
at: mesh_set_blend_shape_count (servers/rendering/dummy/storage/mesh_storage.h:74)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:97)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:69)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Attempting to use an uninitialized RID
|
||||
at: get_or_null (./core/templates/rid_owner.h:247)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:97)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:69)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Parameter "m" is null.
|
||||
at: mesh_add_surface (servers/rendering/dummy/storage/mesh_storage.h:81)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:97)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:69)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Attempting to use an uninitialized RID
|
||||
at: get_or_null (./core/templates/rid_owner.h:247)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:97)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:69)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Parameter "m" is null.
|
||||
at: mesh_add_surface (servers/rendering/dummy/storage/mesh_storage.h:81)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:97)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:69)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Attempting to use an uninitialized RID
|
||||
at: get_or_null (./core/templates/rid_owner.h:247)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:97)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:69)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Parameter "m" is null.
|
||||
at: mesh_add_surface (servers/rendering/dummy/storage/mesh_storage.h:81)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:97)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:69)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Attempting to use an uninitialized RID
|
||||
at: get_or_null (./core/templates/rid_owner.h:247)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:97)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:69)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Parameter "m" is null.
|
||||
at: mesh_add_surface (servers/rendering/dummy/storage/mesh_storage.h:81)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:97)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:69)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Attempting to use an uninitialized RID
|
||||
at: get_or_null (./core/templates/rid_owner.h:247)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:97)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:69)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Parameter "m" is null.
|
||||
at: mesh_add_surface (servers/rendering/dummy/storage/mesh_storage.h:81)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:97)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:69)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Attempting to use an uninitialized RID
|
||||
at: get_or_null (./core/templates/rid_owner.h:247)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:97)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:69)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Parameter "m" is null.
|
||||
at: mesh_add_surface (servers/rendering/dummy/storage/mesh_storage.h:81)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:97)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:69)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Attempting to use an uninitialized RID
|
||||
at: get_or_null (./core/templates/rid_owner.h:247)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:97)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:69)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Parameter "m" is null.
|
||||
at: mesh_add_surface (servers/rendering/dummy/storage/mesh_storage.h:81)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:97)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:69)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Attempting to use an uninitialized RID
|
||||
at: get_or_null (./core/templates/rid_owner.h:247)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:97)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:69)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Parameter "m" is null.
|
||||
at: mesh_add_surface (servers/rendering/dummy/storage/mesh_storage.h:81)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:97)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:69)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Attempting to use an uninitialized RID
|
||||
at: get_or_null (./core/templates/rid_owner.h:247)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:97)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:69)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Parameter "m" is null.
|
||||
at: mesh_set_blend_shape_mode (servers/rendering/dummy/storage/mesh_storage.h:110)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:97)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:69)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Attempting to use an uninitialized RID
|
||||
at: get_or_null (./core/templates/rid_owner.h:247)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:97)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:69)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
ERROR: Parameter "m" is null.
|
||||
at: mesh_set_blend_shape_mode (servers/rendering/dummy/storage/mesh_storage.h:110)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] instantiate_fighter (res://scripts/presentation/asset_library.gd:110)
|
||||
[1] _place_core (res://scripts/presentation/menu_stage.gd:172)
|
||||
[2] _ready (res://scripts/presentation/menu_stage.gd:61)
|
||||
[3] _build_stage (res://scripts/ui/main_menu.gd:97)
|
||||
[4] _ready (res://scripts/ui/main_menu.gd:69)
|
||||
[5] _make_overlay (res://scripts/ui/hud.gd:492)
|
||||
[6] _ready (res://scripts/ui/hud.gd:112)
|
||||
EXPEDITION_MATCH: Standard gegen Standard; wave 20; cores [669, 669]; outcome -1
|
||||
EXPEDITION_MATCH: Standard gegen Lernmodus; wave 10; cores [2038, 0]; outcome 0
|
||||
EXPEDITION_MATCH: Leeres Baufeld gegen Standard; wave 7; cores [0, 3000]; outcome 1
|
||||
EXPEDITION_PASS: 206 checks; 0 failures; report /home/martin/.local/share/godot/app_userdata/Champions of Luneraria/phase8-verification.json
|
||||
WARNING: 6 ObjectDB instances were leaked at exit (run with `--verbose` for details).
|
||||
at: cleanup (core/object/object.cpp:2536)
|
||||
ERROR: 1 RID allocations of type 'N13RendererDummy9DummyMeshE' were leaked at exit.
|
||||
EXIT 0
|
||||
8
docs/luneraria/logs/m1/legacy-faction.log
Normal file
8
docs/luneraria/logs/m1/legacy-faction.log
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
Godot Engine v4.7.2.stable.fedora.ed1daf0bf - https://godotengine.org
|
||||
|
||||
FACTION_MATCH: Wurzelbund gegen Glutpakt wave 20 cores [1244, 1709]
|
||||
FACTION_MATCH: Glutpakt gegen Wurzelbund wave 20 cores [1709, 1244]
|
||||
FACTION_MATCH: Wurzelbund Spiegel wave 20 cores [1244, 1244]
|
||||
FACTION_MATCH: Wurzelbund Kurzpartie wave 8 cores [3000, 3000]
|
||||
FACTION_PASS: 1665 checks; 0 failures; /home/martin/.local/share/godot/app_userdata/Champions of Luneraria/phase10-verification.json
|
||||
EXIT 0
|
||||
5
docs/luneraria/logs/m1/legacy-smoke.log
Normal file
5
docs/luneraria/logs/m1/legacy-smoke.log
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Godot Engine v4.7.2.stable.fedora.ed1daf0bf - https://godotengine.org
|
||||
|
||||
EXPORT_SMOKE_PASS: 463 checks; 0 failures; engine 4.7.2-stable (fedora); cores [3000, 1035]
|
||||
SMOKE_CAPTURES: /home/martin/.local/share/godot/app_userdata/Champions of Luneraria/phase8-smoke
|
||||
EXIT 0
|
||||
4
docs/luneraria/logs/m1/legacy-test-runner.log
Normal file
4
docs/luneraria/logs/m1/legacy-test-runner.log
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
Godot Engine v4.7.2.stable.fedora.ed1daf0bf - https://godotengine.org
|
||||
|
||||
PASS: 209 checks across economy, combat and the full match lifecycle.
|
||||
EXIT 0
|
||||
5
docs/luneraria/logs/m1/legacy-verify-menu.log
Normal file
5
docs/luneraria/logs/m1/legacy-verify-menu.log
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Godot Engine v4.7.2.stable.fedora.ed1daf0bf - https://godotengine.org
|
||||
Vulkan 1.4.351 - Forward+ - Using Device #0: NVIDIA - NVIDIA GeForce RTX 5060 Ti
|
||||
|
||||
MENU_VERIFY_PASS: 68 checks; 0 failures
|
||||
EXIT 0
|
||||
9
docs/luneraria/logs/m1/lune-core.log
Normal file
9
docs/luneraria/logs/m1/lune-core.log
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
Godot Engine v4.7.2.stable.fedora.ed1daf0bf - https://godotengine.org
|
||||
|
||||
LUNE_FULL_MATCH: seed 2 -> Blau after 8 rounds
|
||||
LUNE_CORE_PASS: 91 checks; 0 failures
|
||||
WARNING: 10 ObjectDB instances were leaked at exit (run with `--verbose` for details).
|
||||
at: cleanup (core/object/object.cpp:2536)
|
||||
ERROR: 1 resources still in use at exit (run with --verbose for details).
|
||||
at: clear (core/io/resource.cpp:822)
|
||||
EXIT 0
|
||||
1940
docs/luneraria/logs/m1/sim-8-seeds.json
Normal file
1940
docs/luneraria/logs/m1/sim-8-seeds.json
Normal file
File diff suppressed because it is too large
Load diff
106
docs/luneraria/logs/m1/sim-8-seeds.log
Normal file
106
docs/luneraria/logs/m1/sim-8-seeds.log
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
Godot Engine v4.7.2.stable.fedora.ed1daf0bf - https://godotengine.org
|
||||
|
||||
R01 cleared 46.7s buildings [9, 9] lost [] gold [123, 173, 123, 128, 123, 128]
|
||||
R02 cleared 53.7s buildings [9, 9] lost [] gold [140, 105, 115, 125, 125, 150]
|
||||
R03 cleared 55.5s buildings [9, 9] lost [] gold [160, 170, 150, 125, 160, 175]
|
||||
R04 cleared 69.1s buildings [8, 9] lost ["blau_top_outer"] gold [182, 142, 132, 182, 172, 257]
|
||||
R05 cleared 74.3s buildings [8, 9] lost [] gold [178, 183, 163, 133, 153, 153]
|
||||
R06 cleared 70.1s buildings [7, 8] lost ["rot_mid_outer", "blau_top_inner"] gold [203, 223, 183, 243, 253, 203]
|
||||
R07 cleared 73.3s buildings [7, 7] lost ["rot_mid_inner"] gold [270, 235, 270, 170, 195, 205]
|
||||
R08 cleared 79.9s buildings [6, 7] lost ["blau_base_1"] gold [245, 185, 165, 275, 245, 280]
|
||||
R09 core 86.9s buildings [4, 7] lost ["blau_base_2", "blau_ancient"] gold [57, 106, 66, 171, 176, 176]
|
||||
SIM_MATCH seed=1 Sieg Rot after 9 rounds (Ancient von Blau zerstört.) in 7091 ms
|
||||
R01 cleared 46.7s buildings [9, 9] lost [] gold [128, 123, 128, 173, 128, 123]
|
||||
R02 cleared 53.7s buildings [9, 9] lost [] gold [125, 125, 150, 105, 125, 115]
|
||||
R03 cleared 54.7s buildings [9, 9] lost [] gold [125, 160, 175, 165, 165, 115]
|
||||
R04 cleared 73.1s buildings [9, 8] lost ["rot_top_outer"] gold [182, 172, 257, 137, 157, 187]
|
||||
R05 cleared 81.9s buildings [8, 7] lost ["blau_mid_outer", "rot_top_inner"] gold [203, 223, 223, 218, 183, 193]
|
||||
R06 cleared 67.3s buildings [8, 7] lost [] gold [158, 178, 133, 138, 153, 133]
|
||||
R07 cleared 74.7s buildings [7, 6] lost ["blau_mid_inner", "rot_base_1"] gold [260, 285, 310, 225, 235, 255]
|
||||
R08 core 92.9s buildings [7, 3] lost ["rot_bot_outer", "rot_base_2", "rot_ancient"] gold [207, 197, 217, 79, 105, 64]
|
||||
SIM_MATCH seed=2 Sieg Blau after 8 rounds (Ancient von Rot zerstört.) in 6499 ms
|
||||
R01 cleared 41.9s buildings [9, 9] lost [] gold [173, 128, 123, 128, 123, 173]
|
||||
R02 cleared 46.7s buildings [9, 9] lost [] gold [105, 125, 115, 135, 140, 105]
|
||||
R03 cleared 59.8s buildings [9, 9] lost [] gold [165, 165, 115, 175, 160, 170]
|
||||
R04 cleared 61.4s buildings [9, 9] lost [] gold [137, 157, 187, 137, 182, 142]
|
||||
R05 cleared 54.9s buildings [9, 9] lost [] gold [168, 133, 143, 133, 178, 183]
|
||||
R06 cleared 57.9s buildings [9, 9] lost [] gold [163, 173, 173, 173, 153, 173]
|
||||
R07 cleared 58.3s buildings [9, 9] lost [] gold [180, 185, 225, 185, 205, 185]
|
||||
R08 cleared 61.9s buildings [8, 9] lost ["blau_bot_outer"] gold [200, 200, 155, 250, 255, 250]
|
||||
R09 cleared 71.3s buildings [8, 9] lost [] gold [213, 218, 188, 198, 168, 198]
|
||||
R10 cleared 74.2s buildings [7, 9] lost ["blau_bot_inner"] gold [215, 250, 215, 300, 265, 300]
|
||||
R11 cleared 83.7s buildings [5, 9] lost ["blau_top_outer", "blau_base_2"] gold [228, 218, 218, 348, 358, 413]
|
||||
R12 core 86.9s buildings [1, 9] lost ["blau_mid_outer", "blau_top_inner", "blau_base_1", "blau_ancient"] gold [101, 106, 133, 348, 318, 323]
|
||||
SIM_MATCH seed=3 Sieg Rot after 12 rounds (Ancient von Blau zerstört.) in 9910 ms
|
||||
R01 cleared 44.6s buildings [9, 9] lost [] gold [128, 123, 173, 123, 128, 123]
|
||||
R02 cleared 46.5s buildings [9, 9] lost [] gold [135, 140, 105, 115, 125, 125]
|
||||
R03 cleared 55.1s buildings [9, 9] lost [] gold [175, 160, 170, 150, 125, 160]
|
||||
R04 cleared 63.1s buildings [9, 9] lost [] gold [137, 182, 142, 132, 132, 122]
|
||||
R05 cleared 62.3s buildings [9, 9] lost [] gold [133, 178, 183, 163, 173, 153]
|
||||
R06 cleared 59.7s buildings [9, 9] lost [] gold [173, 153, 173, 133, 213, 148]
|
||||
R07 cleared 72.1s buildings [9, 8] lost ["rot_bot_outer"] gold [235, 255, 235, 160, 190, 165]
|
||||
R08 cleared 62.5s buildings [8, 8] lost ["blau_top_outer"] gold [180, 180, 180, 205, 210, 215]
|
||||
R09 cleared 74.8s buildings [8, 7] lost ["rot_bot_inner"] gold [268, 263, 268, 238, 223, 178]
|
||||
R10 cleared 80.3s buildings [8, 7] lost [] gold [235, 205, 235, 210, 265, 185]
|
||||
R11 core 117.5s buildings [7, 4] lost ["blau_mid_outer", "rot_base_2", "rot_base_1", "rot_ancient"] gold [288, 348, 303, 223, 178, 178]
|
||||
SIM_MATCH seed=4 Sieg Blau after 11 rounds (Ancient von Rot zerstört.) in 9299 ms
|
||||
R01 cleared 42.1s buildings [9, 9] lost [] gold [123, 128, 123, 128, 173, 128]
|
||||
R02 cleared 50.3s buildings [9, 9] lost [] gold [115, 125, 125, 150, 105, 125]
|
||||
R03 cleared 55.1s buildings [9, 9] lost [] gold [150, 125, 160, 175, 165, 165]
|
||||
R04 cleared 66.9s buildings [9, 9] lost [] gold [132, 132, 122, 207, 137, 157]
|
||||
R05 cleared 60.3s buildings [9, 9] lost [] gold [163, 173, 153, 198, 168, 133]
|
||||
R06 cleared 61.9s buildings [9, 9] lost [] gold [133, 213, 148, 178, 163, 173]
|
||||
R07 cleared 87.3s buildings [9, 8] lost ["rot_top_outer"] gold [210, 240, 215, 180, 180, 185]
|
||||
R08 cleared 89.3s buildings [9, 8] lost [] gold [205, 210, 165, 165, 200, 200]
|
||||
R09 cleared 80.3s buildings [8, 7] lost ["blau_bot_outer", "rot_top_inner"] gold [308, 293, 303, 218, 263, 268]
|
||||
R10 cleared 84.1s buildings [8, 7] lost [] gold [220, 195, 195, 185, 190, 185]
|
||||
R11 cleared 84.8s buildings [7, 6] lost ["blau_bot_inner", "rot_base_1"] gold [363, 343, 358, 323, 313, 308]
|
||||
R12 cleared 83.7s buildings [7, 6] lost [] gold [267, 237, 237, 232, 272, 232]
|
||||
R13 cleared 95.7s buildings [6, 5] lost ["rot_mid_outer", "blau_base_2"] gold [303, 338, 333, 388, 393, 393]
|
||||
R14 cleared 82.1s buildings [6, 5] lost [] gold [390, 295, 305, 310, 320, 375]
|
||||
R15 core 130.3s buildings [6, 3] lost ["rot_base_2", "rot_ancient"] gold [411, 511, 291, 216, 311, 351]
|
||||
SIM_MATCH seed=5 Sieg Blau after 15 rounds (Ancient von Rot zerstört.) in 14879 ms
|
||||
R01 cleared 48.3s buildings [9, 9] lost [] gold [128, 173, 128, 123, 128, 123]
|
||||
R02 cleared 52.5s buildings [9, 9] lost [] gold [150, 105, 125, 115, 135, 140]
|
||||
R03 cleared 60.7s buildings [9, 9] lost [] gold [175, 165, 165, 115, 175, 160]
|
||||
R04 cleared 64.5s buildings [9, 9] lost [] gold [207, 137, 157, 187, 137, 182]
|
||||
R05 cleared 59.1s buildings [9, 9] lost [] gold [198, 168, 133, 143, 133, 178]
|
||||
R06 cleared 58.5s buildings [9, 8] lost ["rot_mid_outer"] gold [228, 213, 223, 173, 173, 153]
|
||||
R07 cleared 72.7s buildings [8, 8] lost ["blau_top_outer"] gold [230, 155, 165, 275, 235, 255]
|
||||
R08 cleared 86.1s buildings [7, 7] lost ["rot_mid_inner", "blau_top_inner"] gold [285, 245, 250, 230, 250, 250]
|
||||
R09 cleared 72.4s buildings [7, 6] lost ["rot_bot_outer"] gold [218, 248, 273, 243, 203, 203]
|
||||
R10 cleared 74.8s buildings [7, 6] lost [] gold [195, 220, 215, 270, 245, 250]
|
||||
R11 cleared 92.9s buildings [7, 5] lost ["rot_bot_inner"] gold [288, 343, 278, 283, 218, 278]
|
||||
R12 core 89.1s buildings [7, 2] lost ["rot_base_2", "rot_base_1", "rot_ancient"] gold [328, 288, 348, 108, 163, 87]
|
||||
SIM_MATCH seed=6 Sieg Blau after 12 rounds (Ancient von Rot zerstört.) in 10244 ms
|
||||
R01 cleared 41.3s buildings [9, 9] lost [] gold [123, 128, 123, 173, 123, 128]
|
||||
R02 cleared 51.5s buildings [9, 9] lost [] gold [115, 135, 140, 105, 115, 125]
|
||||
R03 cleared 52.5s buildings [9, 9] lost [] gold [115, 175, 160, 170, 150, 125]
|
||||
R04 cleared 57.7s buildings [9, 9] lost [] gold [187, 137, 182, 142, 132, 132]
|
||||
R05 cleared 57.5s buildings [9, 9] lost [] gold [143, 133, 178, 183, 163, 173]
|
||||
R06 cleared 61.7s buildings [9, 9] lost [] gold [173, 173, 153, 173, 133, 213]
|
||||
R07 cleared 61.1s buildings [9, 9] lost [] gold [225, 185, 205, 185, 160, 190]
|
||||
R08 cleared 57.5s buildings [9, 9] lost [] gold [155, 200, 205, 200, 155, 160]
|
||||
R09 cleared 72.9s buildings [9, 9] lost [] gold [188, 218, 193, 218, 188, 173]
|
||||
R10 cleared 72.1s buildings [8, 9] lost ["blau_bot_outer"] gold [215, 250, 240, 280, 285, 265]
|
||||
R11 cleared 84.4s buildings [5, 9] lost ["blau_mid_outer", "blau_top_outer", "blau_bot_inner"] gold [218, 218, 238, 398, 453, 408]
|
||||
R12 core 98.9s buildings [0, 9] lost ["blau_mid_inner", "blau_top_inner", "blau_base_2", "blau_base_1", "blau_ancient"] gold [156, 101, 123, 463, 563, 528]
|
||||
SIM_MATCH seed=7 Sieg Rot after 12 rounds (Ancient von Blau zerstört.) in 10269 ms
|
||||
R01 cleared 41.9s buildings [9, 9] lost [] gold [173, 123, 128, 123, 128, 173]
|
||||
R02 cleared 47.5s buildings [9, 9] lost [] gold [105, 115, 125, 125, 150, 105]
|
||||
R03 cleared 55.5s buildings [9, 9] lost [] gold [170, 150, 125, 160, 175, 165]
|
||||
R04 cleared 55.1s buildings [9, 9] lost [] gold [142, 132, 132, 122, 207, 137]
|
||||
R05 cleared 54.5s buildings [9, 9] lost [] gold [183, 163, 173, 153, 198, 168]
|
||||
R06 cleared 57.7s buildings [9, 9] lost [] gold [173, 133, 213, 148, 178, 163]
|
||||
R07 cleared 58.7s buildings [9, 9] lost [] gold [185, 160, 190, 165, 180, 180]
|
||||
R08 cleared 54.9s buildings [9, 9] lost [] gold [200, 155, 160, 165, 165, 200]
|
||||
R09 cleared 66.5s buildings [9, 8] lost ["rot_top_outer"] gold [268, 238, 223, 178, 168, 213]
|
||||
R10 cleared 87.5s buildings [9, 7] lost ["rot_top_inner"] gold [280, 280, 335, 210, 200, 215]
|
||||
R11 cleared 87.7s buildings [9, 6] lost ["rot_bot_outer"] gold [323, 403, 303, 238, 218, 228]
|
||||
R12 core 103.0s buildings [9, 1] lost ["rot_base_1", "rot_mid_outer", "rot_bot_inner", "rot_base_2", "rot_ancient"] gold [418, 493, 458, 143, 113, 118]
|
||||
SIM_MATCH seed=8 Sieg Blau after 12 rounds (Ancient von Rot zerstört.) in 10274 ms
|
||||
WARNING: 6 ObjectDB instances were leaked at exit (run with `--verbose` for details).
|
||||
at: cleanup (core/object/object.cpp:2536)
|
||||
ERROR: 1 resources still in use at exit (run with --verbose for details).
|
||||
at: clear (core/io/resource.cpp:822)
|
||||
EXIT 0
|
||||
15
docs/luneraria/logs/m1/verify-m1.log
Normal file
15
docs/luneraria/logs/m1/verify-m1.log
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
Godot Engine v4.7.2.stable.fedora.ed1daf0bf - https://godotengine.org
|
||||
Vulkan 1.4.351 - Forward+ - Using Device #0: NVIDIA - NVIDIA GeForce RTX 5060 Ti
|
||||
|
||||
M1_MENU_READY_MS 733
|
||||
M1_SHOT planning-1280x720
|
||||
M1_SHOT planning-1920x1080
|
||||
M1_SHOT combat-mid-live
|
||||
M1_SHOT settlement
|
||||
M1_SHOT combat-top
|
||||
M1_SHOT overview-combat
|
||||
M1_SHOT core-siege
|
||||
M1_SHOT result
|
||||
M1_MATCH_RESULT Ancient von Rot zerstört. after 10 waves
|
||||
M1_VERIFY_PASS: 38 checks; 0 failures
|
||||
EXIT 0
|
||||
19
docs/luneraria/logs/m2-acceptance.json
Normal file
19
docs/luneraria/logs/m2-acceptance.json
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"boss_log": [
|
||||
{
|
||||
"chooser": 4,
|
||||
"event": "won",
|
||||
"round": 12,
|
||||
"team": 1
|
||||
}
|
||||
],
|
||||
"checks": 14,
|
||||
"failures": [],
|
||||
"rounds": 12,
|
||||
"seen": [
|
||||
"announce",
|
||||
"hero_field",
|
||||
"hero_items",
|
||||
"grotto"
|
||||
]
|
||||
}
|
||||
4
docs/luneraria/logs/m2-tests.json
Normal file
4
docs/luneraria/logs/m2-tests.json
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"checks": 73,
|
||||
"failures": []
|
||||
}
|
||||
85
docs/luneraria/logs/m2/boss-scenarios-seed3.json
Normal file
85
docs/luneraria/logs/m2/boss-scenarios-seed3.json
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
[
|
||||
{
|
||||
"blau_gold_delta": 284,
|
||||
"blau_hp_after_r8": 0.0,
|
||||
"blau_hp_delta": -1436.5,
|
||||
"blau_mid_towers_lost_r8": 0,
|
||||
"claim_team": -1,
|
||||
"grotto": "none",
|
||||
"phase": "vorbei",
|
||||
"rot_gold_delta": -235,
|
||||
"rot_hp_delta": -50521.0198,
|
||||
"rot_sent_value": 0,
|
||||
"scenario": "kein_versuch",
|
||||
"sent_value": 0,
|
||||
"winner": 0
|
||||
},
|
||||
{
|
||||
"blau_gold_delta": 284,
|
||||
"blau_hp_after_r8": -317.199999999997,
|
||||
"blau_hp_delta": -1753.7,
|
||||
"blau_mid_towers_lost_r8": 0,
|
||||
"claim_team": -1,
|
||||
"grotto": "failed",
|
||||
"phase": "vorbei",
|
||||
"rot_gold_delta": -235,
|
||||
"rot_hp_delta": -50257.2862,
|
||||
"rot_sent_value": 0,
|
||||
"scenario": "gescheitert",
|
||||
"sent_value": 210,
|
||||
"winner": 0
|
||||
},
|
||||
{
|
||||
"blau_gold_delta": 543,
|
||||
"blau_hp_after_r8": -13227.8841,
|
||||
"blau_hp_delta": -15022.5341,
|
||||
"blau_mid_towers_lost_r8": 2,
|
||||
"boss_bounty_to_rot": 1060,
|
||||
"boss_killed": true,
|
||||
"boss_round": 9,
|
||||
"claim_team": 0,
|
||||
"grotto": "won",
|
||||
"phase": "vorbei",
|
||||
"rot_gold_delta": 794,
|
||||
"rot_hp_delta": -35384.1102,
|
||||
"rot_hp_lost_boss_round": 33218.6196,
|
||||
"rot_sent_value": 0,
|
||||
"scenario": "erfolgreich",
|
||||
"sent_value": 1000,
|
||||
"winner": 0
|
||||
},
|
||||
{
|
||||
"blau_gold_delta": 494,
|
||||
"blau_hp_after_r8": -401.375,
|
||||
"blau_hp_delta": -1434.51880000001,
|
||||
"blau_mid_towers_lost_r8": 0,
|
||||
"claim_team": -1,
|
||||
"grotto": "failed",
|
||||
"phase": "vorbei",
|
||||
"rot_gold_delta": -185,
|
||||
"rot_hp_delta": -51276.0262,
|
||||
"rot_sent_value": 995,
|
||||
"scenario": "umkaempft",
|
||||
"sent_value": 1000,
|
||||
"winner": 0
|
||||
},
|
||||
{
|
||||
"blau_gold_delta": -250,
|
||||
"blau_hp_after_r8": -36433.06827,
|
||||
"blau_hp_delta": -68294.9678,
|
||||
"blau_mid_towers_lost_r8": 2,
|
||||
"boss_bounty_to_rot": 1060,
|
||||
"boss_killed": true,
|
||||
"boss_round": 9,
|
||||
"claim_team": 0,
|
||||
"grotto": "won",
|
||||
"phase": "vorbei",
|
||||
"rot_gold_delta": 437,
|
||||
"rot_hp_delta": -25391.9446,
|
||||
"rot_hp_lost_boss_round": 25391.9446,
|
||||
"rot_sent_value": 0,
|
||||
"scenario": "ueberinvestition",
|
||||
"sent_value": 2495,
|
||||
"winner": 1
|
||||
}
|
||||
]
|
||||
85
docs/luneraria/logs/m2/boss-scenarios-seed7.json
Normal file
85
docs/luneraria/logs/m2/boss-scenarios-seed7.json
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
[
|
||||
{
|
||||
"blau_gold_delta": 174,
|
||||
"blau_hp_after_r8": -3771.781,
|
||||
"blau_hp_delta": -9222.031,
|
||||
"blau_mid_towers_lost_r8": 0,
|
||||
"claim_team": -1,
|
||||
"grotto": "none",
|
||||
"phase": "läuft",
|
||||
"rot_gold_delta": 139,
|
||||
"rot_hp_delta": -5573.1798,
|
||||
"rot_sent_value": 0,
|
||||
"scenario": "kein_versuch",
|
||||
"sent_value": 0,
|
||||
"winner": -2
|
||||
},
|
||||
{
|
||||
"blau_gold_delta": 174,
|
||||
"blau_hp_after_r8": -4097.3806,
|
||||
"blau_hp_delta": -9547.6306,
|
||||
"blau_mid_towers_lost_r8": 0,
|
||||
"claim_team": -1,
|
||||
"grotto": "failed",
|
||||
"phase": "läuft",
|
||||
"rot_gold_delta": 139,
|
||||
"rot_hp_delta": -4659.805,
|
||||
"rot_sent_value": 0,
|
||||
"scenario": "gescheitert",
|
||||
"sent_value": 180,
|
||||
"winner": -2
|
||||
},
|
||||
{
|
||||
"blau_gold_delta": -302,
|
||||
"blau_hp_after_r8": -16247.2932,
|
||||
"blau_hp_delta": -67736.578,
|
||||
"blau_mid_towers_lost_r8": 2,
|
||||
"boss_bounty_to_rot": 1060,
|
||||
"boss_killed": true,
|
||||
"boss_round": 9,
|
||||
"claim_team": 0,
|
||||
"grotto": "won",
|
||||
"phase": "vorbei",
|
||||
"rot_gold_delta": 319,
|
||||
"rot_hp_delta": -22792.746,
|
||||
"rot_hp_lost_boss_round": 22792.746,
|
||||
"rot_sent_value": 0,
|
||||
"scenario": "erfolgreich",
|
||||
"sent_value": 930,
|
||||
"winner": 1
|
||||
},
|
||||
{
|
||||
"blau_gold_delta": 174,
|
||||
"blau_hp_after_r8": -4404.387,
|
||||
"blau_hp_delta": -9854.637,
|
||||
"blau_mid_towers_lost_r8": 0,
|
||||
"claim_team": -1,
|
||||
"grotto": "failed",
|
||||
"phase": "läuft",
|
||||
"rot_gold_delta": 139,
|
||||
"rot_hp_delta": -4659.805,
|
||||
"rot_sent_value": 865,
|
||||
"scenario": "umkaempft",
|
||||
"sent_value": 930,
|
||||
"winner": -2
|
||||
},
|
||||
{
|
||||
"blau_gold_delta": -320,
|
||||
"blau_hp_after_r8": -38337.2773,
|
||||
"blau_hp_delta": -67736.578,
|
||||
"blau_mid_towers_lost_r8": 2,
|
||||
"boss_bounty_to_rot": 1060,
|
||||
"boss_killed": true,
|
||||
"boss_round": 9,
|
||||
"claim_team": 0,
|
||||
"grotto": "won",
|
||||
"phase": "vorbei",
|
||||
"rot_gold_delta": 277,
|
||||
"rot_hp_delta": -20684.7692,
|
||||
"rot_hp_lost_boss_round": 20684.7692,
|
||||
"rot_sent_value": 0,
|
||||
"scenario": "ueberinvestition",
|
||||
"sent_value": 2580,
|
||||
"winner": 1
|
||||
}
|
||||
]
|
||||
9
docs/luneraria/logs/m2/lune-core.log
Normal file
9
docs/luneraria/logs/m2/lune-core.log
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
Godot Engine v4.7.2.stable.fedora.ed1daf0bf - https://godotengine.org
|
||||
|
||||
LUNE_FULL_MATCH: seed 2 -> Blau after 7 rounds
|
||||
LUNE_CORE_PASS: 91 checks; 0 failures
|
||||
WARNING: 10 ObjectDB instances were leaked at exit (run with `--verbose` for details).
|
||||
at: cleanup (core/object/object.cpp:2536)
|
||||
ERROR: 1 resources still in use at exit (run with --verbose for details).
|
||||
at: clear (core/io/resource.cpp:822)
|
||||
EXIT 0
|
||||
8
docs/luneraria/logs/m2/lune-m2.log
Normal file
8
docs/luneraria/logs/m2/lune-m2.log
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
Godot Engine v4.7.2.stable.fedora.ed1daf0bf - https://godotengine.org
|
||||
|
||||
LUNE_M2_PASS: 65 checks; 0 failures
|
||||
WARNING: 14 ObjectDB instances were leaked at exit (run with `--verbose` for details).
|
||||
at: cleanup (core/object/object.cpp:2536)
|
||||
ERROR: 1 resources still in use at exit (run with --verbose for details).
|
||||
at: clear (core/io/resource.cpp:822)
|
||||
EXIT 0
|
||||
3327
docs/luneraria/logs/m2/sim-12-seeds.json
Normal file
3327
docs/luneraria/logs/m2/sim-12-seeds.json
Normal file
File diff suppressed because it is too large
Load diff
15
docs/luneraria/logs/m2/verify-m1.log
Normal file
15
docs/luneraria/logs/m2/verify-m1.log
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
Godot Engine v4.7.2.stable.fedora.ed1daf0bf - https://godotengine.org
|
||||
Vulkan 1.4.351 - Forward+ - Using Device #0: NVIDIA - NVIDIA GeForce RTX 5060 Ti
|
||||
|
||||
M1_MENU_READY_MS 792
|
||||
M1_SHOT planning-1280x720
|
||||
M1_SHOT planning-1920x1080
|
||||
M1_SHOT combat-mid-live
|
||||
M1_SHOT settlement
|
||||
M1_SHOT combat-top
|
||||
M1_SHOT overview-combat
|
||||
M1_SHOT core-siege
|
||||
M1_SHOT result
|
||||
M1_MATCH_RESULT Ancient von Rot zerstört. after 7 waves
|
||||
M1_VERIFY_PASS: 38 checks; 0 failures
|
||||
EXIT 0
|
||||
16
docs/luneraria/logs/m2/verify-m2.log
Normal file
16
docs/luneraria/logs/m2/verify-m2.log
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
Godot Engine v4.7.2.stable.fedora.ed1daf0bf - https://godotengine.org
|
||||
Vulkan 1.4.351 - Forward+ - Using Device #0: NVIDIA - NVIDIA GeForce RTX 5060 Ti
|
||||
|
||||
M2APP_SHOT m2-hud-hero-round1
|
||||
M2APP_SHOT m2-grotto-fight
|
||||
M2APP_SHOT m2-hero-field
|
||||
M2APP_SHOT m2-hero-items
|
||||
M2APP_SHOT m2-announcements
|
||||
M2APP_SHOT m2-boss-deployed
|
||||
M2APP_BOSS_LOG [{ "round": 5, "event": "failed" }, { "round": 6, "event": "failed" }, { "round": 7, "event": "failed" }, { "round": 8, "event": "won", "team": 1, "chooser": 4 }, { "round": 9, "event": "deployed", "team": 1, "lane": "top" }, { "round": 12, "event": "won", "team": 1, "chooser": 4 }]
|
||||
M2APP_VERIFY_PASS: 15 checks; 0 failures
|
||||
WARNING: 8 ObjectDB instances were leaked at exit (run with `--verbose` for details).
|
||||
at: cleanup (core/object/object.cpp:2536)
|
||||
ERROR: 1 resources still in use at exit (run with --verbose for details).
|
||||
at: clear (core/io/resource.cpp:822)
|
||||
EXIT 0
|
||||
6
docs/luneraria/logs/m3/balance-before-summary.txt
Normal file
6
docs/luneraria/logs/m3/balance-before-summary.txt
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
Partien 40 · Ergebnisse {'blau': 20, 'rot': 20} · Testlimit 0 · Zeitfenster-Kämpfe 1 · längster Kampf 180 s
|
||||
Wellen bis Ende: min 7 · median 9 · max 14
|
||||
Seitentausch: dieselbe Zusammensetzung gewinnt beide Male in 20/20 Paaren
|
||||
Profile (Siege/Einsätze): {'ausgewogen': '24/48 (50 %)', 'bossjagd': '2/34 (6 %)', 'druck': '28/34 (82 %)', 'fernkampf': '26/48 (54 %)', 'teamhilfe': '28/48 (58 %)', 'verteidigung': '12/28 (43 %)'}
|
||||
Bünde: {'glutpakt': '68/124 (55 %)', 'wurzelbund': '52/116 (45 %)'}
|
||||
Boss: {'won': 18, 'deployed': 10, 'failed': 63} · Heldenstufen am Ende (Median): 4
|
||||
1738
docs/luneraria/logs/m3/balance-before.json
Normal file
1738
docs/luneraria/logs/m3/balance-before.json
Normal file
File diff suppressed because it is too large
Load diff
26
docs/luneraria/logs/m3/balance-before.log
Normal file
26
docs/luneraria/logs/m3/balance-before.log
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
Godot Engine v4.7.2.stable.fedora.ed1daf0bf - https://godotengine.org
|
||||
|
||||
BALANCE 00 ["ausgewogen", "druck", "teamhilfe"] | ["teamhilfe", "verteidigung", "ausgewogen"] -> blau (7) / swapped rot (8)
|
||||
BALANCE 01 ["bossjagd", "bossjagd", "teamhilfe"] | ["fernkampf", "teamhilfe", "fernkampf"] -> rot (8) / swapped blau (8)
|
||||
BALANCE 02 ["bossjagd", "ausgewogen", "teamhilfe"] | ["druck", "ausgewogen", "verteidigung"] -> rot (9) / swapped blau (9)
|
||||
BALANCE 03 ["fernkampf", "druck", "ausgewogen"] | ["druck", "fernkampf", "verteidigung"] -> blau (13) / swapped rot (13)
|
||||
BALANCE 04 ["ausgewogen", "teamhilfe", "fernkampf"] | ["ausgewogen", "verteidigung", "fernkampf"] -> blau (9) / swapped rot (9)
|
||||
BALANCE 05 ["teamhilfe", "fernkampf", "verteidigung"] | ["fernkampf", "bossjagd", "bossjagd"] -> blau (8) / swapped rot (8)
|
||||
BALANCE 06 ["bossjagd", "ausgewogen", "teamhilfe"] | ["fernkampf", "teamhilfe", "ausgewogen"] -> rot (7) / swapped blau (8)
|
||||
BALANCE 07 ["ausgewogen", "ausgewogen", "ausgewogen"] | ["teamhilfe", "teamhilfe", "ausgewogen"] -> rot (12) / swapped blau (12)
|
||||
BALANCE 08 ["teamhilfe", "ausgewogen", "bossjagd"] | ["druck", "ausgewogen", "druck"] -> rot (10) / swapped blau (10)
|
||||
BALANCE 09 ["verteidigung", "druck", "druck"] | ["bossjagd", "ausgewogen", "teamhilfe"] -> blau (9) / swapped rot (9)
|
||||
BALANCE 10 ["druck", "ausgewogen", "ausgewogen"] | ["teamhilfe", "bossjagd", "ausgewogen"] -> blau (9) / swapped rot (9)
|
||||
BALANCE 11 ["bossjagd", "fernkampf", "fernkampf"] | ["teamhilfe", "verteidigung", "teamhilfe"] -> rot (8) / swapped blau (8)
|
||||
BALANCE 12 ["fernkampf", "fernkampf", "teamhilfe"] | ["teamhilfe", "ausgewogen", "fernkampf"] -> blau (8) / swapped rot (9)
|
||||
BALANCE 13 ["teamhilfe", "druck", "fernkampf"] | ["fernkampf", "druck", "ausgewogen"] -> rot (12) / swapped blau (12)
|
||||
BALANCE 14 ["bossjagd", "druck", "fernkampf"] | ["bossjagd", "bossjagd", "bossjagd"] -> blau (8) / swapped rot (8)
|
||||
BALANCE 15 ["fernkampf", "fernkampf", "verteidigung"] | ["druck", "fernkampf", "ausgewogen"] -> rot (13) / swapped blau (13)
|
||||
BALANCE 16 ["teamhilfe", "verteidigung", "verteidigung"] | ["teamhilfe", "verteidigung", "ausgewogen"] -> rot (14) / swapped blau (14)
|
||||
BALANCE 17 ["fernkampf", "verteidigung", "fernkampf"] | ["druck", "fernkampf", "bossjagd"] -> blau (10) / swapped rot (10)
|
||||
BALANCE 18 ["verteidigung", "ausgewogen", "bossjagd"] | ["druck", "teamhilfe", "druck"] -> rot (8) / swapped blau (8)
|
||||
BALANCE 19 ["druck", "teamhilfe", "teamhilfe"] | ["fernkampf", "verteidigung", "bossjagd"] -> blau (7) / swapped rot (7)
|
||||
WARNING: 16 ObjectDB instances were leaked at exit (run with `--verbose` for details).
|
||||
at: cleanup (core/object/object.cpp:2536)
|
||||
ERROR: 1 resources still in use at exit (run with --verbose for details).
|
||||
at: clear (core/io/resource.cpp:822)
|
||||
6
docs/luneraria/logs/m3/balance-step1-summary.txt
Normal file
6
docs/luneraria/logs/m3/balance-step1-summary.txt
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
Partien 40 · Ergebnisse {'blau': 19, 'rot': 21} · Testlimit 0 · Zeitfenster-Kämpfe 1 · längster Kampf 180 s
|
||||
Wellen bis Ende: min 7 · median 12 · max 14
|
||||
Seitentausch: dieselbe Zusammensetzung gewinnt beide Male in 19/20 Paaren
|
||||
Profile (Siege/Einsätze): {'ausgewogen': '26/48 (54 %)', 'bossjagd': '9/34 (26 %)', 'druck': '22/34 (65 %)', 'fernkampf': '29/48 (60 %)', 'teamhilfe': '28/48 (58 %)', 'verteidigung': '6/28 (21 %)'}
|
||||
Bünde: {'glutpakt': '69/124 (56 %)', 'wurzelbund': '51/116 (44 %)'}
|
||||
Boss: {} · Heldenstufen am Ende (Median): 5
|
||||
1673
docs/luneraria/logs/m3/balance-step1.json
Normal file
1673
docs/luneraria/logs/m3/balance-step1.json
Normal file
File diff suppressed because it is too large
Load diff
26
docs/luneraria/logs/m3/balance-step1.log
Normal file
26
docs/luneraria/logs/m3/balance-step1.log
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
Godot Engine v4.7.2.stable.fedora.ed1daf0bf - https://godotengine.org
|
||||
|
||||
BALANCE 00 ["ausgewogen", "druck", "teamhilfe"] | ["teamhilfe", "verteidigung", "ausgewogen"] -> blau (7) / swapped rot (8)
|
||||
BALANCE 01 ["bossjagd", "bossjagd", "teamhilfe"] | ["fernkampf", "teamhilfe", "fernkampf"] -> rot (10) / swapped blau (9)
|
||||
BALANCE 02 ["bossjagd", "ausgewogen", "teamhilfe"] | ["druck", "ausgewogen", "verteidigung"] -> blau (9) / swapped rot (9)
|
||||
BALANCE 03 ["fernkampf", "druck", "ausgewogen"] | ["druck", "fernkampf", "verteidigung"] -> blau (13) / swapped rot (13)
|
||||
BALANCE 04 ["ausgewogen", "teamhilfe", "fernkampf"] | ["ausgewogen", "verteidigung", "fernkampf"] -> blau (9) / swapped rot (9)
|
||||
BALANCE 05 ["teamhilfe", "fernkampf", "verteidigung"] | ["fernkampf", "bossjagd", "bossjagd"] -> blau (12) / swapped rot (12)
|
||||
BALANCE 06 ["bossjagd", "ausgewogen", "teamhilfe"] | ["fernkampf", "teamhilfe", "ausgewogen"] -> rot (9) / swapped rot (9)
|
||||
BALANCE 07 ["ausgewogen", "ausgewogen", "ausgewogen"] | ["teamhilfe", "teamhilfe", "ausgewogen"] -> rot (12) / swapped blau (12)
|
||||
BALANCE 08 ["teamhilfe", "ausgewogen", "bossjagd"] | ["druck", "ausgewogen", "druck"] -> rot (13) / swapped blau (13)
|
||||
BALANCE 09 ["verteidigung", "druck", "druck"] | ["bossjagd", "ausgewogen", "teamhilfe"] -> rot (9) / swapped blau (9)
|
||||
BALANCE 10 ["druck", "ausgewogen", "ausgewogen"] | ["teamhilfe", "bossjagd", "ausgewogen"] -> blau (13) / swapped rot (13)
|
||||
BALANCE 11 ["bossjagd", "fernkampf", "fernkampf"] | ["teamhilfe", "verteidigung", "teamhilfe"] -> blau (11) / swapped rot (11)
|
||||
BALANCE 12 ["fernkampf", "fernkampf", "teamhilfe"] | ["teamhilfe", "ausgewogen", "fernkampf"] -> blau (8) / swapped rot (9)
|
||||
BALANCE 13 ["teamhilfe", "druck", "fernkampf"] | ["fernkampf", "druck", "ausgewogen"] -> rot (12) / swapped blau (12)
|
||||
BALANCE 14 ["bossjagd", "druck", "fernkampf"] | ["bossjagd", "bossjagd", "bossjagd"] -> blau (12) / swapped rot (12)
|
||||
BALANCE 15 ["fernkampf", "fernkampf", "verteidigung"] | ["druck", "fernkampf", "ausgewogen"] -> rot (13) / swapped blau (13)
|
||||
BALANCE 16 ["teamhilfe", "verteidigung", "verteidigung"] | ["teamhilfe", "verteidigung", "ausgewogen"] -> rot (14) / swapped blau (14)
|
||||
BALANCE 17 ["fernkampf", "verteidigung", "fernkampf"] | ["druck", "fernkampf", "bossjagd"] -> blau (13) / swapped rot (13)
|
||||
BALANCE 18 ["verteidigung", "ausgewogen", "bossjagd"] | ["druck", "teamhilfe", "druck"] -> rot (9) / swapped blau (9)
|
||||
BALANCE 19 ["druck", "teamhilfe", "teamhilfe"] | ["fernkampf", "verteidigung", "bossjagd"] -> blau (7) / swapped rot (7)
|
||||
WARNING: 18 ObjectDB instances were leaked at exit (run with `--verbose` for details).
|
||||
at: cleanup (core/object/object.cpp:2536)
|
||||
ERROR: 1 resources still in use at exit (run with --verbose for details).
|
||||
at: clear (core/io/resource.cpp:822)
|
||||
6
docs/luneraria/logs/m3/balance-step2-summary.txt
Normal file
6
docs/luneraria/logs/m3/balance-step2-summary.txt
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
Partien 40 · Ergebnisse {'blau': 20, 'rot': 20} · Testlimit 0 · Zeitfenster-Kämpfe 3 · längster Kampf 180 s
|
||||
Wellen bis Ende: min 7 · median 10 · max 14
|
||||
Seitentausch: dieselbe Zusammensetzung gewinnt beide Male in 20/20 Paaren
|
||||
Profile (Siege/Einsätze): {'ausgewogen': '26/48 (54 %)', 'bossjagd': '10/34 (29 %)', 'druck': '24/34 (71 %)', 'fernkampf': '28/48 (58 %)', 'teamhilfe': '28/48 (58 %)', 'verteidigung': '4/28 (14 %)'}
|
||||
Bünde: {'glutpakt': '64/124 (52 %)', 'wurzelbund': '56/116 (48 %)'}
|
||||
Boss: {'won': 21, 'deployed': 12, 'failed': 2} · Heldenstufen am Ende (Median): 3
|
||||
1725
docs/luneraria/logs/m3/balance-step2.json
Normal file
1725
docs/luneraria/logs/m3/balance-step2.json
Normal file
File diff suppressed because it is too large
Load diff
26
docs/luneraria/logs/m3/balance-step2.log
Normal file
26
docs/luneraria/logs/m3/balance-step2.log
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
Godot Engine v4.7.2.stable.fedora.ed1daf0bf - https://godotengine.org
|
||||
|
||||
BALANCE 00 ["ausgewogen", "druck", "teamhilfe"] | ["teamhilfe", "verteidigung", "ausgewogen"] -> blau (7) / swapped rot (8)
|
||||
BALANCE 01 ["bossjagd", "bossjagd", "teamhilfe"] | ["fernkampf", "teamhilfe", "fernkampf"] -> rot (9) / swapped blau (8)
|
||||
BALANCE 02 ["bossjagd", "ausgewogen", "teamhilfe"] | ["druck", "ausgewogen", "verteidigung"] -> blau (10) / swapped rot (10)
|
||||
BALANCE 03 ["fernkampf", "druck", "ausgewogen"] | ["druck", "fernkampf", "verteidigung"] -> blau (13) / swapped rot (13)
|
||||
BALANCE 04 ["ausgewogen", "teamhilfe", "fernkampf"] | ["ausgewogen", "verteidigung", "fernkampf"] -> blau (9) / swapped rot (9)
|
||||
BALANCE 05 ["teamhilfe", "fernkampf", "verteidigung"] | ["fernkampf", "bossjagd", "bossjagd"] -> blau (11) / swapped rot (11)
|
||||
BALANCE 06 ["bossjagd", "ausgewogen", "teamhilfe"] | ["fernkampf", "teamhilfe", "ausgewogen"] -> rot (9) / swapped blau (9)
|
||||
BALANCE 07 ["ausgewogen", "ausgewogen", "ausgewogen"] | ["teamhilfe", "teamhilfe", "ausgewogen"] -> rot (12) / swapped blau (12)
|
||||
BALANCE 08 ["teamhilfe", "ausgewogen", "bossjagd"] | ["druck", "ausgewogen", "druck"] -> rot (11) / swapped blau (11)
|
||||
BALANCE 09 ["verteidigung", "druck", "druck"] | ["bossjagd", "ausgewogen", "teamhilfe"] -> rot (9) / swapped blau (9)
|
||||
BALANCE 10 ["druck", "ausgewogen", "ausgewogen"] | ["teamhilfe", "bossjagd", "ausgewogen"] -> blau (12) / swapped rot (12)
|
||||
BALANCE 11 ["bossjagd", "fernkampf", "fernkampf"] | ["teamhilfe", "verteidigung", "teamhilfe"] -> blau (10) / swapped rot (10)
|
||||
BALANCE 12 ["fernkampf", "fernkampf", "teamhilfe"] | ["teamhilfe", "ausgewogen", "fernkampf"] -> blau (8) / swapped rot (9)
|
||||
BALANCE 13 ["teamhilfe", "druck", "fernkampf"] | ["fernkampf", "druck", "ausgewogen"] -> rot (12) / swapped blau (12)
|
||||
BALANCE 14 ["bossjagd", "druck", "fernkampf"] | ["bossjagd", "bossjagd", "bossjagd"] -> blau (10) / swapped rot (10)
|
||||
BALANCE 15 ["fernkampf", "fernkampf", "verteidigung"] | ["druck", "fernkampf", "ausgewogen"] -> rot (13) / swapped blau (13)
|
||||
BALANCE 16 ["teamhilfe", "verteidigung", "verteidigung"] | ["teamhilfe", "verteidigung", "ausgewogen"] -> rot (14) / swapped blau (14)
|
||||
BALANCE 17 ["fernkampf", "verteidigung", "fernkampf"] | ["druck", "fernkampf", "bossjagd"] -> rot (9) / swapped blau (9)
|
||||
BALANCE 18 ["verteidigung", "ausgewogen", "bossjagd"] | ["druck", "teamhilfe", "druck"] -> rot (8) / swapped blau (8)
|
||||
BALANCE 19 ["druck", "teamhilfe", "teamhilfe"] | ["fernkampf", "verteidigung", "bossjagd"] -> blau (7) / swapped rot (7)
|
||||
WARNING: 26 ObjectDB instances were leaked at exit (run with `--verbose` for details).
|
||||
at: cleanup (core/object/object.cpp:2536)
|
||||
ERROR: 1 resources still in use at exit (run with --verbose for details).
|
||||
at: clear (core/io/resource.cpp:822)
|
||||
6
docs/luneraria/logs/m3/balance-step3-summary.txt
Normal file
6
docs/luneraria/logs/m3/balance-step3-summary.txt
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
Partien 40 · Ergebnisse {'rot': 20, 'blau': 20} · Testlimit 0 · Zeitfenster-Kämpfe 0 · längster Kampf 135 s
|
||||
Wellen bis Ende: min 9 · median 11 · max 14
|
||||
Seitentausch: dieselbe Zusammensetzung gewinnt beide Male in 20/20 Paaren
|
||||
Profile (Siege/Einsätze): {'ausgewogen': '28/48 (58 %)', 'bossjagd': '8/34 (24 %)', 'druck': '18/34 (53 %)', 'fernkampf': '26/48 (54 %)', 'teamhilfe': '22/48 (46 %)', 'verteidigung': '18/28 (64 %)'}
|
||||
Bünde: {'glutpakt': '68/124 (55 %)', 'wurzelbund': '52/116 (45 %)'}
|
||||
Boss: {'won': 24, 'deployed': 16} · Heldenstufen am Ende (Median): 4
|
||||
1770
docs/luneraria/logs/m3/balance-step3.json
Normal file
1770
docs/luneraria/logs/m3/balance-step3.json
Normal file
File diff suppressed because it is too large
Load diff
6
docs/luneraria/logs/m3/balance-step4-summary.txt
Normal file
6
docs/luneraria/logs/m3/balance-step4-summary.txt
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
Partien 40 · Ergebnisse {'rot': 20, 'blau': 20} · Testlimit 0 · Zeitfenster-Kämpfe 0 · längster Kampf 157 s
|
||||
Wellen bis Ende: min 9 · median 11 · max 14
|
||||
Seitentausch: dieselbe Zusammensetzung gewinnt beide Male in 20/20 Paaren
|
||||
Profile (Siege/Einsätze): {'ausgewogen': '28/48 (58 %)', 'bossjagd': '8/34 (24 %)', 'druck': '18/34 (53 %)', 'fernkampf': '26/48 (54 %)', 'teamhilfe': '22/48 (46 %)', 'verteidigung': '18/28 (64 %)'}
|
||||
Bünde: {'glutpakt': '68/124 (55 %)', 'wurzelbund': '52/116 (45 %)'}
|
||||
Boss: {'won': 20, 'deployed': 8} · Heldenstufen am Ende (Median): 4
|
||||
1754
docs/luneraria/logs/m3/balance-step4.json
Normal file
1754
docs/luneraria/logs/m3/balance-step4.json
Normal file
File diff suppressed because it is too large
Load diff
14
docs/luneraria/logs/m3/matchups-step2-summary.txt
Normal file
14
docs/luneraria/logs/m3/matchups-step2-summary.txt
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
Partien 30 · Ergebnisse {'blau': 15, 'rot': 15} · Testlimit 0 · Zeitfenster-Kämpfe 4 · längster Kampf 180 s
|
||||
Wellen bis Ende: min 6 · median 10 · max 16
|
||||
Seitentausch: dieselbe Zusammensetzung gewinnt beide Male in 15/15 Paaren
|
||||
Profile (Siege/Einsätze): {'ausgewogen': '24/30 (80 %)', 'bossjagd': '0/30 (0 %)', 'druck': '12/30 (40 %)', 'fernkampf': '18/30 (60 %)', 'teamhilfe': '30/30 (100 %)', 'verteidigung': '6/30 (20 %)'}
|
||||
Bünde: {'glutpakt': '30/60 (50 %)', 'wurzelbund': '60/120 (50 %)'}
|
||||
Boss: {'won': 8, 'deployed': 4} · Heldenstufen am Ende (Median): 4
|
||||
Duelle (Siege Zeile gegen Spalte, je 2 Partien mit Seitentausch):
|
||||
ausgew bossja druck fernka teamhi vertei gesamt
|
||||
ausgewogen - 2 2 2 0 2 8/10
|
||||
bossjagd 0 - 0 0 0 0 0/10
|
||||
druck 0 2 - 0 0 2 4/10
|
||||
fernkampf 0 2 2 - 0 2 6/10
|
||||
teamhilfe 2 2 2 2 - 2 10/10
|
||||
verteidigung 0 2 0 0 0 - 2/10
|
||||
1271
docs/luneraria/logs/m3/matchups-step2.json
Normal file
1271
docs/luneraria/logs/m3/matchups-step2.json
Normal file
File diff suppressed because it is too large
Load diff
21
docs/luneraria/logs/m3/matchups-step2.log
Normal file
21
docs/luneraria/logs/m3/matchups-step2.log
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
Godot Engine v4.7.2.stable.fedora.ed1daf0bf - https://godotengine.org
|
||||
|
||||
BALANCE 00 ["ausgewogen", "ausgewogen", "ausgewogen"] | ["verteidigung", "verteidigung", "verteidigung"] -> blau (11) / swapped rot (11)
|
||||
BALANCE 01 ["ausgewogen", "ausgewogen", "ausgewogen"] | ["druck", "druck", "druck"] -> blau (13) / swapped rot (13)
|
||||
BALANCE 02 ["ausgewogen", "ausgewogen", "ausgewogen"] | ["fernkampf", "fernkampf", "fernkampf"] -> blau (14) / swapped rot (14)
|
||||
BALANCE 03 ["ausgewogen", "ausgewogen", "ausgewogen"] | ["teamhilfe", "teamhilfe", "teamhilfe"] -> rot (8) / swapped blau (8)
|
||||
BALANCE 04 ["ausgewogen", "ausgewogen", "ausgewogen"] | ["bossjagd", "bossjagd", "bossjagd"] -> blau (9) / swapped rot (9)
|
||||
BALANCE 05 ["verteidigung", "verteidigung", "verteidigung"] | ["druck", "druck", "druck"] -> rot (16) / swapped blau (16)
|
||||
BALANCE 06 ["verteidigung", "verteidigung", "verteidigung"] | ["fernkampf", "fernkampf", "fernkampf"] -> rot (12) / swapped blau (12)
|
||||
BALANCE 07 ["verteidigung", "verteidigung", "verteidigung"] | ["teamhilfe", "teamhilfe", "teamhilfe"] -> rot (8) / swapped blau (8)
|
||||
BALANCE 08 ["verteidigung", "verteidigung", "verteidigung"] | ["bossjagd", "bossjagd", "bossjagd"] -> blau (10) / swapped rot (10)
|
||||
BALANCE 09 ["druck", "druck", "druck"] | ["fernkampf", "fernkampf", "fernkampf"] -> rot (12) / swapped blau (12)
|
||||
BALANCE 10 ["druck", "druck", "druck"] | ["teamhilfe", "teamhilfe", "teamhilfe"] -> rot (6) / swapped blau (6)
|
||||
BALANCE 11 ["druck", "druck", "druck"] | ["bossjagd", "bossjagd", "bossjagd"] -> blau (10) / swapped rot (10)
|
||||
BALANCE 12 ["fernkampf", "fernkampf", "fernkampf"] | ["teamhilfe", "teamhilfe", "teamhilfe"] -> rot (8) / swapped blau (8)
|
||||
BALANCE 13 ["fernkampf", "fernkampf", "fernkampf"] | ["bossjagd", "bossjagd", "bossjagd"] -> blau (9) / swapped rot (9)
|
||||
BALANCE 14 ["teamhilfe", "teamhilfe", "teamhilfe"] | ["bossjagd", "bossjagd", "bossjagd"] -> blau (6) / swapped rot (6)
|
||||
WARNING: 10 ObjectDB instances were leaked at exit (run with `--verbose` for details).
|
||||
at: cleanup (core/object/object.cpp:2536)
|
||||
ERROR: 1 resources still in use at exit (run with --verbose for details).
|
||||
at: clear (core/io/resource.cpp:822)
|
||||
14
docs/luneraria/logs/m3/matchups-step3-summary.txt
Normal file
14
docs/luneraria/logs/m3/matchups-step3-summary.txt
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
Partien 30 · Ergebnisse {'blau': 15, 'rot': 15} · Testlimit 0 · Zeitfenster-Kämpfe 0 · längster Kampf 169 s
|
||||
Wellen bis Ende: min 9 · median 10 · max 14
|
||||
Seitentausch: dieselbe Zusammensetzung gewinnt beide Male in 15/15 Paaren
|
||||
Profile (Siege/Einsätze): {'ausgewogen': '30/30 (100 %)', 'bossjagd': '0/30 (0 %)', 'druck': '6/30 (20 %)', 'fernkampf': '12/30 (40 %)', 'teamhilfe': '18/30 (60 %)', 'verteidigung': '24/30 (80 %)'}
|
||||
Bünde: {'glutpakt': '30/60 (50 %)', 'wurzelbund': '60/120 (50 %)'}
|
||||
Boss: {'won': 10, 'deployed': 2} · Heldenstufen am Ende (Median): 5
|
||||
Duelle (Siege Zeile gegen Spalte, je 2 Partien mit Seitentausch):
|
||||
ausgew bossja druck fernka teamhi vertei gesamt
|
||||
ausgewogen - 2 2 2 2 2 10/10
|
||||
bossjagd 0 - 0 0 0 0 0/10
|
||||
druck 0 2 - 0 0 0 2/10
|
||||
fernkampf 0 2 2 - 0 0 4/10
|
||||
teamhilfe 0 2 2 2 - 0 6/10
|
||||
verteidigung 0 2 2 2 2 - 8/10
|
||||
1285
docs/luneraria/logs/m3/matchups-step3.json
Normal file
1285
docs/luneraria/logs/m3/matchups-step3.json
Normal file
File diff suppressed because it is too large
Load diff
14
docs/luneraria/logs/m3/matchups-step4-summary.txt
Normal file
14
docs/luneraria/logs/m3/matchups-step4-summary.txt
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
Partien 30 · Ergebnisse {'blau': 15, 'rot': 15} · Testlimit 0 · Zeitfenster-Kämpfe 0 · längster Kampf 169 s
|
||||
Wellen bis Ende: min 9 · median 10 · max 14
|
||||
Seitentausch: dieselbe Zusammensetzung gewinnt beide Male in 15/15 Paaren
|
||||
Profile (Siege/Einsätze): {'ausgewogen': '30/30 (100 %)', 'bossjagd': '0/30 (0 %)', 'druck': '6/30 (20 %)', 'fernkampf': '12/30 (40 %)', 'teamhilfe': '18/30 (60 %)', 'verteidigung': '24/30 (80 %)'}
|
||||
Bünde: {'glutpakt': '30/60 (50 %)', 'wurzelbund': '60/120 (50 %)'}
|
||||
Boss: {'won': 4, 'deployed': 2} · Heldenstufen am Ende (Median): 5
|
||||
Duelle (Siege Zeile gegen Spalte, je 2 Partien mit Seitentausch):
|
||||
ausgew bossja druck fernka teamhi vertei gesamt
|
||||
ausgewogen - 2 2 2 2 2 10/10
|
||||
bossjagd 0 - 0 0 0 0 0/10
|
||||
druck 0 2 - 0 0 0 2/10
|
||||
fernkampf 0 2 2 - 0 0 4/10
|
||||
teamhilfe 0 2 2 2 - 0 6/10
|
||||
verteidigung 0 2 2 2 2 - 8/10
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue