← Back to blog

SOTAログパーサー v0.0.4 - ダウンロード準備完了!

英語からの機械翻訳です。 原文を見る

By admin · 7/31/2026

ログがすでに知っていたこと

sotalogparserのツアー、そしてそれを形作った誤った答えの数々。

Shroud of the Avatarはすべてを書き留めます。すべての一振り、すべての釣果、すべての失敗した傑作、あなたの近くで誰かが言ったすべての言葉を、タイムスタンプ付きで、あなたがすでに所有しているフォルダに平文で記録します。2年間プレイしているプレイヤーは、その数百万行の上に座っています。

チャットログは記録ではなく、記録のための原材料であるため、ほとんど誰もそれらを読みません。これはその読み取りを行うアプリです:そのフォルダを解析してクエリ可能なインデックスに変換し、13の方法でレポートするクロスプラットフォームのデスクトップアプリケーションです。

ルールは実際のコーパス384万行に対して導出され、その99.91%を認識します。そのコーパスこそが、この投稿の興味深い部分が存在する理由です。以下のすべての非自明な決定は、最初はもっともらしい答えであり、コーパスがそれが間違っていることを証明したのです。


構造

3つの層、厳密に一方向。

SotaLogParser.Core

解析、発見、インデックス作成、レポート。UI依存なし。

SotaLogParser.App

Avaloniaビューとビューモデル。

SotaLogParser.Desktop

エントリポイントのみ。

.NET 10、Avalonia 12、MVVM。1つのコードベースから、Windows、macOS、Linuxのx64とarm64の6つのランタイム向けに自己完結型のシングルファイルビルドが生成されます。テストする価値のあるものはすべてCoreにあり、522のテストがあり、そのいずれもウィンドウを必要としません。

パイプライン

LogLineReader[タイムスタンプ] メッセージを分割し、継続行を折りたたみます。ChatLogParserは順序付けられたルールのリストを実行し、最初に一致したものが優先されます。何も主張しないものはUnrecognizedEventになります。

最後の部分はフォールバックではなくルールです。行を決して落とさない。未認識バケットは、ルールセットのギャップがまったく見える唯一のメカニズムです。一致しないものを静かに破棄すると、それを修正するために必要な情報が正確に隠されてしまいます。アプリはカバレッジ率を表示し、ログを未請求の行だけにフィルタリングできるようにします。これが99.91%が99.91%になった方法です。

インデックス

1つのログファイルにはLogSummaryが割り当てられます。コーパス全体のすべてはSQLiteインデックスを通過します:解析、シーンコンテキストの添付、ファクト行の書き込み、ファイルごとに1つのトランザクション、サイズまたは変更時刻が変更されたファイルのみを再読み取りします。384万行は約20秒で約19MBにインデックス化されます。

インデックスは使い捨てキャッシュであり、真実の源ではありません。スキーマまたはパーサーの変更はバージョンを上げ、ファイルは移行ではなく削除されて再構築されます。その中の何もログから再生成できないものはないため、移行バグのリスクを冒す価値のあるものは何もありません。

コーパスを必要とした2つのこと。

パーサーは行ごとにステートレスであるため、ゾーン変更行だけが何がどこで起こったかを知っています。トラッカーは最後に入ったシーンをラッチし、セッション開始時にリセットします。実際のイベントの約4分の1はEntering行の前に発生します。それらは(unknown)シーンに分類され、これはレポートが表示しなければならない実際のバケットであり、フィルタリングして除外するギャップではありません。

戦闘には方向があります。コーパス内の攻撃行の4分の1はモブがプレイヤーを攻撃しているものであり、そのアビリティはプレイヤーのものとまったく同じように見えます。方向で分割しないと、「あなたのスキル」にはプレイヤーが一度も使用したことのないスキルがリストされます。


13のレポート

レールがそれらをグループ化します。それぞれが最初に開かれたときに遅延ロードされ、日付、シーン、またはキャラクターフィルターが変更されると再ロードされます。すべてCSVにエクスポートできます。

概要とログブラウザ

インデックスがカバーするもの、およびパーサーが見た単一のログのすべての行。ブラウザは上記のカバレッジルールのために存在します。未認識にフィルタリングすると、パーサーの残りのブラインドスポットが順番に表示されます。

戦闘 — スキルvsモブ

各スキルが各ターゲットに対してどのように機能するか、そしてペアリングが残りのデータが予測するものを上回る場所。65のスキルが282のターゲットと交差するのは双方向テーブルであり、興味深いセルは行と列の両方を上回るセルです。3つの選択肢、それぞれが最初は間違っていました:

  • 平均ではなく中央値研磨。平均を使用すると、1つの例外的なセルが自分のスキル行ターゲット列の両方を引き上げるため、すべての隣接セルが耐性があるように読み取られます。1つの実際の発見、6つの発明されたもの。

  • 重みなし。中央値に重みを付けると、行の観測値の半分以上を保持するセルが独自のベースラインを定義できるようになります。これはまさに、最も測定したい、頻繁にファームされるペアリングです。

  • サンプルゲートだけでなくスプレッドゲート。2つのターゲットに対してのみ使用されるスキルには独立したベースラインがないため、2つのセル間のギャップは巨大な交互作用として読み取られます。実際のコーパスに対して、この単一のゲートは、1つの防御可能な発見と8つのアーティファクトの違いです。

戦闘 — あなたに当たるもの

鏡の質問、そして最新のレポート:どのクリーチャーが何で、いくらのダメージで、どのくらいの頻度であなたを攻撃し、あなたの防御がそれをどのくらいの頻度で止めるか。これは矢印を逆にした前のレポートでは決してありません。発信メカニズムを再利用することは4つの点で間違っていたでしょう。そのすべてが目に見える失敗ではなくもっともらしい数字を生成します。

受信攻撃の半分以上がペットに当たります。

試行回数

プレイヤーを狙ったもの

51,138

ペットを狙ったもの

64,248

そしてそれらはまったく異なる動作をします:プレイヤーを狙った打撃の52%は何も与えずに当たりますが、ペットを狙った打撃の0.5%だけが当たります。プールすると、防御プロファイルはどちらにも属しません。ペットは除外され、その割合は報告されます。「これはあなたに投げられたものの44%をカバーしています」というのは読者が知る権利があるからです。

明白な軽減率は軽減の大部分を省略しています。発信レポートの式は、回避、ブロック、パリィ、かすり傷を数え、18%の受信になります。しかし、受信攻撃の52%は接続され、何も与えませんでした — その式では除外されています。正直な数字は66.2%です。一方、ブロックと耐性は受信行に完全に存在しません — 384万行でそれぞれゼロです。したがって、それらの列は構造的なゼロとして表示されるのではなく省略されます。なぜなら、常にゼロの列は「あなたは一度もブロックしたことがない」と読まれるからです。

回避は何を回避したかを決して名前を付けません。受信回避7,120件と発信回避17,474件のすべてが、何が引き起こしたかに関係なく名前のないバケットにあります。したがって、アビリティごとのレートはアビリティに名前を付けた攻撃で除算され、回避率はそれが真実であるクリーチャーごとのロールアップに存在します。

そしてランキングはスイングあたりのダメージによるものです。なぜなら、3つのもっともらしい順序はほとんど一致しないからです:

試行回数

スイングあたり

ヒットあたり

通り抜ける

巨大ワニ、基本

4,310

2.1

58

4%

イノシシ (T18)、基本

217

23.4

461.5

5%

ヴィゴレム・カヴァス (T14)、シャドウブラスト

309

247.9

247.9

100%

頻度でランク付けすると、レポートは2ダメージを与えるワニで始まります。ヒットあたりのダメージでランク付けすると、20回に1回発生するイベントで始まります。スイングあたりのみが接続率を折り込み、これは私にいくらかかるのかという質問に答えます。

戦闘 — 記録

自己ベスト:スキルごとの最大クリティカル、受けた最大の打撃、それぞれが由来する行にトレース可能。これはアプリの残りが依存するロールアップを元に戻す必要がある唯一のレポートです。ペットのダメージは所有者にクレジットされます。これは合計には正しいですが、記録には間違っています:

プレイヤー

ペット

最大クリティカル

1,843 (チェーンライトニング)

6,735 (ワイバーンスティング)

受けた最大の打撃

1,206

2,628

プレイヤーよりもペットに多くの打撃が当たります — 64,245対44,329 — したがって、「あなたが受けた最大の打撃」は、確認しない限り他の誰かの傷です。ベストはキャラクターごとであり、決してプールされず、同点は最も早いものに優先され、ダメージオーバータイムは除外されます:コーパス内の最大のものは13,555で、すべての攻撃を上回り、それを静かに折り込むと別の質問に答えることになります。

ワールド — シーンアクティビティ

時間がどこに費やされたか、そして各場所が何に適していたか。正しく取得する必要がある3つのこと:

  • レートには信頼できる分母が必要です。Arliaでの3分間で10,000 XPの報酬が1つ収集されました — 1時間あたり206,897、80時間ファームされたスポットを抑えて2位。シーンごとの数値は、それが由来する分と一緒に表示されますが、ランキングは30分の下限を適用し、除外されたシーンの数を示します。

  • キルとデスは同じ行を反対側から読んだものです。281の死亡行は、246のキル、22のデス、15の傍観者、2の自殺です。行を数えると、実際に行われたキルより5分の1多く報告され、すべてのデスが隠されます。

  • 死体の戦利品は戦闘であり、収穫は採取です。Tanglemireは743の攻撃、1,305の収穫、そして死体の戦利品をまったく記録しません。1つの結合された戦利品バケットは、どちらの合計が勝つかによってラベルを付けます。したがって、オオカミがいる釣りスポットは戦闘ゾーンとして出てきます。

ワールド — 戦利品と釣り

ドロップがどこから来たか、各場所が実際に何をもたらすか。すべての釣果は、釣った場所、由来する水域、種によってピボットされます。

クラフト — レシピ

レシピごとの非凡な率、傑作がどこまで押し上げられるか、そしてそれが何を費やしたか。間隔は正規近似ではなくWilsonのスコア間隔です。これにより、8回中7回の成功で上限が1を超え、12回中0回で点に崩壊します。さらに3つ:

  • 試行は1つのクラフトです。2つの完了行は代替であり、両方ではありません。コーパスはすぐに間違いを明らかにします:ダークレッドダイは73,231の普通と73,433の非凡を記録するため、非凡を試行のサブセットとして扱うと成功率が100%を超えます。

  • 傑作の失敗は、試行が行われた場所の1つ下のアイテムに名前を付けます。印刷された番号で集計すると、何もないところから滑らかな曲線が発明されます。

  • 有意性と効果量は別の量です。間隔はレシピが全体的な率と本当に異なるかどうかを決定します。観測された率は、言及するのに十分に異なるかどうかを決定します。それらを混同すると、45%近くにクラスター化された3つの食品レシピのうち1つにフラグが付けられ、他の2つはマークされませんでした。

その他 — 進行

獲得した経験値と訓練したスキル。静かなスライスは保持されます — 何かが起こった日だけから構築されたシリーズは、1か月を途切れのない連続として描きます。これは読者が開いた目的の正反対です。

そしてステップはレベルではありません。ゲームはすべてのレベルを通知するわけではありません:裁縫は44、48、51、54と続くため、85の通知が117のレベルをカバーします。レポートはステップと観測された範囲を示し、通知されたよりも多くのレベルが経過した行をマークします。「獲得したレベル」は単にログに存在せず、レポートは推測するのではなくそれを述べます。

関連する罠、コーパス全体:経験値の読み出しは累計であり、プールごとに4つの異なるものがあります — 生涯獲得、キャラクタープール、共有プール、およびそれらの合計がブロックとして一緒に書き込まれます。読み出しは、実際に付与された1億8,700万に対して1兆5,700億に合計されます。報酬は種類によって積極的に選択され、「読み出しではないもの」として決して選択されません。なぜなら、その表現は後で追加されたすべての読み出し種類を静かに認めるからです。

その他 — 会話

フラットなチャットストリームが交換に戻されました。ログには会話マーカーがまったくないため、会話が10分間止まった場所でランが分割されます。2つのルールがその場所を獲得します:プレイヤー以外に誰もいないランは会話ではありません(そうでなければ、Tradersでの広告に費やされたセッションは一方的な「交換」でレポートを満たします)、そしてタイムスタンプのないメッセージはファイル内の位置を保持します(nullを先頭にソートすると、会話全体の幅のギャップが開きます)。

「私」はログ自身のキャラクターに対して行ごとに解決されます — 6人のキャラクターがいるコーパスには、私は誰かに対する6つの答えがあります。

その他 — 経済

主に、計算を拒否することで注目に値します。ログには価格も購入行もありません。したがって、販売されたユニットは知ることができ、収益は知ることができません。どこにもある唯一のゴールドの数値はYou picked up N gold.であり、これはあなたのベンダーとは何の関係もありません。レポートはそれを述べます。なぜなら、販売テーブルの隣に印刷されたゴールドの数値は売上として読まれるからです。

それが表面化するのは常時注文の分割です — 注文完了対閲覧 — これはデータ内で売り手が行動できる唯一のものであり、コーパスできれいに分割されて出てきました:すべての原材料は100%注文、すべての精製品は100%閲覧。

その他 — トレード

プレイヤー間トレードが一緒に折りたたまれました。トレードは行のランです — 開かれ、アイテムが置かれ、取り戻され、閉じられます — そして、何が交換されたかを示す単一の行はありません。4つのこと:

  • ゴールドは累計であり、変化ではありません。行は新しい数値を述べます。コーパス内の実際のトレードは、完了する前にゴールドを99,000にし、0に戻します。行を合計すると、決して動かなかった9万9千のゴールドが報告されます。

  • 両側は非対称に記録されます。ゲームはパートナーがアイテムを追加および削除することを記録しますが、プレイヤーは追加のみ — 引き出しは決して記録しません。したがって、プレイヤー側は「提供されたもの」であり、過大評価する可能性があります。パートナー側は正確です。レポートはどちらがどちらかを述べます。

  • ほとんどの「トレード」は自分自身とのものです。完了した106のトレードのうち64はプレイヤー自身の別キャラクター間であり、両方の別キャラクターのログが存在する場合、同じトレードが両側から1回ずつ2回保存されます。フラグが付けられ、フィルタリング可能です。

  • パートナー名はゲームによって時々壊されますZealoty,,1]Zealoty。これはログにあり、パーサーが行うことではありません。修復はその正確な二重形状のみに一致します。なぜなら、実際の名前にはカンマが含まれているからです。


コンパニオンサイト

アプリはオプションでコンパニオンウェブサイトにサインインし、4つのデータセットを公開できます:自己ベスト、釣果、スキル対ターゲットセル、モンスターアビリティ。

最後の2つは、最初の2つとは尊重しなければならない点で異なります。それらは累計であるため、再公開は累積ではなく置き換えです — つまり、公開は常に日付とシーンでフィルタリングされていない必要があります。なぜなら、置換セマンティクスの下では、フィルタリングされたスライスは弱い数値を送信するのではなく、より完全な数値を削除するからです。また、サーバーのセル上限を超えるキャラクターは、同じ理由で切り詰められるのではなく、全体がスキップされます。

アップロードされるのは十分統計量 — カウント、Σln(1+ダメージ)、Σln(1+ダメージ)² — であり、適合結果ではありません。なぜなら、中央値研磨はプレイヤー間でプールされず、合計はプールされるからです。それらは加算的であり、それが正確なコミュニティプーリングと定数時間のリーブワンアウトを可能にするものです。(1 +は重要な役割を果たします:逆数はexp(x) − 1であり、それらを素のexpで読み戻すと、数百ダメージで1%未満、3で3分の1の誤差になります。どこでももっともらしく、どこでも間違っています。それがサイトの最初の実装が出荷された方法です。)

ここでもコーパスが教えた1つのこと。アビリティは主にそのクリーチャーの特性です — 74のアビリティのうち22は正確に1つに属し、272のクリーチャーのうち169は2つ以下です。したがって、適合する双方向モデルはありません。それを置き換えるものは、3つ以上のクリーチャーが使用する場合にのみアビリティをそれ自体と比較します。リーブワンアウトにより、アビリティの観測値のほとんどを保持するクリーチャーは独自のベースラインを定義して自分自身を普通として報告できません。アースエレメンタルはアースクエイクの3,637スイングのうち2,955を保持し、0.08×で出てきます。自己包含プールは約1.0を読み取り、何も言わなかったでしょう。

アカウントはオプションであり、オプションのままです。セッションの復元はファイルを読み取り、リクエストを行いません。最初のパケットは、[サインイン]または[公開]をクリックしたときにマシンを離れ、それ以前ではありません。レポートはサインインに依存せず、公開コントロールはサインアウト時に無効表示ではなく非表示になります。


プライバシー

チャットログには他のプレイヤーのメッセージが含まれており、その事実はポリシーで言及されるのではなくコードを制約します。

インデックスは生のメッセージテキストを保存します — それが会話レポートです。それはリポジトリの外のアプリデータディレクトリにあり、そこから何もアップロードされることはありません。将来のペイロードは、ユーザーに明確な言葉で尋ねることなくそれを変更すべきではありません。

公開が送信するのは、キャラクター名、スキルとクリーチャー名、数値、シーン、時刻です。そのうちの1つは注意が必要です:ログは攻撃者がクリーチャーか別のプレイヤーかを決して述べません。したがって、攻撃者名は実在の人物のものである可能性があります。そのため、公開は最初のアップロードの前にデータセットごとに実際の行を1回表示し、単に数えるだけではありません。アップロードは外向きであり、ここから元に戻すことはできません。

実際のログはgit-ignoreされ、テストフィクスチャは手動で編集されています。


現在の状態

エンドツーエンドで動作しています。13のレポート、レールにプレースホルダーは残っておらず、522のテスト、6つのリリースターゲット。パーサーはコーパスの99.91%を持ち、残りの0.09%はアプリで表示可能であり、隠されることはありません。

すべてを通して走る糸があるとすれば、それはコーパスが正しく、推論が間違っていたことです。上記の「3つのこと」で始まる各見出しは、誰かが実際に起こった300万行に対してチェックするまで正しく見えた数字のリストです。それが全体の方法です:ゲームがおそらく書くものについて推論するのではなく、コーパスに対してパターンをチェックすること。

Downloads