SOTA Log Parser v0.0.4 - Bereit zum Download!
Maschinell aus dem Englischen übersetzt. Original anzeigen
Was die Logs bereits wussten
Ein Rundgang durch sotalogparser und die falschen Antworten, die ihn geprägt haben.
Shroud of the Avatar schreibt alles auf. Jeden Schlag, jeden Fang, jedes fehlgeschlagene Meisterwerk, jedes Wort, das jemand in deiner Nähe gesagt hat, mit Zeitstempel, im Klartext, in einem Ordner, den du bereits besitzt. Ein Spieler mit zwei Jahren Spielzeit sitzt auf ein paar Millionen Zeilen davon.
Fast niemand liest sie, denn ein Chat-Log ist keine Aufzeichnung – es ist das Rohmaterial für eine. Dies ist eine App, die das Lesen übernimmt: eine plattformübergreifende Desktop-Anwendung, die diesen Ordner in einen durchsuchbaren Index parst und auf dreizehn Arten darüber berichtet.
Die Regeln wurden gegen einen realen Korpus von 3,84 Millionen Zeilen abgeleitet und erkennen 99,91 % davon. Dieser Korpus ist der Grund, warum die interessanten Teile dieses Beitrags existieren. Jede nicht offensichtliche Entscheidung unten war zuerst eine plausible Antwort, und der Korpus hat bewiesen, dass sie falsch war.

Die Form des Ganzen
Drei Schichten, streng einseitig.
| Parsing, Erkennung, Indizierung, Berichterstattung. Keine UI-Abhängigkeit. |
| Avalonia-Ansichten und View-Modelle. |
| Nur Einstiegspunkt. |
.NET 10, Avalonia 12, MVVM. Eine Codebasis erzeugt eigenständige Einzeldatei-Builds für sechs Laufzeiten – Windows, macOS und Linux, jeweils x64 und arm64. Alles, was einen Test wert ist, lebt in Core, weshalb es 522 davon gibt und keiner ein Fenster benötigt.
Die Pipeline
LogLineReader teilt [Zeitstempel] Nachricht und faltet Fortsetzungszeilen. ChatLogParser führt eine geordnete Liste von Regeln aus, der erste Treffer gewinnt. Was nichts beansprucht, wird zu einem UnrecognizedEvent.
Dieser letzte Teil ist eine Regel, kein Fallback. Verliere niemals eine Zeile. Der nicht erkannte Eimer ist der einzige Mechanismus, durch den eine Lücke im Regelsatz überhaupt sichtbar wird – das stille Verwerfen von Nicht-Übereinstimmungen würde genau die Informationen verbergen, die zur Behebung benötigt werden. Die App zeigt den Abdeckungsprozentsatz an und ermöglicht es dir, ein Log auf nur die nicht beanspruchten Zeilen zu filtern – so wurde aus 99,91 % 99,91 %.
Der Index
Eine Logdatei erhält eine LogSummary. Alles über den gesamten Korpus geht durch einen SQLite-Index: parsen, Szenenkontext anhängen, Faktenzeilen schreiben, eine Transaktion pro Datei, nur Dateien erneut lesen, deren Größe oder Änderungszeit sich geändert hat. 3,84 Mio. Zeilen werden in etwa zwanzig Sekunden in ungefähr 19 MB indiziert.
Der Index ist ein wegwerfbarer Cache und niemals eine Quelle der Wahrheit. Schema- oder Parseränderungen erhöhen eine Version, und die Datei wird gelöscht und neu aufgebaut, anstatt migriert zu werden. Nichts darin kann nicht aus den Logs regeneriert werden, also ist nichts darin das Risiko eines Migrationsfehlers wert.
Zwei Dinge darüber, die einen Korpus brauchten, um gelernt zu werden.
Der Parser ist zustandslos pro Zeile, also weiß nur eine Zonenwechselzeile, wo etwas passiert ist. Ein Tracker verriegelt die zuletzt betretene Szene und setzt bei einem Sitzungsstart zurück. Ungefähr ein Viertel der realen Ereignisse tritt vor jeder Entering-Zeile auf – sie landen in einer (unbekannten) Szene, was ein echter Eimer ist, den die Berichte zeigen müssen, keine Lücke, die weggefiltert werden soll.
Kampf hat eine Richtung. Ein Viertel der Angriffszeilen im Korpus sind Mobs, die den Spieler treffen, und ihre Fähigkeiten sehen genauso aus wie die des Spielers. Ohne Aufteilung nach Richtung listet „deine Fähigkeiten" Fähigkeiten auf, die der Spieler nie benutzt hat.
Dreizehn Berichte
Die Leiste gruppiert sie. Jeder lädt träge beim ersten Öffnen und lädt neu, wenn sich der Datums-, Szenen- oder Charakterfilter ändert; alles exportiert nach CSV.
Übersicht und Log-Browser
Was der Index abdeckt, und jede Zeile eines einzelnen Logs, wie der Parser sie gesehen hat. Der Browser existiert für die Abdeckungsregel oben – filtere auf „Nicht erkannt" und du siehst die verbleibenden blinden Flecken des Parsers, in Reihenfolge.
Kampf – Fähigkeiten vs. Mobs
Wie jede Fähigkeit gegen jedes Ziel abschneidet, und wo eine Paarung schlägt, was der Rest der Daten vorhersagt. 65 Fähigkeiten, die 282 Ziele kreuzen, ist eine zweiseitige Tabelle, und die interessante Zelle ist die, die sowohl ihre Zeile als auch ihre Spalte schlägt. Drei Entscheidungen, von denen jede zuerst falsch war:
Median-Politur, nicht Mittelwerte. Mit Mittelwerten zieht eine außergewöhnliche Zelle ihre eigene Fähigkeitszeile und ihre Zielspalte hoch, sodass jeder Nachbar als resistent gelesen wird. Ein echter Befund, sechs erfundene.
Ungewichtet. Die Gewichtung des Medians lässt jede Zelle, die über die Hälfte der Beobachtungen ihrer Zeile hält, ihre eigene Basislinie definieren – was genau die stark bewirtschaftete Paarung ist, die du am meisten messen willst.
Ein Streuungs-Gate sowie ein Stichproben-Gate. Eine Fähigkeit, die nur gegen zwei Ziele verwendet wird, hat keine unabhängige Basislinie, also liest sich die Lücke zwischen ihren beiden Zellen als enorme Interaktion. Gegen den realen Korpus ist dieses einzelne Gate der Unterschied zwischen einem vertretbaren Befund und acht Artefakten.
Kampf – Was dich trifft

Die Spiegel-Frage und der neueste Bericht: welche Kreaturen dich angreifen, womit, für wie viel, und wie oft deine Verteidigung es stoppt. Es ist ausdrücklich nicht der vorherige Bericht mit umgekehrtem Pfeil – die Wiederverwendung der ausgehenden Maschinerie wäre auf vier Arten falsch gewesen, von denen jede eine plausible Zahl statt eines sichtbaren Fehlers erzeugt.
Mehr als die Hälfte des eingehenden Feuers landet auf dem Begleiter.
Versuche | |
|---|---|
auf den Spieler gerichtet | 51.138 |
auf den Begleiter gerichtet | 64.248 |
Und sie verhalten sich überhaupt nicht gleich: 52 % der auf den Spieler gerichteten Schläge treffen ohne Wirkung, gegenüber 0,5 % der auf einen Begleiter gerichteten Schläge. Zusammengefasst gehört das Verteidigungsprofil zu keinem von beiden. Begleiter werden ausgeschlossen – und ihr Anteil berichtet, denn „das deckt 44 % dessen ab, was auf dich geworfen wurde" ist etwas, das einem Leser geschuldet ist.
Die offensichtliche Abschwächungszahl lässt den Großteil der Abschwächung aus. Die Formel des ausgehenden Berichts zählt Ausweichen, Blocken, Parieren und Streifschläge und kommt auf 18 % eingehend. Aber 52 % der eingehenden Angriffe sind getroffen, haben nichts bewirkt – von dieser Formel ausgeschlossen. Die ehrliche Zahl ist 66,2 %. In der Zwischenzeit fehlen Blocken und Resistenzen in eingehenden Zeilen vollständig – null von jedem in 3,84 Mio. Zeilen – also werden diese Spalten weggelassen, anstatt als strukturelle Nullen gezeigt zu werden, weil eine Spalte, die immer null ist, wie „du hast noch nie etwas geblockt" gelesen wird.
Ein Ausweichen nennt nie, was ausgewichen wurde. Alle 7.120 eingehenden Ausweichmanöver und alle 17.474 ausgehenden sitzen im unbenannten Eimer, was auch immer sie ausgelöst hat. Also teilt jede Pro-Fähigkeits-Rate durch die Angriffe, die eine Fähigkeit nannten, und die Ausweichrate lebt auf der Pro-Kreatur-Rollup, wo sie wahr ist.
Und die Rangfolge ist nach Schaden pro Schlag, weil die drei plausiblen Ordnungen kaum übereinstimmen:
Versuche | pro Schlag | pro Treffer | kommt durch | |
|---|---|---|---|---|
Massives Krokodil, Basis | 4.310 | 2,1 | 58 | 4 % |
Razorback (T18), Basis | 217 | 23,4 | 461,5 | 5 % |
Vigorem Cavas (T14), Shadow Blast | 309 | 247,9 | 247,9 | 100 % |
Rangfolge nach Häufigkeit und der Bericht öffnet sich mit einem Krokodil, das zwei Schaden macht. Rangfolge nach Schaden pro Treffer und er öffnet sich mit einem Ereignis, das einmal in zwanzig passiert. Nur pro Schlag faltet die Trefferquote ein und beantwortet was wird mich das kosten.
Kampf – Rekorde

Persönliche Bestleistungen: größter kritischer Treffer pro Fähigkeit, härtester erlittener Schlag, jeder zurückverfolgbar bis zur Zeile, aus der er stammt. Dies ist der eine Bericht, der ein Rollup rückgängig machen muss, von dem der Rest der App abhängt. Begleitschaden wird dem Besitzer gutgeschrieben, was für Summen richtig und für einen Rekord falsch ist:
Spieler | Begleiter | |
|---|---|---|
größter kritischer Treffer | 1.843 (Chain Lightning) | 6.735 (Wyvern Sting) |
härtester erlittener Schlag | 1.206 | 2.628 |
Mehr Schläge landen auf dem Begleiter als auf dem Spieler – 64.245 gegen 44.329 – also ist „der härteste Treffer, den du erlitten hast" der Bluterguss von jemand anderem, wenn du nicht nachsiehst. Bestleistungen sind pro Charakter und niemals zusammengefasst, Gleichstände gehen an den frühesten, und Schaden über Zeit ist ausgeschlossen: der größte davon im Korpus ist 13.555, was jeden Angriff schlägt, und das stille Einklappen beantwortet eine andere Frage.
Welt – Szenenaktivität
Wohin die Zeit ging und wofür jeder Ort gut war. Drei Dinge, die es richtig machen muss:
Eine Rate braucht einen Nenner, dem du vertrauen kannst. Drei Minuten in Arlia sammelten eine 10.000-XP-Auszeichnung – 206.897 pro Stunde, zweiter Platz vor einem Ort, der achtzig Stunden lang bewirtschaftet wurde. Die Pro-Szene-Zahl wird trotzdem angezeigt, neben den Minuten, aus denen sie stammt, aber die Rangfolgen wenden eine 30-Minuten-Untergrenze an und sagen, wie viele Szenen das ausgeschlossen hat.
Tode und Tötungen sind dieselben Zeilen, von gegenüberliegenden Enden gelesen. 281 Todeszeilen sind 246 Tötungen, 22 Tode, 15 Umstehende und 2 Selbsttötungen. Das Zählen von Zeilen meldet ein Fünftel mehr Tötungen als gemacht wurden und versteckt jeden Tod.
Leichenbeute ist Kampf; Ernten ist Sammeln. Tanglemire protokolliert 743 Angriffe, 1.305 Ernten und überhaupt keine Leichenbeute. Ein kombinierter Beuteeimer beschriftet ihn nach dem Gesamtsieger, also kommt ein Angelplatz mit Wölfen als Kampfzone heraus.
Welt – Beute und Angeln
Woher die Beute kam und was jeder Ort tatsächlich ergibt; jeder Fang gedreht nach Ort des Angelns, nach dem Wasser, aus dem er kam, und nach Art.
Handwerk – Rezepte
Außergewöhnliche Raten pro Rezept, wie weit ein Meisterwerk getrieben werden kann und was es kostete. Intervalle sind Wilsons Score-Intervall, nicht die Normalnäherung – was die Obergrenze bei sieben Erfolgen in acht über 1 setzt und bei null in zwölf auf einen Punkt kollabiert. Drei weitere:
Ein Versuch ist ein Handwerk. Die beiden Abschlusszeilen sind Alternativen, niemals beide. Der Korpus verrät den Fehler sofort: Dunkelroter Farbstoff protokolliert 73.231 gewöhnliche und 73.433 außergewöhnliche, also ergibt die Behandlung von Außergewöhnlichem als Teilmenge von Versuchen eine Erfolgsrate über 100 %.
Ein Meisterwerk-Fehlschlag nennt das Objekt eine Stufe unter dem, wo der Versuch gemacht wurde. Das Zählen nach der gedruckten Zahl erfindet eine glatte Kurve aus dem Nichts.
Signifikanz und Effektgröße sind getrennte Größen. Das Intervall entscheidet, ob sich ein Rezept wirklich von der Gesamtrate unterscheidet; die beobachtete Rate entscheidet, ob es sich genug unterscheidet, um erwähnt zu werden. Das Vermischen kennzeichnete eines von drei Nahrungsrezepten, die um 45 % gehäuft waren, und ließ seine beiden Nachbarn unmarkiert.
Mehr – Fortschritt
Verdiente Erfahrung und trainierte Fähigkeiten. Ruhige Abschnitte werden behalten – eine Serie, die nur aus Tagen aufgebaut ist, an denen etwas passiert ist, zeichnet einen Monat als ununterbrochenen Lauf ab, das genaue Gegenteil von dem, was der Leser geöffnet hat, um herauszufinden.
Und Schritte sind nicht Stufen. Das Spiel kündigt nicht jede Stufe an: Schneiderei läuft 44, 48, 51, 54, also decken 85 Ankündigungen 117 Stufen ab. Der Bericht zeigt Schritte und den beobachteten Bereich und markiert Zeilen, in denen mehr Stufen vergingen als angekündigt wurden. „Stufen gewonnen" ist einfach nicht im Log, und der Bericht sagt das, anstatt zu raten.
Die verwandte Falle, korpusweit: Erfahrungsanzeigen sind laufende Summen, und es gibt vier verschiedene pro Pool – lebenslang verdient, der Charakterpool, der gemeinsame Pool und ihre Summe, zusammen als Block geschrieben. Die Anzeigen summieren sich auf 1,57 Billionen gegen 187 Millionen tatsächlich vergeben. Auszeichnungen werden positiv nach Art ausgewählt, nie als „alles, was keine Anzeige ist", weil diese Formulierung stillschweigend jede später hinzugefügte Anzeigenart zulässt.
Mehr – Gespräche
Der flache Chat-Stream zurück in Austausche eingefädelt. Es gibt überhaupt keinen Gesprächsmarker im Log, also wird ein Lauf geteilt, wo immer das Reden für zehn Minuten aufhörte. Zwei Regeln verdienen ihren Platz: ein Lauf mit niemandem außer dem Spieler ist kein Gespräch (sonst füllt eine Sitzung, die mit Werbung auf Traders verbracht wurde, den Bericht mit einseitigen „Austauschen"), und eine Nachricht ohne Zeitstempel behält ihre Dateiposition (das Sortieren von Nullen nach vorne öffnet eine Lücke in der Breite des gesamten Gesprächs).
„Ich" wird pro Zeile gegen den eigenen Charakter des Logs aufgelöst – ein Korpus mit sechs Charakteren hat sechs Antworten auf wer bin ich.
Mehr – Wirtschaft
Meistens bemerkenswert für das, was es sich weigert zu berechnen. Das Log hat keine Preise und keine Kaufzeilen, also sind verkaufte Einheiten bekannt und Einnahmen nicht. Die einzige Goldzahl irgendwo ist Du hast N Gold aufgehoben., was nichts mit deinem Händler zu tun hat. Der Bericht sagt das, weil eine Goldzahl, die neben einer Verkaufstabelle gedruckt wird, als Einnahmen gelesen wird.
Was es aufdeckt, ist die Dauerauftrags-Teilung – Auftrag erfüllt gegen durchsucht – was das eine Ding in den Daten ist, auf das ein Verkäufer reagieren kann, und das im Korpus sauber geteilt herauskam: jedes Rohmaterial 100 % Aufträge, jedes veredelte Gut 100 % durchsucht.
Mehr – Handel

Spieler-zu-Spieler-Handel wieder zusammengefaltet. Ein Handel ist ein Lauf von Zeilen – geöffnet, Dinge bereitgestellt und zurückgenommen, geschlossen – und keine einzelne Zeile sagt, was die Hände gewechselt hat. Vier Dinge:
Gold ist eine laufende Summe, keine Änderung. Die Zeile gibt die neue Zahl an. Ein echter Handel im Korpus läuft Gold auf 99.000 und zurück auf 0, bevor er abgeschlossen wird; das Summieren der Zeilen meldet neunundneunzigtausend Gold, das sich nie bewegt hat.
Die beiden Seiten werden asymmetrisch protokolliert. Das Spiel zeichnet den Partner auf, der Gegenstände hinzufügt und entfernt, aber nur den Spieler, der hinzufügt – niemals zurückzieht. Also ist die Spielerseite „was angeboten wurde" und kann übertreiben; die Partnerseite ist exakt. Der Bericht sagt, was was ist.
Die meisten „Handel" sind mit dir selbst. 64 von 106 abgeschlossenen Handeln sind zwischen den eigenen Alts des Spielers, und wo beide Alt-Logs vorhanden sind, wird derselbe Handel zweimal gespeichert, einmal von jeder Seite. Markiert und filterbar.
Der Partnername wird manchmal vom Spiel verstümmelt –
Zealoty,,1]Zealoty. Das ist im Log, nicht etwas, das der Parser tut. Die Reparatur passt nur auf diese exakte doppelte Form, weil echte Namen Kommas enthalten.
Die Begleitwebsite
Die App kann sich optional bei einer Begleitwebsite anmelden und vier Datensätze veröffentlichen: persönliche Bestleistungen, Angel Fänge, Fähigkeit-gegen-Ziel-Zellen und Monsterfähigkeiten.
Die letzten beiden unterscheiden sich von den ersten beiden auf eine Weise, die respektiert werden muss. Sie sind kumulative Summen, also ersetzt eine erneute Veröffentlichung, anstatt zu akkumulieren – was bedeutet, dass das Veröffentlichen immer nach Datum und Szene ungefiltert sein muss, weil unter Ersetzungssemantik eine gefilterte Scheibe keine schwächeren Zahlen sendet, sie löscht die vollständigeren. Und ein Charakter über dem Zellenlimit des Servers wird ganz übersprungen, anstatt abgeschnitten, aus demselben Grund.
Was hochgeht, sind die hinreichenden Statistiken – Anzahl, Σln(1+Schaden), Σln(1+Schaden)² – nicht das angepasste Ergebnis, weil Median-Politur nicht über Spieler hinweg zusammenfasst und Summen es tun. Sie sind additiv, was exaktes Community-Pooling und Leave-one-out in konstanter Zeit überhaupt möglich macht. (Das 1 + ist tragend: die Umkehrung ist exp(x) − 1, und das Zurücklesen mit einfachem exp ist bei ein paar hundert Schaden unter einem Prozent daneben und bei dreihundert ein Drittel. Überall plausibel und überall falsch. So wurde die erste Implementierung der Website ausgeliefert.)
Eine Sache, die der Korpus auch hier lehrte. Eine Fähigkeit ist weitgehend eine Eigenschaft ihrer Kreatur – 22 von 74 Fähigkeiten gehören zu genau einer, und 169 von 272 Kreaturen haben zwei oder weniger. Es gibt also kein zweiseitiges Modell anzupassen; was es ersetzt, vergleicht eine Fähigkeit nur gegen sich selbst, wo drei oder mehr Kreaturen sie verwenden, Leave-one-out, sodass die Kreatur, die die meisten Beobachtungen einer Fähigkeit hält, nicht ihre eigene Basislinie definieren und sich selbst als gewöhnlich melden kann. Erdelementar hält 2.955 von 3.637 Erdbeben-Schlägen und kommt bei 0,08× heraus; ein selbstinkludierender Pool hätte etwa 1,0 gelesen und nichts gesagt.
Das Konto ist optional und bleibt optional. Das Wiederherstellen einer Sitzung liest eine Datei und macht keine Anfrage. Das erste Paket verlässt den Rechner, wenn du auf „Anmelden" oder „Veröffentlichen" klickst, niemals vorher. Kein Bericht macht eine Abhängigkeit davon, angemeldet zu sein, und die Veröffentlichungssteuerungen sind versteckt, wenn abgemeldet, anstatt deaktiviert gezeigt zu werden.
Datenschutz
Chat-Logs enthalten Nachrichten anderer Spieler, und diese Tatsache schränkt den Code ein, anstatt in einer Richtlinie erwähnt zu werden.
Der Index speichert rohen Nachrichtentext – das ist der Gesprächsbericht. Er lebt in deinem App-Datenverzeichnis, außerhalb des Repositorys, und nichts davon wird jemals hochgeladen. Keine zukünftige Nutzlast sollte das ändern, ohne den Benutzer in so vielen Worten zu fragen.
Was das Veröffentlichen sendet, sind Charakternamen, Fähigkeits- und Kreaturnamen, Zahlen, Szenen und Zeiten. Eines davon verdient Sorgfalt: Das Log sagt nie, ob ein Angreifer eine Kreatur oder ein anderer Spieler war, also kann ein Angreifername eine echte Person sein. Deshalb zeigt das Veröffentlichen die tatsächlichen Zeilen einmal pro Datensatz vor dem ersten Upload, anstatt sie nur zu zählen. Das Hochladen ist nach außen gerichtet und kann von hier aus nicht rückgängig gemacht werden.
Echte Logs sind git-ignoriert; Test-Fixtures sind handgeschwärzt.
Wo es steht
Ende-zu-Ende funktionsfähig. Dreizehn Berichte, keine Platzhalter mehr in der Leiste, 522 Tests, sechs Release-Ziele. Der Parser hat 99,91 % des Korpus und die verbleibenden 0,09 % sind in der App sichtbar, anstatt weggefegt zu werden.
Wenn es einen roten Faden gibt, der durch alles läuft, dann den, dass der Korpus recht hatte und die Argumentation falsch war, immer und immer wieder. Jede Überschrift oben, die mit „drei Dinge" beginnt, ist eine Liste von Zahlen, die korrekt aussahen, bis jemand sie gegen drei Millionen Zeilen dessen prüfte, was tatsächlich passiert ist. Das ist die ganze Methode: Prüfe das Muster gegen den Korpus, anstatt darüber nachzudenken, was das Spiel wahrscheinlich schreibt.
Downloads
- ⬇ SotaLogParser-0.0.4-linux-arm64-0.0.4.zip41 MB · 6 downloadssha256 4730c85a2f0e24fd99c482c910bc85555ae7fe0f3020fd05d6d99c9bda8451db
- ⬇ SotaLogParser-0.0.4-linux-x64-0.0.4.zip43 MB · 10 downloadssha256 f2b238d29931a4870c9b3833383f77f2738598cf7cf1134d7d8ca4a3464025a4
- ⬇ SotaLogParser-0.0.4-osx-arm64-0.0.4.zip44 MB · 9 downloadssha256 19b63abac37cdc3978b9e1912075ca5d0c68b2c06f9e049e6ef0d7e49849e26b
- ⬇ SotaLogParser-0.0.4-win-arm64-0.0.4.zip68 MB · 13 downloadssha256 290855d72cf515bdcc9be5595b84a17e33e7eded4c930c3cef93fcd18de7f499
- ⬇ SotaLogParser-0.0.4-osx-x64-0.0.4.zip46 MB · 5 downloadssha256 8403aa7488fa4c58a833b98e5e11106730c3db1f691596dbe998847bc8182cbd
- ⬇ SotaLogParser-0.0.4-win-x64-0.0.4.zip70 MB · 13 downloadssha256 9e8ba3948b49a650859eb28859cc8aec104ae98db27fce708470e37454537266
