ワールドロジック type の追加
SDK 1.2 以降、プラグインは ワールドロジック に新しいトリガー・条件・アクションを追加できます。host.AddSceneEvent で登録した type は、内蔵 type とまったく同じように次の場所に表示されます。
| 表示される場所 | 表示内容 |
|---|---|
| ワールドロジックのフォーム | トリガー・条件・アクションのメニューの Category グループ、項目の入力 |
| ロジックグラフ | ノードとピン |
| チェック | 必須項目・アクターの kind・数値の範囲・enum の値 |
| ルールの 1 行説明 | Summary テンプレート |
| プレイ のプレビュー | Simulate の処理・「発動」ボタン |
| AI 接続 (MCP) | scene_rules section=schema の一覧に [<プラグイン id>] を表示 |
エディターへの登録は、フォーム・チェック・MCP・プレビュー用です。ゲームサーバーで実際に動かすには、サーバープラグイン NP Scene 側にも同じ type を登録する必要があります。下の「サーバー側」を参照してください。
plugin.json には "sdk": "^1.2" 以上を書きます。項目の種類 ActorList を使う場合は "^1.3" です。
host.AddSceneEvent(new NpSceneEvent(NpSceneEventRole.Trigger, "myquest_npc_talk", "NPC 에게 말 걸 때", "퀘스트", new[] { new NpSceneField("npc", NpSceneFieldKind.Actor, Required: true, ActorKinds: new[] { "display", "text", "spawn" }, Label: "NPC"), new NpSceneField("line", NpSceneFieldKind.Text, Label: "대사 id"), }, Help: "플레이어가 NPC 와 대화를 시작할 때", Icon: "interact", Summary: "플레이어가 NPC {npc} 에게 말을 걸면")); // Simulate なし = 「発動」ボタンでのみ
host.AddSceneEvent(new NpSceneEvent(NpSceneEventRole.Action, "myquest_start", "퀘스트 시작", "퀘스트", new[] { new NpSceneField("quest", NpSceneFieldKind.Text, Required: true, Label: "퀘스트 id"), }, Icon: "star", Summary: "퀘스트 {quest} 시작", Simulate: s => { s.Log($"퀘스트 {s.Str("quest")} 시작 → {s.Player}"); return true; }));この type を使ったルールは、scene.json に次のように保存されます (ルールの一部)。
{ "trigger": { "type": "myquest_npc_talk", "npc": "npc_guard" }, "actions": [ { "type": "myquest_start", "quest": "q1" } ]}NpSceneEvent
Section titled “NpSceneEvent”public sealed record NpSceneEvent(NpSceneEventRole Role, string Type, string Label, string Category, IReadOnlyList<NpSceneField> Fields, string Help = "", string Icon = "event", string Summary = "", Func<NpSceneSim, bool>? Simulate = null);public enum NpSceneEventRole { Trigger, Condition, Action }| 項目 | 必須 | 説明 |
|---|---|---|
Role | はい | 役割: Trigger (トリガー)・Condition (条件)・Action (アクション) |
Type | はい | 保存名 (JSON の "type")。前に自分の名前を付けます (下の「命名ルール」)。 |
Label | はい | フォーム・グラフに表示される名前 |
Category | いいえ | メニューのグループ名。空の場合はプラグイン名 (plugin.json の name) |
Fields | はい | 項目の一覧 (NpSceneField)。項目がなければ空の配列 |
Help | いいえ | 説明 (ツールチップ) |
Icon | いいえ | アイコン名 (trigger ・ event ・ signal ・ interact ・ logic ・ star …)。既定は event、不明な名前なら既定の画像 |
Summary | いいえ | 1 行説明のテンプレート (下の「Summary テンプレート」)。空の場合は Label |
Simulate | いいえ | プレイのプレビュー処理 (下の「Simulate」) |
プラグインの type は、同じグループ内で内蔵 type の後ろに表示されます。
NpSceneField
Section titled “NpSceneField”public sealed record NpSceneField(string Name, NpSceneFieldKind Kind, bool Required = false, string Default = "", string[]? Options = null, string[]? ActorKinds = null, string Label = "", string Help = "", double? Min = null, double? Max = null);| 項目 | 説明 |
|---|---|
Name | JSON キー |
Kind | 項目の種類 (下の表) |
Required | 必須の場合、空ならチェックエラー |
Default | 既定値の文字列。形式は下の表の「Default の書き方」 |
Options | Enum の選択肢 |
ActorKinds | Actor 項目が受け付けるアクターの kind (trigger ・ blocker ・ display ・ text ・ spawn ・ camera ・ path …)。空の場合は任意の kind |
Label ・ Help | フォームに表示される名前・説明 |
Min ・ Max | Number の範囲 (チェック) |
項目の種類 NpSceneFieldKind
Section titled “項目の種類 NpSceneFieldKind”| 種類 | フォームの入力 | JSON の値 | Default の書き方 | SDK |
|---|---|---|---|---|
Text | 文字列 | 文字列 | "안녕" | 1.2 |
Number | 数値 | 数値 | "1.5" | 1.2 |
Bool | チェック | true / false | "true" | 1.2 |
Enum | 選択肢の 1 つ (Options) | 文字列 | "none" | 1.2 |
Actor | アクターの選択 (ActorKinds のみ) | アクター id の文字列 | アクター id | 1.2 |
Anim | アニメーションクリップ | クリップ id の文字列 | クリップ id | 1.2 |
SoundEvent | サウンドイベント | "ns:path" の文字列 | "minecraft:block.note_block.bell" | 1.2 |
Block | ブロックステート | 文字列 (minecraft:stone) | ブロックステートの文字列 | 1.2 |
Item | アイテム | 文字列 (minecraft:diamond_sword) | アイテム id | 1.2 |
Particle | パーティクル | 文字列 (minecraft:happy_villager) | パーティクル id | 1.2 |
Effect | ポーション効果 | 文字列 (minecraft:speed) | 効果 id | 1.2 |
Vec3 | x・y・z | [x, y, z] | "[0,1,0]" | 1.2 |
Signal | シグナル名 | 文字列 | シグナル名 | 1.2 |
Flag | シーンフラグ名 | 文字列 | フラグ名 | 1.2 |
ActorList | 複数のアクター | アクター id の配列 | "cam_a,cam_b" | 1.3 |
内蔵 type だけが使う項目の種類が他にもあります: フラグ値・関数 (ロジック関数の呼び出し)・ブロックのマスの一覧 (
Cells)。これらの種類はまだ SDK にありません。項目の表示条件・整数のみ・#タグの許可といった項目オプションも、まだ SDK にありません。
ロジックグラフでの扱い
Section titled “ロジックグラフでの扱い”プラグインの type も ロジックグラフ にノードとして表示されます。ピンのルールは内蔵 type と同じです。
| ピン | 接続できる数 |
|---|---|
| 実行ピン (白い矢印) | 1 本のチェーン。ノード 1 つの後ろにノード 1 つ |
| 関数ピン (黄色のひし形) | ピン 1 つに線 1 本。既に接続済みのピンにもう一度接続すると置き換わります。 |
| データピン (紫の丸、アクター参照) | アクター 1 つを複数の項目に接続できます。 |
Actor項目はデータピンを受け付けます。グラフでアクターを接続するとActorKindsをチェックします。- 関数ピンは内蔵の「関数を呼ぶ」系にのみあります。プラグインの type は関数ピンを作れません。
0.9.11 以降: 関数を呼ぶ黄色のピンは、ピンごとに線 1 本です。
Summary テンプレート
Section titled “Summary テンプレート”ルール一覧の 1 行説明に使うテンプレートです。{項目名} の位置にその項目の値が入ります。
| テンプレート | 項目の値 | 表示される文字列 |
|---|---|---|
퀘스트 {quest} 시작 | quest = q1 | 퀘스트 q1 시작 |
플레이어가 NPC {npc} 에게 말을 걸면 | npc = npc_guard (名前「경비병」) | 플레이어가 NPC 「경비병」 에게 말을 걸면 |
퀘스트 {quest} 가 {state} 일 때 | state は空、Default = none | 퀘스트 q1 가 none 일 때 |
Actor項目は、アクター id の代わりに「アクター名」に置き換わります。- 値のない項目は
Defaultで埋めます。
Simulate — プレイのプレビュー
Section titled “Simulate — プレイのプレビュー”Simulate は、プレイ・シミュレート中にルールをプレビュー実行する関数です。ゲームサーバーでは使いません。
| 役割 | Simulate の処理 | 戻り値 | ない場合 |
|---|---|---|---|
| Trigger | プレビューの 1 ティックごとに、その type のルールごとに 1 回呼ばれる。起こすには s.Fire(player) | 無視 | ワールドロジック・プレイパネルの「発動」ボタンでのみ起こす |
| Condition | 真・偽の判定 | true = 真 | 常に真とみなす |
| Action | アクションの実行 (記録・自分の状態の変更) | 無視 | 記録だけを残す |
Simulate で例外が発生すると、そのプラグインは隔離されます。そのプラグインの type はすべて取り除かれ、プレビューは動作を続けます。
NpSceneSim
Section titled “NpSceneSim”Simulate が受け取る値です。
| メンバー | 型 | 説明 |
|---|---|---|
Role ・ Type | NpSceneEventRole ・ string | 現在処理中の役割・type |
RuleId | string | ルール id |
Player | string? | トリガーした人。トリガーの処理では null |
Players | IReadOnlyList<string> | 現在のプレイヤーたち |
Now | double | プレビューの時刻 (秒) |
Args | IReadOnlyDictionary<string, string> | ノードの項目値 (すべて文字列) |
Str(string key, string fallback = "") | string | 項目値の文字列 |
Num(string key, double fallback = 0) | double | 項目値の数値 |
Bool(string key, bool fallback = false) | bool | 項目値 "true" / "false" |
PositionOf(string player) | NpVec3? | プレイヤーの足の位置。なければ null |
Log(string text) | void | プレビューの記録 1 行 ([<id>] …) |
Fire(string? player) | void | (Trigger の処理のみ) このルールを起こす。他の役割では何も起きない |
Args の値の文字列形式です。
| 項目の値 | Args の文字列 |
|---|---|
| 文字列 | そのまま |
| 数値 | "1.5" (ドット区切りの小数、カルチャーに依存しない) |
| 真・偽 | "true" / "false" |
配列・オブジェクト (Vec3 ・ ActorList) | JSON 文字列 ("[0,1,0]")。ActorList はカンマ区切りの文字列で保存されたものもそのまま渡されます。 |
例: 自動で起こるトリガー
Section titled “例: 自動で起こるトリガー”host.AddSceneEvent(new NpSceneEvent(NpSceneEventRole.Trigger, "myquest_near_spawn", "스폰 가까이 올 때", "퀘스트", new[] { new NpSceneField("r", NpSceneFieldKind.Number, Default: "5", Label: "반경", Min: 1, Max: 64), }, Summary: "스폰 {r}칸 안에 들어오면", Simulate: s => { foreach (var p in s.Players) if (s.PositionOf(p) is { } pos && Math.Abs(pos.X) + Math.Abs(pos.Z) < s.Num("r", 5)) s.Fire(p); return true; }));- この関数はプレビューのティックごとに呼ばれます。軽い処理にしてください。
- フィルター (1 回のみ・クールダウンなど) と条件は、
Fireの後にエディターが評価します。
例: 状態を記憶する条件・アクション
Section titled “例: 状態を記憶する条件・アクション”private readonly Dictionary<string, string> _quests = new(); // プレイヤー:クエスト → 状態
// 条件: クエストの状態Simulate: s => Get(s.Player, s.Str("quest")) == s.Str("state", "none")
// アクション: クエスト開始Simulate: s => { _quests[(s.Player ?? "") + ":" + s.Str("quest")] = "active"; s.Log("시작"); return true; }
// 新しいワールドではクリアhost.WorldChanged += _ => _quests.Clear();全体のコードは サンプル: event_example にあります。
| ルール | 理由 |
|---|---|
Type の前に自分の名前を付けます (myquest_start)。 | 同じ役割に同じ type が既にあると (内蔵を含む) 登録時に例外 → そのプラグインを隔離 |
小文字・数字・_ で書きます。 | サーバープラグイン・JSON と合わせやすくなります。 |
一度使った Type は変更しません。 | 保存済みのルールがその名前を使っています。 |
内蔵 type の名前 (cinematic ・ enter ・ sound …) を使いません。 | 内蔵と重なるとプラグインが有効になりません。内蔵の一覧は ワールドロジック type 一覧 にあります。 |
プラグインを無効にすると
Section titled “プラグインを無効にすると”- そのプラグインの type がメニュー・グラフのパレットから取り除かれます。
- その type を使うルールは削除されません。「不明な type」の注意になり、項目の値はそのまま残ります。
- プレビューでは、不明なトリガーはそのルールをスキップし、不明な条件は偽、不明なアクションはそのアクションだけをスキップします。
ゲームでルールを実行するのは、サーバープラグイン NP Scene (Paper) です。エディタープラグインはサーバーでは動作しません。
- 同じ type のハンドラーを Paper プラグインとして作ります。
- Bukkit の
ServicesManagerから NP Scene のSceneEventsApiを取得し、その type を登録します。 - 項目名と値の形式 (JSON) を、エディター側の
NpSceneFieldとまったく同じに合わせます。
サーバーが知らない type は、警告を 1 回出してスキップします (トリガー = ルールをスキップ、条件 = 偽、アクション = そのアクションだけをスキップ)。そのため、サーバーのハンドラーがなくてもマップは開けますが、そのルールは動作しません。