Repository navigation
Expand file tree
/
Copy pathHandbuch.html
More file actions
381 lines (368 loc) · 50.8 KB
/
Copy pathHandbuch.html
File metadata and controls
381 lines (368 loc) · 50.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
<title>Selfaware-AI Handbuch</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Barlow+Condensed:wght@600;700&family=Source+Sans+3:wght@400;600&family=JetBrains+Mono:wght@400;600&display=swap">
<style>
/* Layout: Laborbuch einer Spiel-KI - schmale Inhaltsspalte, links ein festes Kapitelregister, Messreihen als Tabellen */
:root {
--bg: #f3f2ef; --fl: #ffffff; --fg: #1d1f22; --mute: #5d6168; --rand: #d9d6cf; --akzent: #a3241b; --akzent-hell: #f6e3e0;
--gut: #2e6b3a; --warn: #8a5a00;
--t-display: "Barlow Condensed", "Arial Narrow", sans-serif;
--t-text: "Source Sans 3", "Segoe UI", system-ui, sans-serif;
--t-mono: "JetBrains Mono", Consolas, monospace;
}
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) {
--bg: #16171a; --fl: #1f2125; --fg: #e8e6e1; --mute: #a2a5ab; --rand: #34363b; --akzent: #e0665b; --akzent-hell: #3a1f1c;
--gut: #7fc28c; --warn: #e2b04e; color-scheme: dark } }
:root[data-theme="dark"] {
--bg: #16171a; --fl: #1f2125; --fg: #e8e6e1; --mute: #a2a5ab; --rand: #34363b; --akzent: #e0665b; --akzent-hell: #3a1f1c;
--gut: #7fc28c; --warn: #e2b04e; color-scheme: dark }
body { background: var(--bg); color: var(--fg); font: 16px/1.6 var(--t-text); }
.rahmen { display: grid; grid-template-columns: 15rem minmax(0, 1fr); gap: 3rem; max-width: 72rem; margin: 0 auto; padding-inline: 1.25rem; padding-block: 2rem 4rem; }
nav { position: sticky; top: calc(env(safe-area-inset-top, 0px) + 1.5rem); align-self: start; font-size: .9rem; }
nav p { font: 700 .75rem/1 var(--t-display); letter-spacing: .12em; text-transform: uppercase; color: var(--mute); margin: 0 0 .6rem; }
nav ol { list-style: none; margin: 0; padding: 0; display: grid; gap: .3rem; counter-reset: k; }
nav li { counter-increment: k; }
nav a { color: var(--fg); text-decoration: none; display: flex; gap: .5rem; }
nav a::before { content: counter(k); color: var(--akzent); font: 600 .8rem/1.6 var(--t-mono); min-width: 1.2rem; }
nav a:hover, nav a:focus-visible { color: var(--akzent); }
main { min-width: 0; }
header { border-bottom: 3px solid var(--akzent); padding-bottom: 1.25rem; margin-bottom: 2rem; }
header .marke { font: 600 .8rem/1 var(--t-mono); color: var(--akzent); letter-spacing: .08em; text-transform: uppercase; }
h1 { font: 700 clamp(2.2rem, 5vw, 3.2rem)/1.05 var(--t-display); margin: .5rem 0 .75rem; text-wrap: balance; letter-spacing: .01em; }
header p { color: var(--mute); max-width: 62ch; margin: 0; }
section { padding-block: 1.5rem; border-bottom: 1px solid var(--rand); }
h2 { font: 700 1.7rem/1.15 var(--t-display); margin: 0 0 .75rem; text-wrap: balance; }
h2 small { font: 600 .8rem var(--t-mono); color: var(--akzent); margin-right: .5rem; vertical-align: .2em; }
h3 { font: 600 1.05rem/1.3 var(--t-text); margin: 1.4rem 0 .4rem; }
p, li { max-width: 68ch; }
ul { padding-left: 1.2rem; display: grid; gap: .35rem; }
code, .mono { font: .88em var(--t-mono); }
code { background: var(--fl); border: 1px solid var(--rand); border-radius: 3px; padding: 0 .3em; overflow-wrap: anywhere; }
.tab { overflow-x: auto; margin: .75rem 0 1rem; border: 1px solid var(--rand); border-radius: 4px; background: var(--fl); }
table { border-collapse: collapse; width: 100%; font-size: .92rem; font-variant-numeric: tabular-nums; }
th, td { text-align: left; padding: .45rem .7rem; border-bottom: 1px solid var(--rand); vertical-align: top; }
th { font: 600 .78rem var(--t-display); letter-spacing: .08em; text-transform: uppercase; color: var(--mute); background: var(--bg); }
tr:last-child td { border-bottom: 0; }
td.z { text-align: right; white-space: nowrap; }
.merk { border-left: 3px solid var(--akzent); background: var(--akzent-hell); padding: .7rem 1rem; margin: 1rem 0; border-radius: 0 4px 4px 0; }
.merk b { color: var(--akzent); }
.status { display: inline-block; font: 600 .7rem/1.6 var(--t-mono); padding: 0 .45rem; border-radius: 3px; border: 1px solid currentColor; text-transform: uppercase; letter-spacing: .05em; }
.gemessen { color: var(--gut); } .abgelesen { color: var(--akzent); } .offen { color: var(--warn); }
.getestet { color: var(--gut); } .ungeprueft { color: var(--warn); } .daniel { color: var(--akzent); } .fest { color: var(--gut); background: var(--akzent-hell); }
.legende { display: flex; flex-wrap: wrap; gap: .75rem; font-size: .85rem; color: var(--mute); margin-top: 1rem; }
@media (max-width: 800px) {
.rahmen { grid-template-columns: minmax(0, 1fr); gap: 1.5rem; }
nav { position: static; border: 1px solid var(--rand); background: var(--fl); padding: .9rem 1rem; border-radius: 4px; }
nav ol { grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr)); }
}
@media (prefers-reduced-motion: no-preference) { nav a { transition: color .15s; } }
</style>
<div class="rahmen">
<nav aria-label="Kapitel">
<p>Kapitel</p>
<ol>
<li><a href="#ziel">Ziel und Aufbau</a></li>
<li><a href="#kanal">Der Befehlskanal</a></li>
<li><a href="#start">Spielstart und Saat</a></li>
<li><a href="#balance">Liga-Balance</a></li>
<li><a href="#wirtschaft">Eroeffnung und Wirtschaft</a></li>
<li><a href="#assassinen">Assassinen</a></li>
<li><a href="#lord">Lord-Angriff</a></li>
<li><a href="#testen">So wird getestet</a></li>
<li><a href="#architektur">Zielarchitektur nach Sharky</a></li>
<li><a href="#offen">Offen</a></li>
<li><a href="#quellen">Dateien</a></li>
</ol>
</nav>
<main>
<header>
<span class="marke">Stronghold Crusader · UCP3 · Stand 08.10.2026</span>
<h1>Selfaware-AI Handbuch</h1>
<p>Alles, was die Selfaware-KI bisher gelernt hat: wie sie das Spiel steuert, was gemessen ist, was nur aus dem Spielcode abgelesen ist, und was noch offen ist. Jede Zahl stammt aus einem Testlauf oder aus einer Datei; Vermutungen sind als offen markiert.</p>
<div class="legende">
<span><span class="status gemessen">gemessen</span> im Spiel gemessen</span>
<span><span class="status abgelesen">abgelesen</span> aus Spielcode, Balance-Datei oder Handbuch</span>
<span><span class="status offen">offen</span> Vermutung oder ungeprueft</span>
</div>
</header>
<section id="ziel">
<h2><small>01</small>Ziel und Aufbau</h2>
<p>Eine selbst gebaute KI spielt Platz 1 auf <code>Liga_Grumpy Neighbors</code> gegen die Liga-KI Rotkaeppchen (Platz 2, Vanilla-Platz "Ratte") und soll ihren Lord toeten, ohne den eigenen zu verlieren. Gespielt wird mit den Liga-Bedingungen: 0 Gold, 150 Holz, je 15 von vier Nahrungssorten, Ausgleich 3.</p>
<p>Die Strategie stammt von Daniel und gilt in dieser Reihenfolge:</p>
<ul>
<li><b>So frueh wie moeglich raiden</b>, ohne Ruecksicht auf Verluste.</li>
<li><b>Parallel die Wirtschaft maximal aufbauen</b> (Farmen nicht vergessen). Apfel-Seasoning gleich am Anfang ist eine gute Investition, denn Nahrung ist fuer Beliebtheit und Verkauf unersetzlich.</li>
<li><b>Ihre Wirtschaft abreissen</b>, ihre Wachen im Kreis herumfuehren, bis wir die Uebermacht sind.</li>
<li><b>Mit allen Assassinen moeglichst gleichzeitig auf den Lord.</b></li>
</ul>
<p>Technisch: ein Python-Lenker (<code>erstes_spiel.py</code>) liest jede Runde das Lagebild aus dem Spielspeicher und schickt Befehle ueber ein UCP3-Lua-Modul ins Spiel. Er befiehlt nur eigene Einheiten und spielt nach den Regeln eines Menschen.</p>
</section>
<section id="kanal">
<h2><small>02</small>Der Befehlskanal</h2>
<p>Python schreibt <code>befehl.json</code>, das Lua-Modul (<code>logik.lua</code>, wird im laufenden Spiel neu geladen) liest die Datei in jedem Tick, fuehrt aus und antwortet im <code>ucp3.log</code>.</p>
<h3>Quittung statt fester Wartezeit <span class="status gemessen">gemessen</span></h3>
<p>Jeder Befehl traegt eine Nummer; das Modul schreibt nach der Ausfuehrung <code>QUITTUNG <nr></code>. Der Kanal wartet genau darauf. Vorher wartete jede Abfrage fest eine Sekunde.</p>
<div class="tab"><table>
<tr><th>Abfrage</th><th class="z">feste Wartezeit</th><th class="z">mit Quittung</th></tr>
<tr><td>Vorrat lesen</td><td class="z">1,01 s</td><td class="z">0,034 s</td></tr>
<tr><td>Gebaeude einer Art lesen</td><td class="z">1,01 s</td><td class="z">0,030 s</td></tr>
</table></div>
<div class="merk"><b>Learning (06.10.):</b> Die Quittung sagt, dass der Befehl ausgefuehrt wurde - nicht, dass er gewirkt hat. Beim Laden kommt die Quittung im selben Tick wie der Knopfdruck, das Laden selbst erst danach; seit Einfuehrung der Quittung meldete darum jedes Laden "kein Laden erkannt" (Codex umging das im Messwerkzeug). Jetzt wartet das Laden auf die Lade-Meldung des Spiels.</div>
<div class="merk"><b>Learning:</b> Bei Tempo 40 ist eine Sekunde 40 Spielticks. Feste Wartezeiten machten die Eroeffnung um tausende Ticks langsamer. Nie fest warten, immer auf eine Antwort oder auf eine Spielzeit.</div>
<h3>Spielbefehle wie ein Mensch <span class="status abgelesen">abgelesen</span></h3>
<ul>
<li>Auswahl: Spielbefehl 16 (MakeUnitSelection) mit freier Gruppennummer; dann Befehl 36 (ClickGiveUnitsInstruction) fuer Angreifen/Anhalten.</li>
<li>Laufen: Spielbefehl 17 (ClickMoveUnit). Nur dieser Weg bricht einen Nahkampf ab; reines Laufziel-Setzen (<code>setDestinationForUnit</code>) laesst den Kampfzustand stehen.</li>
<li>Bauen 28, Anwerben 31, Steuern 34, Rationen 35, Kaufen/Verkaufen 38, Abreissen 29.</li>
<li>Eine Testsperre je Spielkopie verhindert, dass zwei Sitzungen gleichzeitig steuern.</li>
</ul>
</section>
<section id="start">
<h2><small>03</small>Spielstart und feste Saat</h2>
<p>Jede Partie startet frisch ab Tick 0 (frueher: Laden eines Standes von Tick 600, Rotkaeppchen hatte 600 Ticks Vorsprung). Tempo wird vor dem Start gesetzt, die Startplaetze sind fest (Mensch Platz 0, Rotkaeppchen Platz 1), es gibt keine Pausen.</p>
<h3>Gleicher Zufall, gleiche Partie <span class="status gemessen">gemessen</span></h3>
<p>Nach dem Vorbild des Replay-Moduls <a href="https://github.com/Krarilotus/ucp_recorder">ucp_recorder</a> schreibt der Start Karten-Saat <code>0x01A279C4</code>, Zufallswerte <code>0x01A279C0/C2</code> und Zaehler <code>0x01A3160C/08</code>, nachdem die Zufallstabelle neu gefuellt wurde (<code>0x0046A760</code>).</p>
<div class="tab"><table>
<tr><th>Vergleich bei Tick ~3.015</th><th>Ergebnis</th></tr>
<tr><td>Gleiche Saat, zwei Partien</td><td>Rotkaeppchens 48 Gebaeude identisch nach Art und Ort; unser Lord startet am selben Feld</td></tr>
<tr><td>Andere Saat</td><td>Lord startet an anderem Feld, eine ihrer Apfelplantagen an anderer Stelle</td></tr>
</table></div>
<p>Restunterschiede entstehen durch unseren Lenker, der in Echtzeit reagiert. <span class="status offen">offen</span> Befehle auf einen genauen Tick planen (0x00480210 scheduleCommand, aus ucp_recorder) wuerde auch das angleichen.</p>
</section>
<section id="balance">
<h2><small>04</small>Liga-Balance</h2>
<p>Quelle: <code>Mod-KI-Team-Liga-2.0.2/resources/balance/liga_ai.json</code>, beide Spielkopien laden sie (rebalancer 1.1.3). <span class="status abgelesen">abgelesen</span></p>
<div class="tab"><table>
<tr><th>Wert</th><th>Liga</th><th>Bedeutung fuer uns</th></tr>
<tr><td>Assassine</td><td>12.500 Leben, 70 Gold, Schaden 250</td><td>gegen Bogenschuetzen 225, Speer 120, Lord nur 100 je Schlag</td></tr>
<tr><td>Lord</td><td>150.000 Leben <span class="status gemessen">gemessen</span></td><td>rund 1.500 Assassinen-Schlaege</td></tr>
<tr><td>Pfeil gegen Assassine</td><td>1.200 (Speertraeger: 3.000)</td><td>Assassinen halten Beschuss gut aus</td></tr>
<tr><td>Schussweite Bogen/Armbrust</td><td>40 Felder</td><td>Gefahrenzaehlung jetzt bis 40 (vorher 16)</td></tr>
<tr><td>Schrecken</td><td>Kampfkraft 80 % bis 140 %</td><td>Galgen 40 Gold - billiger Hebel <span class="status offen">offen</span></td></tr>
<tr><td>Hunde</td><td>Zwinger ab 16 Feinden</td><td>20 Assassinen vor ihrer Burg wecken die Hunde</td></tr>
<tr><td>Hoehenvorteil</td><td>reduce_height_advantage</td><td>wirkt bei uns nicht (nur Extreme), Mauerschuetzen voll</td></tr>
<tr><td>Schlagende Arbeiter</td><td>Holzfaeller/Steinmetz/Schmied 10, Jaeger 5</td><td>zaehlen bei der Uebermacht mit (Gewicht Schaden / 25)</td></tr>
<tr><td>Preise</td><td>Kaese 30, Brot 20, Apfel 15, Fleisch 5 je 5 Stueck</td><td>Fleisch behalten kostet fast nichts</td></tr>
</table></div>
</section>
<section id="wirtschaft">
<h2><small>05</small>Eroeffnung und Wirtschaft</h2>
<h3>Raid zuerst, ohne Pausen <span class="status gemessen">gemessen</span></h3>
<p>Alles, was nur Holz kostet, geht beim Start in einem Befehl raus (Kornspeicher, Markt, 14 Holzfaeller, Steinbruch, Ochsenjoch, Huetten). Sobald alle vier Nahrungssorten im Kornspeicher liegen, werden Kaese, Brot und Aepfel verkauft (Fleisch bleibt), das bringt rund 195 Gold. Seit 05.10. 23:45 kommen dann <b>Soeldnerposten und die drei A-Apfelplantagen in einem Befehl</b> (120 + 3 × 15 Gold); vorher kam zuerst der Assassine, die Plantagen danach (siehe Seasoning am Anfang). Die Zeiten unten stammen aus der alten Reihenfolge.</p>
<div class="tab"><table>
<tr><th>Schritt</th><th class="z">alte Eroeffnung</th><th class="z">neu, Tempo 40</th></tr>
<tr><td>Erster Baubefehl</td><td class="z">nach Laden bei 600</td><td class="z">106</td></tr>
<tr><td>Startnahrung da und verkauft</td><td class="z">~720</td><td class="z">137</td></tr>
<tr><td>Soeldnerposten + erster Assassine</td><td class="z">833 / 5.930 (1. Raid)</td><td class="z">372</td></tr>
<tr><td>Holz-Wirtschaft komplett</td><td class="z">~990</td><td class="z">391</td></tr>
</table></div>
<ul>
<li><b>Farmen nicht vergessen:</b> fehlende A-Plantagen werden nachgeholt, sobald 15 Gold und 3 Holz da sind; solange werden keine weiteren Assassinen angeworben. Ohne A wird A nie reif und B nie gesetzt.</li>
<li><b>Anwerben ab 70 Gold</b> (ein Assassine kostet 70); vorher lagen 30 Gold Ruecklage obendrauf, das Gold stand meist bei 40–97 und reichte nie (gewinn_2).</li>
<li><b>Nahrung:</b> sofort beim ersten Essen verkaufen ging schief (es kommt nach und nach an) - erst wenn alle vier Sorten da sind.</li>
<li><b>Ochsenjoche</b> nach Daniels Regel: erster Ochse beladen unterwegs, dann sofort das zweite; liegen dann noch mehr als 8 Steine am Haufen, ein weiteres; keine Obergrenze.</li>
<li><b>Holz wird nicht mehr verkauft</b> (Daniel 06.10.: "statt Holz verkaufen einfach mehr Holzfaeller, weil Holz kann man spaeter immer brauchen"): Wo bisher Holz verkauft wurde - Ueberschuss ueber 30 und das alte Lager vor dem Abriss -, baut der Lenker einen Holzfaeller am besten Platz; geht das gerade nicht (kein Arbeiter frei, B-Ruecklage), bleibt das Holz liegen. Nur ein Rest von 1–4 im alten Lager geht beim Abriss verloren (Codex). Vorher (Codex, 06.10.): Lagerholz in 5er-Losen verkauft, 25 Holz = 25 Gold. <span class="status gemessen">gemessen</span> holz_partie_1: kein Sieg bis 28.717, 20. Assassine erst bei 19.785 (vorher 16.013) - verzerrt durch einen Fehler (1.009 Bauversuche am selben unbebaubaren Platz, behoben). holz_partie_2 (Fehler behoben): 5 Holzfaeller statt Verkauf, 10./20. Assassine bei 16.592 / 20.190 (mit Holzverkauf: 12.446 / 16.013), Angriff erst kurz vor 28.744, kein Sieg. <b>Holzverkauf war frueh eine wichtige Goldquelle fuer die Assassinen</b> - Zielkonflikt mit "so frueh wie moeglich gewinnen", liegt Daniel zur Entscheidung vor.</li>
<li><b>B-Plantage erst bestaetigt, wenn sie steht</b> (Codex 06.10.): ein gesendeter Baubefehl zaehlt nicht mehr als gebaut, erst das sichtbare Gebaeude; nach 50 Ticks ohne Gebaeude wird neu beauftragt. Mehrere B-Plantagen in einer Runde geben Holz und Gold nicht mehr doppelt aus. Vorher hielt eine einzige "offene" B-Plantage das Anwerben fest.</li>
<li><b>Ertrags-Planer:</b> baut nur, was sich bis Spielende bezahlt macht; Erträge werden im Spiel gemessen (Zugang = Bestandsaenderung + Verkauf + Verbaut). Holz wird nicht gekauft, sondern mit seinem Verkaufswert gerechnet; Stein bis auf den Bedarf der naechsten Eisenmine (6) verkauft.</li>
</ul>
<h3>Testpartie gegen die leere KI: 10.000 Gold <span class="status gemessen">gemessen</span></h3>
<p>Ohne Assassinen, Rotkaeppchen ohne Waren und Gold. Erster Lauf: 60.000 Ticks, nur 1.013 Gold - der Verkauf am Markt stand im Lenker im Assassinen-Teil und lief ohne Assassinen nie (behoben). Zweiter Lauf mit Verkauf:</p>
<div class="tab"><table>
<tr><th class="z">Gold</th><th class="z">1.000</th><th class="z">2.000</th><th class="z">4.000</th><th class="z">6.000</th><th class="z">8.000</th><th class="z">10.000</th></tr>
<tr><td class="z">Tick</td><td class="z">15.975</td><td class="z">20.808</td><td class="z">25.483</td><td class="z">29.103</td><td class="z">32.767</td><td class="z">36.226</td></tr>
</table></div>
<p>Verkauft (Runden mit Verkauf): Holz 166, Fleisch 146, Aepfel 103, Stein 95, Eisen 27. <span class="status abgelesen">abgelesen</span> Liga-Steuern je Einwohner und Beliebtheit: Stufe 3 (heute) 0,25 Gold / -25; Stufe 6 1,0 / -200; Stufe 9 2,0 / -500 - Steuern sind der Hebel fuer stabiles Wachstum, bezahlt mit Beliebtheit aus Bier, Essensvielfalt, Religion, Angstfaktor (Daniel 19:33: Rohstoffverkauf reicht gegen mehrere Gegner nicht).</p>
<h3>Streitkolbenkaempfer 10-20-30-40-50 <span class="status offen">offen</span></h3>
<p><span class="status gemessen">gemessen</span> Messpartie 06.10. (<code>streitkolben_messen.py</code>, Waren gesetzt, kein Benchmark): Markt je Kauf 5 Keulen fuer 300 Gold, Verkauf 5 fuer 150; Leder je Kauf 5 fuer 160, Verkauf 5 fuer 50 - ein Streitkolbenkaempfer ueber den Markt also 60 + 32 + 20 = 112 Gold. <span class="status offen">offen</span> Kaserne (Mapper 87, im Werkzeug als BARRACKS_ARAB bezeichnet), Schmiede (83) und Gerberei (85) wurden vom Spiel angenommen (abgesetzt=true), erschienen aber nie - Waffenlager, Markt, Milchviehhoefe und Huetten schon. Ursache (Daniel: "du brauchst gewisse Gueter, siehe Balance"): Alle drei brauchen Stein; ein gesetzter Stein-Zaehler wird vom Spiel aus den Lagern neu gezaehlt (300 gesetzt, kurz darauf 0) - nur Gold ist eine reine Zahl. Mit am Markt gekauftem Stein stehen alle drei.</p>
<p><span class="status gemessen">gemessen</span> Messpartie 3: Kaserne zieht je Streitkolbenkaempfer 20 Gold + 1 Keule + 1 Lederharnisch ab. Gerberei macht aus einer Kuh 3 Lederharnische (2 Spruenge zu je +3, ~1.800 Ticks auseinander, 2 Milchviehhoefe).</p>
<p><span class="status gemessen">gemessen</span> Warum der Eisenkauf scheiterte (Tipp Daniel: Ware ungleich im Lager verteilt): Jedes Lagerteil fasst nur EINE Warenart, hoechstens 48 (Menge +0x184, Grenze +0x188, Warenart +0x18C im Gebaeude-Datensatz). Die 4 Teile hielten Holz 13 + 48 und Stein 17 + 2 - alle belegt, also kein Platz fuer Eisen; 2 Stein blockierten ein ganzes Teil. Fuer die Challenge: vor jedem Kauf einer neuen Warenart ein freies Teil schaffen (Lager anbauen oder Reste verkaufen).</p>
<p><span class="status gemessen">gemessen</span> Messpartie 4: Mit angebautem Lagerblock 20 Eisen fuer 1.080 Gold gekauft. Die Schmiede macht ohne Umstellung <b>Schwerter</b> (1 Eisen -> 1 Schwert); sie holte je 1 Eisen bei Tick 4.654 und 8.745 - ~4.100 Ticks je Stueck bei ~55 Feldern Weg zum Lager. Werkstaetten direkt ans Lager.</p>
<p><span class="status gemessen">gemessen</span> Messpartien 5/6: Die Schmiede wird mit Spielbefehl 33 <code>ClickSetBuildingProductionType</code> (Gebaeude, Art 21, UID) auf Keulen gestellt - danach 3 Keulen aus 3 Eisen. Am Lager (~6 Felder) holt sie alle ~2.100 Ticks ein Eisen (bei 55 Feldern ~4.100). <b>Lager zuerst vergroessern</b>: alles direkt ans Lager gebaut liess keinen Anbau mehr zu, Eisenkauf scheiterte.</p>
<h3>25 Streitkolbenkaempfer: 24-Monats-Grenze <span class="status offen">Plan</span></h3>
<p><span class="status gemessen">gemessen</span> Ein Monat hat 800 Ticks. Daniels Grenze vom 08.10. ist Tick 19.200 (24 Monate), Wunschziel Tick 16.000 (20 Monate). Die fuenf bisherigen Haushalt-Laeufe endeten bei 21.348 / 19.205 / 17.716 / <b>16.753</b> / 16.966 Ticks; der Rekord entspricht 20,94 Monaten, stammt aber nur aus einem Lauf. Lauf 6 ist wegen einer bis zu 1.459 Ticks verspaeteten B-Plantage kein sauberer Kontrolllauf.</p>
<p><span class="status gemessen">gemessen</span> Neue Kettenmessung 08.10.: Eine Mine liefert 0,59 Eisen je 1.000 Ticks, unabhaengig von 7 bis 54 Feldern Lagerweg; die erste Lieferung kommt 3.600–4.000 Ticks nach dem Bau. Eine Schmiede fertigt eine Keule je 2.000–2.300 Ticks, die erste nach etwa 3.300. Eine Gerberei mit zwei Milchviehhoefen liefert 3 Leder je 2.100–2.800 Ticks; der Gerber ist der Engpass.</p>
<div class="merk"><b>Planregel:</b> Entscheidend ist das spaeteste von Keulen, Leder, 500 Gold, 25 Bauern und fertiger Kaserne/Waffenlager. Laufende Ware in Mine, Transport, Schmiede, Kuh und Gerberei zaehlt mit; nur der echte Rest wird gekauft. Reihenfolge: Grundlinie dreimal bestaetigen, Stein mit zwei fruehen Ochsenjochen vor Tick 3.500 liefern, dann zuerst 4 Hoefe + 2 Gerbereien, danach nur bei ausreichendem Holz, Stein und Arbeitern 4 Minen + 6 Schmieden. Tick 14.500 ist Kaufentscheidung, Tick 17.500 Sicherungsumschaltung, Tick 19.200 harte Grenze. Voller Plan: <code>Plan_Streitkolben.md</code>.</div>
<h3>Abriss gibt die Haelfte zurueck - abgerundet <span class="status gemessen">gemessen</span></h3>
<p><span class="status abgelesen">abgelesen</span> Spielcode: Der Abriss-Knopf schickt Spielbefehl 29 mit <b>50 %</b> (<code>MenuItemActionHandler_BuildMenu_DeleteAction</code>, 0x00438ad9). Die Rueckgabe ist je Ware <code>Kosten × 50 / 100</code> in ganzen Zahlen - ohne Anteil fuer den Zustand des Gebaeudes (Daniel 20:06: "die Haelfte, egal in welchem Zustand"). Unser Modulbefehl <code>abreissen</code> schickte bis 06.10. 0 % (Wert des Klicks war nicht gefunden) - darum kam 4-mal nichts zurueck; jetzt Standard 50, hoeher wird gedeckelt.</p>
<p><span class="status gemessen">gemessen</span> Messpartie 8 und <code>abriss_messen.py</code> (06.10. 20:12, Erwartung vorher aufgeschrieben, alle 6 passten): <b>es wird abgerundet, und kein Rest wird gemerkt</b> - bei 3 kommt 1 zurueck.</p>
<div class="tab"><table>
<tr><th>Gebaeude</th><th>Kosten Holz / Stein / Gold</th><th>zurueck</th></tr>
<tr><td>Schmiede</td><td class="z">20 / 8 / 0</td><td class="z">10 / 4 / 0</td></tr>
<tr><td>Gerberei</td><td class="z">15 / 3 / 75</td><td class="z">7 / 1 / 37</td></tr>
<tr><td>Gerberei (zweite gleich danach)</td><td class="z">15 / 3 / 75</td><td class="z">7 / 1 / 37</td></tr>
<tr><td>Milchviehhof</td><td class="z">7 / 0 / 15</td><td class="z">3 / 0 / 7</td></tr>
<tr><td>Kaserne</td><td class="z">0 / 12 / 0</td><td class="z">0 / 6 / 0</td></tr>
<tr><td>Huette</td><td class="z">5 / 0 / 0</td><td class="z">2 / 0 / 0</td></tr>
</table></div>
<p>Folgen: Ungerade Kosten verlieren beim Abriss je Ware eine halbe Einheit mehr. In der Liga haben 25 von 63 Bauwerken mindestens einen ungeraden Wert (z. B. kleines Torhaus 15 Stein → 7, Turm 4 35 → 17, Weizenfarm 13 Holz → 6). <span class="status offen">nur Code, nicht gemessen</span> Ist im Lager kein Platz fuer die Ware, spielt das Spiel den Ton "kein Platz" und die Rueckgabe ist weg - vor dem Abriss Lagerplatz pruefen. Mauern laufen ueber einen eigenen Weg, der Bruchteile ueber mehrere Abrisse sammelt - nicht gemessen.</p>
<h3>Laufwege <span class="status offen">laeuft</span></h3>
<p>Daniel 20:05–20:32: Laufwege sichtbar machen, alle moeglichen Wege durch Gebaeude, alle Abstaende fuer 2/3/4 Gebaeude testen, dann der beste Aufbau fuer 5, 15, 30 Schmiede und Gerber. <b>Jede Aussage hat eine Stufe</b> (Wissensregister <code>Wissensregister.md</code>): <span class="status ungeprueft">ungeprueft</span> nur Code oder Weg-Ebene, <span class="status getestet">getestet</span> im Spiel gemessen, <span class="status daniel">Daniel</span> aus Spielerfahrung, <span class="status fest">fest</span> getestet und von Daniel bestaetigt.</p>
<p>Werkzeuge: Modulbefehl <code>wegkarte</code> liest die Weg-Ebene des Spiels (je Feld 8 erlaubte Schritte, PathLinkageLayer 0x01E1E4F8) → <code>wegkarte.py</code> zeichnet sie (grau gesperrt, rot schraeg zwischen zwei Ecken, orange nur eine Richtung). <code>wege_abstand.py</code> (Grundrisse, Paare, Dreier, Vierer), <code>arbeitsgang_messen.py</code> + <code>arbeitsgang_auswerten.py</code> (Arbeiter alle 2 Ticks), <code>eingang_messen.py</code>, <code>aufbau_planer.py</code> + <code>aufbau_bauen.py</code>.</p>
<ul>
<li><span class="status getestet">getestet</span> Arbeiter laufen <b>24 Ticks je Feld, gerade und schraeg gleich</b> (Milchbauer 16). Schmied: <b>927 Ticks Arbeit je Keule</b>, je Zyklus ein Rundgang Schmiede → Lager (Eisen) → Waffenlager → Schmiede. Gerber: ~1.550 Ticks je Kuh, 3 Lederharnische in <b>einem</b> Gang zum Waffenlager.</li>
<li><span class="status getestet">getestet</span> Bau-Richtung dreht den Eingang (4x4): 0 unten (x+2,y+4), 2 links (x-1,y+2), 4 oben (x+1,y-1), 6 rechts (x+4,y+1). Nur <b>eine Kaserne</b> je Spieler (0 von 25); ein weiteres <b>Waffenlager nur Kante an Kante</b> an ein bestehendes.</li>
<li><span class="status getestet">widerlegt</span> "Lagerteile nur herunter": Arbeiter treten zum Abholen sehr wohl vom Boden auf Lagerteile (19 von 19 Schritten, die die Weg-Ebene nicht erlaubt). Alle anderen ~700 Schritte passten zur Weg-Ebene.</li>
<li><span class="status ungeprueft">ungeprueft</span> (Weg-Ebene, Code): Werkstaetten/Lager/Huetten Ecke an Ecke → schraeg durchgaengig; Kaserne, Waffenlager, Tuerme, Torhaeuser, Muehle, Kapelle sind Ecksperren. Gerade ohne Abstand nie durch, ab 1 Feld immer. Kaserne = Haus 5x5 + 3 Exerzierplatz-Stuecke (10x10, begehbar bis auf 4 Pfosten); Milchviehhof Zaun mit 2 Felder breiten Toren je Seite; Apfelplantage nur Huette 3x3; Lagerplatz 4 Teile 2x2 mit Bodenkreuz.</li>
<li><span class="status daniel">Daniel</span> Wassergraben schraeg durch, Mauern/Tuerme nicht; Eingaenge zubauen lenkt Arbeiter auf andere Eingaenge (gespeicherter Eingang bleibt laut Messung gleich - Lauftest offen).</li>
<li><span class="status offen">offen</span> 13 Keulen aus 11 Eisen (mehr als 1:1?); woher der Gerber die naechste Kuh bekommt; ob Arbeiter laufende Wege nach einem Neubau neu suchen (Daniel 20:17, das Wegnetz baut das Spiel nur alle 200 Takte neu - Code).</li>
</ul>
<p>Plan in <code>Plan_Streitkolben.md</code>: erst jede Werkstatt messen (Kuehe je Zeit, Harnische je Kuh, Keulen je Eisen), dann die Kette mit Kaserne und Waffenlager direkt am Lager bauen, bauen erst wenn die Ware im Lager ist; Gegenprobe mit Kauf am Markt. Liga: 20 Gold + Keule + Lederharnisch je Kaempfer; Keule am Markt 300, Leder 160.</p>
<h3>Apfel-Seasoning <span class="status gemessen">gemessen</span></h3>
<p>Ein Apfelbaum durchlaeuft sechs Stufen (500 / 300 / 200 / 1.000 / 40 / 40 Ticks) und wird nur in Stufe 3 geerntet. Der Apfelbauer nimmt jeden reifen Baum im Umkreis von 30 Feldern, auch fremde. Daniels Regel: Gruppe B neben Gruppe A genau dann setzen, wenn A in Stufe 3 springt; dann versorgen sie sich gegenseitig.</p>
<h3>Seasoning am Anfang <span class="status gemessen">gemessen</span></h3>
<p>Ganze Partien ab Tick 0, Tempo 300, feste Saat; Werte aus <code>serie.werte</code>, jede Zeile ein Schritt mehr als die davor.</p>
<div class="tab"><table>
<tr><th>Partie</th><th>Stand</th><th class="z">A reif</th><th class="z">B steht</th><th class="z">1. / 10. Assassine</th><th class="z">Beliebtheit 5k / 10k / 20k</th><th>Ergebnis</th></tr>
<tr><td>gewinn_2</td><td>Anwerben ab 100 Gold, A-Baum-Fehler</td><td class="z">nie</td><td class="z">nie</td><td class="z">630 / 16.418</td><td class="z">78 / 72 / 64</td><td>Zeit um</td></tr>
<tr><td>gewinn_3</td><td>Anwerben ab 70, A-Baum wird neu gesucht</td><td class="z">2.325</td><td class="z">6.601</td><td class="z">646 / 13.443</td><td class="z">83 / 77 / 65</td><td>Sieg 26.081</td></tr>
<tr><td>gewinn_4</td><td>+ Planer legt B-Holz zurueck</td><td class="z">2.324</td><td class="z">5.158</td><td class="z">640 / 12.892</td><td class="z">77 / 71 / 61</td><td>Zeit um</td></tr>
<tr><td>gewinn_5</td><td>+ A-Plantagen mit dem Posten in der Eroeffnung</td><td class="z">1.500</td><td class="z">3.978</td><td class="z">nicht protokolliert / 12.218</td><td class="z">92 / 86 / 74</td><td>Sieg 24.935</td></tr>
<tr><td>gewinn_6</td><td>+ gemeinsame B-Ruecklage fuer alle Ausgeber</td><td class="z">1.473</td><td class="z">1.554</td><td class="z">3.778 / 13.571</td><td class="z">93 / 87 / 80</td><td>Sieg 23.336</td></tr>
</table></div>
<div class="merk"><b>Learnings:</b> (1) Eine Suche, die einmal nichts findet, darf sich das nicht fuer immer merken: Der A-Baum wurde beim Start gesucht, als noch keine A-Plantage stand; der Lenker merkte sich "keiner" und A wurde 28.700 Ticks lang nie reif. Jetzt wird gesucht, sobald eine A-Plantage steht. (2) Eine Ruecklage wirkt nur, wenn jeder Ausgeber sie abzieht: Erst als Anwerben, Planer und Huettenbau dieselbe B-Ruecklage (3 Holz + 15 Gold je offener B-Plantage, sobald alle A stehen) beachteten, stand B 81 Ticks nach der A-Reife statt 2.478–4.276. (3) Eigenes Essen haelt die Beliebtheit: mit Seasoning am Anfang 87 statt 70–77 bei Tick 10.000. (4) Preis: Nach Posten + A-Plantagen bleiben 30 Gold, der erste Assassine kam erst bei 3.778 statt ~640. <span class="status offen">offen</span> Erster Assassine trotzdem frueh (Daniel 23:51).</div>
</section>
<section id="assassinen">
<h2><small>06</small>Assassinen</h2>
<h3>Klettern <span class="status abgelesen">abgelesen</span></h3>
<p>Der Wegfinder sucht nur dann einen Kletterweg, wenn die befohlene Gruppe nur aus Assassinen besteht; der Laufbefehl 17 prueft das ausdruecklich (giveTribeMoveInstruction → findPathUsingClimbingWithHeightMargin16). Rotkaeppchen baut in dieser Karte kein Torhaus, nur Mauern um den Bergfried; ihr Lord steht oben auf dem Bergfried (Gebaeudehoehe 92).</p>
<h3>Ausweichen bei Uebermacht <span class="status gemessen">gemessen</span></h3>
<p>Mehr feindliche Nahkaempfer (plus schlagende Arbeiter) als eigene Assassinen im Umkreis 10 → sofort weg, per echtem Laufbefehl, Richtung eigener Truppen nur wenn die dort stark genug sind, sonst im Kreis um einen Punkt 35 Felder in Fluchtrichtung, nie unter feindliche Schuetzen. Flucht vorbei, wenn 30 Ticks kein Verfolger im Umkreis 15 ist; blockiert, wenn 30 Ticks kein Feldwechsel.</p>
<div class="tab"><table>
<tr><th>Stand (je Lauf bis Tick 8.000)</th><th class="z">zerstoert</th><th class="z">Assassinen tot</th><th class="z">eigene Soldaten tot</th></tr>
<tr><td>kein Ausweichen</td><td class="z">2</td><td class="z">1</td><td class="z">0</td></tr>
<tr><td>Wartebefehl / neuer Befehl jede Runde</td><td class="z">2</td><td class="z">1</td><td class="z">0</td></tr>
<tr><td>echter Laufbefehl, frueh erkennen, Leute im Weg</td><td class="z">8</td><td class="z">0</td><td class="z">1–6</td></tr>
<tr><td>+ Arbeiter-Gefahr, nach Hause nur wenn stark</td><td class="z">7–8</td><td class="z">0</td><td class="z">1–3</td></tr>
<tr><td>+ seitlich ins Leere (ohne Kreis)</td><td class="z">1</td><td class="z">1</td><td class="z">0</td></tr>
</table></div>
<div class="merk"><b>Learnings:</b> (1) Ein Wartebefehl bricht keinen Nahkampf ab, nur ein echter Laufbefehl. (2) Jeder neue Befehl ist ein kurzer Halt - nur neu befehlen, wenn er steht oder kaempft. (3) Ihre Verteidigungs-Assassinen sind gleich schnell und folgen 4.000 Ticks lang; abschuetteln geht nicht, nur wohin fuehren. (4) Unsere Speertraeger und Bogenschuetzen toeten getarnte Assassinen nicht (2 Laeufe, 13 Verteidiger, 0 Treffer) - nie Verfolger in die eigene Burg ziehen. (5) Regeln in Ticks, nicht in Lenker-Runden: als die Runden schneller wurden, wurde "2 Runden" zu 6 Ticks. (6) Ihre Burg ist tabu: In gewinn_1 starb ein Assassine auf der Flucht an ihrer Aussenmauer (13 Felder neben ihrem Lord, 14 Schuetzen im Umkreis 40). Fluchtpunkte und Kreismitte liegen jetzt mindestens 40 Felder von ihrem Lord entfernt.</div>
</section>
<section id="lord">
<h2><small>07</small>Lord-Angriff</h2>
<p><span class="status gemessen">gemessen</span> Serie a, 3 Laeufe, 5 Angriffe mit je 20 Assassinen: beim Befehl standen sie 12–91 Felder vom Lord entfernt, am Lord kamen gleichzeitig hoechstens 2 an, Verluste 14–17 je Angriff, Lord-Schaden nur einmal (150.000 → 106.300).</p>
<p><span class="status gemessen">gemessen</span> In den ganzen Partien greifen jeweils 20 Assassinen in zwei Wellen an. Die erste Welle opfert jedes Mal 17 (gewinn_3: Lord 75.000 → 58.500; gewinn_6: 75.000 → 32.700), erst die zweite toetet ihn (3 bzw. 6 tot). <span class="status offen">offen</span> Warum der Lord hier 75.000 Leben hat und in Serie a 150.000.</p>
<div class="merk"><b>Learning:</b> Gleichzeitig befohlen ist nicht gleichzeitig angekommen. Daniels Regel: erst raiden, bis eine kritische Menge auf dem ganzen Feld ist, dann alle zugleich - und der Schaden stapelt sich nur, wenn sie zusammen ankommen.</div>
<h3>Gemeinsamer Angriff (06.10., gebaut von Codex) <span class="status gemessen">gemessen</span></h3>
<p>Ab 20 Assassinen sammeln alle an einem begehbaren Punkt mehr als 45 Felder vor ihrem Lord (ausser Schussweite von Lord und Schuetzen); neue Assassinen kommen dazu; erst wenn mindestens 40 da sind und alle angekommen sind, geht ein einziger Angriffsbefehl heraus. Serie <code>gemeinsam_1</code>, 3 Partien, feste Saat, Tempo 300:</p>
<div class="tab"><table>
<tr><th>Partie</th><th class="z">Angriff mit</th><th>Ergebnis</th><th class="z">zerstoert</th><th class="z">eigene Verluste</th></tr>
<tr><td>gewinn_6 (zwei 20er-Wellen, zum Vergleich)</td><td class="z">20 + 20</td><td>Sieg 23.336</td><td class="z">61</td><td class="z">31</td></tr>
<tr><td>partiegemeinsam_1_1</td><td class="z">52</td><td>Sieg 27.347</td><td class="z">44</td><td class="z">11</td></tr>
<tr><td>partiegemeinsam_1_2</td><td class="z">47</td><td>Sieg 26.666</td><td class="z">54</td><td class="z">18</td></tr>
<tr><td>partiegemeinsam_1_3</td><td class="z">60</td><td>Sieg 26.385</td><td class="z">44</td><td class="z">10</td></tr>
</table></div>
<div class="merk"><b>Learning:</b> Gemeinsam ankommen halbiert die Verluste (10–18 statt 31), aber der Sieg kommt rund 3.000 Ticks spaeter und es wird weniger zerstoert: Ab 20 sammeln die Assassinen statt zu raiden, und jeder Nachzuegler muss erst am Treffpunkt ankommen, bevor es losgeht - angegriffen wurde mit 47–60 statt 40. Daniel 06.10.: viel zu viele werden gehortet; gegen mehrere Gegner spielt die Zeit gegen uns.</div>
<h3>Wie viele reichen? Trainingsstand <span class="status gemessen">gemessen</span></h3>
<p>Aus einem gespeicherten Stand (Tick 24.521, 40 Assassinen gesammelt ausser Schussweite, ihr Lord mit 150.000 Leben; <code>SAI Lordminimum Basis 2026-10-06</code>) greift je Gruppengroesse dreimal dieselbe Auswahl an (die gesuendesten zuerst), hoechstens 3.500 Ticks lang (<code>lordminimum_messen.py</code>):</p>
<div class="tab"><table>
<tr><th class="z">Assassinen</th><th>3 Laeufe</th><th class="z">Lord-Leben am Ende</th></tr>
<tr><td class="z">5</td><td>alle tot</td><td class="z">146.000–150.000</td></tr>
<tr><td class="z">10</td><td>Zeit um</td><td class="z">132.000–139.600</td></tr>
<tr><td class="z">15</td><td>1 Sieg, 2 Zeit um</td><td class="z">0 / 60.100 / 60.800</td></tr>
<tr><td class="z">16</td><td>Zeit um</td><td class="z">1.500–58.800</td></tr>
<tr><td class="z">17</td><td>Zeit um</td><td class="z">13.500–42.900</td></tr>
<tr><td class="z">18</td><td>2 Siege, 1 Zeit um</td><td class="z">0 / 0 / 38.000</td></tr>
<tr><td class="z">19</td><td>3 Siege</td><td class="z">0</td></tr>
<tr><td class="z">20, 25, 30, 35, 40</td><td>je 3 Siege</td><td class="z">0</td></tr>
</table></div>
<div class="merk"><b>Learnings:</b> (1) In <b>dieser einen Lage</b> reichen 19; 20–40 gewinnen nicht schneller (alle Siege zwischen Tick 26.186 und 26.417, also 1.700–1.900 Ticks nach dem Befehl) - groessere Gruppen verlieren nur weniger. Die 19 ist keine allgemeine Formel: Sie gilt nur fuer diese Verteidigung, diesen Weg und dieses Lord-Leben. (2) 15–17 machen viel Schaden, schaffen es aber nicht in 3.500 Ticks - "reicht nicht" und "dauert laenger" sind verschiedene Ergebnisse. (3) Codex sah keinen Feind auf einen Assassinen zielen, weil das gelesene Zielfeld (+926) nur Spielerbefehle enthaelt; KI-Einheiten stehen auf Zielart 3. Siehe "Wer trifft wirklich?". (4) <span class="status offen">offen</span> Warum ihr Lord in den ganzen Partien mit 75.000 Leben gemeldet wird und hier mit 150.000.</div>
<h3>Wer trifft wirklich? <span class="status gemessen">gemessen</span></h3>
<p><code>zielfeld_suchen.py</code> haelt das Spiel an, sobald ein Assassine Leben verliert, liest die ganze Einheit (1.168 Byte) aller Feinde im Umkreis 45 und sucht jedes Feld, das auf den Getroffenen zeigt. Vorher festgelegt: Ein Feld zaehlt nur, wenn es auf Getroffene zeigt und nicht auf Unbeteiligte. Trainingsstand, 20 Assassinen, 12 Schadens-Momente:</p>
<div class="tab"><table>
<tr><th>Feld</th><th>Bedeutung</th><th>Befund</th></tr>
<tr><td><code>+0x33E</code> (830) bei Feinden</td><td>wen er gerade im Nahkampf schlaegt (attackedUnitID)</td><td>16-mal auf den Getroffenen, 0-mal auf Unbeteiligte - alle 16 waren Speertraeger 0–2 Felder neben ihm</td></tr>
<tr><td><code>+0x3AE</code> (942) beim Opfer</td><td>wie viele ihn gerade schlagen (attackedBy)</td><td>1 → 3 → 2, deckt sich genau mit den Speertraegern, die auf ihn zeigen</td></tr>
<tr><td>Bogenschuetzen</td><td>kein Zielfeld gefunden</td><td>ihr +0x33E steht immer auf 0; die anderen Treffer waren Zufall (Laufziel-Koordinate 242 = Nummer des Assassinen 242)</td></tr>
</table></div>
<p>Beide Felder stehen jetzt im Lagebild jeder Runde (<code>nahziel</code>, <code>nahangreifer</code>; Modul <code>logik.lua</code>). Vier der Treffer hatten keinen Nahkampfgegner: Assassinen 6–12 Felder vor Bogenschuetzen - vermutlich Pfeile. <span class="status offen">offen</span> Das Zielfeld der Fernkaempfer (vermutlich am Geschoss, nicht an der Einheit).</p>
<h3>Bedarf aus gemessenen Lagen statt fester Zahl <span class="status gemessen">gemessen</span></h3>
<p>Daniel 06.10.: nicht pauschal 40 sammeln; jede Einheit, jedes Gebaeude und das Gelaende kann Einfluss haben; keine Formel aus Lord-Leben oder Fern/Nah-Zahl; Zeit ist kritisch. Darum vergleicht <code>bedrohung.py</code> die aktuelle Lage mit gemessenen Lagen (<code>daten/lagen_belegt.json</code>):</p>
<ul>
<li><b>Fingerabdruck:</b> Leben und Ort ihres Lords, alle feindlichen Einheiten nach Typ bis 15 und bis 45 Felder um ihn, ihre Gebaeude nach Typ bis 15 Felder; weiter entfernte werden nur mitgeschrieben (in der einzigen Messung war keine beteiligt - offene Annahme).</li>
<li><b>Belegt:</b> Ist die aktuelle Lage in keinem Wert gefaehrlicher als eine gemessene, gilt deren belegte Mindestzahl (kleinste Groesse, die selbst und alle groesseren 3 von 3 gewannen) - dazu das gemessene Gruppenleben, damit angeschlagene Assassinen nicht wie volle zaehlen.</li>
<li><b>Vorlaeufig:</b> Deckt keine gemessene Lage, gilt der Ersatzwert 40 und das Protokoll nennt den Grund (z. B. "einheiten 15:22: 13 statt hoechstens 12").</li>
<li><b>Angriff:</b> Sobald so viele leben, sammeln sie ausser Schussweite; sobald die kleinste ausreichende Gruppe (die gesuendesten zuerst) am Treffpunkt steht, greift genau sie an - Nachzuegler raiden weiter.</li>
</ul>
<p>Eingetragen ist bisher <b>eine</b> Lage (Trainingsstand T24521: 12 Bogenschuetzen, 3 Speertraeger, 3 Assassinen bis 15 Felder, Lord 150.000) mit belegter Zahl 19. Pruefungen ohne Spiel: <code>bedrohung_pruefen.py</code> 10/10 (Gegenprobe mit sabotiertem Vergleich: 4 rot), <code>lordtrupp_pruefen.py</code> 10/10 (gegen den Stand davor: 7 rot). Im Spiel aus dem Trainingsstand: Bedarf "19 belegt", 43 sammeln, 19 greifen an, 25 raiden weiter, <b>Sieg bei Tick 26.482</b>, 6 Verluste.</p>
<h3>Zweite Lage: die ganze Partie <span class="status gemessen">gemessen</span></h3>
<p>Ganze Partie ab Tick 0 im Trainingsmodus (<code>trainingsstand_ab=25</code>): gesichert bei Tick 19.596 mit 26 Assassinen am Treffpunkt (bis 15 Felder um ihren Lord: 40 Bauern, 14 Bogenschuetzen, 3 Speertraeger, 3 Assassinen). Je 3 Laeufe:</p>
<div class="tab"><table>
<tr><th class="z">Assassinen</th><th>Ergebnis</th><th class="z">Lord-Leben am Ende</th></tr>
<tr><td class="z">10</td><td>alle tot</td><td class="z">120.200–145.300</td></tr>
<tr><td class="z">15</td><td>alle tot</td><td class="z">41.700–81.700</td></tr>
<tr><td class="z">20</td><td>3 Siege (8–11 ueberleben)</td><td class="z">0</td></tr>
<tr><td class="z">25</td><td>3 Siege (14–16 ueberleben)</td><td class="z">0</td></tr>
</table></div>
<p>Belegt: 20 (16–19 nicht gemessen). Ganze Partien mit dem neuen Bedarf:</p>
<div class="tab"><table>
<tr><th>Partie</th><th>Stand</th><th>Ergebnis</th><th>Angriff</th></tr>
<tr><td>bedarf_partie_1</td><td>Sammeln erst ab Bedarf (40)</td><td>kein Angriff, Zeit um</td><td>durch Raid-Verluste nie 40 gleichzeitig am Leben (34 Tote)</td></tr>
<tr><td>bedarf_partie_2</td><td>Sammeln ab 20</td><td>kein Angriff, Zeit um</td><td>Sammeln erst ab 23.994 (vorher unter 20), hoechstens 27 da</td></tr>
<tr><td>bedarf_partie_3</td><td>+ zweite Lage eingetragen</td><td><b>Sieg 26.015</b></td><td>40 (vorlaeufig) ab 24.219, 3 Verluste im Angriff, 4 Nachzuegler raiden weiter</td></tr>
</table></div>
<div class="merk"><b>Learnings:</b> (1) Sammeln ab dem Bedarf geht schief, wenn der Bedarf hoeher ist, als durch die Raid-Verluste je gleichzeitig lebt - darum Sammeln wieder spaetestens ab 20. (2) Ob 20 Lebende rechtzeitig zusammenkommen, kippt an Kleinigkeiten: In Codex' Partien ab ~17.600, in bedarf_partie_2 erst ab 23.994 (zwischen 16.000 und 24.000 starben 30 beim Raiden nahe ihrer Burg). <span class="status offen">offen</span> Nicht weiter raiden, wenn nur noch gefaehrliche Ziele uebrig sind. (3) In bedarf_partie_3 deckte keine der zwei Lagen die echte Lage beim Angriff; der Grund wird seitdem beim Sammeln und Angriff mitgeschrieben.</div>
<div class="merk"><b>Learnings:</b> (1) Der Fingerabdruck ist mit Absicht streng: Ein einziger Arbeiter mehr im 45er-Ring macht eine Lage "nicht gedeckt" - dann gilt vorlaeufig 40, bis diese Art Lage gemessen ist. Schneller wird die KI also nur mit mehr gemessenen Lagen. (2) Waehrend des Angriffs springt die Bewertung, wenn ein Arbeiter in den Ring laeuft (gemeldet, aendert den laufenden Angriff nicht).</div>
</section>
<section id="testen">
<h2><small>08</small>So wird getestet</h2>
<ul>
<li><b>Erst Wissen holen:</b> Handbuch, SHC-Wiki, Liga-Balance, Spielcode (Ghidra mit der OpenSHC-Benennung) - bevor ein Test laeuft.</li>
<li><b>Pruefung ohne Spiel:</b> jede Regel bekommt eine Attrappe mit vorher festgelegten Faellen (z. B. 21 Faelle fuer das Ausweichen). Gegenprobe: gegen den alten Code-Stand muessen die neuen Faelle rot sein, sonst ist das Gruen hohl.</li>
<li><b>Code-Kennung</b> in der ersten Zeile jeder Partie: Pruefsumme ueber alle beteiligten Dateien, damit nie unbemerkt alter Code getestet wird.</li>
<li><b>Kurze Laeufe</b> fuer Eroeffnungsfragen (bis Tick 8.000), feste Saat fuer Vergleiche, ganze Partien erst danach.</li>
<li><b>Sieg oder Niederlage schwankt trotz gleicher Saat</b> (gewinn_3 Sieg, gewinn_4 Zeit um), weil der Lenker in Echtzeit reagiert. Darum vergleicht <code>serie.werte</code> die stabileren Wirtschaftszahlen: A reif, B steht, 1./10./20. Assassine, Beliebtheit bei 5.000 / 10.000 / 20.000, Aepfel im Schnitt.</li>
<li><b>Trainingsstand statt ganzer Partie:</b> <code>trainingsstand=<Name></code> speichert die Partie, sobald 40 Assassinen gemeinsam am Treffpunkt stehen; <code>lordminimum_messen.py</code> laedt diesen Stand und wiederholt jeden Angriff dreimal. Eine Groesse gilt erst als belegt, wenn alle drei Laeufe gleich ausgehen.</li>
<li><b>Nichts vorher aussortieren</b> (Daniel 06.10.: jede Einheit, jede Person, jedes Gebaeude, gebaut oder nicht, und das Gelaende kann ablenken oder schaden): Das Angriffsprotokoll schreibt je Runde alle Einheiten, alle Gebaeude, den Schaden je Angreifer und einmal die ganze Gelaendekarte. Was davon wirklich zaehlt, zeigt erst der gemessene Schaden.</li>
<li><b>Kein Gefecht ohne Gegner</b> <span class="status gemessen">gemessen</span>: <code>gegner: 0</code> setzt sofort gameOver 1, Endbildschirm bei Tick 2.665.</li>
<li><b>Leere KI</b> <span class="status gemessen">gemessen</span>: Rotkaeppchen spielt mit, bekommt aber jede Runde alle Waren und Gold auf 0 (Modulbefehl <code>leereKI</code>; <code>erstes_spiel.py leere_ki=ja</code>) - ihr Lord steht, sie baut und wirbt nichts. Gemessen: 1.000 Ticks lang alle Waren 0. Falle: Im Hauptmenue reicht der UCP-Haken (<code>init.lua</code>) nur bestimmte Befehle und Befehlslisten an die Logik durch - ein einzelner <code>leereKI</code>-Befehl verschwand dort still, ohne Quittung. Darum geht er als Liste hinaus und wird bei jeder normalen Partie ausdruecklich abgeschaltet (der Zustand ueberdauert das Gefecht). Goldmarken je 1.000 mit <code>gold_ziel=10000</code>.</li>
<li><b>Flucht-Protokoll je Runde:</b> Ort, Zustand, Laufziel, Abstand zum Verfolger - so sieht man "er bleibt stehen" im Log und nicht nur am Bildschirm.</li>
<li><b>Gemessen schlaegt gerechnet:</b> die aus der Balance gerechnete Staerke unserer Speertraeger gegen Assassinen (0,21) war falsch; gemessen ist sie 0.</li>
</ul>
</section>
<section id="architektur">
<h2><small>09</small>Zielarchitektur nach Sharky</h2>
<p><a href="https://github.com/sharknice/Sharky">Sharky</a> ist ein Framework fuer StarCraft-II-Bots: eine Liste von Managern, die jeden Frame laufen und Befehle zurueckgeben; Bauphasen mit Uebergaengen; Mikro-Aufgaben, die Einheiten nach Prioritaet beanspruchen. Uebertragen auf unser Spiel:</p>
<div class="tab"><table>
<tr><th>Sharky</th><th>bei uns heute</th><th>Ziel</th></tr>
<tr><td>Manager mit OnStart / OnFrame / OnEnd</td><td>Wirtschaft, Ertragsplaner, Waechter, Assassinen - jedes mit eigener Schnittstelle</td><td>eine gemeinsame Form: <code>start()</code>, <code>runde(lage) → befehle</code>, <code>bericht()</code>; der Lenker ruft nur noch die Liste auf</td></tr>
<tr><td>UnitManager / MapDataManager</td><td>Lagebild, Feindlisten, Mauerkarte, Begehbarkeit verstreut</td><td>ein Lagebild-Objekt je Runde: Einheiten, Gebaeude, Gefahrenkarte (Schaden je Feld aus Schussweite 40 und Nahkampf), Wegnetz</td></tr>
<tr><td>BuildManager + BuildSequences + Transition</td><td>Eroeffnung (phase1) und Ertragsplaner getrennt</td><td>Daniels vier Phasen als Bauphasen mit Uebergangsbedingung: Raid-Start → Wirtschaft → Armee → Lord-Angriff</td></tr>
<tr><td>CounterTransition / EnemyStrategy</td><td>fehlt</td><td>Rotkaeppchens Muster erkennen (Grossangriff ab ~Tick 25.000, Wach-Assassinen) und gezielt umschalten</td></tr>
<tr><td>MicroManager + MicroTasks (beanspruchen Einheiten)</td><td>Rollen als lose Mengen: Ziel, Jagd, Warten, Flucht, Stapel, Lord-Trupp</td><td>Aufgaben mit Prioritaet; jede Einheit gehoert genau einer: Flucht > Lord-Angriff > Weglocken > Stapel > Raid > Warten</td></tr>
<tr><td>IndividualMicroController je Einheitentyp</td><td>alles im Assassinen-Lenker</td><td>Verhalten je Typ: Assassine (klettern, ausweichen, kreisen), Speer, Bogen, Lord</td></tr>
<tr><td>AttackDataManager (lohnt der Kampf?)</td><td>Uebermacht und Staerke an zwei Stellen</td><td>eine Stelle fuer "wer ist staerker hier", gespeist aus gemessenen Werten</td></tr>
<tr><td>UnitCommander (kein Befehls-Spam)</td><td>einzeln nachgebaut (nur neu befehlen, wenn noetig)</td><td>fuer alle Einheiten: letzter Befehl je Einheit, neu nur bei Aenderung oder Stillstand</td></tr>
<tr><td>BuildDecisionService + Ergebnis-JSON</td><td>Serien-Auswertung, gelernte Ertraege</td><td>Eroeffnung nach Gewinnquote waehlen, mit fester Saat vergleichbar</td></tr>
</table></div>
<p><span class="status offen">offen</span> Vorschlag, noch nicht gebaut. Umbau Schritt fuer Schritt: zuerst die gemeinsame Manager-Form und das Lagebild-Objekt, dann die Aufgaben mit Prioritaet.</p>
</section>
<section id="offen">
<h2><small>10</small>Offen</h2>
<ul>
<li>Stufe 2 und 3 der Assassinen-Taktik: Wachen weglocken, waehrend andere raiden; sammeln bis zur eigenen Uebermacht, dann die Wachen schlagen.</li>
<li><b>Als Naechstes:</b> mehr Lagen messen - vor allem die Lage, in der die ganze Partie wirklich angreift (dort gilt bisher nur der vorlaeufige Ersatzwert). Der Fingerabdruck soll Weg, Sicht und gemessenen Schaden (nahziel/nahangreifer) einbeziehen, sobald mehrere Lagen vorliegen.</li>
<li>Zielfeld der Fernkaempfer finden (Pfeile).</li>
<li><b>Daniel 06.10. 19:38 - Angriff:</b> Ein Sammelpunkt bringt wenig. Besser die groesste Schwachstelle finden und von den naechsten Punkten aus angreifen; an mehreren Stellen sammeln statt an einer (alle an einem Punkt werden auch zusammen getoetet); wer sammelt, raidet nicht - das ist kontraproduktiv.</li>
<li><b>Daniel 06.10. 19:33 - Wachstum:</b> Gegen mehrere Gegner braucht es stabiles Wachstum; Einkommen aus Rohstoffverkauf reicht dafuer nicht. Holzverkauf bleibt vorerst nur, solange Gold das Anwerben bremst; auch Assassinen sind nicht die besten Einheiten.</li>
<li>Mehr Lagen messen: holz_partie_3 sammelte ab 22.702 und griff erst bei 27.160 mit der vorlaeufigen 40 an, weil ein vierter Speertraeger am Lord stand (gemessen: hoechstens 3).</li>
<li><b>Daniel 06.10.:</b> so frueh wie moeglich gewinnen. Testpartie gegen eine leere KI: wie kommt man am schnellsten auf 10.000 Gold, auf 10/20/30/40/50 Streitkolbenkaempfer, dann jede Einheit. Wirtschaft: Hopfen/Bier, Brot, Religion, positiver/negativer Angstfaktor.</li>
<li><b>Als Naechstes:</b> erster Assassine frueher (gewinn_6: 3.778, Trainingslauf: 3.207); Holz: zusaetzliche Holzfaeller nur, wenn sie den Ausbau beschleunigen, sonst verkaufen.</li>
<li>Eigenen Lord schuetzen: der Waechter schickt heute den Lord mit in den Kampf gegen Assassinen.</li>
<li>Beliebtheit faellt auch mit Seasoning noch (93 → 80 bis Tick 20.000): Essen wird bis auf einen kleinen Puffer verkauft. Mehr Plantagen-Paare oder weniger verkaufen - erst messen.</li>
<li>Befehle auf einen genauen Tick planen (scheduleCommand), damit gleiche Saat ganz gleiche Partien ergibt.</li>
</ul>
</section>
<section id="quellen">
<h2><small>11</small>Dateien</h2>
<div class="tab"><table>
<tr><th>Datei</th><th>Inhalt</th></tr>
<tr><td><code>Selfaware-AI/Spielwissen.md</code></td><td>Regeln, Liga-Balance, Replay-Modul, Rotkaeppchen</td></tr>
<tr><td><code>Selfaware-AI/Plan_Lord.md</code></td><td>Plan, Messreihen Raid zuerst und Ausweichen</td></tr>
<tr><td><code>Selfaware-AI/Meilensteine.md</code></td><td>alle Meilensteine mit Messungen</td></tr>
<tr><td><code>Selfaware-AI/werkzeug/</code></td><td>Lenker (<code>erstes_spiel.py</code>), Assassinen, Wirtschaft, Ertragsplaner, Pruefungen ohne Spiel</td></tr>
<tr><td><code>Selfaware-AI/daten/</code></td><td>Laufprotokolle, Saat, Spielcode-Auszuege (dekomp_*.c)</td></tr>
<tr><td><code>VillageStudio/doku/Wissensstand.md</code></td><td>Spielspeicher, Adressen, Strukturen</td></tr>
</table></div>
</section>
</main>
</div>