本文へスキップ
Server Changelog

サーバー更新記録

プラグイン、マップ、ルールの変更記録。GitHub から同期し、取れなければローカルキャッシュを出します。

キャッシュ時間: 2026-10-15 05:32 Using cache GitHub で原文を表示する

2026年10月5日 Tank の投石タイミングと岩の保護(ai_tank3 2.3.2 / l4d_rock_lagcomp 2.2-anne)

  • 岩の耐久値は100固定です。投石後の保護を全難度で0.1秒延長し、音理以外の5段階ではさらに0.05秒延長しました。6段階で 0.15 / 0.20 / 0.25 / 0.30 / 0.35 / 0.35 秒としました。AIとプレイヤーのTankに共通で、プラグイン既定値は0.25秒です。耐久値や距離による追加保護はありません。第1~5段階の投射速度800、音理1000を仮定すると、低角度での保護中の水平移動は約 120 / 160 / 200 / 240 / 280 / 350 単位です。実際の距離は速度と投射角度によって変わります。
  • 通常のAI投石は、200~450単位(両端を含む)の範囲内で最も近い有効な可視対象を選びます。追跡対象が近すぎる場合も遠すぎる場合も、範囲内の別の対象へ投石できます。候補がいなければ新たに投石を開始しません。岩を放す時点でも範囲内の対象を選び直し、候補がいなくなった場合は元の弾道を維持して開始済みの投石を完了します。頭上の妨害や頭乗りへの強制投石は従来の専用ルールを使います。通常の連続ジャンプの強さ、投石間隔、生存者へのダメージは変更していません。
  • 投石開始時に上向きの速度を追加するジャンプ処理と、ai_tank3_jump_rock および全6段階の設定項目を削除しました。通常の連続ジャンプは従来どおりで、ジャンプ中の投石は可能ですが、投石アニメーションによる追加ジャンプは発生しません。
  • 岩の保護と過去位置への命中を同じ射手時刻で判定します。巻き戻しはoutgoing遅延と補間時間を使い、sv_maxunlag と有効履歴で制限します。照準射線の近似判定は遮蔽物を確認し、最も手前の岩だけにダメージを与えます。
  • 既定の sm_rock_native_shotgun 1 は全散弾を一本の照準射線に集約せず、エンジンの実際の散弾命中ダメージを使います。散弾銃には本プラグインの位置巻き戻しを行いません。0にすると従来の近似に戻せます。
  • ai_tank3.smx と l4d_rock_lagcomp.smx を再コンパイルし、6段階の設定と文書を更新しました。保護境界、巻き戻し履歴、散弾ダメージ経路、投石タイミングの回帰検証は通過しました。実サーバーには未配備で、命中率と高遅延時の挙動は未検証です。

2026年10月3日 キャンペーンマップを対戦で使う際の Boomer モデル初期化修正

  • マップ投票を 0.9.4-custom に更新しました。OnMapInit で前マップの注入キャッシュを消去し、versus のミッション情報を再注入します。Utopia 第1章のモデル初期化時にミッション情報が取得できず、Boomer のモデル一覧が不完全になってスポーン時にクラッシュする問題を修正します。男性・女性の両モデルを維持します。
  • 既存の l4d2_mapvote_versus_from_coop 設定を引き続き使用し、マップ読み込み前に有効にする必要があります。更新後はマップを再読み込みしてください。no_female_boomers の上書きや NAV の変更は不要です。

2026年10月3日 キャンペーン専用マップの対戦用 I/O 互換対応

  • l4d2_coop_versus_compat.smx を追加しました。マップ実体の読み込み前に、キャンペーン専用カスタムマップの info_gamemode の OnCoop / OnCoopPostIO 接続を対応する対戦出力へ移します。引数・遅延・発火回数を維持し、ゲームモードの偽装やグローバルな OnCoop 発火は行いません。
  • 元から versus 定義を持たない coop マップを自動判定し、公式マップと対戦対応マップを保護します。configs/l4d2_coop_versus_compat.cfg でマップ別に有効化・除外でき、コンソールの sm_coop_versus_status で結果を確認できます。プラグイン読み込み後や設定変更後はマップの再読み込みが必要です。
  • マップ投票を 0.9.3-custom に更新し、coop の章情報を versus に追加する既定の範囲を全設定へ拡大しました(l4d2_mapvote_versus_from_coop 2)。NAV、スクリプト内のモード判定、独自フィナーレは修復しません。交代・章移行・スコア集計は各マップで検証が必要です。
  • 実際のカスタム戦役メニュー項目を読み取るサーバーコンソール専用の sm_mapvote_list を追加しました。cloud35 で Utopia を検証し、versus で注入を無効にすると非表示、有効にすると表示され、全3章の読み込みと章・フィナーレ判定を確認しました。実プレイヤー操作、自然な交代、救出完了は未検証です。このサーバーでは拡張子より前の余分なドットが VPK のマウントを妨げ、余分なドットのない一時リンクで読み込めました。検証後はサーバーを元に戻しました。詳細は docs/coop_versus_cloud35_test_2026-10-03.md。

2026年10月1日 ネットワーク品質ヒント:choke 検出漏れとロス方向の修正

  • network_quality_hint を 1.1.7 に更新しました。エンジンの loss/choke は直近約 1 秒の移動平均にすぎず、旧版は 5 秒ごとに 1 回読むだけだったため、実質ランダムな 1 秒を抜き出していました。ホードや実体が多い場面の 1〜2 秒の choke はほぼ拾えず、チャット警告は 3 回連続の超過も必要だったため、choke はほとんど発火しませんでした。
  • 現在は毎秒計測し、各判定周期(nqh_check_interval、既定 5 秒)の平均で ping/loss/choke を判定します。タイムアウトは周期内に一度でもあれば対象です。しきい値は変更なし:チャット警告は choke 5%、サイトの異常イベントは 20%。
  • サイトへの報告は avg/p95 に各周期の平均、max に周期内で最も高い 1 秒の値を使うため、短いスパイクも残ります。
  • パケットロスはプレイヤーからサーバーへ送る方向で計測するようにしました(status の loss と同じ値)。サーバーは自分が送ったパケットが失われたか分からないため、旧版が見ていた「サーバー→プレイヤー」方向のロスは常に 0 で、ロス警告もサイトの異常イベントも一度も発火していませんでした。
  • nqh_report_loss_limit(既定 5%)を追加しました。周期平均のロスがこれを超えた場合のみサイトの異常イベントを記録します。チャット警告は従来通り nqh_loss_limit(2%、3 周期連続)です。
  • !net の計測方向の説明にロスの方向を追加しました。警告の原因と固定の「[网络]」タグは翻訳ファイルから取得し、6 言語ともプレイヤーの言語で表示されます。
  • network_quality_hint.smx を再コンパイルしました。NewAnneWeb 側も対応済みです:管理画面のロス列はプレイヤー→サーバー方向を表示し、接続異常の記録には原因(loss / ping / choke / timing_out)を表示します。

2026年9月26日 RPG メニューにアイテムビーム設定を追加

  • !rpg / !buy のメインメニューで、ヒットフィードバックメニューの後ろに「アイテムビーム設定」を追加しました。選ぶと !beam のビーム設定メニューが開きます。l4d_random_beam_item を読み込むモードでだけ表示されます(このプラグインが同名のライブラリを登録するようになり、rpg.smx はそれで判定します)。
  • rpg.smx と l4d_random_beam_item.smx を再コンパイルしました。

2026年9月26日 鎮痛剤のビームを小さく

  • data/l4d_random_beam_item.cfg の鎮痛剤ビームの高さを 250 から 100 に、幅を 15 から 10 に変更しました。色(緑)、HDR の明るさ、壁越しに見える光輪は変わりません。これはサーバーのデフォルト値で、!beam で長さや幅を変えたプレイヤーは新しい値に対する割合で表示されます。

2026年9月25日 データベース接続の削減:anne_db 接続ハブを追加

  • extend/anne_db.smx を追加し、cfg/generalfixes.cfg の先頭行で読み込みます。同じデータベースへの MySQL 接続は 1 本だけ共有し、各プラグインはその複製を使います。1 台あたりのデータベース接続は最大約 22 本から 3 本(Anne モードは 5 本)に減りました。SourceMod のスレッドクエリはもともと 1 本のデータベーススレッドに並ぶため、接続を共有しても速度は落ちません。
  • 対応済み:l4d_stats、rpg、l4d2_hitsound、l4d2_damage_show、l4d2_scripted_hud、l4d2_blacklist、global_chat、chatlog、lilac、l4d_player_count_unload_mode、l4d_random_beam_item、annehappy_dynamic_ai_difficulty、anne_traitor_quota、spawn_vote_menu、sbpp_main、sbpp_comms、sbpp_checker、sbpp_sleuth。anne_db が読み込まれていない場合、各プラグインは従来どおり独自の接続に戻ります。
  • データベースが落ちてもサーバーが固まらなくなりました。接続に失敗してから 30 秒間は待たずにすぐ返し、ゲーム中の再接続でもメインスレッドを止めません。databases.cfg の MySQL 接続タイムアウトは既定の 60 秒から 15 秒に短縮しました。
  • 接続ハブが 120 秒ごとにキープアライブを送るため(MySQL の wait_timeout は 600 秒)、しばらく使わなかった後の最初のクエリが失敗しなくなりました。各プラグイン独自のキープアライブと、マップごとの切断・再接続は削除しました。
  • 修正:l4d_player_count_unload_mode で複数の cvar が続けて変わるとデータベース接続がリークしていた問題。l4d_stats の統計クリアを SourceMod のトランザクションに変更し、他のプラグインのクエリが同じトランザクションに混ざらないようにしました。l4d_stats で影響行数を読むときの競合も修正しました。
  • 管理者用コンソールコマンド sm_annedb_status で各データベース接続の状態を確認できます。
  • データベースプラグインの書き方のルールを AGENTS.md に追記しました。

2026年9月25日 アイテムビームをプレイヤーが自由に設定可能に(l4d_random_beam_item 1.1.0)

  • 標準ビーム:data/l4d_random_beam_item.cfg の default セクションを standard(標準ビーム:長さ 100、幅 6、HDR 2.0、白、光輪なし)に変更し、各アイテムには標準と異なる値だけを書くようにしました。すべてのアイテムはランダム色をやめ、カテゴリごとの固定色になりました。このファイルはサーバーのデフォルト設定という位置づけになり、初期状態で表示されるのはこれまでどおり鎮痛剤(緑、長さ 250、幅 15、光輪あり)とノーム(白、長さ 30、幅 5)だけです。
  • アイテムグループ:アイテムを 14 グループ(鎮痛剤、アドレナリン、救急キット、除細動器、投擲武器、アップグレードパック、T1 武器、T2 武器、特殊武器、ハンドガン、近接武器、弾薬とアップグレード、運搬物、その他)に分類しました。グループとメニューの並び順はデータファイルの group / groups で設定します。
  • プレイヤー設定:!beam でメニューを開きます。変わるのは自分の画面だけです:
  • すべてのアイテム:表示(デフォルト / すべて非表示)、長さと幅(標準の 50%〜300%)、色(9 色)、光輪(オン / オフ)。
  • アイテム別:グループごとに表示(表示 / 非表示)、長さ、幅、色、光輪を設定できます。未設定の項目は「すべてのアイテム」に従い、個別に設定したグループには [カスタム] が付きます。
  • クイックスタイル:強調(長さと幅 150%、光輪オン)、控えめ(長さ 50%、幅 75%、光輪オフ)、すべてオフ、デフォルト。「すべてのアイテム」だけを変更し、倍率はデータファイルの styles セクションで調整できます。!beam bright/subtle/off/default で直接切り替えることもでき、!beam reset ですべて初期状態に戻ります。
  • 初期状態で非表示のアイテムも表示できる:たとえば誰かがアドレナリンを表示にすると、サーバーはアドレナリンのビームを作成しますが、表示を選んだプレイヤーにだけオンにし、他の人には見えません。必要とするプレイヤーがいなくなるとビームは削除されます。サーバーのエディクト数が l4d_random_beam_item_player_edict_limit(デフォルト 1900)に達すると新規作成をやめてプレイヤーに知らせます。0 にするとこの機能をオフにできます。物理プロップ(prop_physics)は数が多すぎるため対象外です。
  • MySQL に保存:設定は databases.cfg の rpg データベースの新しいテーブル beam_item_prefs(Steam2 ID がキー)に保存されます。テーブルはプラグインが自動で作成し、database.sql にも追加しました。参加時に読み込み、変更の 3 秒後に保存し、切断時にもう一度保存します。データベースが使えない場合、設定はその接続中だけ有効で、プレイヤーに知らせます。
  • 仕組み:SendProxy 拡張(sendproxy2)で、各ビームのオン / オフ、長さ、幅、色、光輪をクライアントへ送るときにプレイヤーごとに書き換えます。サーバー上のビーム自体は変わりません。クライアントは色と光輪をビーム生成時にしか読まないため、設定を変えるとそのプレイヤーに対してビームを 0.3 秒オフにしてから再びオンにします。サーバーの値と異なる項目だけを書き換えるので、デフォルト設定のプレイヤーでは余分なパック処理は増えません。SendProxy 拡張がない場合は全員がデータファイルどおりに表示され、!beam は利用できない旨を表示します。
  • sm_beamreload でデータファイルを再読み込みしても、オンラインのプレイヤーの設定はグループ名で引き継がれます。
  • チャットメッセージとメニューは簡体字中国語、繁体字中国語、英語、日本語、韓国語、ベトナム語に対応しています。
  • docs/plugin_commands.md に sm_beam を追記し、l4d_random_beam_item.smx を再コンパイルしました。

2026年9月23日 Tank の目標が背後に回ったとき、後ろ向きに跳び続けず折り返しジャンプをするように(ai_tank3 2.3.0)

  • 問題:直接追跡中に生存者に横へかわされたり、背後の目標に切り替えたりして、Tank の速度方向と目標方向の角度が 89° を超えると、空中補正は向きを変えなくなります(共有移動コードの上限)。着地時は 1.x の加算ルールで跳ぶので、元の速度をそのまま残し、目標方向へ加速を 1 回分足すだけです。そのため同じ方向へ跳び続け、1 回ごとに数十しか遅くなりません。人を見つめたまま後ろ向きに何回も跳んでいるように見え、速度が 200 を下回るか壁にぶつかるまで折り返しませんでした。
  • 空中ブレーキ:直接追跡として踏み切ったジャンプで、向かいたい方向が背後に回ったら、ai_tank3_bhop_reverse_brake(既定 1500 ユニット/秒²)で水平速度を走行速度までブレーキします。減速するだけで向きは変えません。ブレーキ前に減速後の速度で残りのルートを確認し直し、着地点が安全でない(段差・穴の縁)ならブレーキしません。
  • 着地時の折り返しジャンプ:着地した時点で目標がまだ背後 89° の外にあれば、ai_tank3_bhop_reverse_hop(既定 1)で折り返しジャンプに切り替えます。目標にまっすぐ向けて走行速度で踏み切り、このジャンプでは加速も左右ジャンプもしません。連続ジャンプは途切れませんが、溜めた速度はリセットされ、その後はいつも通り 1 回ごとに加速します。かわされたときの代償は「何秒も逆方向へ走り去る」から「溜めた連続ジャンプの速度を失う」に変わります。
  • 逆方向へ跳ぶのは今のジャンプの残り分だけになり(1 回のジャンプは最長約 0.77 秒)、後ろ向きに跳び続けることはなくなりました。目標が前方 89° 以内にある直接追跡(左右ジャンプや 45°〜60° の補正しきい値を含む)と、経路に沿った連続ジャンプは変わりません。
  • どちらも動的難易度の段階分けには含めていません。ai_tank3_bhop_reverse_hop 0、ai_tank3_bhop_reverse_brake 0 で以前の動作に戻せます。ai_tank3_log_level 2 のときはコンソールに reverse hop のログが出るので、実機での確認に使えます。
  • docs/annehappy_dynamic_ai_difficulty.md と Tank の状況図鑑(docs/ai_tank3_scenarios_2026-09-14.html)を同期し、ai_tank3.smx を再コンパイルしました。

2026年9月23日 薬役モードの薬の出現位置を制御(confoglcompmod ItemTracking)

  • 通常 / ハードコア / ショットガン薬役(通常薬役の設定を共有する WitchParty と Charger 突進モードも含む)は、マップ進行度 30%〜90% の間にしか薬が出なくなりました:confogl_pills_flow_min 0.3、confogl_pills_flow_max 0.9。上流の ItemTracking に元からある進行度ウィンドウで、これまで薬役では有効にしていませんでした。薬の数は引き続き confogl_pills_limit / mapinfo の pain_pills に従い、30%〜90% の間で進行度に沿って均等に選びます。
  • confogl_pills_flow_max_detour を追加しました(薬役では 300):スタートからゴールまでのメインルート上の薬だけを残します。まずスタートからゴールのセーフルームまでの歩ける最短ルートの長さを測り、それぞれの薬を取りに行くと余分にどれだけ歩くかを調べます。メインルートを通れば取れる薬は余分がほぼ 0、奥行き d の脇部屋・行き止まり・分かれ道にある薬は約 d です。300 を超えるものは削除します。この処理は薬の間隔と数の選別より前に行うので、残る薬はすべてメインルート上の位置から選ばれます。
  • confogl_pills_flow_fill を追加しました(薬役では 1):選別後に薬が上限に届かないとき、脇部屋の薬で数を埋めるのではなく、足りない分を進行度 40%〜80% のメインルート上に出します(confogl_pills_flow_fill_min 0.4、confogl_pills_flow_fill_max 0.8。上の 30%〜90% からははみ出しません)。足りない本数だけ 40%〜80% を等分し、それぞれの区間でランダムな進行度を選びます。その進行度に最も近いメインルートのナビエリア(ESCAPE_ROUTE 付き、スタート地点・セーフルーム・救助エリアを除く)の中でランダムな位置を探します。床があり、薬を置く余地があり、他の薬から 128 ユニット以上離れ、mapinfo のスタート / ゴールのセーフルーム範囲外であることが条件です。1 つの進行度につき最大 32 個のナビエリアを試し、それでも足りなければ 40%〜80% の中でさらに何度かランダムに試します。元のマップに薬が 1 本もなくても補充します。この処理は経路探索をしません。新しく出した薬は ItemTracking に記録されるので、全滅してやり直しても同じ位置に出ます。上限まで補充できなかったときは、何本出したかをログに記録します。
  • 薬のビームを目立つようにしました:data/l4d_random_beam_item.cfg の鎮痛剤のビームを、白・高さ 20 から緑・高さ 250・幅 15 に変え、根元のハロー(壁越しに見える)を有効にしました。このファイルは Anne キャンペーンと Anne 絶境でも使っているので、そちらの薬のビームも変わります。
  • anne_pill_hint.smx を追加しました(通常 / ハードコア / ショットガン薬役、WitchParty、Charger 突進モードで読み込み):最初の生存者がセーフルームを出たとき、この道中に薬が何本あり、それぞれ進行度いくつにあるかをチャットで全員に伝えます(例:「38%、52%×2、71%」)。セーフルームの薬は数えません。進行度は薬のあるナビエリアの進行度で、薬を削除するときと同じ計算です。メッセージは簡体字中国語、繁体字中国語、英語、日本語、韓国語に対応しています。
  • マップごとに mapinfo の pillflow_min、pillflow_max、pillflow_max_detour、pillflow_fill、pillflow_fill_min、pillflow_fill_max で個別に調整できます。confogl_pills_flow_visualize 1 にすると薬を削除せず、結果を発光で表示します(白 = 残す、緑 = 補充、赤 = 進行度ウィンドウ外、マゼンタ = メインルート外、オレンジ = 直前の薬に近すぎる、シアン = 数の上限超過)。フィナーレのマップでは既定でこれらの選別を行いません(confogl_pills_flow_finale 0)。
  • confoglcompmod.smx を再コンパイルし、新しい anne_pill_hint.smx をコンパイルしました。

2026年9月23日 Charger の空中旋回を制限(ai_charger3 1.0.1.18)

  • 空中旋回の予算:ai_charger3_air_turn_budget を追加しました。Charger は地面を離れるたびに踏み切り方向を記録し、そのジャンプの間の空中補正では速度の向きをこの角度までしか踏み切り方向からずらせません。使い切ったあとは慣性のまま着地します。接近中の空中補正と突進前の空中追尾は同じ予算を共有します。これまで突進前のジャンプは 0.05 秒ごとに予測位置へ向き直し、最小しきい値も 1 度しかなかったため、跳んだのを見てから横に動いてもほとんど避けられませんでした。今は予算の外まで横に動けば空振りさせられます。6 段階は 12 / 16 / 20 / 30 / 40 / 45 度で、横方向の連続ジャンプ(S 字)の振れ幅もこの予算で頭打ちになります。
  • 曲がるほど加速が減る:すべてのジャンプの加速量を 加速量 × (1 − θ / 90) に割り引きます。θ が 90 を超えたら 90 として扱います(加速なし)。θ は踏み切りの向き変更、つまり跳ぶ前の地上での速度の向きとこのジャンプの向きとの角度です。着地直後のジャンプなら、直前のジャンプの空中補正が踏み切り方向から離れた最大角度も足します。蛇行・追尾・加速を同時にこなすことも、着地した瞬間の急な向き変更も、もうタダではありません。近接の駆け引きでの後ろ跳びはほぼ U ターンなので、割り引いたあとは走行速度しか残らないことがほとんどです。
  • 突進前の最後のジャンプ:これまでは加速量を満額そのまま加えていたため、走りながら踏み切っても丸ごと一回分の加速を得ていました。今は他のジャンプと同じ規則です(最初のジャンプは ai_charger3_bhop_first_hop_ratio で割り引き、さらに旋回角で割り引き)。一跳びで突進距離に届く場面が減り、最後の区間を走ることが増えます。
  • 高難易度の速度上限:ai_charger3_bhop_max_speed を極限(level5)で 600 → 500、音理(level6)で 700 → 600 にしました。
  • デバッグログ:Path / Direct の踏み切りログの landing hop が常に 0 になっていました(着地フラグを消費したあとに読んでいたため)。修正し、4 種類のジャンプすべてで、そのジャンプに数えた旋回角と加速の割引率を出力するようにしました。
  • ai_charger3.smx を再コンパイルしました。

2026年9月22日 全難易度で Smoker のはしご上からの引っ張りを禁止

  • Neri 難易度で Smoker がはしごの上から舌を出せ、捕まえたあとも生存者を引きずりながら登り続けられる問題を修正しました。Neri で有効になる l4d_air_abilities_patch_neri は、空中で舌を出して引っ張れるように、舌の「地面に立っていること」という本来の判定を二か所外しています。CTongue::IsAbilityReadyToFire の発射条件と、CTongue::OnUpdateAttachedToTargetState の「地面を離れたら舌が切れる」処理です。はしごを登っている間も地面に立っていない扱いなので、はしごの上でも舌を出せ、捕まえたあとも舌が切れませんでした。本来、引っ張り中の Smoker は GetRunTopSpeed を 1 に抑えて動けなくしていますが、はしごの昇降は固定の登攀速度を使うためこの制限が効かず、AI のはしご登りがそのまま続いて生存者を上へ引きずっていました。l4d2_ai_ladder_boost のはしご加速がその速度をさらに数倍にしていました。
  • 空中引きは空中引きであって、はしご引きではありません。l4d_air_abilities_patch は難易度にも Neri のパッチの有無にも関係なく、Smoker が登攀状態にある間は舌を常に準備未完了として扱うようになり、AI も人間も舌を出せません。捕まえたまま登攀状態になった Smoker はその場で舌を放します(本来の舌切れと同じ ReleaseTongueVictim の流れで、通常どおりクールダウンに入ります)。本来も舌を出すには地面に立っている必要がありますが、はしごの下端に取り付いたばかりで足がまだ床に着いている間は接地扱いになるため、このケースも合わせて禁止しました。Neri の空中での発射・引っ張りには影響しません。
  • 引っ張り中は本当に動けないようにしました。本来の「捕まえたら動けない」は、舌が出ている間 Smoker の走行速度の上限を 1 に抑え、ジャンプとしゃがみを外すだけで(CTerrorGameMovement::CheckParameters)、前進キーと移動入力は残っています。はしごに取り付くには、はしごへ向かう移動入力があり、はしごまで 2 単位以内であればよいため、AI がはしごの下に着いたところで地上から生存者を捕まえると、経路追従がはしごへ押し続けてそのまま取り付き、固定の登攀速度で登っていました(本来は地面を離れた時点で舌が切れ、Neri では引きずったまま登っていました)。今は舌が出てから戻るまで(m_tongueState が 0 以外。本来の拘束と同じ判定です)、すべての Smoker の移動キーと移動入力を消すので、本当に動けず、はしごにも取り付けません。舌を強制的に放してこの一回を無駄にすることもありません。「捕まえたままはしごにいたら放す」処理は保険として残しています。ai_smoker3 もこの間は連続ジャンプと空中の速度補正を行いません。どちらも速度を直接書き換えるため、拘束をすり抜けてしまうからです。
  • ai_smoker3_jump_pull は「接地エンティティがない」ことで空中かどうかを判定しており、はしごの上でも成立するため、AI が登りながら舌のボタンを押し続けていました。はしごの上は除外しました。
  • l4d2_air_data.txt に CTongue::IsAbilityReadyToFire の DHooks 関数定義を追加し、l4d_air_abilities_patch.smx と ai_smoker3.smx(1.0.1.5)を再コンパイルしました。

2026年9月22日 Tank のターゲット切り替えを緩和、胆汁を浴びた生存者を後回しに、通背拳が倒れている人を追撃しないように(ai_tank3 2.2.0)

  • Tank が一人を追い続けてなかなか狙いを変えない問題を修正しました。原因は三つ重なっていました。一つ目は、経路距離の推定がゲームの ChooseVictim 呼び出しのついでにしか更新されず、1 回に 1 人しか更新しなかったため、Tank に近づいてきた生存者が以前の遠い推定値を持ったままだったこと。二つ目は、推定値として一致した段の上限をそのまま使っていたため、1.15 倍の段と 1.5 倍の段の間だけで 30% も跳ねたこと。三つ目は、そのノイズを抑えるために切り替え条件を厳しくしすぎていたこと(得点 25% 減かつ 150 以上の差、間隔 2 秒)で、生存者が 100〜200 単位以内に固まっていると事実上切り替わりませんでした。
  • 推定は OnPlayerRunCmd で独立して更新するようにしました。各 Tank は 0.5 秒ごとに各生存者を 1 回ずつ推定し直し(到達できない相手は 1 秒)、プラグイン全体で 1 tick に最大 1 人です。段が一致したら「前の段は通れず、この段は通れる」区間を 64 単位以内まで二分し、その中点を使います。得点 = 現在の直線距離 × 迂回係数なので、更新の合間も実際の距離に追従します。
  • 同じ層での切り替え条件は、新しい得点 ≤ 現在 × 0.85(ai_tank3_target_switch_ratio)、かつ 75 以上低い(新規 ai_tank3_target_switch_gain)、前回の切り替えから 1 秒(ai_tank3_target_commit_time)になりました。新しい得点が現在の半分以下なら 1 秒を待ちません(新規 ai_tank3_target_decisive_ratio、0 で無効)。75 は二人分の推定誤差の合計の上限 64 より大きいので、推定のノイズだけで切り替わることはありません。はしご付近とはしごの上での凍結はそのままです。
  • 胆汁を浴びた生存者のターゲット得点倍率を 1.25 から 2.0 に引き上げました。経路距離が同じなら Tank は胆汁を浴びた生存者を避け、近くに他に誰もいないときだけ追います。
  • 設定との違いについて:l4d_target_override の Tank 項目は order 1,2 と voms2 0 で、胆汁を浴びた生存者は候補の段階で丸ごと除外されるため order 2 は実際には一致しません。プラグイン側はソフトな減点のままにして、周りが胆汁を浴びた人だけになっても Tank が棒立ちにならないようにしています。
  • docs/ai_tank3_scenarios_2026-09-14.html は履歴比較という位置づけをやめました。「高台の人 vs 地上の人」の情景とターゲット選択の計算機は 2.2.0 の規則で計算し(推定の二分、胆汁 ×2、切り替え用の 4 つの cvar をページ上で直接変更可能)、ほかの情景は引き続き 2.0 の判定で描いています。「同じ高さの空き地で追う」「前方が高台の縁」の 2 枚には 2.1 の変更を注記しました。あわせて、胆汁を浴びた生存者についての 1.x 比較の説明を修正しました(voms2 0 で候補の段階で外れるため、order 2 には回りません)。現在の値は docs/annehappy_dynamic_ai_difficulty.md にあります。
  • 通背拳が倒れている人や崖につかまっている人へのとどめを刺さなくなりました。射程内にまだ立っている人がいる間は追加の SweepFist は立っている人だけを狙い、周りが全員倒れたときだけ従来どおり倒れている人も扫きます。以前のループは「生存・可視・128 以内」しか見ていなかったため、Tank の足元に倒れた仲間は一振りごとに余分な一発を受けていました(1.x も同じ実装です)。
  • ai_tank3.smx を再コンパイルしました。

2026年9月19日 ダンス中に誰かがセーフルームのドアを開けると固まる問題を修正

  • ダンス中に他のプレイヤーがセーフエリアを出る、またはセーフルームのドアを開けると、踊っていたプレイヤーが撃つことも何の操作もできなくなる問題を修正しました。ダンス開始時に fornite_l4d は m_hActiveWeapon を -1 にして元の武器エンティティを記憶しますが、l4d2_med_dynamic は player_left_start_area で各生存者の古い救急キットを削除して新しいものを配ります。削除されたのが踊っている人の隠した武器そのものだった場合、保存したエンティティ参照はすでに無効で WeaponUnblock() は復元をスキップし、m_hActiveWeapon は -1 のままになっていました。
  • fornite_l4d は player_left_start_area と door_open(セーフルームのドアのみ)を EventHookMode_Pre でフックするようになり、アイテムを配る Post 処理より先に全員のダンスを終了させます。
  • ダンス開始時に武器エンティティだけでなく、その武器のスロットも記録するようにしました。WeaponUnblock() の代替順序は、元の武器エンティティ → 同じスロットに現在ある武器 → 所持している任意の武器(実際に手ぶらの場合のみ)です。救急キットを持って踊った人は、主武器に切り替わるのではなく救急キットを持ったまま復帰します。復元時に m_flNextAttack、m_flNextPrimaryAttack、m_bInReload もクリアし、m_hActiveWeapon を直接書き換えたせいで撃てないままになることを防ぎます。
  • StopEmote() はダンスのエンティティが有効な間しか視点・武器・MOVETYPE_WALK を戻さず、エンティティが先に消えるとフラグを消すだけでした。TerminateEmote()(round_start、入室、切断で呼ばれます)は移動方式をまったく戻していませんでした。両方とも新しい RestoreEmoteState() を呼ぶようになり、ダンスのエンティティの有無にかかわらず親子関係・視点・武器・移動方式を復元します。
  • 自己修復も追加しました。OnPlayerRunCmd がダンス終了後も状態が戻っていないプレイヤーを見つけたらその場で復元するため、固まったプレイヤーは死亡やマップ変更を待つ必要がありません。
  • fornite_l4d.smx を再コンパイルしました。

2026年9月19日 1vht の命中率統計が出たり出なかったりする問題を修正

  • 1v1_skeetstats の発砲カウントは player_left_start_area イベントが立てる bPlayerLeftStartArea に依存していましたが、round_start のたびにこのフラグが falseに戻されていました。イベントが発火しなかった場合や、セーフルームを出た後にもう一度 round_start が来た場合、そのラウンドの発砲数はずっと 0 のままで、精度の行は「発砲なし」だけを表示し、この制限を受けないキル数やスキート数は普通に表示されていました。発砲カウントは left4dhooks の L4D_HasAnySurvivorLeftSafeArea() で director に直接問い合わせる方式に変更し、L4D_OnFirstSurvivorLeftSafeArea_Post も追加しました。
  • 命中率が 100% を超えることがある問題を修正しました。player_hurt の命中は無条件に数えられる一方、weapon_fire の発砲は制限されていました。現在は両方が同じ条件を使います。
  • iClientPlaying は round_start と player_left_start_area でしか設定されず、ラウンド途中で生存者枠に入ったプレイヤーは集計されませんでした。また GetCurrentSurvivor() が場つなぎの bot を選ぶこともありました。現在は使用時に解決し直し、bot を除外します。
  • 1vHunters は versus で動作し versus_round_restarttimer 2 のため、3 秒の遅延レポートより先に round_start が全カウンターを消去し、統計全体が 0 になるか表示されませんでした。現在は round_end の時点でスナップショットを取ってから表示し、遅延も 2 秒に短縮しました。
  • 1v1_skeetstats.smx を再コンパイルしました。

2026年9月19日 Hunter が空中で方向転換する問題を修正

  • 飛びかかり中に何度も再度飛びかかり、空中で方向を変えられる問題を修正しました。高難易度帯では z_lunge_interval、z_lunge_cooldown、z_pounce_crouch_delay が 0 になり l4d2_hunter_patch_crouch_pounce 2 が有効なため、AI が空中で毎ティック再度飛びかかり、エンジンが現在の速度を新しいベクトルで上書きしていました。ai_hunter_2 と ai_hunter_new の両方で、飛行中は攻撃ボタンを無効化します。
  • ai_hunter_2 の angleLunge() は「現在位置 → 目標の現在位置」で飛びかかりベクトルを丸ごと再計算するため、飛行中に呼ばれると Hunter が狙い直して全速の新しいベクトルを得ていました。今後は地面を蹴った直後(離地 0.25 秒以内)の飛びかかりのみ m_queuedLunge の書き換えを許可します。ai_hunter_new も同様です。
  • ai_hunter_2 が ignoreCrouch を計算しながら一切使っていなかった問題を修正しました。l4d2_hunter_patch_crouch_pounce 2 では Hunter がしゃがまないため、視界外からの飛びかかり待機と飛びかかり前の引っかきが完全に動作していませんでした。
  • ai_hunter_2.smx と ai_hunter_new.smx を再コンパイルしました。

2026年9月17日 Tank の追跡旋回しきい値を復元

  • ai_tank3_airvec_modify_degree を 6 段階で 60 / 55 / 50 / 45 / 45 / 45°、ai_tank3_airvec_modify_degree_max を全段階で 135° に戻しました。プラグイン既定値も 45° / 135° に戻します。
  • 共有移動コードによる方向差の実効上限 89° は維持します。1° からの経路追従、空中経路の更新、左右連続ジャンプ、安全な段差降下、難易度別の岩保護も維持します。
  • 3D デモとパラメーター説明を更新し、ai_tank3.smx を再コンパイルしました。

2026年9月17日 Charger のドア破壊(ai_charger3 1.0.1.16)

  • 通常のドアで目標への視界が遮られると、Charger が殴らずにドアに引っかかる問題を修正しました。地上で障害物に阻まれて低速になった際、移動方向の爪攻撃の射程内に通常のドアがあれば、通常の殴り攻撃を優先します。
  • 壁・プレイヤー・他のエンティティによる遮蔽を維持します。セーフルームのドア、破壊不能なドア、空中・はしご・よろめき・突進・拘束中は対象外です。
  • ドア処理の回帰チェックを追加し、ai_charger3.smx を再コンパイルしました。

2026年9月16日 Tank の岩の投擲直後保護(l4d_rock_lagcomp 2.1-anne)

  • 岩が実際に手を離れた後の無敵時間を、簡単 / 普通 / 困難 / エキスパート / 極限 / 音理の 6 段階で 0 / 0.05 / 0.10 / 0.15 / 0.20 / 0.25 秒とし、動的難易度の設定とともに適用します。保護対象は岩のエンティティで、AI・プレイヤー操作の Tank に共通です。
  • sm_rock_release_godframes を追加(既定 0.15、0 なら投擲直後から破壊可能)。既存の sm_rock_godframes 1.7 は、投擲コールバックが来ない場合にエンティティ生成から計る予備の期限として維持します。両タイマーは独立し、半透明表示も実際の保護期間に連動します。
  • 時間境界の回帰チェックを通過し、Anne 版 l4d_rock_lagcomp.smx を再コンパイルしました。

2026年9月16日 Tank の安全な段差での連続ジャンプ

  • 経路が確認でき、落差が 256 単位以下の通常の下りでは、安全確認後に事前の減速・ジャンプ停止を行わず、速度を保って飛び出し、慣性で落下して、着地直後に着地推力を全量使って次のジャンプへ移ります。
  • 実際の落差から長くなる滞空時間を計算し、全行程の壁・天井と着地点の四隅の支持を確認します。縁では能動的な横跳びやジャンプ投石を行わず、さらに深い落差、梯子、ジャンプで越える隙間、安全を確認できない経路には制限を維持します。
  • 3D 比較を更新し、2.0 の事前減速も比較用に残しました。移動の回帰チェックを通過し、ai_tank3.smx を再コンパイルしました。

2026年9月15日 Tank の空中追従と左右連続ジャンプ(ai_tank3 2.1.0)

  • 空中では 0.05 秒ごとに安全な経路の前方目標を更新し、古い点を通過しても次の区間へ追従します。追跡の補正開始角は 6 段階で 10 / 8 / 6 / 5 / 4 / 3°、経路追従は 1° からとなり、滑らかな旋回と 89° の上限を維持します。
  • 元の左右入力による横方向の推力を復元。600 単位より遠い安全な直追いでは、段階ごとに 8 / 10 / 12 / 15 / 18 / 20° の左右ジャンプを行います。最初は左右ランダム、着地確認後の次の跳躍で反対側に切り替えます。角度を 0 にすると無効です。
  • 横跳びは、同じ高さの目標が見え、経路も直追いを支持する場合のみ有効です。近距離、経路の曲がり角、側方の障害物では通常追従へ戻ります。旋回前に足元の地面と残り滞空時間を求め、実際の衝突形状で上昇部分を含む放物線を区切って壁・天井を確認し、段差・特殊経路区間も調べ、梯子対応、速度上限、着地加速を維持します。
  • ai_tank3.smx を再コンパイル。小角度の目標移動、経路更新、側方障害時の復帰、左右交替、危険地形の拒否を回帰チェックに追加しました。

2026年9月15日 AI 挙動レビューの修正

  • Spitter の吐き直し記録は、最初に着地したフレームで必ず消費します。視界を失った場合、能力が未準備の場合、別の分岐で早期 return する場合も破棄し、次の跳躍で勝手に吐かないようにしました。
  • Tank の経路前方チェックは、各 Tank が tick ごとに最大 3 回の独立した予算を持ち、経路の近い点から遠い点へ調べます。障害物や予算切れに達しても到達可能と確認済みの点を保持し、遠い曲がり角や別の Tank の予算消費で連続ジャンプの経路を失わないようにしました。
  • 再コンパイル:ai_spitter_3.smx、ai_tank3.smx。

2026年9月15日 Spitter の着地吐き直し(ai_spitter_3 3.0.11)

  • 症状:簡単〜エキスパートの 4 段階で AI Spitter がほとんど痰を吐けず、能力の使い方を知らないように見えていました。
  • 理由:ai_spitter3_air_spit が 0 のとき、空中の IN_ATTACK はその場で捨てられます(キューにも入らず、遅延もしません)。吐けるのは FL_ONGROUND が立っているフレームだけです。一方でプラグイン自身が ai_SpitterBhopStartDistance(Anne 3 モードの設定ではすべて 2500)以内で着地のたびに即座に再ジャンプしており、z_spit_range はそれよりずっと小さいので、吐痰の射程がまるごと連続ジャンプの半径の内側に入っています。1 回の滞空は sqrt(2 × 56 / sv_gravity) × 2、TickrateFixes が sv_gravity を 750 に固定しているので約 0.77 秒。100 tick なら滞空 77 フレーム + 着地 1 フレームで、地上フレームの割合は約 1/78 です。98% 以上のフレームで攻撃ボタンが消され、残り 2% 弱も AI の発射タイミングと一致する必要がありました。極限/音理段階が問題なかったのは空中吐きが有効で、地上判定をまったく見ない buttons |= IN_JUMP の跳び吐きルートを通るからです。
  • 着地での吐き直し:空中で消された 1 回分に時刻を記録し(SPIT_OWE_TTL 1 秒。1 回の滞空より少し長く、今の跳躍で発生した分だけを対象にします)、着地の最初のフレームでターゲットがまだ見えていて能力も出せる状態なら、プラグインが代わりに攻撃を押し、そのフレームだけジャンプを飛ばします。止まるのはそのフレームだけで、次のフレームは通常どおり跳びます。着地から 1 tick しか経っていないため 0.15 秒の着地推力ウィンドウ内に収まり、連続ジャンプの鎖は切れず推力も満額のままです。押すときの視点は AI 自身のものです。関数冒頭の if (buttons & (IN_ATTACK | IN_ATTACK2)) AIPathMovement_Reset(spitter); がその跳躍の経路補正をすでに切っており、AlignFacing は向きを上書きしません。プラグインはボタンを押すだけで、狙いは代行しません。
  • 吐いた直後からまた跳べる:地上の攻撃分岐は従来 IN_ATTACK が押されている限り IN_JUMP を消していたため、AI がボタンを押し続けると Spitter は地面に貼り付いたままでした。今は spitReadyToFire()(m_nextActivationTimer の時刻を過ぎている)を条件にしています。痰がまだ出ていない間だけジャンプを抑え、前段モーションやクールダウンに入ったあとは押しっぱなしを無視して連続ジャンプを続けます。
  • 新しい cvar は追加せず、段階別の値も設けません。これは不具合修正であって弱体化ではありません。極限と音理は ai_spitter3_air_spit が 1 で、従来の跳び吐きルートのまま変わりません。
  • 再コンパイル:ai_spitter_3.smx。

2026年9月9日 zonemod_anne から特感を塞ぐ新規 stripper エンティティを削除

  • 上流 zonemod は stripper の add: で clip、blocker、実体プロップ、梯子を足します。Anne 側は対応 nav を更新していないため、特感は古いナビのまま歩き、新しいエンティティにぶつかって詰まります。
  • 対象はカスタムマップのみです。2026 年 5 月の zonemod 同期以降に足された、特感を塞ぐ梯子/実体プロップを cfg/stripper/zonemod_anne から外しました(City 17、No Echo m3、Carried Off、Dark Carnival Remix、Parish Overgrowth など)。公式 c1–c14 の nav は既に確認済みなので、そちらの幾何 add: はすべて元に戻しています。env_physics_blocker と env_player_blocker は残し、BlockType を生存者のみ(1)にしています。
  • カスタムマップでは filter/modify、アイテム/痛み止めの add:、nav_fixes の logic_auto、それ以前から anne にあった clip は残します。今後カスタムマップを同期するときは、対応 nav なしに特感を塞ぐ梯子/実体プロップの add: をコピーしません。

2026年9月9日 Charger 連跳の難易度別弱体化(設定のみ、プラグイン変更なし)

  • なぜ連跳だけか:Charger の走行速度は生存者と同じ 220 で、実際に人へ届くかどうかは連跳が全てを決める。つまり連跳パラメータそのものが Charger の圧力である。ここでの変更はすべて「どう跳ぶか」だけを変え、「跳ぶかどうか」は変えない。Charger は変わらず能動的に襲いに来るが、撃ちやすく避けやすくなる。棒立ちの間抜けにはならない。変更はすべて dynamic_ai_difficulty.cfg の 6 段の中にあり、プラグインのソースと挙動は不変、音理段(level6)の値はプラグイン既定値と完全一致で従来通り。
  • 横方向連跳(費用対効果が最も高い):ai_charger3_bhop_strafe_mindeg / maxdeg は 6 段で 8〜18 / 14〜28 / 20〜38 / 25〜46 / 28〜52 / 30〜55 度。振幅は tan(random(mindeg, maxdeg)) なので 30〜55 度は 0.58〜1.43、8〜18 度なら 0.14〜0.32 しか残らず、接近経路はほぼ直線になる。速度は一切落ちない。ただ射線を避ける蛇行をやめるだけで、エイムが良ければ接近中に撃ち落とせる。ai_charger3_bhop_strafe_mindist の 800 / 700 / 600 / 500 / 420 / 400 と合わせると、低段は「遠くでだけ蛇行し、800 に入ったら直線」になる。
  • 連跳をやめる距離:ai_charger3_bhop_min_dist は 170 / 150 / 130 / 115 / 105 / 100。これを下回ると APPROACH から BAIT に移り、連跳をやめる。CHARGE_GUARANTEED_MAX_DIST(110)が既に命中保証の下限を抑えているため、これを大きくしても 170 から突進するようにはならない。最後の 60 単位が 220 の走行速度になるだけで、プレイヤーは顔面へ一跳ではなく、見える助走を得る。
  • 視界なし連跳:ai_charger3_bhop_no_vision は 0 / 1 / 1 / 1 / 1 / 1、ai_charger3_bhop_nvis_maxang は 35 / 35 / 50 / 65 / 80 / 90。簡単段では加速前に視線を要求する。視界がないと executeGroundBhop は早期 return して原生の地上移動に戻るので、状態機械が詰まることはない。消えるのは「見えない曲がり角の裏から 400 速で飛び出す」挙動で、爆発力は見られてから始まる。
  • 空中旋回:ai_charger3_airvec_modify_min_deg / max_deg は 65〜70 / 60〜74 / 55〜78 / 50〜83 / 47〜89 / 45〜89 度。方向修正はこの角度帯の内側でのみ働く。min を上げれば小さな回避には追従せず、max を下げれば大きなズレは修正を諦める。簡単段は 65〜70 度という狭い帯だけが残り、跳んだ方向へほぼそのまま飛ぶので着地点をずらして避けやすい。S 字が経路へ戻る処理はこの min ではなく AIR_CORRECTION_MIN_TARGET_DEG(1.0)を使うため、曲線自体は影響を受けない。
  • 速度軸ももう一段:ai_ChagrerBhopSpeed 30/40/50/60/80 → 20/30/42/55/70、ai_charger3_bhop_max_speed 400/400/400/500/700 → 330/360/390/450/600、ai_charger3_bhop_first_hop_ratio 0.2/0.3/0.4/0.5/0.6 → 0.0/0.15/0.3/0.45/0.55。簡単段の第一跳 0 は、走行から直接跳んだ一跳目は方向のみ変えて加速しないという意味。音理段は 3 項目とも据え置き。
  • 触っていないもの:ai_charger3_bhop_before_charge は全段 1 のまま。切ると CHARGING が (commitDist, bhopMinDist + 50] の許容帯で APPROACH へ戻り、APPROACH ↔ CHARGING の往復が見えるリスクがある一方、得られるのは突進開始距離が約 150 から約 110 になるだけで割に合わない。もう一段削るならまずこれを試すのが良い。
  • 再コンパイル不要。

2026年9月8日 Charger 近接後退ジャンプの正規化(ai_charger3 1.0.1.15)

  • 現象:近接持ちの生存者へ連跳接近すると、空中で突然水平速度が消えて真っすぐ落下する。着地後の後退ジャンプもプレイヤーには出せない速度だった。
  • 空中急停止:Approach から近接にらみ合い帯へ入る時、および Bait で後退ジャンプ以外の空中フレームが、TeleportEntity で水平速度を 0 にしていた。プレイヤーは空中で 400 速を一瞬で捨てられないので、物理が消えたように見える。この書き込みをやめ、今のジャンプの運動量のまま着地してから後退ジャンプする。
  • 後退ジャンプ速度:生存者の追い速度 × 1.2 を走行速度に足していたため、1 跳で 400 超が出た。Path / Direct 連跳と同じ式に揃える:すでに離れる成分は残し、相手へ飛んでいた速度は旋回時に捨て、着地加速を足し、連跳上限で切る。
  • 再コンパイル:ai_charger3.smx。

2026年9月8日 Charger の近接にらみ合いでの痙攣と無限膠着の修正(ai_charger3 1.0.1.14)

  • 症状:Charger が瀕死で生存者が近接武器を持っていると、駆け引き帯の中で「一歩踏み込んですぐ停止」を繰り返して痙攣し、しかもにらみ合いが延々と続く。
  • 痙攣の直接原因:maintainMeleeBaitDistance が bang-bang 制御だった——baitZoneMin より近ければ全速後退、baitZoneMax より遠ければ全速前進、その間の 35 ユニットの不感帯では毎ティック TeleportEntity で水平速度をゼロにしていた。誤差 1 ユニットでも 30 ユニットでも runTopSpeed を使うため帯全体を 3〜5 ティックで横断し、「全速で飛び出す → 速度が瞬時にゼロ → 生存者が一歩詰める → また飛び出す」に収束していた。
  • 距離制御をヒステリシス + 比例速度 + 最短保持に変更:動き出したら帯の中心まで進んでから手を離す(方向反転には帯の半分を横断する必要がある)。速度は中心までの誤差に比例し、BAIT_MOVE_SPEED_RAMP に達して初めて全速、下限は 35%。同じ方向を最低 BAIT_MOVE_HOLD_TIME(0.25 秒)維持する。
  • 不感帯では速度をゼロにせず毎ティック 0.7 倍で減衰させ、急停止ではなく滑らかに止まるようにした。
  • 後退ジャンプの着地後 0.45 秒はロックし、距離制御がすぐ前進に転じないようにして「飛び出す → 着地即前進 → また近すぎる → また飛び出す」の毎フレームの綱引きを断ち切った。
  • 緊急しきい値の逆転:緊急後退ラインが melee_range + 20(90)で固定されており、駆け引き帯(85〜120)の内側に入り込んでいた。帯の最も内側の 5 ユニットは常に「緊急」状態で、そこでは後退ジャンプが不感帯を上書きするため、85 まで下がった瞬間にまた後退を命じられていた。現在は帯の内側(melee_range + min(20, baitZoneMinRange × 0.5) = 77.5)に置き、35 ユニットの帯全体で実際に踏みとどまれるようにした。
  • 保険の強制突進が一度も働いていなかった:isTargetVulnerable にある ai_charger3_bait_max_duration(7 秒)の保険は Bait 状態の getStateDuration に依存しており、状態の startTime は transitionTo のたびにリセットされる——後退ジャンプ一回で Bait の離脱ラインを越え、Bait → Approach → Bait を一周するだけでタイマーがゼロになるため、膠着が無限に続いていた。膠着タイマーを「対象 + 連続した近接駆け引き」に紐付け、2 回の近接駆け引きの間隔が 2 秒未満なら加算を続けるようにしたので、Approach ↔ Bait の往復ではリセットされない。
  • 瀕死 Charger の選択肢:shouldChargeInMeleeBait の 3 経路のうち「体力が近接即死ラインより上」は弱体化後は常に偽で、isTargetVulnerable も近接対象に対して同じ体力判定を内包しているため、残るのは「対象がよそを向いた」だけだった。isTargetVulnerable には汎用の攻撃間隔判定があるが、全武器一律で「次の攻撃 > 現在 + 0.5 秒」を使うため、利用できる窓は「武器の振り間隔 − 0.5 秒」になる。振り間隔が短いほど窓は狭くなり、高速な近接(振り間隔 0.5 秒以下)では窓幅が 0 になり一度も発動しない。空振りの硬直を狩る経路を追加し、近接対象には 0.2 秒のしきい値を使うことで、どの近接武器でも実際の窓が残り、瀕死の Charger にも実力で入る機会が生まれる。
  • 膠着エスカレーション:ai_charger3_bait_max_duration を超えたら フェイント → 強制突進 → ターゲット変更 と段階的に上げる。フェイントは踏み込んで攻撃を誘い(緊急ラインまで詰めたら通常ロジックに戻して後退ジャンプで離脱)、無目的な出入りをリズムのある意図的な駆け引きに変える。空振りは上記の硬直狩りが拾う。フェイント回数を使い切ったら突進する——1 人倒してから斬られる方が、その場で震えているより得だからだ。能力がクールダウン中なのは「まだ突進できない」だけで詰みではないため、CD を理由にターゲットを変えることはない。
  • 新規 cvar:
  • ai_charger3_melee_bait_orbit(既定値 1):帯の中では棒立ちの代わりに対象の周りを接線方向に回り、「その場での痙攣」を「隙を探して回り込む」動きに変える。回り込む方向が壁で塞がれていれば反転して再試行し、両方向とも危険なら制御をネイティブ経路探索に返さずその場に留まる(返すと PathFollower が Charger を生存者に直進させてしまい、かえって悪化する)。0 で従来の棒立ちに戻る。
  • ai_charger3_melee_bait_stalemate_switch(既定値 0):最終段階。能力は使えるのに突進が通らない(高低差 / 経路が塞がれている)場合に別の生存者へ切り替える。既定では無効で、まず他の項目の手触りを確認してから判断する。
  • ai_charger3_melee_bait_blacklist_dur(既定値 10.0):膠着で諦めた対象をターゲット選択から外す時間。これがないと L4D2_OnChooseVictim が距離順で同じ近接生存者(たいてい最も近い)をすぐ選び直し、ターゲット変更自体が新たなブレになる。ブラックリストはあくまで優先度で、最後の手段である getClosestSurvivorAndValid は無視するため対象が居なくなることはない。
  • 再コンパイル:ai_charger3.smx。

2026年9月4日 スポーンが Director フォールバックに落ちる問題の修正(infected_control + anne_spawn_accel 1.5.0)

  • 問題:2026-09-02.1 以降、多くの特殊感染者が Director API フォールバックでスポーンし、配置が散らばった。空きクラウド 2 台での 5% マトリクス A/B で再現・特定:既定の枠では差が小さい(クラウド8 1.24% vs 0.88%、クラウド4 4/480 vs 0/480)が、前ウェーブの生存特殊が台帳を占めている本番状態に合わせて枠を絞ると急増——クラウド8 SI_target_limit_manual 2 で 12.78% vs 基線 1.94%、クラウド4 同設定で 80/480(16.7%)vs 基線 0/480。単変数分離:target_override を 2.27 に戻すと悪化(14.44%)、infected_control だけ戻すと 2.22% に回復。原因は infected_control の新規「ロック待ち予約」が枠を一瞬で使い切り、SpawnAccel_CollectEligibleTeamTargets() が容量で owner を空になるまで除外し、spawn_core.inc が owner 集合空で SpawnSearch_Exhausted を無言で返す(ログなし、ownerCapacity 常に 0)こと。TryNormalSpawnOnce は毎フレーム band++ し、10 フレームで Director 段へ到達。3 秒の inf_spawn_nav_band_timeout 経路は関与していない。
  • 拡張 anne_spawn_accel 1.5.0:チームスナップショットは引き続き全員で構築・キャッシュしつつ、生存者ごとに 1 層の有向距離場を保持。新 native AnneSpawn_NavCandidatesCollectTeamEx(..., excludedClients, excludedCount) は上限に達した生存者を渡すと、各行を残りの生存者の最近者で再解決し、除外者しか到達できない行はスキップ。除外集合の変化でスナップショット再構築や Pending は発生しない。全員除外時は除外なしとして扱う。Linux 32bit .so は pve の Docker(Ubuntu 22.04 + hl2sdk-l4d2 + SM 1.12 + AMBuild)でビルド、nav_graph_test 通過。初版は新 GCC の libgcc を動的リンクしていた(GCC_7.0.0 シンボルバージョンが必要)ため、Valve 同梱の古い bin/libgcc_s.so.1 を強制する srcds では dlopen に失敗し、sm exts unload/load は常駐する 1.4.4 イメージを無言で再利用していた。AMBuilder に -static-libgcc を追加して再ビルド済み(libgcc_s 依存なし、readelf -V に GCC_*/GLIBCXX_* 要求なし)。拡張差し替え後は必ず sm exts info でバージョンを確認し、必要ならコンテナを再起動する。Windows .dll は未再ビルド(旧拡張ではプラグインが自動的に「除外なし」に戻る)。
  • infected_control.smx 2026-09-04.1:チーム owner 集合は生存/行動可能のみで決まり容量は無関係;除外リストは EnsureCursor で計算し変化時はページングのみ再開;ホットループは明示的に除外された owner のみスキップし IsAtCapacity を直接見ない;IsAtCapacity(硬判定)は target_override の実台帳のみ参照、予約は ChooseTargetSurvivor の重み付けのみ(TTL 2.5→1.5 秒、制御クラスのみ計上);commit でチーム集合キャッシュを無効化しない;早期終了経路に [FIND EARLY-EXHAUSTED] のスロットル付きログとカウンタを追加。
  • 検証:クラウド4(4 マップ × 10 進度点、12 SI)は既定枠・絞った枠とも 480/480 有向 Nav 直スポーン、Director 0 回、平均 245ms(基線 249ms)、稼働中版は同設定で Director 80 回;クラウド8 全量 1083 格(docs/infected_control_refactor/NAV_WAVE_MATRIX_20260904_TEAM_EXCLUDE_FULL.md)は 12984/12984 欠損ゼロ、Nav 99.445%、Director Range 118→72、[FIND EARLY-EXHAUSTED] と ownerCapacity は終始 0、平均 364.6→332.4ms。上記の装載問題により両ラウンドは実際には拡張 1.4.4 で動いており、検証したのは旧拡張下の「除外なし」フォールバック経路でのプラグイン側修正。再ビルドした拡張 1.5.0 はクラウド8 で検証済み(docs/infected_control_refactor/NAV_WAVE_MATRIX_20260904_TEAM_EXCLUDE_EXT150.md):一時ファイル名での装載、正式パス上書き+docker restart 後の両方で sm exts info が 1.5.0;枠を絞った再現で 480/480 有向 Nav・Director 0 回(稼働中版は 80/480)、全量 1083 格で Nav 12906 / Director 77・平均 359.8ms と 1.4.4 ラウンドとノイズ内で同等、08-26 基線に対する改善は全て維持。既定枠では各人 5 枠で誰も満たないため除外リストは常に空で、このマトリクスは 1.5.0 の無回帰は示せるが高速経路の効果は測れない。1.5.0 では除外 owner の候補が native 内で再帰属されるためホットループの ownerCapacity が 0 なのは正常で、新設の [TEAM EXCLUDE] ログを見る。テスト後クラウド4/8 は本番ファイルをハッシュ照合で復元、cvar リセット済み。
  • ウェーブ時序(キルフェーズ + 独立 16 秒カウントダウン + Anti-Bait)は今回も 09-02 も未変更。「固定 24 秒になった」体感は遠方フォールバックの特殊が死なず早期開始条件が満たされにくくなった副作用。
  • scripts/run_nav_wave_matrix.py:ウォッチドッグによる srcds 再起動後に infected_control とフィクスチャだけ再ロードし SI_Target_limit/l4d_target_override を無言で落としていた(クラウド8 の初回全量はこれで無効となり再実行)。両者を随伴プラグインとして扱い、開始時に動いていたものは復旧時に infected_control より前にロード順で再ロードする。
  • 再コンパイル:infected_control.smx;再ビルド:anne_spawn_accel.ext.2.l4d2.so(-static-libgcc)。

2026年9月3日 特殊感染者の連続ジャンプ:初回ジャンプ加速比率 + 梯子上端の着地誤判定修正

  • 「初回ジャンプ加速比率」cvar を新設:ai_charger3_bhop_first_hop_ratio、ai_tank3_bhop_first_hop_ratio、ai_BoomerBhopFirstHopRatio、ai_SpitterBhopFirstHopRatio(0.0–1.0)。走行から直接跳ぶ初回ジャンプは 加速度 × 比率 を受け取り、着地直後の再ジャンプは従来どおり加速度全量。0 は前項の「初回ジャンプで加速しない」、1 は旧挙動と同じ。共有 AIPathMovement_GetHopImpulse に省略可能な firstHopRatio 引数を追加(既定 0、互換維持)。
  • このつまみが必要な理由:初回ジャンプで加速しないことによる連鎖開始の遅れは ≈ 0.75 秒 × (1 − 比率) × (連跳上限 − 走行速度) で、加速度の大きさに依存しないため BhopSpeed / impulse では補償できない。高い段階ほど上限が高く、削られ方が最も大きくなっていた(音理段 Charger 0.48 秒、Boomer 0.62 秒、簡単段は 0.28 / 0.53 秒)——難易度の階段が逆転していた。
  • 動的 AI 難易度 dynamic_ai_difficulty.cfg 6 段階:Charger・Boomer・Spitter は共通で 0.2 / 0.3 / 0.4 / 0.5 / 0.6 / 0.8、Tank は 0 / 0.2 / 0.4 / 0.6 / 0.8 / 1.0(Tank は最も影響が小さい職業で連鎖が 1 跳ずれるだけのため、音理段は旧来の初回ジャンプ全量加速を維持)。補正後の遅れは段階が上がるほど単調に減少(音理段:Charger 0.10 秒、Tank 0 秒、Boomer 0.12 秒、Spitter 0.12 秒)。Tank 以外は最上段でも 1.0 にはせず、Boomer / Spitter の推力 250 による「初回ジャンプの急加速」が戻らないようにした。プラグイン既定値は音理段に合わせ 0.8 / 1.0 / 0.8 / 0.8。
  • 梯子上端の dismount が着地扱いされる問題を修正:AIPathMovement_NotifyGrounded(client, onLadder) が前回の登録が梯子上だったかを記録し、梯子の頂上でエンジンが行う短い dismount(梯子上でも地面でもない区間)の後の接地は着地と見なさない。梯子を登り終えた後の初回ジャンプが加速度を余分に受け取らなくなった。4 プラグインすべてで onLadder を渡す。
  • ai_boomer_3 を 3.0.10 に更新:地面/梯子登録を m_customAbility 無効時の早期 return より前に移動(登録漏れのフレームで地面にいる Boomer が滞空着地と誤判定されるのを防ぐ);round_start でも連跳チェーンをリセット。
  • ai_spitter_3 を 3.0.9 に更新:player_spawn をフックして連跳チェーンをリセット(Boomer / Charger と揃える)。
  • ai_charger3 を 1.0.1.13、ai_tank3 を 1.0.0.13 に更新:Path / Direct / 駆け引き後退ジャンプ(Charger)と通常 / Path 連跳(Tank)の離陸後に AIPathMovement_MarkHopStart を呼び、着地許可を消費(Boomer / Spitter と同じ)。
  • 再コンパイル: ai_charger3.smx、ai_tank3.smx、ai_boomer_3.smx、ai_spitter_3.smx。

2026年9月3日 特殊感染者の連続ジャンプ:初回ジャンプで加速しない

  • 原因特定:共有の空中補正 ai_path_movement.inc 自体は決して加速しない(速度を離陸速度以下に底上げするだけで、旋回時はむしろ減速)。4 種の特殊感染者で「初回ジャンプが空中で急に速くなる」と見えたのは全て離陸フレームが原因:Path / Direct 離陸が速度を 走行速度 + 加速度一回分 にそのまま置き換えていた(Charger 250→350、+40%;Boomer 175→325、+86%、さらに ClientPush が 250 以下の速度を 251 まで強制的に引き上げていた)。人間のバニーホップのように着地で伸びる形ではなかった。
  • ai_path_movement.inc に連続ジャンプ鎖の追跡を追加:AIPathMovement_NotifyGrounded を地上(または梯子)フレームごとに可能な限り早く呼び、地面を離れて 0.1 秒以上経ってから再び接地した時点を着地として登録する。プラグインのジャンプ、エンジンのジャンプ、経路に沿って段差を歩き降りた場合を区別せず、高所からの落下も着地扱いで滞空時間の上限は設けない——落下で得た速度はそのまま保持され、着地時のジャンプで加速度が追加される。AIPathMovement_GetHopImpulse は「着地から 0.15 秒以内に再ジャンプ」した時だけ加速度をまるごと返し、地面から直接跳んだ初回ジャンプには 0 を返して方向だけ変える。AIPathMovement_MarkHopStart は離陸ごとに着地許可を消費する(BeginPathHop 内で自動呼び出し)。エンジンがジャンプを拒否した場合は次フレームも地面に立ったままで一度も離地していないため着地扱いにならず、その場での再試行で毎フレーム加速度を受け取ることはない。梯子は地面として扱い、梯子を登り終えた後の初回ジャンプは加速しない。
  • ai_charger3 を 1.0.1.12 に更新:Path / Direct の地上離陸を着地加速に変更、突進前の最終ジャンプも離陸として登録し接近状態に戻った後も鎖が続く。新規 Charger / リスポーン時に鎖をリセット。デバッグログに地上速度と着地ジャンプかどうかを追加。
  • ai_tank3 を 1.0.0.12 に更新:通常ジャンプ(前/後/横方向のインパルス)と Path 先読みジャンプの両方を着地加速に変更。ラウンド開始と接続時に鎖をリセット。
  • ai_boomer_3 を 3.0.9 に更新:推力を着地時のみ追加。離陸速度を先に構築し経路チェックと Teleport で同じものを使用(従来の経路チェックは推力ベクトル単体しか見ておらず、推力のない初回ジャンプでは長さゼロのチェックに退化していた)。最低ジャンプ速度 251 は実際に推力を加えるジャンプでのみ適用し、初回ジャンプにこっそり速度を足すことはなくなった。
  • ai_spitter_3 を 3.0.8 に更新:推力を着地時のみ追加。spitterDoBhop は経路チェック済みの離陸速度をそのまま書き戻し、Teleport 前に再計算しない。
  • 4 プラグインの加速度 cvar 説明を「着地直後の再ジャンプで追加、走行から直接跳ぶ初回ジャンプには加えない」に統一。加速の鎖が一段後ろへずれるだけで、上限・空中補正・旋回減速のロジックは変更なし。
  • 再コンパイル: ai_charger3.smx、ai_tank3.smx、ai_boomer_3.smx、ai_spitter_3.smx。

2026年9月2日 特殊感染者ターゲット上限の連携修正(infected_control / SI_Target_limit / l4d_target_override)

  • infected_control.smx を 2026-09-02.1 に更新。ランナー(走り屋)状態が ON になった時だけ外部へ通知していた退行を修正:解除時(隊列復帰、ウェーブ/ラウンドリセット、ギミックイベント)に OnDetectRushman(0) を送るようになり、SI_Target_limit が一度の検出後にマップ終了まで「全員の上限解放」に留まらなくなった。解除には確認ウィンドウを設けた:新 cvar inf_antibait_runner_off_confirm(既定 2.3 秒)で、ランナーが判定閾値内に戻っただけ(差が縮まった、味方が追いついた)の場合はその時間継続してから解除し、味方が一瞬追いついて再び離れた際にターゲット上限が頻繫に切り替わるのを防ぐ。ランナーの死亡/ダウン/拘束/切断は従来通り即時解除。ウェーブリセットで gAB.runner だけ消して gST.bPickRushMan を残すこともなくなり、両方のランナー状態が一致する。
  • スポーン側の容量判定を「残り枠」基準に変更:まだ ChooseVictim を通っていない新規スポーンは誘導先に予約枠を記録(台帳に登録されるか 2.5 秒後に解放)し、同一フレームの連続スポーンが全員同じ生存者に向くことがなくなった。ランダムなターゲット選択は残り枠で重み付けし、先頭プレイヤーの ×2 上限が自然に多くの圧力を受ける。
  • テレポート補充のクラスが生存枠を使い切っている場合(通常キューや内通者予約が先に消費)は枠の残るクラスに差し替え。全クラスが満杯なら 1 秒バックオフし、毎フレーム空回りしない。
  • SI_Target_limit.smx を 1.9 に更新。新 cvar SI_target_rushman_scope(既定 1):ランナー検出中はランナー本人の個人上限のみ解放(SetTargetedCap)、他の生存者は通常の保護を維持。0 で旧挙動(全員を SI 総数上限まで引き上げ)。SI_target_enable が実際に機能するようになった(無効時は target_override の targeted オプションをクリアし、全 native が「制限なし」を返す)。再計算は一度計算・一度送信に変更し、クラス単位オプションを 66 スロット分送らない。手動モードも初期化時に送信。survivor_rescued / defibrillator_used / player_team / 生存者の player_spawn トリガーを追加し、毎秒の検証で可動人数の変化や target_override の設定再読込(sm_to_reload は targeted を 0 に戻す)によるずれを自動補正。infected_control 再読込後に l4d_infected_limit を二重フックしない。si_target_limit.inc のライブラリ名を RegPluginLibrary と同じ小文字に統一。
  • l4d_target_override.smx を 2.28 に更新。ChooseVictim に post detour を追加:pre 段階が判断をゲームに委ねた場合(type=1 で視界内に誰もいない、クラスがオーバーライド対象外、forward が Handled を返した)でもエンジンが選んだ被害者を targeted 台帳へ登録し、GetValue(VALUE_INDEX_TOTAL) の恒常的な過少報告を解消。SetLastVictim で登録したターゲットは wait/dist の意味を保持し、次の呼び出しで捨てて再選択しない。forward が Plugin_Handled を返した時の ArrayList ハンドルリークを修正。
  • 再コンパイル: infected_control.smx、SI_Target_limit.smx、l4d_target_override.smx。

2026年9月2日 spechud タンクパネル修正

  • spechud を 3.10.1 に更新。タンク HUD パネルは観戦者と感染者プレイヤーだけに送信し、以前 versus_coop 向けに追加した生存者への送信分岐を削除。チーム移動時に CancelClientMenu でパネルを回収しようとするコードも削除した——この SourceMod 関数はサーバー側の状態を消すだけでクライアントには何も送らず、radio パネルは 3 秒のタイムアウトまで残るため、実際には何の効果もなかった。
  • AI タンクのターゲットが常に「索敵中」と表示される問題を修正。従来は l4d_target_override が記録した被害者しか読んでいなかったが、タンクのターゲット変更は実際には Left4DHooks の L4D2_OnChooseVictim(ai_tank3 や SI_Target_limit が使用)を通るため、記録が空のままだった。spechud 自身が L4D2_OnChooseVictim を監視して各タンクの最新ターゲットを userid でキャッシュし、target_override に記録がある場合はそちらを優先する。
  • タンクパネルの文言をすべて翻訳ファイル経由にし、受信者ごとにクライアント言語でパネルを構築。サーバー既定言語は chi のため、対応言語がないプレイヤーには中国語が表示される。en/chi/zho/jp/ko/vi/es の 7 つの spechud.phrases.txt にフレーズを追加。
  • scripts/spcomp-docker.sh を bind mount 依存から tar ストリーム方式(ソースを stdin で送り、.smx を stdout で受け取る)に変更。既定では SSH 経由で pve-yma ホスト上の spcomp64 をネイティブ実行(SPCOMP_SSH_HOST で変更可)、SPCOMP_BACKEND=docker でコンテナ実行に切替。ローカルに Docker デーモンがない Mac でもコンパイルできる。
  • 再コンパイル: spechud.smx。

2026年9月2日 Scripted HUD の表示言語メニュー

  • l4d2_scripted_hud を 1.7.0 へ更新。!hud メニューに「言語」項目を追加し、!lang / !hudlang から直接開くこともできます。ゲームの言語に従う、English、簡体字中国語、繁体字中国語、日本語、韓国語、ベトナム語を切り替えられます。languages.cfg にあってサーバーが実際に認識している言語だけを一覧するため、選んでも何も起きない項目は表示されません。
  • 選択内容は SteamID ごとに scripted_hud_prefs の新しい lang_code 列と、独立した Cookie l4d2_scripted_hud_lang_v1 に保存します。他の HUD 設定と同じ revision マージ規則を使うため、サーバー移動・再接続・データベース一時停止をまたいでも維持されます。
  • 言語は SetClientLanguage で適用するので、HUD と HUD メニューに加えて、他プラグインがそのプレイヤーへ送るチャット翻訳も一緒に切り替わります。SourceMod はクライアントが設定を変更するたび cl_language を読み直すため、そのプレイヤーの HUD を構築するたびに上書き値を確認して再適用します。
  • !hud の「デフォルトに戻す」は言語を意図的にリセットしません。メニュー自体の表示言語を決める設定であり、消すと戻す操作が読めなくなるためです。戻す場合は言語メニューの「ゲームの言語に従う」を選んでください。
  • 既知の制限:HUD2 のモードタグ([普通药役] など)と AI 難易度名は全体共有のハードコードされた中国語のままで、この設定では切り替わりません。
  • docs/plugin_commands.md に sm_hudlang / sm_lang を追記しました。
  • 再コンパイル:l4d2_scripted_hud.smx。

2026年9月1日 AI Smoker の即時解除クールダウンと退避修正

  • ai_smoker3 を 1.0.1.4 へ更新。命中した舌が切断/即時解除された場合、Actions 拡張が残留した SmokerTongueVictim を終了し、原生の SmokerRetreatToCover を維持したまま、Action コールバック外で被害者から離れる Nav 移動を指示します。舌が使用可能になると原生 AI へ戻ります。イベントは 1 フレーム待って m_tongueVictim が空であることを確認するため、通常の絞め移行を即時解除と誤判定しません。
  • Anne、Hardcore、Shotgun、Alone で Zonemod の l4d2_tongue_timer.smx を再び読み込みます。生存者による即時解除は最低 4 秒。Tank ダメージによる解除は Anne 系設定では 1 秒に引き下げ(上流の Zonemod は 8 秒のまま)、AI Tank のパンチや岩が味方 Smoker を重く罰しないようにしました。空振りは tongue_miss_delay のままで Easy~Expert は 7 秒、Extreme/Neri は 3 秒、通常命中後の解放は tongue_hit_delay 13 のままです。
  • l4d2_tongue_timer を 1.3-anne.1 へ更新。被害者ごとに実際に引いている Smoker を記録するため、Tank の即時解除で先頭の Smoker に誤って 8 秒を与えません。舌の解放も対応する組だけを消去し、複数 Smoker の同時プルに対応します。
  • 再コンパイル:ai_smoker3.smx、l4d2_tongue_timer.smx。

2026年9月1日 Charger 爪コンボのキーと駆け引き修正

  • ai_charger3 を 1.0.1.11 へ更新。近距離の爪攻撃と拘束中の殴りは再び IN_ATTACK2(左クリックは突進能力)。以前の IN_ATTACK では最大 2.5 秒立ち尽くして一発も出ませんでした。
  • 銃所持対象へのコンボは、相手が見ていない・Charger の体力が近接即死線より上・相手がリロード/ショブ CD 中でない場合だけ開始し、500 体力で銃の正面に立ち続けるのをやめます。
  • 2 撃予測は 2 撃目の 0.85 秒だけを見るように変更。確定突進の下限は 110 で上限し、横移動速度 ≥ 150 のときは commit 距離を引き上げません。
  • 爪攻撃カウントに有効な m_flNextPrimaryAttack 基準値の状態を追加し、初期値が 0、または爪武器が一時的に取得できない場合でも初撃を数え落とさないようにしました。爪距離属性の取得失敗はマップごとに間隔を空けて最大 3 回だけ再試行し、毎フレームの native 呼び出しと Left4DHooks のエラーログ連打を防ぎます。
  • 再コンパイル:ai_charger3.smx。

2026年9月1日 2026-08 AI バランス調整

  • ai_charger3 を 1.0.1.10 へ更新。Charger 専用 CVar ai_charger3_air_speed_floor_ratio(既定 0.50)を追加:Path / Direct 起跳時、空中方向補正に登録する hopSpeed を実際の起跳速度×この比率にし、m_flLastHopSpeed は実起跳速度のまま残します。
  • 動的 AI 難易度 6 段階で Charger を弱体化:加速度 30/40/50/60/80/100、上限 400/400/400/500/700/700、空中補間 0.10/0.15/0.20/0.25/0.30/0.40、旋回減速 0.50/0.39/0.325/0.26/0.195/0.13、保速下限 0.50/0.60/0.65/0.70/0.80/0.80。簡単段階の減速は既存の硬上限 0.50 を使用します。
  • ai_spitter_3 を 3.0.7 へ更新。ai_spitter3_air_spit(既定 0)を追加:極限と音理だけ 1 で、AI Spitter の空中吐痰を許可。簡単〜エキスパートは空中吐痰を禁止し、地上吐痰はそのまま、プラグインがジャンプを付けません。プレイヤー Spitter は制限しません。
  • Smoker の tongue_fly_speed は 6 段階すべて明示的に 1000(極限/音理は 1200 から引き下げ)。
  • 再コンパイル:ai_charger3.smx、ai_spitter_3.smx。

2026年8月31日 コミット前レビュー修正

  • ai_charger3.smx を再コンパイル。従来の成果物は 1.0.1.8 のままで、1.0.1.9 の「先に2撃してから突進」、銃所持向けの命中確実帯 resolveChargeCommitDist、制御系上限のターゲット変更ゲート、連跳上限の登録がいずれも入っていませんでした。すでにソースから削除済みの確率突進が動いたままでした。
  • ai_boomer_3 / ai_spitter_3 の押し出しベクトル正規化のゼロ除算を修正。水平成分がゼロのとき(目標が真上・真下、視点ピッチ ±90)正規化は純粋な垂直ベクトルへ退化し、特感をそのまま空へ打ち上げます。今回直そうとしていた「空飛び」の別ルートそのものです。共有ヘルパー AIPathMovement_NormalizeHorizontal() を追加し、ゼロベクトルなら押し出しを行いません。
  • getChargerClawRange() のキャッシュをマップ切り替えで失効させ、範囲外の値を読んだときはキャッシュしないようにしました。従来は関数内 static に永久キャッシュしていたため、武器スクリプト読み込み前に最初の呼び出しが起きると 70.0 のフォールバックがプロセス終了まで固定されていました。
  • spechud の FillTankInfo を固定長配列に変更し、HUD 描画パスでパネルを組むたびに発生していた new int[MaxClients] のヒープ確保を削除しました。
  • sm_navtest は対象生存者が使えないとき GetTargetAnchorPos にフォールバックするようにし、候補点と自分自身の高さを比べる(高さ点が常に 0 になる)状態を解消しました。あわせて未初期化の targetEye も修正しています。
  • 特感 AI プラグイン 5 本で #include <si_target_limit> の後に #define REQUIRE_PLUGIN を戻し、ai_tank3.sp と揃えました。任意依存はこの 1 行の include だけに限定されます。
  • si_target_limit.inc が l4d_target_override を推移的に include する際、呼び出し側の REQUIRE_PLUGIN 状態を保つようにしました。サードパーティのプラグインに硬依存が黙って追加されることはありません。
  • 扇区システム削除後に infected_control.sp へ残っていた未参照マクロ 5 個を整理し、PEN_LIMIT_SCALE_LO のコメントを訂正しました。
  • .gitignore の重複を整理し、/test_results ですでにカバーされる 9 行の個別パスを削除しました。
  • anne_server_redirect の jp / ko / vi 翻訳を追加し、他の Anne プラグインと同じ六言語カバレッジに揃えました。
  • ドキュメント訂正:README_SPAWN_ARCHITECTURE.md の分散度 2 項目、annehappy_dynamic_ai_difficulty.md の反応時間行・Tank 行・新設の連跳上限 cvar 2 つ、ai_charger3/readme.md で確率突進を説明したままだった 4 箇所。あわせて対比表の Charger 連跳速度も訂正しました(旧記載 45/60/75/90/150、実際の設定は 40/50/60/70/100)。

2026年8月30日 AI の反応時間を全難易度で統一

  • dynamic_ai_difficulty.cfg の z_acquire_far_time / z_acquire_near_time を、簡単〜エキスパートの 4 段階で 5.0 / 0.5 から 0.0 / 0.0 へ変更しました。もともと 0.0 / 0.0 だった極限 / 音理と揃います。ターゲット捕捉の遅延はもう難易度軸ではなく、段階差はすべて職業ごとの挙動 cvar で表現します。
  • 設定のみの変更で再コンパイルは不要です。docs/annehappy_dynamic_ai_difficulty.md の「反応時間」行も同期しました。

2026年8月30日 高SIの生成後排斥を緩和

  • infected_control.smx を 2026-08-30.1 へ更新。高SIではウェーブ後半が「生成後の排斥」で近帯から押し出されていました。核密度がすでに生存者の眼前にいる特感まで占有源にし、しかも特感上限スケールを掛けていませんでした。硬分散のほうは上限に応じて縮むため、緩めるべき高SIでかえって厳しくなっていました。
  • いずれかの生存者から 400 未満の生存特感は核密度源に入れません。特感上限スケールは減点値ではなく核半径(inf_spawn_kernel_radius × 係数)に移しました。低SIでは押し広げ、高SIでは重なり防止だけに効きます。曲線全体が平坦化して分解能を失うことがなくなります。inf_spawn_kernel_points の既定は 30 から 50 へ引き上げました。
  • 扇区による分散軸は一式削除しました(recentSectors、ウェーブ内の扇区クォータ、inf_spawn_sector_quota_bonus)。方向の好みは連続的な戦術ジオメトリ点のみで表現し、分散点は核密度だけになりました。
  • 硬分散は固定半径になり、特感上限にもウェーブ内占有にも連動しません。この判定は「ここに湧いてよいか」だけを答えます。inf_spawn_sep_radius の既定は 120 から 100 へ下げました。ウェーブ時序は変更していません。

2026年8月30日 Charger 銃所持の近距離は先に2撃してから突進

  • ai_charger3 を 1.0.1.9 へ更新。ai_charger3_bhop_min_dist(既定 100)に入った銃所持目標は命中確実とみなし、確率待ちをやめ、突進距離も 36–95 に圧縮しません。
  • 爪撃距離内で2撃する間に目標が逃げ切れない場合は、先に2撃してから突進します。届かない、後退中、または 2.5 秒を超えた場合は即座に突進します。ショットガンは 100 以内で即突進のままです。近接武器との駆け引きは変更していません。
  • 再コンパイル:ai_charger3.smx。

2026年8月30日 トレイター登録のキャンセル対応とトレイター Tank の廃止

  • infected_control.smx を 2026-08-30 へ更新。!itcancel(!neiguicancel と同等)を新設:ウェーブ解放前ならいつでもトレイター登録をキャンセルできます。登録済みの状態で !it を開くとメニューには「登録キャンセル」項目のみ表示されます。キャンセルしたスロットを AI で即時補充することはなくなりました。解放ウィンドウが開いた後(SpawnAllowed)はキャンセルできず、「ウィンドウは閉じられました」と表示します。
  • トレイタークラスから Tank を削除:選択可能クラスは現在のスポーンプールが決めるようになり、Tank は登録できなくなりました。inf_traitor_class_mask の既定値と上限は 127 のままです(bit 64 はロールバック互換のためだけに残しており、実際には効きません)。z_max_player_zombies がトレイター Tank 用に余分なスロットを予約することもなくなりました。
  • 選択可能クラスは現在のスポーンプールとの積集合になりました:inf_*_limit 0 で無効化されたクラスは登録不可、allcharger / allhunter モードではそれぞれ Charger / Hunter のみ登録できます。
  • inf_traitor_max_slots の有効値は l4d_infected_limit - 1 にクランプされ、毎ウェーブ最低 1 つの AI スポーン予算を確保します。トレイターの自動連跳は OnPlayerRunCmd チャンネルへ移行(内部リファクタリング、挙動は同じ)。usage とメニュー文言は六言語の翻訳を同期更新しました。
  • バージョンロールバック設定 Anne26-07 / Anne25-11 / Anne25-10 に smart_ai_rock.smx の読み込みを補いました(従来は unloadall.cfg がアンロードした後、ロールバック版では Tank のスマート投石が失われていました)。

2026年8月30日 Tank 各難易度の連跳上限を引き下げ

  • 動的 AI 難易度の ai_tank3_bhop_max_speed を各段階で 200 引き下げ、上限 800 でクランプ:簡単 500、普通 600、困難 700、専門 800、極限 800(850 が上限に到達);音理段階は 1000 を維持。設定のみの変更(dynamic_ai_difficulty.cfg)で再コンパイル不要;プラグイン既定値(動的難易度を使わない場合)は 1000 のままです。

2026年8月29日 AI 特感 path 連跳「空飛ぶ大ジャンプ」修正

  • path 連跳(バニーホップ)で稀に 1 回のジャンプが異常に遠くへ飛ぶ、空を飛ぶように見える問題を修正しました。根因は 3 つ:ai_spitter_3 / ai_boomer_3 のジャンプ加速が「現在速度への加算」で上限が一切なく、長い直線では毎ジャンプ +100/+150 と雪だるま式に加速していたこと;共有の空中補正が記録したジャンプ速度を滞空中ずっと下限として維持し、壁に当たってエンジンに減速されてもピーク値へ戻していたこと;推進ベクトルに垂直成分が含まれ(Boomer は高所のパス地点へ、Spitter は視線ピッチに沿って)、ジャンプ自体の Z 速度と重なって文字どおり「空飛ぶ」状態になっていたことです。
  • ai_spitter_3 を 3.0.6 へ更新し ai_SpitterBhopMaxSpeed を新設、ai_boomer_3 を 3.0.8 へ更新し ai_BoomerBhopMaxSpeed を新設。加算式の推進は水平速度で上限クランプされ、推進ベクトルは水平成分のみを保持(垂直の高さはジャンプ本体に任せる)、起跳前の安全チェックは実際に適用される速度と同じ速度でトレースします。
  • 両方の新しい上限は「Charger 上限 +200」の規則に従います:プラグイン既定値は 1000(= ai_charger3_bhop_max_speed 既定 800 + 200)、動的 AI 難易度 dynamic_ai_difficulty.cfg の 6 段階には 600 / 600 / 700 / 800 / 1000 / 1000 を設定(Charger の各段階 400 / 400 / 500 / 600 / 800 / 800 に対応)。
  • 共有モジュール ai_path_movement.inc:AIPathMovement_BeginPathHop に最大速度引数を追加。空中補正は各特感自身の連跳上限を超える速度を維持しなくなり、外力によるスパイクも滞空中に保持されません。
  • ai_smoker3 を 1.0.1.3、ai_tank3 を 1.0.0.11 へ更新:起跳フレームも ai_smoker3_bhop_max_speed / ai_tank3_bhop_max_speed でクランプします(従来は空中フレームのみ制限で、起跳の瞬間は超過できました)。ai_charger3 を 1.0.1.8 へ更新。地上/Direct 連跳には元々上限があり、今回その上限を共有空中補正に登録するようにしました。
  • 再コンパイル:ai_smoker3.smx、ai_boomer_3.smx、ai_spitter_3.smx、ai_tank3.smx、ai_charger3.smx。Jockey は元々 1 ジャンプ 400+80 の上限があり、Hunter には連跳ロジックがないため変更不要です。

2026年8月30日 Jockey 突き飛ばし後抑制を AI 難易度別に段階化

  • ai_JockeyShovedCooldown を動的 AI 難易度システムに接続しました。dynamic_ai_difficulty.cfg の 6 段階でそれぞれ、簡単 3.0、ノーマル 2.5、困難 2.0、エキスパート 1.5、極限/音理 1.0 秒です。値は annehappy_dynamic_ai_difficulty.smx が段階ごとに適用し、段階切替時にベースラインへ復元するため残留しません。
  • プラグイン既定値 3.0 は簡単段階と同じ強度なので、動的難易度プラグインを実行しないモードは自動的に最も緩い設定になります。

2026年8月29日 AI Jockey 突き飛ばし後抑制の修正

  • ai_jockey_2.smx を 2026.08.29 へ更新。「Jockey を突き飛ばしたその一撃が逆に懲罰分岐を武装させる」抜け穴を修正:生存者の直近のスイングが Jockey 自身を突き飛ばしたものである場合、「シャブ CD 中に即座に飛びつく」懲罰は発動しません。本当に無駄撃ちしたシャブ(空振り、他の特感への使用)に対する懲罰は従来どおりです。
  • 突き飛ばし後の抑制時間は z_jockey_leap_time(Anne 設定では 0.4 秒)を流用せず、新設の独立 cvar ai_JockeyShovedCooldown(既定 3.0 秒、対戦ルールで突き飛ばされた Jockey に適用される jumpcap ブロック標準時間に一致)で管理します。抑制中はプラグインによる bhop/飛びつき強化を一切行わず、ネイティブ AI の跳躍ボタンも抑止するため、0.9 秒のよろけが終わった瞬間に空中で再飛びつきすることはなくなりました。移動や後退は通常どおり可能です。jumpcap パッチの AI 除外とよろけ関連 cvar は変更していません。

2026年8月28日 Scripted HUD スロットのチーム別表示

  • Scripted HUD を 1.6.0 へ更新。!hudmenu の各スロットに「表示チーム」サブメニューを追加し、生存者/観戦/感染者を任意に組み合わせられます(最低 1 つは選択)。例えば観戦中のみ表示するスロットが作れます。選択は Cookie とデータベースに保存され(scripted_hud_prefs に slot_team_masks 列を追加、自動移行)、既存の設定は全チーム表示のままです。
  • 機密コンテンツソースのチーム許可はハードコードから cvar l4d2_scripted_hud_source_teams へ移行(ソース:チームマスク 形式、ビット 1=観戦 2=生存者 4=感染者)。既定値 2:5,7:5,13:5 は旧動作と同じで、特感体力・次ウェーブカウントダウン・スポーンキューは観戦/感染者のみ。13:1 のように設定すれば観戦専用に絞れます。メニューの「(観戦/特感)」タグは実際の設定から動的に生成され、6 言語の翻訳も追加済みです。
  • チーム制限で非表示のスロットはテキスト自体をクライアントへ送信しなくなりました(従来は描画しないだけで文字列はネットワークを流れていました)。チーム変更時は即座に表示を更新します。

2026年8月29日 コントロール特感の独立ターゲット上限

  • SI_Target_limit.smx を 1.7 へ更新。Smoker / Hunter / Jockey / Charger が共通のロック上限を持ち、計算式は「コントロール特感予算 / 行動可能な生存者 + 1」。予算は有効なコントロール職の z_* / inf_* 上限の合計で、l4d_infected_limit で打ち止め。Boomer / Spitter / Tank はこの枠を使いません。
  • l4d_target_override.smx を 2.26 へ更新し targeted_mask を追加。カウント対象はコントロール特感のみ。先頭フロー ×2 とランナー解除の意味は従来どおりです。
  • Anne 各モードの shared_settings.cfg に SI_enable_option 53 を明示しました。
  • l4d_target_override.smx を 2.27 へ更新:L4D_TargetOverride_SetLastVictim を追加し、L4D2_OnChooseVictim 経由でターゲットを書き換える AI プラグインも同じロック台帳に登録できるようにしました。L4D_OnTargetOverride forward の書き換えが台帳に反映されない問題も修正。
  • SI_Target_limit.smx を 1.8 へ更新:IsClassTargetLimited native と管理者向けデバッグコマンド sm_targetlimit_status を追加。1.7 の更新履歴コメントが早期終端しコンパイルできなかった問題を修正。
  • 特感 AI の台帳統一:ai_hunter_2 / ai_jockey_2 / ai_charger3 はターゲット変更前にコントロール系上限を尊重(新ターゲットが満杯なら変更しない)、ai_spitter_3 / ai_boomer_3 / ai_tank3 は変更後に台帳へ登録。ai_smoker3 はターゲットを書き換えないため対象外です。
  • 人数自動適応:4 人、5〜8 人マルチ、ソロ残局のいずれでも式が自動スケールします。総容量は常に「コントロール系予算 + 行動可能な生存者数」で、場のコントロール特感数を必ず上回ります。生存者が少ない場合は上限が自動的に緩和され、特感が合法ターゲットを失うことはありません。
  • バージョンロールバック設定 Anne25-11 / Anne25-10 / Anne24-5 / Anne23-1 に SI_Target_limit.smx のロードを追加(従来は unloadall.cfg でアンロード後に再ロードされず、ターゲット上限が無効化されていました)。

2026年8月19日 Tank の頭乗りと梯子落下

  • ai_tank3 を 1.0.0.9 へ更新。頭上ブロックを「Tank の衝突体の上に立っている」騎乗と、届かない高台停滞の 2 種類に分けました。
  • 騎乗は 2 秒の停止待ちもブラックリスト切替もしません。パンチ時に騎乗者へ上向き SweepFist を追加し、3 秒経っても頭上ならその場で強制投石します。250 離れる必要はありません。近距離の石は目標へ直接狙い、水平距離が 0 に近いときの弾道除算を避けます。騎乗中はジャンプ投石しません。
  • 高台停滞は従来の 2 秒移動ウィンドウです。他の生存者がいれば切替(立っている → ピン留め → ダウン)。代替がいなければその場で投石し、同じ届かない目標へ CommandABot RESET しません。これが同じ梯子を登って落ちる主因の一つでした。梯子付近でも RESET しません。
  • 梯子上ではピッチを水平に戻し、m_climbableNormal でヨーを梯子へロックして、バニラの「登りながら被害者を見て落ちる」循環を減らします。

2026年8月20日 Tank 頭乗り判定をモデル埋め込みに対応

  • ai_tank3 を 1.0.0.10 へ更新。騎乗の第一証拠は引き続き m_hGroundEntity == Tank で、隣接する高台や階段を騎乗と見なしません。
  • 地面エンティティが Tank でない場合は「水平の衝突投影が重なる + 足元から下向き hull が実際に Tank に当たる」を要求します。モデルに埋まり地面が world のままの騎乗を拾い、壁に当たらない中心レイを証拠にしません。

2026年8月23日 帽子設定の二層永続化

  • l4d_hats.smx を 1.47.0 へ更新。帽子種類、着用、1人称で自分を見る、3人称で自分を見る、他プレイヤーの帽子表示の5項目を clientprefs Cookie に保存し、l4d_hats_save 0 でも読み込みます。
  • rpg.smx を 2.1.0 へ更新。databases.cfg に rpg MySQL がある場合は4つの切り替えを RPG テーブル優先で保存し、MySQLが使えない場合や列移行に失敗した場合は clientprefs SQLite にフォールバックします。既存アカウントの NULL 列は Cookie 準備完了後だけ移行し、既定値による上書きを防ぎます。
  • ラウンドで再作成された帽子にも観戦者別 SetTransmit フィルターを常時設定するため、他人の帽子を隠す設定が維持されます。冪等マイグレーション 20260823_hat_preferences.sql を追加し、プラグインから同じ列を自動追加することもできます。

2026年8月23日 共通サウンドカタログと全イベント自由選択

  • l4d2_hitsound.smx を 2.8.0 へ更新。プリセット内の空でない25参照を実パスで重複排除し、安定ID S01..S22 の22音にしました。プリセット1/3で重複する3音は一度だけ保持し、ダウンロードとプリキャッシュも各音一回です。
  • ヘッドショット、ヒット、キル、ヘッドショットキルの全メニューが同じ共通カタログを表示し、どの音も任意のイベントへ割り当てて即時試聴できます。プリセット9の表示は [頭:S21 中:無 殺:無 爆殺:S22] です。
  • 既存DB/KVの正数プリセット値は移行不要です。新しい共通選択は -1..-127 を使うため4列は符号付き整数である必要があります。リポジトリ既定schemaは対応済みで、20260823_hitsound_sound_catalog.sql は誤って UNSIGNED で作られた表だけを冪等に修正します。

2026年8月23日 ヒットフィードバックの個別音源を再設計

  • l4d2_hitsound.smx を 2.7.0 へ更新。サウンドセットは実在する音だけを適用する「プリセット」になり、空の項目は自動で無効になります。セット 9 はヘッドショット音と専用ヘッドショットキル音だけを有効にし、ヒット/キルを有効とは表示しません。
  • プレイヤーはヘッドショット、ヒット、キル、ヘッドショットキルの音源を個別に選択できます。各メニューは該当音を持つ音源だけを表示し、選択後すぐ試聴します。ヘッドショットキルの 0 は通常ヘッドショット音への追従です。
  • ダメージ前に発火する infected_hurt の致死判定、管理者の単項目無効化が3項目を消す問題、DB初回ロード前の上書き、認証順序、高速連続保存の逆転、動的マスタースイッチを修正。既存DB/KV値はロード時に正規化されます。今回の再設計で列は増えませんが、hitsound_stack_mode / hitsound_headkill が未追加のDBでは、既存の冪等マイグレーション 20260820_hitsound_personal_prefs.sql を一度実行してください。

2026年8月20日 ヒットフィードバックの「チンチン」セットを旧 killsound に近づける

  • l4d2_hitsound.smx を 2.6.0 へ更新。サウンドセットの任意キーは 3 つに整理:headshot_kill(ヘッドショットキル専用音)、stack(同フレーム重ね/まとめ)、apply_special_only(選択時に範囲を書き込む)。キルは死亡イベントで 1 音だけ。再生は常に SNDCHAN_AUTO。火・燃焼弾・DMG_DIRECT・爆発・weapon_id==0 のフィルタは変更しません。
  • サウンドセットはヘッドショット、ヒット、キル、ヘッドショットキルの4項目を一括設定します。ヘッドショットキルは 0..N から個別に選択でき(0=通常のヘッドショット音)、そのIDと再生モードを RPG テーブルに保存し、旧 SoundSelect.txt から一度だけ移行します。重複するオーバーレイクイックトグルと sm_hitui は削除し、アイコンセット0を無効化に使います。
  • セット 9「元のチン投票プラグイン」:ヘッドショット命中はチン、ヘッドショットキルはベル、それ以外は無音。選択すると範囲を全感染者にします。

2026年8月19日 Scripted HUD が生存者向け「特感数/間隔」を復帰

  • Scripted HUD を 1.5.1 へ更新。1.4.2 は HUD2 の「特殊感染者数/間隔」を、特殊感染者HP・次ウェーブ秒数・スポーンキューと同じ観戦/感染者向け情報として隠していました。[N特M秒] はホスト名と同じ公開ルーム設定であり、場の情報ではありません。生存者にも再表示し、内蔵 CS キルフィードと共存します。キルフィードは引き続きそのプレイヤーのエンジンスロット 8–14 だけを使います。
  • 特殊感染者HP、次ウェーブ秒数、次ウェーブキューは観戦/感染者のみのままです。

2026年8月19日 低体力・医療キットなしで Anti-Bait を停止

  • infected_control.smx を 2026-08-19.1 へ更新。立っている生存者の実体力が全員 inf_antibait_lowhp(既定 40)未満で、生存者(ダウン含む)が医療キット/除細動器/痛み止め/アドレナリンを誰も持っていないとき、Anti-Bait 全体を Paused にします。ダウン体力は実体力ではありません。閾値 0 で無効化できます。

2026年8月15日 死体溶解投票を削除

  • 各モードメニューから「死体を溶解」の投票を削除し、cfg/vote/dissolve_on.cfg と cfg/vote/dissolve_off.cfg も削除しました。

2026年8月15日 Scripted HUD に CS キル HUD を統合

  • Scripted HUD を 1.5.0 へ更新しました。独立した l4d2_cs_kill_hud.smx と旧キル HUD 投票を削除し、CS 風キルフィードを内蔵しました。各プレイヤーは既定で無効で、!hudmenu から個別に切り替えられます。サーバー全体の有効化 CVar は使いません。
  • 有効にしたプレイヤーにだけ SendProxy でエンジンスロット 8–14(メニュー上は HUD 9–15)を上書きし、そのプレイヤーの設定メニューから隠します。無効のプレイヤーは標準キル一覧を透過し、自分のスロット設定を保持します。
  • !hudmenu を CS キルフィード、基本 HUD(1–4)、追加 HUD(5–8)、拡張 HUD(9–15)、画面レイアウト、HUD 2 項目のグループ構成に整理しました。キルフィードとスロット設定はプレイヤーごとに保存されます。

2026年8月15日 Scripted HUD の次ウェーブ状態を修正

  • infected_control.smx を 2026-08-15.2 へ更新し、撃破フェーズ、独立した基礎カウントダウン、Anti-Bait ホールドを区別するウェーブ状態 native を追加しました。従来の ETA native との互換性は維持します。
  • Scripted HUD を 1.4.4 へ更新。正確な秒数は基礎カウントダウン中だけ表示し、撃破フェーズと Anti-Bait ホールドは明確な多言語状態を表示します。状態 API がない 2026-07 以前では、約8秒ずれる推定値の代わりに -- を表示します。

2026年8月15日 新規プレイヤーのトレイター状態残留を修正

  • infected_control.smx を 2026-08-15.1 へ更新。プレイヤーがサーバーへ入る際、使用する client slot のトレイター登録を明示的に消去します。前の利用者の切断処理が完了していなくても、新規プレイヤーは非トレイターとして開始し、感染者チームへ誤って割り当てられた場合は join.smx が観戦へ戻せます。その後の通常のトレイター登録には影響しません。

2026年8月15日 Actions クラッシュ修正

  • actions.ext が Action 破棄時に存在しない user-data キーを再挿入し、3組の Action ポインタキャッシュを削除しない問題を修正しました。Linux 拡張は 3.7.6-anne.2 となり、破棄時に user-data、identity-data、actor キャッシュを削除します。
  • リスナーが存在しない場合でも Action ごとに空の pre/post リスナーハッシュを作成し、破棄後も外側の Action ポインタキーを保持していた問題を修正しました。候補 Action の pending マーカーも削除します。
  • ai_charger3 を 1.0.1.7 に更新しました。ChargerEvade の CommandABot(MOVE) は次フレームへ遅延し、Actions の OnUpdate コールバック内で NextBot 行動ツリーを同期的に再構築しません。

2026年8月14日 プレイヤー向けテキストの六言語揃え

  • !xx 状態行の末尾を「バージョン」に変更し、「電信回線」との誤記をやめました。英語の Tank stall / HP return と、日本語のエキスパート・連続ジャンプも源码の意味に合わせています。
  • トレイターと Anti-Bait の提示は、停滞(キャンプ)、ホールド中、ウェーブ解放を分けます。日/韓/越の英語残りを補い、トレイター訳名を統一しました。
  • 既定の Scripted HUD 生存者状態はクライアント言語で組み立て、見出しを「蘇生回数」にしました。
  • 白黒 Hint はフレーズ化し、次のダウンで即死と明記。!ht メニューに日/韓/越を追加。技能告知の中国語クラス名をトレイター/統計と揃えました。

2026年8月14日 ネットワーク品質レポートはロス優先

  • network_quality_hint.smx を 1.1.5 へ更新。ウェブサイトの異常イベントはパケットロスを優先します。choke が nqh_report_choke_limit(既定 20%)以下なら異常として報告しません。ゲーム内チャット警告は引き続き nqh_choke_limit(既定 5%)を使います。
  • 異常理由:タイムアウトは timing_out。それ以外は loss を優先し、次に ping、しきい値を超えた choke です。

2026年8月13日 スポーン分散と職業多様性

  • infected_control.smx を 2026-08-13.11 へ更新。Hunter / Jockey / Charger の後方生成をもう一段締めます。ハード拒否 -5→-4(inf_score_behind_reject_gap_hjc)、後方減点倍率 2.0→2.5、Flow 後アンカー -4/-3。Hunter の rear は 0.15→0.05、Jockey は rear を使いません。同じ進捗の候補は引き続き採点します。Smoker / Spitter / Boomer とウェーブ時序は変わりません。
  • infected_control.smx を 2026-08-13.10 へ更新。Hunter / Jockey / Charger が生存者後方に出る確率をさらに下げます。この3種の後方ハード拒否は全局の -8 から -5(inf_score_behind_reject_gap_hjc)へ、後方減点は inf_score_behind_hjc_scale(既定 2.0)倍。Flow 後アンカーは -10/-9 から -5/-4 へ。同じ進捗の候補は引き続き採点します。Hunter の戦術品質は rear を減らし側面/端を優先、Jockey の rear 比重は 0.15→0.05。Smoker / Spitter / Boomer の全局後方ルールは変更しません。ウェーブ時序は変わりません。
  • infected_control.smx を 2026-08-13.9 へ更新。ハード分散をもう一段緩めます。inf_spawn_sep_radius 150→120、inf_spawn_sep_ttl 2.5→1.5。同一 Nav クールダウン NAV_CD_SECS は 1.0 秒のまま。ウェーブ時序は変わりません。
  • infected_control.smx を 2026-08-13.8 へ更新。Hunter の飛びつき準備距離を少し外へ。優先帯を 350–750 から 350–850 へ、甘口を環の 38%(約 500)から 48%(約 590)へ。中距離のまま、旧 950 の遠点には戻しません。Charger / Jockey は変更なし。ウェーブ時序は変わりません。
  • infected_control.smx を 2026-08-13.7 へ更新。Charger / Jockey / Hunter が遠すぎる地点に落ちやすい問題を抑えます。Hunter の優先帯を 350–950 から 350–750 へ縮め、距離の甘口を環の 45% から 38%(約 500)へ、高所ソート 0.90→0.95、高所距離補償 800→450 とし、遠い高台を「中距離」に換算しにくくします。Jockey は 250–550、Charger は 250–600、甘口をやや手前へ。分散ウェイトは 1.15/1.00→0.75/0.65。全体のハード分散半径 180→150、カーネル 40→30、採点枠は近/中/遠 6/4/2 から 6/5/1。ウェーブ時序は変わりません。
  • infected_control.smx を 2026-08-13.6 へ更新。距離帯を 10 段階から 6 段階 に戻します(stage 0 は優先帯のまま、stage 1–5 は優先上限と最終上限の間を線形補間)。10 段階では 1 環が数百単位しかなく近/中/遠を分ける意味が薄く、6 段階の方が三分位に距離の意味が出ます。近/中/遠は現在ページの min/max ではなく、現在帯の検索環(scanMin..maxRange)を三等分します。セクター配分は前 2/3(0–3)のみ制限、後ろ 1/3(4–5)は対象外。ウェーブ時序は変わりません。
  • infected_control.smx を 2026-08-13.5 へ更新。採点枠は「この tick で先に合格した 8 点」ではなく、現在の候補ページを経路距離の三分位に分け 近 6 / 中 4 / 遠 2(合計 12)で採点します。消費順は 3:2:1、枠が埋まった三分位は高コストの可視/経路判定を飛ばし、空き枠は他の三分位へ溢れさせて出特を遅らせません。inf_spawn_nav_expensive_per_slice の既定は 24(旧 16)。CVar:inf_spawn_budget_near/mid/far(すべて 0 で三分位オフ)。ranked 高所チャンネルはグループ内順を保ち、三分位の入れ替えのみ行います。ウェーブ時序は変わりません。
  • infected_control.smx を 2026-08-13.4 へ更新。1 ウェーブの特殊感染者が狭い一角に固まる問題に対して分散処理を作り直し、職業構成に制御されたランダム性を導入しました。ウェーブ時序契約(キルフェーズ、独立した 16 秒基礎カウントダウン、Anti-Bait)は変わりません。
  • 距離帯を 6 段階から 10 段階へ細分化:各職業の優先帯(stage 0、例 Smoker 500–1200)は分割せず維持し、スポーンが平均的に近くならないようにしています。失敗時の拡張は優先上限と最終上限の間を線形補間(Smoker は 1 段階ごとに +200、最大 3000)し、1 回の昇段で走査する環が小さくなり距離の上昇がより滑らかになり、1 つの環がシャッフル済みの 1 ページに収まりやすくなります。セクター配分は前 2/3 の帯のみ制限し、後ろ 1/3 は対象外に変更しました。
  • 有向候補ページの取得後にページ内シャッフル(inf_spawn_candidate_shuffle、既定オン):旧実装は経路距離の昇順で候補を消費し、1 回の試行で最大 8 個の合格点しか受け付けないため、常に「最も近い一塊」からしか選べませんでした。シャッフル後は採点対象が距離帯全体に広がります。ranked 高所チャンネルは並び順の利点を保つためシャッフルしません。
  • ハード分散を CVar 化して強化:inf_spawn_sep_radius(既定 180、旧ハードコード 80)と inf_spawn_sep_ttl(既定 2.5 秒、旧 0.5 秒)。特殊上限によるスケーリングは維持。
  • 分散スコアに連続カーネル減点を追加:生存中の特殊感染者と直近スポーン地点に対して exp(-d/r) を累積して減点(inf_spawn_kernel_radius 既定 280、inf_spawn_kernel_points 既定 40)。「直近 3 セクターだけ覚える」粗い記憶を補完し、セクター減点は維持します。
  • ウェーブ内セクター配分を新設:1 ウェーブ・1 セクターの着地数 ≤ ceil(特殊上限/セクター数)+inf_spawn_sector_quota_bonus(既定 +1、-1 で無効)。制約は近い 4 つの距離帯のみで、遠帯とディレクター代替は対象外のため、細長いマップでもスポーンが止まりません。
  • 高所優先は拡張の ranked 有向候補へ移行:inf_nav_high_sort_scale を再有効化(新既定 Smoker 0.85 / Hunter 0.90)。ターゲットより inf_nav_high_sort_min_height(既定 64)以上高い候補は割引距離で前倒しされ、限られた採点枠に入ります。地面近くの塊の中で事後加点に頼る必要がなくなりました。
  • 職業多様性:職業選択の希少度に ±inf_class_scarcity_jitter(既定 0.06)の小さなランダム揺らぎを加え、占有率が近い職業間の固定ローテーションを崩します。支援ゲート(Boomer/Spitter は圧制職の後)はウェーブごとに確率 inf_support_gate_waive_prob(既定 0.15)で緩和。Breach ウェーブは緩和しません。
  • [SCORE-CHOSEN] デバッグログと sm_navdebug の採点内訳にカーネル項(kern)を追加。

2026年8月13日 Scripted HUD 15 スロット開放

  • extend/l4d2_scripted_hud.smx を 1.4.0 へ更新。EMS の 15 スロットすべてを !hudmenu →「HUDスロット15個すべて」で表示内容に割り当て可能(サーバー既定 / 未使用 / 生存者状態 / SI HP / キル / Ping / Tank ダメージ / チームアイテム / 次ウェーブ / 速度 / ラウンド時間 / Witch 警告 / 進行タンクWitch / サーバー状態)。
  • HUD 1–4 の既定動作は維持。スロット 5–8(エンジン 4–7)は選ぶまで非表示で、選ぶと左列に出る。スロット 9–15(エンジン 8–14)は既定でエンジンのキル一覧を透過し、内容を割り当てたときだけそのキル行を上書きして右下へ移す(クロスヘアを避けます)。
  • 設定は Cookie と scripted_hud_prefs に保存(hud_mask を smallint へ拡張、slot_sources 追加。旧 6 フィールド Cookie と hud3/hud4 列は引き続き読める)。メニューとスロット名は 6 言語。
  • 1.4.1:スロット座標を画面比に合わせて配置。!hudmenu →「画面レイアウト」で 16:9 / 16:10 / 4:3 / 21:9 を選択。追加スロットは左列 4–9・右列 10–14 で、HUD1–4・キルフィード・クロスヘア・武器欄を避ける間隔。4:3 は右端切れ防止、21:9 は中央の 16:9 安全領域へ。SendProxy でプレイヤーごとに適用。
  • 1.4.2:特感 HP・次ウェーブ倒計時・次ウェーブ隊列、および HUD2 の「特感数/間隔」は観戦と特感だけに表示し、生存者はそのスロット全体を隠す。メニューは「(観戦/特感)」と注記。新内容「次ウェーブ隊列」は infected_control の InfectedControl_GetSpawnQueue を読む(旧プラグインは --)。同じ列の追加スロットは実行数で下に積み、追加スロットは最大 4 行、HUD3/4 は最大 6 行で長文の重なりを防ぐ。

2026年8月13日 Scripted HUD 追加コンテンツ

  • extend/l4d2_scripted_hud.smx を 1.3.0 へ更新。HUD 3 / HUD 4 の表示内容に 6 項目を追加し、スロットごとに選んで Cookie/データベースへ保存できます。
  • Tank ダメージ:この Tank 戦の与ダメージ上位 4 人(割合付き)。撃破後も次の Tank まで残し、不在時は「Tank なし」。
  • チームアイテム:生存者ごとに投擲/回復/一時アイテムを圧縮表示。
  • 次の特殊感染:infected_control の GetNextSpawnTime を読み取り(未ロード時は --)、場の小型 SI 数/上限も表示。
  • 速度/連跳:自分(観戦中は視点先)の水平速度と今回の連跳ピーク。接地して歩き始めて約 0.25 秒でピークをリセット。
  • ラウンド時間+ホード:round_start からの mm:ss。create_panic_event の 60 秒窓では「発生中」、それ以外はディレクターのホード倒計時。
  • Witch 距離警告:最も近い Witch のメートル距離と状態(静/近/警戒/激怒)。15 m 以内は「近」。複数体は残り数を併記。新フレーズは 6 言語。

2026年8月13日 Scripted HUD カスタムスロットと白枠対策

  • extend/l4d2_scripted_hud.smx を 1.2.0 へ更新。HUD 3 / HUD 4 でプレイヤーが表示内容を選べるようになり、!hudmenu に「HUD 3/4 表示内容」サブメニューを追加(サーバー既定 / 生存者状態 / 特殊感染者のHP / キル統計 / プレイヤーのPing)。選択は Cookie と scripted_hud_prefs データベースに保存され(旧テーブルは自動で ALTER 移行)、サーバーをまたいで保持されます。
  • 特殊感染者HPページは生存 SI 数/上限、各小型 SI の現在HP、Tank の現在/最大HP、Witch 数を表示。キル統計は生存者ごとのラウンド内 SI/雑魚キルを集計し、Ping ページは人間プレイヤーの遅延を一覧します(生存者優先)。文言はすべて翻訳フレーズ(簡中/繁中/英/日/韓/越)です。
  • hudmenu 周りで時々出ていた「白い縁取りの空の長方形」への対策:あれは EMS スクリプト HUD スロットが一時的に「可視だが NOBG/TEXT なし」のフラグ状態で描いた空の背景パネルです。クライアント別フラグをサーバーの正規フラグから再構築するようにし、ResetHUD のリフレッシュ窓でフラグ 0 が配信されることをなくしました。加えて両 HUD プラグインが使わない EMS スロット 4-7 をマップ開始時に明示的に非表示へ。
  • パネルの高さをクライアントごとの実際の行数で個別化(m_fScriptedHUDHeight の sendproxy を追加)し、複数行のカスタム内容が切れなくなりました。l4d2_scripted_hud_hud3_team の既定値を 2(感染者のみ)から 0(全員)へ変更し、生存者が選んだ HUD 3 の内容が実際に見えるようにしました。
  • HUD 2 に「全滅回数」フィールドを追加:server.smx が公開する anne_round_wipe_count(現在マップの全滅数、マップ移動でリセット)を読み取り、1 回以上全滅すると HUD 2 の末尾に [全滅xN] を表示します。HUD のみで、部屋名には書き込みません。!hudmenu →「HUD 2 表示フィールド」で個別に切り替え可能。HUD 2 設定を保存済みのプレイヤーは既定でオフのため一度オンにする必要があり、新規プレイヤーは既定でオンです。

2026年8月13日 server_name の AI 難度タグ残留

  • server_name.smx を 1.4.8 へ更新。[AI:専門家] のような部屋名タグは、annehappy_dynamic_ai_difficulty.smx が実際にロードされ、かつ档位が決まっているときだけ表示します。
  • 動的難度プラグインをアンロードしても SourceMod は ah_ai_dynamic_current_level を残します。旧処理は残留した 1-6 档を hostname / sn_main_name へ書き続けていました。いまはプラグインが動作中かを確認し、すでに部屋名へ書き込まれた [AI:...] も取り除きます。
  • annehappy_dynamic_ai_difficulty.smx を 2026.08.13.1 へ更新。annehappy_dynamic_ai_difficulty ライブラリを登録し、アンロード時に current_level / current_mode / current_ppm / current_locked を 0 に戻します。HUD、!xx、スポーン戦略が古い档位を読み続けないようにします。

2026年8月13日 水中減速チャット翻訳

  • l4d2_slowdown_control の Tank 出現中/撃破後の水中減速チャットを修正。英語の中国語直訳(「tank generation」など)、ベトナム語の Tank を「xe tăng」と誤訳する問題、日本語のプラグイン名の不一致を解消しました。
  • 簡体中文、繁体中文、英語、日本語、韓国語、ベトナム語を上流の意味に揃えました。Tank 出現中は水中減速が弱まり、Tank がいなくなると通常に戻ります。

2026年8月13日 Anne Tank 出現通知の翻訳

  • optional/AnneHappy/l4d2_tank_announce.smx を 1.0.1.1 へ更新。チャット、Hint、中央文字をすべて i18n 化し、プレイヤー/AI 接頭辞はクライアント言語で組み立てるため、英語プレイヤーに中国語の「(玩家)」が出なくなりました。
  • 英語の中国語直訳(「has been generated / controller」)をやめ、Hint フレーズを追加。スペイン語に欠けていた Anne 専用キーも補いました。
  • 対戦版 Spawned の日/韓/越/繁中の表現も揃え、Tank は固有名詞のままにしています。

2026年8月13日 l4d_stats チャット i18n

  • l4d_stats.smx を 1.5.6 へ更新。チャットに残っていたハードコード英語を翻訳フレーズへ移し、簡中/繁中/英/日/韓/越の 315 フレーズを揃えました。言語別ファイルは地図記録の 13 件だけではありません。
  • 特殊感染者キル、Smoker/Hunter 救助、Charger 救助、Tank 岩ヒットの告知は閲覧者の言語でクラス名を出します。人間プレイヤーはニックネームのままです。
  • マップ記録のチーム名フォールバックとコンソール [RANK] 接頭辞も翻訳します。global_chat.smx を 1.1.1 へ更新し、全サーバーのマップ記録放送も同じチーム名翻訳を使います。

2026年8月13日 Survivor MVP 翻訳

  • survivor_mvp.smx を 0.3.4 へ更新。ラウンド MVP/LVP、個人順位、BOT 接頭辞の中国語ハードコードをやめ、クライアント言語で出力します。英語プレイヤーに「特感/小僵尸/友伤/[机器人]」が出なくなりました。
  • 日/韓/越で「特感・黒槍・薬役」を「特殊感覚・黒い銃・医薬品」と誤訳していた問題を修正し、スペイン語に欠けていた Tag と Anne 簡易統計キーを補いました。

2026年8月13日 text プラグイン状態表示の翻訳

  • optional/AnneHappy/text.smx の !xx / 入室 / ラウンド開始の状態行をクライアント言語で出すようにし、英語プレイヤーに「特感、連跳、動態難度、回血」などの中国語ハードコードが出なくなりました。
  • 英語の「does not exceed 10 special」直訳をやめ、日本語で AnneHappy を「アンハッピー」と誤訳していた問題も修正しました。

2026年8月13日 全員初心者チームボーナス

  • l4d_stats.smx を 1.5.6 へ更新。場の人間生存者が全員初心者で 4 人以上のとき、全員が 1.5 倍の新人チームボーナスを受け取ります。従来は「初心者本人には倍率なし」のため誰も受け取れませんでした。
  • 初心者が 1~3 人のときは従来どおり、経験者だけが 1.1 / 1.3 / 1.5 を受け取ります。
  • l4d_stats_newbie_bonus_all_newbie_multiplier(既定 1.5)と l4d_stats_newbie_bonus_all_newbie_min(既定 4)を追加。セーフルーム、フィナーレ、ラウンド開始のチャットは各言語でチームボーナスを説明します。

2026年8月13日 帽子/スキン保存修正

  • l4d_hats.smx を 1.46.1 へ更新:Hats_SetClientHat / Hats_GetClientHat native を追加し、RPG は sm_hatclient コンソールコマンドを使わずに帽子を復元できます。
  • 帽子を外したとき L4D_OnHatLoadSave は -1 を返すようになり、最初の帽子の 0 番インデックスと衝突しません。Cookie 削除と自動装着は帽子メニュー権限(上位 100 を含む)に合わせ、ランキングキャッシュ待ちで保存済み帽子を消さないようにしました。
  • rpg.smx を 2.0.1 へ更新:データベース読み込み完了後に帽子・スキン・輪郭を再適用し、ランキング未準備のまま帽子/スキンを 0 にクリアしなくなりました。
  • 最初の帽子は -2 で保存し、HAT=0 が「未装着」と「1 番目の帽子」の両方を意味しないようにしました。旧データの読み込み前に帽子を選んでも上書きされません。
  • スキンにも同じ「非同期 DB 読み込み後に復元されない / ランキング未準備でクリアされる」問題があり、まとめて修正しました。称号、反動、ダメージ HUD、ヒット音は各自の読み込み完了コールバックまたは独立した Cookie/DB で復元しており、同様の穴はありません。

2026年8月13日 ネットワーク品質レポート

  • network_quality_hint.smx を 1.1.4 へ更新。プラグインの ConVar 既定値は引き続き nqh_report_enable "0" で、ローカルの ping/loss/choke 検出はレポートに依存しません。本リポジトリはウェブサイトのホワイトリスト内 Anne ゲームサーバー向けに cfg/sourcemod/network_quality_hint.cfg で nqh_report_enable "1" を明示します。
  • レポートには SteamWorks が必要です。SteamWorks が無い場合でもプラグインはロードされローカル通知は出ますが、nqh_report_url へは送信しません。
  • ウェブサイトのホワイトリスト外のコミュニティサーバーは nqh_report_enable "0" のままにしてください。

2026年8月13日 ヒットフィードバック音セットのカスタマイズ

  • l4d2_hitsound.smx の音セットに「いつ鳴るか」を定義する 2 つのオプションキーを追加:headshot_kill はヘッドショットキル専用の音を指定(空 = headshot 音へフォールバック、従来動作)。stack はそのセットのヒット/キルイベントを毎回即座に個別再生するか(同フレームで重ねられるか)を制御します。stack の既定値は 1(スタック)で、明示的に stack 0 と書いた場合のみ「1 フレーム 1 音、キル>ヘッドショット>ヒット」の優先度マージが有効になります。
  • セット 9「元の叮投票プラグイン」はこれで旧 killsound(Dingshot)の手触りを再現:ヘッドショット命中=チン(littlereward)、ヘッドショットキル=ベル(bell_normal)、非ヘッドショットの命中/キルは無音。ショットガンの複数キルはキルごとに鳴る挙動に戻ります。
  • !snd メインメニューに全プレイヤー向けの個人再生設定を 2 つ追加(サーバーごとの KV ファイルに保存、データベースには入れません):「ヘッドショットキル専用音 オン/オフ」(オフ = 通常のヘッドショット音にフォールバック)と、3 状態の「効果音再生モード」(セットに従う / 強制スタック / 強制マージ)。切替時の応答は各モードの意味を説明する翻訳フレーズ(簡中/繁中/英/日/韓/越の 5 フレーズを追加)を使います。

2026年8月13日 AI3 プラグイン監査修正

  • ai_tank3 を 1.0.0.8 へ更新:OnPlayerRunCmd が各サブロジックの戻り値を集約して返すようになり、投石距離制限、頭上ブロック対策の強制投石、連続ジャンプのキー変更がエンジンに捨てられる問題を修正しました。パンチ視点ロックは GameTime 時計に統一し、投石の出手高さはアニメーション活動名から解決し、tank_swing_range の変更フックはマップ切替ごとに重複登録されなくなりました。
  • ai_charger3 を 1.0.1.6 へ更新:状態機械 transitionTo が旧状態の OnExit を実行しなかった問題を修正(静的構造体を読み込む前に判定していた)。空中急停止、後跳、人為的な突進遅延フラグが状態切替時に正しくリセットされます。player_spawn は Post フックになり、梯子上でジャンプ/しゃがみ入力を消した後は正しく Plugin_Changed を返します。
  • ai_boomer_3 を 3.0.6 へ更新:L4D_OnVomitedUpon が attacker を検証し、胆汁弾などで attacker が 0 のたびにエラーが出る問題を修正。既存の転噴キューがあるときは再構築せず、強制胆汁の再帰による目標重複膨張を防ぎます。被害者選択の早期 return での trace ハンドル漏れと、強制胆汁ループの誤インデックスも修正。最近の生存者検索は 0.2 秒キャッシュして毎フレームのソート負荷を下げます。
  • ai_spitter_3 を 3.0.4 へ更新:人混み目標がピン留め対象の座標を誤用していたコピーペースト(-1 インデックスエラー含む)を修正。getTargetByPriority がピン留め中または生存者 1 人のときに ArrayList を漏らす問題を修正。生存者が 1 人でも flow で選べるようにし、群衆距離累積セルを明示的にゼロ初期化し、常に偽になるレイフィルタの死コードを削除しました。
  • レイコスト最適化:ai_path_movement.inc にジャンプ経路失敗のスロットルを追加。地形(壁、段差、危険な着地点)で失敗した安全確認は 0.1 秒冷却中に再試行しません。4 つの AI の地上ジャンプ試行がこれを使い、地形に引っかかっているときの hull/ray trace コストを約 1/6(60 tick)に下げます。AIPathMovement_IsJumpRouteSafe はレイ不要の無視界角度拒否を hull trace より前に移し、拒否された試行は一切トレースを出しません。

2026年8月13日 infected_control 監査修正

  • infected_control.smx を 2026-08-13.2 へ更新し、全体コード監査で見つかったカウント・状態の問題を修正しました。ウェーブ時系列の契約(キルフェーズ、独立した 16 秒基礎カウントダウン、上限なしの Anti-Bait ホールド)の挙動は変わりません。
  • 特殊感染者の生存数二重カウントを修正:RecalcSiCapFromAlive などの全体再集計はキックキュー内の一時的なクライアントをスキップするようになり、テレポートキック中に職業/合計上限が先に埋まってウェーブ判断が歪む問題を防ぎます。
  • 動的 Nav トポロジー(エレベーター等)再構築後に進捗エクスポートが失敗すると、スポーン探索が永遠に Pending のまま止まるデッドロックを修正:待機フラグを解除して旧 Flow バケットへフォールバックし、ディレクター代替も復旧します。
  • マップ間のキャッシュ汚染を修正:生存者進捗のフォールバック値とバケット別生存特感カウントのキャッシュをラウンド/マップ切替時にリセットし、新マップで GetGameTime が戻っても前マップのデータを使い続けないようにしました。バケット構築のたびに漏れていた 2 つの ArrayList ハンドルも解放します。
  • Nav バケットのディスクキャッシュを堅牢化:メタデータは一致しても有効な区域が 1 つもない破損キャッシュは削除して再構築し、エクスポート失敗時は書きかけのファイルを残さず削除します。
  • テレポート監視の 2 つの問題を修正:出生時刻が不明な場合を永続的な出生猶予として扱わなくなり(ウォッチドッグのハード復旧後に引き継いだ特感へ出生時刻を再付与し、正常にテレポートできます)、Smoker は能力クールダウン中も不可視カウントを蓄積し、準備完了後に秒数を貯め直す必要がなくなりました。
  • GetNextSpawnTime native はキルフェーズ中に「残り確認ウィンドウ + 完全な基礎カウントダウン」の上限見積もりを返し、ポーズ中も凍結した時計で見積もりを続け、キルフェーズの時間を基礎カウントダウンに算入しません。
  • Anti-Bait 状態機の再設計:散開によるホールド解除は継続確認が必要になりました。新しい inf_antibait_spread_confirm(既定 3 秒)の間、隊形が連続して散開し続けない限り Pressure は降格しません。「少し離れてすぐ戻る」フェイクではホールドを騙せず、散開は停滞タイマーもリセットしません。武装ウィンドウ内で再集結し依然停滞しているチームは、同一ホールドの継続として直接 Pressure に復帰します。
  • Anti-Bait 進行度スナップショットの分離:生存者の flow 読み取り失敗(エレベーター、不正 Nav)を「脆弱メンバー」として扱わなくなり、ホールドを誤って阻止/解除しません。該当メンバーは隊形統計には通常どおり参加し、進行度統計からのみ除外されます。flow が回復したら基線を再構築しますが、停滞タイマーはリセットしません。
  • 内通者(Traitor)の実体化は totalSI 上限の制限を受けなくなりました。放出ウェーブが到来した SpawnAllowed 状態の内通者(枠は開波時にそのウェーブの AI 予算から控除済み)は、残存 AI が一時的に上限を埋めていても実体化できます。超過中は AI の補充が自動的に停止します。
  • create_panic_event は 60 秒のローリングウィンドウになりました。新しい panic イベントを受け取るたびに更新し、panic_event_finished で即座にクリアします。終了イベントを送らないカスタムマップが Anti-Bait をラウンド全体で静かにバイパスするのを防ぎ、連続/無限ホードスクリプトはウィンドウを更新し続けるため影響を受けません。
  • sm_wavestatus と Nav デバッグコマンドの応答が翻訳フレーズ(簡中/繁中/英/日/韓/越の 12 フレーズを追加)を使うようになり、中国語のハードコードを廃止しました。
  • 早期カウントダウン開始の「生存者が健康 + Tank なし」という慈悲ゲートは意図的な設計であることを確認し、AGENTS.md の行動契約に記載しました(散開確認と内通者免除の仕様も併記)。

2026年8月10日 Boomer/Spitter Path Follow 連続ジャンプ

  • ネイティブ拡張 anne_nextbot を 1.3.0 へ更新しました。唯一の PathFollower::Update detour として、上限付きの経路ノード値をネイティブ側で直接コピーします。Tank、Charger、Boomer、Spitter は native 経由でスナップショットを読み取り、SourcePawn は PathFollower/PathSegment ポインタを受け取らず、読み取りもしません。共通の経路シグネチャと仮想関数オフセットは anne_nextbot.games.txt に集約しました。
  • Tank ai_tank3 を 1.0.0.4、Charger ai_charger3 を 1.0.1.4 に更新し、既存の Path Follow 連続ジャンプを同じ native スナップショットへ移行しました。各 gamedata には爪攻撃、突進、locomotion など固有の呼び出しだけを残し、共通 PathFollower 定義の重複を削除しました。
  • Boomer を ai_boomer_3.smx 3.0.4、Spitter を ai_spitter_3.smx 3.0.2 へ更新しました。連続ジャンプは有効な経路先読み地点を優先し、経路が古い、遮られている、または前方に登り・隙間ジャンプなどの特殊移動がある場合は従来の AI/直線動作へ戻ります。
  • 4 つの AI は、滞空時間予測、壁・着地点・局所的な段差の安全確認、段階的な空中速度補正を ai_path_movement.inc で共有します。Charger 固有の突進、再経路探索、横方向の駆け引きは従来どおり状態機械が担当します。
  • Boomer は一時的に直接視認できない曲がり角でも、有効な PathFollower 経路があれば接近を続けます。26-07 AI2 の吐しゃ角度修正も維持しています。
  • 現行 2026-08 の AnneHappy、Hardcore、Shotgun は AI3 を読み込みます。Anne26-07.cfg は未変更の ai_boomer_2.smx と ai_spitter_2.smx を引き続き読み込み、26-07 ロールバック版として保持します。

2026年7月26日 マップ記録 v2

  • l4d_stats.smx に汎用 ruleset_key、ルールセットバージョン、記録ポリシー、計時/難易度プロファイルを追加しました。Anne 系はベストタイムランキングを維持し、Co-op/Survival はルールごとに分離し、Versus、Realism Versus、Scavenge は最速比較ではなくラウンド履歴として保存します。
  • map_runs、map_run_players、legacy_map_bests と、再実行可能な移行/ロールバックスクリプトを追加しました。旧 timedmaps/timedmap_runs は保持し、旧版のプレイヤー別ベストと実際のランを分けて扱います。
  • NewAnneWeb のプレイヤーページ、マップ一覧、詳細ページを v2 に対応し、ルール、バージョン、難易度/AI レベル、チーム人数、Anne スポーン設定で絞り込めます。導入手順は docs/map_records_v2_migration.md を参照してください。

2026年7月23日 FastDL マップ切り替え安定性修正

  • l4d2_blackscreen_fix.smx から非公開エンジン関数 CNetworkStringTable::DeleteAllStrings() の呼び出しを削除し、マップ読み込み中に downloadables テーブルを消去してサーバーがクラッシュまたは watchdog により再起動される可能性をなくしました。
  • ダウンロード配信を追加専用に変更しました。各マップでは優先フィードバック素材のみを追加し、実際のマップ切り替え時に SourceMod 公開 API AddFileToDownloadsTable() で 3 個のダンスモデルとランダムな曲グループ 1 組を追加します。文字列テーブルの削除、上書き、復元は行いません。
  • fornite_l4d.smx は従来の全ダンス素材ダウンロード登録を、新しい既定無効の sm_emotes_add_downloads スイッチの内側に保持します。このサーバーではグローバルに読み込まれる l4d2_blackscreen_fix.smx が段階的ダウンロードを管理し、他のサーバーではスイッチを有効にすると従来の一括ダウンロードへ戻せます。

2026年7月22日 動的難度 PPM 修正

  • 自動難度が round_start の時点でチーム PPM を早くロックしすぎ、その後観戦へ移ったプレイヤーが当該ラウンドの難度計算に残る問題を修正しました。
  • ラウンド開始時の難度は暫定値となります。セーフルーム内で生存者メンバーが変わると暫定 PPM を無効化し、最初の生存者が退出した時点で生存者チームに残っている実プレイヤーだけを再計算してロックします。観戦者と Bot は対象外です。

2026年7月16日 新規プレイヤーのダウンロード最適化

  • l4d2_blackscreen_fix.smx の FastDL 配信を再構成しました。初回接続では命中フィードバック用アイコンとゲーム内蔵ではないフィードバック音を優先し、ダンス素材は実際のマップ切り替え時に段階的に補います。
  • restrict_strings.cfg は初回接続用の優先リストとなり、44 個のフィードバック素材ファイルと重複を除いた 17 個のフィードバック音声ファイルを含みます。ダンスモデルは初回接続時にはダウンロードされません。
  • 60 曲のダンス曲を管理する deferred_strings.cfg を追加し、既定では 8 グループに分割しました。実際の changelevel ごとにランダムな 1 グループを配信し、8 グループがすべて出るまでは同じグループを繰り返しません。一巡後は再度シャッフルします。sm_fixscreen_deferred_group_count でグループ数を変更でき、クライアント側にあるファイルはゲームのキャッシュにより自動的にスキップされます。
  • 相互依存する 3 個のダンスモデルファイルは、最初のマップ切り替え時にまとめてダウンロードし、不完全なモデルによるエラーを防ぎます。同じ切り替えでランダムな曲グループも 1 つ配信し、その後はランダムかつ重複しない順序で補います。
  • フィードバック、モデル、ダンス曲の全 124 リソースを元のディレクトリ構造を保った .bz2 として NewAnneWeb のファイル管理へ移行しました。FastDL は Cloudflare キャッシュを利用する http://anne.trygek.com/fastdl/left4dead2 へ切り替えました。

2026年7月15日 動的難度修正

  • 制御対象 CVar の基準値スキャンが後半の難度セクションを見落とす可能性を修正しました。level1 から level6 まで明示的に走査し、Expert 以下へ戻した際に Extreme または Neri 固有値が残らないようにしました。
  • 動的難度で視点上げ/旋回が有効なとき、旧 ai_boomer_2 が下向きの俯角を残して地面へ吐くことがある問題を修正しました。初回照準と複数目標への旋回は最低 5 度の仰角を維持し、連続ジャンプやジャンプ吐きの設定は変更しません。
  • 使用中の AI プラグインに登録されていない旧 CVar 4 個を削除しました。SourceMod から取得・変更できる hidden/launcher CVar 3 個は設定を維持します。
  • 固定難度から自動へ戻す際、PPM データが一時的に利用できないと Neri/高難度 CVar が残る問題を修正しました。まず Easy を安全な基準として適用し、統計が利用可能になった時点で自動難度を再選択します。
  • サーバーコンソール/RCON の sm_aidiff までセーフルーム退出後のロックで次ラウンドへ延期され、運用上の難度変更が未適用に見える問題を修正しました。コンソール/RCON は即時適用し、退出後にプレイヤーが実行した管理者コマンドは従来どおり次ラウンドから適用します。
  • Boomer2 と Smoker3 に、既定で無効の空中能力 CVar を追加しました。Neri のみ有効化し、既存の連続ジャンプ動作は従来どおり継続します。追加のジャンプを強制せず、すでに空中にいる AI が吐しゃまたは舌を使用できるようにするだけで、地上攻撃と発動距離は変更しません。

2026年7月14日 動的難度ホットフィックス

  • ハードコードされた level0 が 1vHunters、Alone、WitchParty などのモード固有値を上書きする問題を修正しました。各モードの設定適用後に実際の CVar 基準値を記録し、難度変更、マップ変更、アンロード時に復元します。
  • 低難度へ誤って追加された z_lunge_up 0、z_lunge_interval 0.08、z_lunge_cooldown 0 などを削除し、旧 ai_hunter_2 で Hunter がその場で飛ぶ、または繰り返ししゃがむ問題を修正しました。Jockey、Tank、Boomer への意図しない上書きも防止します。
  • 極限と音理の明示的な強化値は維持し、高難度から離れる際は現在のモードで記録した基準値へ戻します。

2026年6月12日-7月3日 更新記録

Anne モードと特殊感染者スポーン

  • Anne 系の対戦モードで第三者視点が使えない問題を修正しました。!tp と第三者視点関連 cvar は Anne 系共有設定から適用されます。
  • infected_control.smx のリファクタリングと最適化を継続しました。Left4DHooks PVS/可視性補助、スポーン性能設定、キュー調整、ウェーブ判定整理を追加し、異常スポーン、Smoker の二重舌、補充ウェーブが速すぎる問題を減らしました。
  • anne_cvar_shield.smx を追加し、Anne の重要 cvar を保護します。プラグインや投票の残留設定が別モードの難度へ混ざるのを防ぎます。
  • 26-7 テスト設定 Anne25-11.cfg を追加し、旧版 infected_control25-11.smx をロールバック用として保持しました。動的難度ドキュメントも更新しました。
  • 極限難度の値が他の難度へ影響する問題を修正しました。動的難度切り替え時に Tank、Hunter などの段階別パラメータをより明確にリセットします。
  • セーフルーム内の近接武器が出ない場合がある問題を修正し、MeleeInTheSafeRoom の処理を整理しました。
  • 刷特投票メニュー spawn_vote_menu.smx を従来の SourceMod メニューへ戻し、外部メニュー依存を削除しました。Anne/キャンペーンの特殊感染者数、間隔、自動モード、テレポート判定は項目を選ぶたびに単項目投票を開始し、プリセットは従来通り一括 preset 投票になります。
  • not0721 系 coop/community/mutation モード、dirspawn preset、武器設定、SI limit 設定を追加・整理しました。
  • infected_control に裏切り者モード関連ロジック、スポーン preset テーブル、多言語フレーズを追加し、今後の玩法拡張に備えました。

プレイヤー体験、投票、フィードバック

  • l4d_stats.smx のカスタムマップのスコア精算を調整しました。通常のカスタムマップは実際のマップ時間が5分を超えた場合のみ安全部屋通過分と強勢通過ボーナスを付与し、公式マップは従来のスコアを維持します。カスタム救援マップにはチーム通過分を付与せず、マップ時間・マップ記録・特感統計は通常通り保存します。
  • 旧 hextags を hextags_lite.smx に置き換え、称号色の問題を修正しました。管理者コマンドを隠し、設定ファイルは hextags_lite.cfg に移行しました。
  • global_chat.smx、join.smx と関連メッセージに多言語フレーズを追加し、全体チャット状態やチーム募集受信状態などを補いました。
  • l4d_stats.smx の四半期ランキングと永続化まわりを修正し、ラウンド状態記録を補強しました。一部のデータベース処理と混雑時ステータス書き込み負荷も下げました。
  • 旧 killsound と「叮叮叮」音效投票の機能を l4d2_hitsound.smx に統合しました。古い sound_on/off 投票ファイルを削除し、命中、キル、ヘッドショットの音效とアイコンをフィードバック插件で一元管理します。
  • spechud.sp を更新し、ping 表示、ボーナス割合の内訳表示、観戦遅延表示の修正を追加しました。
  • basevotes.smx を無効化し、無蓄力 Hunter の直接投票項目を削除しました。Anne 動的難度と新しい投票メニューとの衝突を減らします。
  • server_name.smx は SourceBans description を直接書き換えなくなりました。表示処理は外部 proxy 側へ移しました。
  • 混雑時アンロードと NPC 管理のチェック/提示頻度を下げ、混雑時の追加負荷を抑えました。
  • 一部の管理者コマンド出力を隠し、プレイヤー向けチャットのノイズを減らしました。

上流同期、マップ、基礎依存

  • Left4DHooks、gamedata、include、テスト用源码を更新し、新しい native/forward を補いました。関連插件も再ビルドしました。
  • ai_tank3.smx を更新し、RPG スコア権限処理と極限難度の callback/パラメータ問題を修正しました。Tank 行動設定も調整しました。
  • Dead Center 2025、City 17、No Echo m3、Carried Off cwm1_intro などの上流 map/stripper 修正を同期しました。適用できる zonemod 更新は zonemod_anne にも反映しました。
  • cwm1_intro の hittable/clipwall 修正を同期し、複数モードの mapinfo.txt を補いました。
  • Rust 製サーバーブラウザ工具と Docker デプロイ README をこの仓库から削除しました。関連ワークフローは外部工具/网页側で维护します。
  • basevotes.smx の配置、SourceMod 設定、データベース字段、複数ドキュメントを更新し、插件包構造を整理しました。