CSMM Custom Hooksは、7 Days to Dieサーバーのログやゲームイベントを監視し、条件に一致した時だけ自動的にコマンドを実行できる機能です。
私は特殊ゾンビの討伐通知、サーバー再起動のDiscord通知、ブラッドムーンホードの通知、接続人数によるTarget FPS変更などに使用しています。
一度仕組みを理解するとかなり色々な事ができますが、最初はSearch StringとRegexの違いが少し分かりにくいと思います。
この記事では基本的な仕組みから、実際に私が使用している設定までまとめておきます。
この記事は2026年8月時点の情報を含みます。
古いCSMM公式ドキュメントではCPM(CSMM Patrons Mod)や[CSMM_Patrons]という名称が使用されていますが、現在CPMはPrismaCoreへ移行しています。
特にlogLineとRegexを利用するHookは、PrismaCore移行後に実際のログ形式が変更されている可能性があります。
必ず自分のサーバーに出力されたログを確認してから設定してください。
Custom Hooksとは
簡単に書くと、以下のような仕組みです。
7DTD Server
↓
サーバーログ・ゲームイベント
↓
CSMM
↓
Custom Hook
↓
条件判定
↓
一致
↓
コマンド実行
例えば特殊なゾンビが倒された時だけ、
PlayerA killed zombie zombieM60DemolitionPLUS with M60 Machine Gun
のようなログが出るのであれば、
killed zombie zombieM60DemolitionPLUS
という文字列を検出して、
say "PlayerAが特殊ゾンビを倒しました!"
を自動実行できます。
さらにRegexを使用すると、ログの中からプレイヤー名、武器名、座標、日数など、毎回変化する値だけを取得する事もできます。
2026年現在のPrismaCoreについて
以前CSMMと組み合わせて使用されていたCPM(CSMM Patrons Mod)は、現在PrismaCoreへ移行しています。
PrismaCore公式のVersion Historyでは、2025年11月にCPMからPrismaCoreへ名称変更・リファクタリングされた事が案内されています。
その際、Server ManagerのHook、特にRegexを使用するlogLine Hookには移行の影響がある事も明記されています。
また、2026年7月5日に公開されたPrismaCore 2.5は、
7 Days to Die 3.1.0 b14 Stable
に対応しています。
そのため、古いCSMMの記事に書かれている、
[CSMM_Patrons]
というログをそのままSearch Stringへ入力するのではなく、現在のサーバーで実際に出力されているログを確認してください。
Custom Hookを構成するもの
基本的には以下を組み合わせます。
- Event
- Commands
- Search String
- Regex
- Custom Variables
- Cooldown
Event
「何が起きた時にHookを見るか」を指定します。
CSMMには最初から認識できるイベントと、サーバーログそのものを監視するlogLineがあります。
Commands
条件に一致した時に実行するコマンドです。
例えば、
say "ブラッドムーンホードが始まります!"
ゲーム内だけではなく、CSMMの関数を利用してDiscordへメッセージを送信する事もできます。
sendDiscord(CHANNEL_ID, "ブラッドムーンホードが始まります!")
Search String
ログやイベントの中に特定の固定文字列が含まれているか確認します。
例えば、
BloodMoon SetDay:
のような文字列です。
単純なイベントであれば、Regexを使用せずSearch Stringだけで十分です。
Regex
RegexはRegular Expression、正規表現です。
例えば、
BloodMoon SetDay: day 35
というログから、
35
だけを取り出したい場合に使用します。
Custom Variables
Regexで取り出した値に名前を付けて保存します。
例えば変数名を、
day
にすると、
${custom.day}
としてCommandsから使用できます。
Cooldown
同じHookが連続して実行される事を防ぎます。
例えば通信エラーが1秒間に何十行も出力された時、Cooldown無しでDiscord通知すると大量のメッセージが送信される場合があります。
ログ監視系のHookではかなり重要な設定です。
CSMMが最初から認識できるイベント
CSMM公式ドキュメントでは、以下のようなBuilt-In Event Hookが用意されています。
| Event | 内容 |
|---|---|
playerJoined |
新規プレイヤーが初めてワールドへ参加 |
playerConnected |
既存プレイヤーが接続 |
playerDisconnected |
プレイヤーが切断 |
chatMessage |
グローバルチャット |
playerKilled |
プレイヤーが別プレイヤーを倒した |
playerDeath |
プレイヤーが死亡 |
playerSuicide |
自◯扱いの死亡 |
playerLevel |
レベルアップ |
zombieKilled |
プレイヤーがゾンビなどの敵対Entityを倒した |
animalKilled |
プレイヤーが動物を倒した |
可能であれば、まずBuilt-In Eventを使用する事をおすすめします。
例えば「特定ゾンビが倒された時」であれば、サーバーログ全体を自分で解析するより zombieKilled を利用した方が設定が簡単です。
logLineとは
Built-In Eventでは取得できないイベントを監視したい場合に使用するのが、
logLine
です。
logLineは、7DTDサーバーから出力されたログそのものを監視します。
例えば以下です。
BloodMoon SetDay: day 35
や、
[PrismaCore]Unauthorized GodMode detected on PlayerName
などです。
MODが独自ログを出力している場合も、logLineを使用すればHookの対象にできます。
そのため自作サーバーサイドMODとCSMMを連携する場合にもかなり便利です。
Search StringとRegexは役割が違います
私は基本的に、
Search String
↓
対象ログを絞り込む
Regex
↓
必要な値を取り出す
という使い方をしています。
例
BloodMoon SetDay: day 35
Search String:
BloodMoon SetDay:
Regex:
(?<=SetDay: day )\d+
結果:
35
Custom Variable:
day
Commands:
say "次のブラッドムーンホードは${custom.day}日です"
Regexでよく使う記号
| Regex | 意味 |
|---|---|
\d |
数字1文字 |
\d+ |
1文字以上の数字 |
\s |
空白文字 |
.+ |
1文字以上の任意文字 |
.* |
0文字以上の任意文字 |
[0-9] |
0~9 |
[1-5] |
1~5 |
(A|B) |
AまたはB |
^ |
文字列の先頭 |
$ |
文字列の末尾 |
(?<=ABC) |
ABCの直後から取得するLookbehind |
(?=ABC) |
ABCの直前まで取得するLookahead |
数字が1桁とは限らない場合
例えば、
\d{1}
では1桁しか取得できません。
再起動まで、
3分
10分
120分
などの可能性がある場合は、
\d+分
の方が扱いやすいです。
実例1:特殊ゾンビを倒した時に通知する
私の環境では、M60 Demolitionという特殊ゾンビの討伐を通知するHookを使用していました。
一番簡単な方法
CSMMが現在の環境で正常に zombieKilled を取得できている場合はこちらを優先します。
Event:
zombieKilled
Search String:
zombieM60DemolitionPLUS
Commands例:
say "[FF0000]${player.name}は強敵M60 Demolitionを倒しました![-]"
CSMM公式の設定例でも、特定ゾンビのEntity ClassをSearch Stringへ指定して討伐通知する方法が紹介されています。
武器名も取得する場合
私が以前使用していたlogLineベースの設定です。
Event:
logLine
Search String:
killed zombie zombieM60DemolitionPLUS
Custom Variable:
weapon
Regex:
(?<=with ).+
Commands:
say "[FF0000]${playerName}は強敵M60 Demolitionを${custom.weapon}で倒しました![-]"
注意:この設定は実際に出力されるkillログの形式に依存します。
また、任意のlogLineで${playerName}が使用できるかどうかもイベントとログ解析結果に依存します。
現在の環境でプレイヤー名が取得できない場合は、実際のkillログからプレイヤー名もCustom VariableとしてRegexで取得してください。
特にPrismaCore移行後は古い [CSMM_Patrons] ベースのRegexをそのまま使用せず、現在の実ログで確認した方が良いです。
実例2:サーバー再起動までの時間をDiscordへ通知する
ゲーム内へ再起動予告を表示している場合、そのログをCSMMが検出してDiscordへ送る事もできます。
私の環境で使用していた例です。
Event:
logLine
Search String:
[00FF00]サーバー再起動まで後[FF0000]
Custom Variable:
time
Regex:
\d+分
Commands:
sendDiscord(CHANNEL_ID, "サーバー再起動まで後${custom.time}")
例えばログが、
[00FF00]サーバー再起動まで後[FF0000]3分
であれば、
${custom.time}
には、
3分
が入ります。
Discord Channel ID
sendDiscord() の最初の値はDiscordのChannel IDです。
例えば、
sendDiscord(123456789012345678, "サーバー再起動まで後3分")
となります。
CSMM Botが対象Discordサーバーへ追加・認証されている必要があります。
Discordのロールをメンションする
管理者ロールへ通知する場合はDiscordのRole IDを使用できます。
<@&ROLE_ID>
例:
sendDiscord(
123456789012345678,
"<@&987654321098765432> サーバーで異常を検出しました。"
)
Discord側でDeveloper Modeを有効にすると、チャンネルやロールを右クリックしてIDをコピーできます。
実例3:次回ブラッドムーンの日をDiscordへ通知する
私が使用していた設定です。
Event:
logLine
Search String:
BloodMoon SetDay:
Custom Variable:
day
Regex:
(?<=SetDay: day )\d+
Commands:
sendDiscord(
CHANNEL_ID,
"---次のブラッドムーンホードは${custom.day}日の22時に開始されます---"
)
例えば、
BloodMoon SetDay: day 35
というログなら、
${custom.day} = 35
となります。
BloodMoonFrequencyやBloodMoonRangeを変更しているサーバーでは、実際のブラッドムーン仕様も確認してください。
特にランダム範囲を設定している場合は「必ず○日」と断定できない構成があります。
実例4:ブラッドムーンまでの日数をDiscordへ通知する
私の環境では、ゲーム側から以下のようなメッセージが出るようにしていました。
[00ff00]Better hurry! Its bloodmoon [FF0000]TONIGHT[-] !!![-]
[00ff00]Remember: Bloodmoon is tomorrow !!![-]
[00ff00]Remember: Bloodmoon is in 2 days !!![-]
これをそれぞれ検出して、
まもなくブラッドムーンホードが始まります。
1日後にブラッドムーンが始まります。
2日後にブラッドムーンが始まります。
とDiscordへ通知できます。
このように変数を取得する必要が無い固定メッセージの場合は、複雑なRegexを使用する必要はありません。
Search Stringだけで十分です。
Custom Discord Notificationsとの違い
CSMMにはCustom Hookだけではなく、ログ中の特定文字列を検出してDiscordへ送る用途に使えるCustom Discord Notificationsもあります。
例えば、
ObjectDisposedException
や、
Failed to connect to the backend
のような固定エラーを監視するだけなら、Custom Discord Notificationsの方が簡単な場合があります。
一方、
- ログから数字を取り出したい
- プレイヤー名を取得したい
- 条件によって実行内容を変えたい
- 複数コマンドを実行したい
- ゲーム内とDiscordの両方へ通知したい
という場合はCustom Hooksの方が向いています。
実例5:接続人数によってTarget FPSを変更する
7DTDは定期的に以下のようなサーバーステータスをログへ出力します。
Time: 0.0m FPS: 20.00 Heap: 1000.0MB Max: 1000.0MB Chunks: 1234 CGO: 123 Ply: 0 Zom: 108 Ent: 0 RSS: 0.0MB
ここにある、
Ply: 0
が現在の接続人数です。
CSMM公式でも、このPly値をRegexで判定し、接続人数に応じてMaxSpawnedZombiesを変更する例が掲載されています。
同じ仕組みを利用して、私はTarget FPSを変更しています。
現在の設定例
| 接続人数 | Target FPS |
|---|---|
| 0人 | 20 |
| 1~2人 | 40 |
| 3~4人 | 35 |
| 5~6人 | 35 |
| 7~8人 | 30 |
| 9~10人 | 28 |
| 11人以上 | 25 |
3~4人と5~6人は同じ35FPSなので、Hookとしては3~6人をまとめても問題ありません。
0人
Event:
logLine
Regex:
(?<=Ply:\s)0(?=\s+Zom:)
Commands:
settargetfps 20
1~2人
(?<=Ply:\s)[12](?=\s+Zom:)
settargetfps 40
3~6人
(?<=Ply:\s)[3-6](?=\s+Zom:)
settargetfps 35
7~8人
(?<=Ply:\s)[78](?=\s+Zom:)
settargetfps 30
9~10人
(?<=Ply:\s)(?:9|10)(?=\s+Zom:)
settargetfps 28
11人以上
(?<=Ply:\s)(?:1[1-9]|[2-9]\d|\d{3,})(?=\s+Zom:)
settargetfps 25
以前使用していた簡易設定
最初は以下だけでした。
0人
(?<=Ply:\s)0
settargetfps 20
1~32人
(?<=Ply:\s)([1-9]|[12][0-9]|3[0-2])
settargetfps 40
これでも動作しますが、現在は人数によって段階的に分けています。
なぜ人数が増えたらTarget FPSを下げるのか
プレイヤーが増えると、
- 読み込まれるチャンク
- Entity
- ゾンビAI
- ネットワーク同期
- 建築物
- 物理処理
- ブラッドムーンホード処理
なども増えます。
CPUが維持できないTarget FPSを要求しても実際のFPSが上がるわけではありませんので、私は人数が多い時には維持しやすい値へ落としています。
尚、この数値が全サーバーで最適という意味ではありません。
CPU、MOD、ワールド、ゾンビ数によってかなり変わります。
応用:MaxSpawnedZombiesも接続人数で変更できる
CSMM公式ドキュメントにも、Ply値を利用してMaxSpawnedZombiesを変更する例があります。
例えばEventを、
logLine
として、
sg MaxSpawnedZombies 128
を実行し、
(Ply:\s)(2[0]|[01]?[0-9])(\sZom:)
のようなRegexで接続人数を判定する方法です。
同じ考え方で、
- Target FPS
- MaxSpawnedZombies
- その他コンソールから変更可能なGameStat
などを動的に変更できます。
ただし、設定値を頻繁に変更しすぎる必要はありません。
実際のログ出力間隔とCooldownを見ながら調整してください。
応用:レベルアップ時に報酬を与える
CSMMには playerLevel Eventがあります。
例えば、
say "${player.name}がレベル${newLvl}になりました!"
のような通知ができます。
CSMMのCurrencyを使用している場合は、
addCurrency(${player.id}, 50)
などを組み合わせる事もできます。
複数のコマンドはセミコロンで分離できます。
say "${player.name}がレベルアップしました!"; addCurrency(${player.id}, 50)
応用:PrismaCoreの異常検出をDiscordへ送る
現在のPrismaCoreは、いくつかの検出結果を明確なログとして出力します。
例えばGodMode検出です。
[PrismaCore]Unauthorized GodMode detected on PlayerName
飛行検出では、
[PrismaCore]Player PlayerName seems to be flying !!!!!
などのログがあります。
このようなログはCSMM Custom HooksやCustom Discord Notificationsと非常に相性が良いです。
ただし、検出しただけで即BANするような自動処理はあまりおすすめしません。
MOD、管理者操作、テレポート、ゲーム側の不具合などによる誤検出の可能性も考えて、最初はDiscord通知だけにしてログを確認する方が安全です。
Custom Variablesの作り方
logLineから特定の値を取りたい場合はCustom Variablesを使用します。
例えば以下のログです。
658 falling blocks prevented! @ 2130 7 161
ここからX座標だけ取得したい場合、
xcoord
というCustom Variableを作り、Regexを設定します。
CSMM公式にも、落下ブロック検出ログからX座標とZ座標をCustom Variablesへ取り込み、周辺プレイヤーを探してDiscordへ通知する応用例があります。
Custom Variablesを使うと、
${custom.xcoord}
または高度なHandlebars構文内で、
{{custom.xcoord}}
などとして利用できます。
${ } と {{ }} の違い
CSMMの設定例を見ると、
${player.name}
と、
{{player.name}}
の両方が登場します。
基本的なCSMM変数では、
${player.name}
${player.steamId}
${custom.day}
などが多く使用されています。
一方、Handlebarsを使用した条件分岐、ループ、計算では、
{{player.name}}
や、
{{#if ...}}
{{/if}}
などを使用します。
例えばオンラインプレイヤーを全員処理する場合です。
{{#each server.onlinePlayers}}
{{this.name}}
{{/each}}
最初からHandlebarsを使う必要はありません。
単純な通知であれば通常のCSMM変数だけで十分です。
Discordでプレイヤー名が文字化けする場合
Handlebarsは特殊文字をHTML Entityへ変換する場合があります。
例えばプレイヤー名にアポストロフィなどが入っている場合です。
CSMM公式では、Discordメッセージで特殊文字をそのまま通したい場合にTriple Bracesを使用する方法が案内されています。
{{{player.name}}}
通常:
{{player.name}}
特殊文字をそのまま出したい場合:
{{{player.name}}}
Hookが二重実行される場合
logLine Hookでは、同じログへ複数のHookが一致すると複数実行される場合があります。
例えば、
Hook A Search String:
test
Hook B Search String:
test message
に対して、
test message
というログが来ると、条件次第では両方に一致します。
そのためSearch Stringは出来るだけ固有のものにしてください。
悪い例:
zombie
良い例:
killed zombie zombieM60DemolitionPLUS
Built-In EventとlogLineを重複させない
CSMM公式ドキュメントでは、Built-In Eventが先に判定され、その後logLineが処理される順番になっています。
同じ内容を、
chatMessage
と、
logLine
の両方で検出するような構成は避けた方が良いです。
既にBuilt-In Eventが用意されている場合は、基本的にそちらを使います。
Hookが動かない時の確認方法
1. 実際のログを見る
最初にこれを確認します。
自分が思っているログと、実際のログが違う事がかなりあります。
PrismaCoreへアップデートした場合は特に確認してください。
2. Search Stringを短くして試す
最初から複雑なRegexを作るのではなく、
BloodMoon SetDay:
など確実に存在する文字列だけでHookが反応するか確認します。
3. Regexを単独で確認する
実ログ1行をコピーし、その1行に対してRegexが一致するか確認します。
4. 一時的に簡単なCommandへする
say "HOOK TEST"
などに変更し、Hook自体が発火しているか確認します。
5. Built-In Eventとの重複を確認する
同じログを別Hookで取得していないか確認します。
6. Cooldownを確認する
テスト中にCooldownが長く設定されていると、一度発火した後しばらく反応しません。
7. PrismaCoreのバージョンを確認する
7DTD本体とPrismaCoreの対応バージョンが合っているか確認してください。
8. 古い[CSMM_Patrons]を検索していないか確認する
CPMからPrismaCoreへ移行した環境ではかなり重要です。
Regexは出来るだけ狭くする
例えば、
.*
だけで大きく取得すると、後からログ形式が変わった時に意図していない文字列まで取り込む可能性があります。
例えばPlyだけ取得したいなら、
(?<=Ply:\s)\d+(?=\s+Zom:)
のように、前後の文字も条件として使用する方が安全です。
チャット内容をそのまま管理コマンドへ渡さない
Custom Hooksは非常に強力なので、セキュリティにも注意してください。
例えばプレイヤーのチャット内容をRegexで取得して、
${custom.message}
をそのまま管理者権限のコンソールコマンドへ入れるような構成はおすすめしません。
入力内容によって別のコマンドとして解釈される可能性が無いようにしてください。
特に、
- ban
- kick
- shutdown
- teleport
- give
- 管理者権限変更
などへユーザー入力をそのまま渡す構成は避けた方が安全です。
プレイヤー名よりIDを使う
プレイヤーを特定して何か操作する場合、可能であれば名前ではなくIDを使用する事をおすすめします。
プレイヤー名は、
- 変更できる
- 似た名前が存在する
- 特殊文字を含む
などの問題があります。
CSMMも、可能であればSteam IDやCross IDなどの一意なIDを使用する方法を推奨しています。
私がCustom Hooksで特に便利だと思う用途
- 特殊ゾンビ討伐通知
- 絶叫ゾンビの召喚通知
- ブラッドムーン通知
- 再起動通知
- EOSやネットワークエラー通知
- Target FPS自動調整
- MaxSpawnedZombies自動調整
- レベルアップ報酬
- 不正行為検出通知
- MOD独自イベントとの連携
- プレイヤー参加・退出時の処理
- サーバー障害のDiscord通知
Custom Hooksと自作サーバーサイドMODを組み合わせる
自分でサーバーサイドMODを作っている場合、Custom Hooksはさらに使いやすくなります。
MOD側から分かりやすい固有ログを出しておきます。
例えば、
[MyMod] BossKilled player=PlayerA boss=BossZombie reward=3
のようなログです。
CSMM側では、
[MyMod] BossKilled
をSearch Stringにして、
player
boss
reward
をそれぞれRegexでCustom Variablesへ取得できます。
この方法なら、CSMM側で複雑な7DTD内部ログを解析する必要がありません。
自作MODと連携する場合は、人間が読んでも機械が読んでも分かりやすい固定形式のログを出力する事をおすすめします。
まとめ
CSMM Custom Hooksは、7DTDサーバーのログやゲームイベントを条件にして自動処理を作れるかなり便利な機能です。
基本的には、
Event
↓
Search String
↓
Regex
↓
Custom Variable
↓
Commands
という順番で考えると分かりやすいです。
そして一番重要なのは、最初からRegexを書く事ではなく、実際にサーバーから出ているログを確認する事だと思います。
7DTDやPrismaCoreはアップデートによってログ形式が変わる事があります。
特に現在はCPMからPrismaCoreへ移行しているため、古いCSMM Custom Hooksの記事をそのままコピーすると正常に動作しない場合があります。
まず実ログを確認してSearch Stringを作り、その後必要な値だけRegexで取得するとトラブルが少なくなります。
私自身も特殊ゾンビ討伐通知、ブラッドムーン通知、再起動通知、人数によるTarget FPS調整などで使用しています。
Custom Hooksはかなり自由度が高いため、他にも便利な設定が出来れば随時追記します。

コメント