ChatGPTでRPGツクールの味方キャラ: スキルを作成する

実験メモ

前の投稿ではRPGツクールのアクターを大量生成しました。

今回は職業ごとの戦闘スキルの効果量や追加効果などを定義していきます。

最終的に以下のようなJSONが作成されます。

skills.json

[
    {
        "name": "ジャスティスストライク",
        "class": "警察官",
        "description": "敵単体に強力な物理攻撃を行い、「スタン」状態を付与する。",
        "tp": 20,
        "type": "物理",
        "scope": "敵単体",
        "effect_type": "HPダメージ",
        "effect_rate": 3.5,
        "variance": 10,
        "repeats": 1,
        "formula": "user.atk*3.5-target.def",
        "element": "なし",
        "target_add_state": [
            "スタン"
        ],
        "target_add_state_rate": 50,
        "icon_index": 76,
        "animation": "SlashPhysical"
    },
    {
        "name": "取り調べ圧力",
        "class": "警察官",
        "description": "敵全体に取り調べの圧力で、攻撃力と素早さをダウンさせる。",
        "tp": 16,
        "type": "なし",
        "scope": "敵全体",
        "effect_type": "",
        "effect_rate": 0,
        "variance": 0,
        "repeats": 1,
        "formula": "",
        "element": "なし",
        "target_add_state": [
            "攻撃ダウン",
            "素早さダウン"
        ],
        "target_add_state_rate": 80,
        "icon_index": 76,
        "animation": "ShootNormal"
    },
 ...
]

このJSONをもとにRPGツクールMZに取り込むことで、最終的以下のようなスキルデータとして使うことができます。

【保存版】ChatGPTでRPGツクールMZのスキル作成

以下がRPGツクールMZにインポートするために元になるJSONを作った時のChatGPT基本プロンプトです。

[ChatGPTへの入力]

ファンタジーRPGの舞台で現代の職業の人たちがモンスターと戦うRPGを作ります。 
職業ごとの戦闘スキル名と、そのスキルの詳細を決定してください。

以下職業ごとのステータス値です。
ステータスの合計値が低い職業には相対的に強いスキルを設定してください。

[ステータス合計値]
* 警察官:580
* 検察官:589
* 消防士:608
* 医者:583
* 歯医者:556
・・・(以下、前に作った職業名と合計ステータスが100個並ぶ)

[前提]
* 通常攻撃ダメージ = (攻撃キャラのatk × 2 - 敵キャラのdef) × (1 + 乱数変動係数)
* 物理スキルダメージ = (攻撃キャラのatk × 物理スキル係数 - 敵キャラのdef) × (1 + 乱数変動係数
* 魔法スキルダメージ = (攻撃キャラのmat × 魔法スキル係数 - 敵キャラのmdf) × (1 + 乱数変動係数)
* 能力名 = HP、攻撃、防御、魔攻、魔防、素早さ、運
* 属性名 = なし、炎、氷、水、電気、風、土、光、闇
* 良い状態 = 不死身、状態異常無効、<属性名>耐性<N>%アップ、<能力名><N>%アップ、命中率<N>%アップ、回避率<N>%アップ、魔法回避率<N>%アップ、反撃率<N>%アップ、魔法反射率<N>%アップ、毎ターン<N>再生、毎ターンTP<N>再生、狙われ率<N>%アップ、狙われ率<N>%ダウン、防御効果率<N>%アップ、回復効果率<N>%アップ、薬効果率<N>%アップ、TPチャージ率<N>%アップ、物理ダメージ<N>%アップ、魔法ダメージ<N>%アップ、攻撃時<属性名>属性付与、攻撃時<状態異常名>付与、攻撃<N>回追加、身代わり、防御(、その他自由に作成してください)
  * <N>には自然数を入れること
* 状態異常 = 毒、暗闇、沈黙、激昂、混乱、魅了、睡眠、麻痺、スタン、状態異常確率アップ、<属性名>耐性ダウン、<能力名><N>%ダウン(、その他自由に作成してください)
  * <N>には自然数を入れること

[出力形式] JSON形式(JSONのキーは以下の通り、必ずすべてのキーを付けてください)
* name:スキル名
* description:説明文(日本語)
* tp:消費TP(消費TPの1の位は1~4,6~9も設定すること、TPは初回ターン10,最大値100,通常攻撃10回復,防御20回復)
* type:物理、魔法、スキルのどれか
* scope:自分、敵単体、敵全体、敵ランダム、味方単体、味方全体のどれか
* effect_type:なし、HPダメージ、TPダメージ、HP回復、TP回復、TP付与、HP吸収、TP吸収、全回復のどれか
* effect_rate:スキル係数
* distributed:乱数変動係数 単位%(例:10)
* repeats:効果を発動する回数
* formula:基本のダメージ計算式(atk,def,mat,mdf,agi,luk 例: user.atk*effect_rate-target.def)
* element:スキルの属性名
* target_add_state:対象者に付与する良い状態または状態異常の配列
* target_add_state_rate:対象者に良い状態または状態異常を付与する確率
* icon_index:アイコンの種類の数字(毒:2, 暗闇:3, 混乱:6, 睡眠:8, 麻痺:9, スタン:11, バリア:81, 物理:76, 炎:64, 氷:65, 雷:66, 水:67, 土:68, 風:69, 光:70, 闇:71, アップ:73, ダウン:74, 魔法:79, ハート:84, 短剣:96, 剣:97, 斧:99, 杖:101, 弓:102, 槍:107, 帽子:130, 兜:132, 服:135, 鎧:137, 小型盾:129, 盾:128, 手袋:142, 装飾品:146)
* animation:スキルのアニメーション(Absorb、ArrowSpecial、BallsOfLight、Bind、Blind、Bodyslam、Breath、ClawEffect、ClawFire、ClawIce、ClawPhysical、ClawSpecial、ClawThunder、Confusion、CureAll1、CureAll2、CureOne1、CureOne2、DarknessAll1、DarknessAll2、DarknessAll3、DarknessOne1、DarknessOne2、Death、EarthAll1、EarthAll2、EarthAll3、EarthOne1、EarthOne2、FireAll1、FireAll2、FireAll3、FireOne1、FireOne2、Flash、Fog、GeneralSpecial1、GeneralSpecial2、HealAll1、HealAll2、HealOne1、HealOne2、HitEffect、HitFire、HitIce、HitPhysical、HitSpecial1、HitSpecial2、HitThunder、IceAll1、IceAll2、IceAll3、IceOne1、IceOne2、LaserAll、LaserOne、LightAll1、LightAll2、LightAll3、LightOne1、LightOne2、LightPillar1、LightPillar2、NeutralAll1、NeutralAll2、NeutralAll3、NeutralOne1、NeutralOne2、Paralyze、PierceEffect、PierceFire、PierceIce、PiercePhysical、PierceSpecial1、PierceSpecial2、PierceThunder、Poison、Pollen、Powerdown1、Powerdown2、Powerdown3、Powerup1、Powerup2、Powerup3、Radiation、Revive1、Revive2、ShootAll、ShootBarrage、ShootNormal、ShootSpecial、Shout、Silence、SlashEffect、SlashFire、SlashIce、SlashPhysical、SlashSpecial1、SlashSpecial2、SlashSpecial3、SlashThunder、Sleep、Song、SonicWave、Sweep、ThunderAll1、ThunderAll2、ThunderAll3、ThunderOne1、ThunderOne2、WaterAll1、WaterAll2、WaterAll3、WaterOne1、WaterOne2、WindAll1、WindAll2、WindAll3、WindOne1、WindOne2のどれか)

1回ですべてJSON出力できない場合は分けて出力してOKですので、省略はしないでください。

すると以下のようなJSONが出力されていきます。(JSON形式で出なかった場合は、JSON形式で出力することを指摘して下さい)

ChatGPTの出力したJSON(skills.jsonとして保存)

[
    {
        "name": "ジャスティスストライク",
        "description": "敵単体に強力な物理攻撃を行い、「防御ダウン」状態を付与する。",
        "tp": 15,
        "type": "物理",
        "scope": "敵単体",
        "effect_type": "HPダメージ",
        "effect_rate": 3.5,
        "distributed": 10,
        "repeats": 1,
        "formula": "user.atk*3.5-target.def",
        "element": "なし",
        "target_add_state": [
            "防御ダウン"
        ],
        "target_add_state_rate": 100,
        "icon_index": 76,
        "animation": "SlashPhysical"
    }, ...
]

前に作成したアクターのJSON(members.json)と、今回作成したスキルのJSON(skills.json)をもとにRPGツクールMZが解釈できる形式に変換していく流れになります。

ChatGPTプロンプト解説

上記のプロンプトをブロックごとに解説していきます。

はじめに

ファンタジーRPGの舞台で現代の職業の人たちがモンスターと戦うRPGを作ります。 
職業ごとの戦闘スキル名と、そのスキルの詳細を決定してください。

ChatGPTに入力した最初のブロックです。全体の概要として、作りたいRPGの種類と決めてほしい内容(スキル名からスキルの詳細を決める)を書いています。

職業ごとのステータス値

以下職業ごとのステータス値です。
ステータスの合計値が低い職業には相対的に強いスキルを設定してください。

[ステータス合計値]
* 警察官:580
* 検察官:589
* 消防士:608
* 医者:583
* 歯医者:556
・・・(以下、前に作った職業名と合計ステータスが100個並ぶ)

ChatGPTに職業ごとの合計ステータス値を入力しているブロックです。

前の投稿で作った職業ごとのステータス値はばらつきがあります。ステータス的に弱い職業はスキルを強くすることで、全体のバランスを整えたいためこのような指示をChatGPTに出しています。

職業は100個あり、プロンプトを手動で作るのは大変なので、Pythonスクリプトで作成しています。

[members.json]

[
    {
        "name": "ユウスケ",
        "class": "警察官",
        "hp": 123,
        "atk": 92,
        "def": 101,
        "mat": 68,
        "mdf": 56,
        "agi": 77,
        "luk": 63,
        "field_skill": "周囲警戒"
    }, ...
]

上のような「members.json」があるとして、以下のようなPythonスクリプトを実行すれば100職業分のステータス合計値が出力できます。

[show_status.py]

import json

with open("./members.json", mode="r", encoding="utf8") as f:
    members = json.load(f)


print("[ステータス合計値]")
for member in members:
    print(
        f'* {member["class"]}:'
        + str(
            member["hp"] + member["atk"] + member["def"] + member["mat"] + member["mdf"] + member["agi"] + member["luk"]
        )
    )

前提

[前提]
* 通常攻撃ダメージ = (攻撃キャラのatk × 2 - 敵キャラのdef) × (1 + 乱数変動係数)
* 物理スキルダメージ = (攻撃キャラのatk × 物理スキル係数 - 敵キャラのdef) × (1 + 乱数変動係数
* 魔法スキルダメージ = (攻撃キャラのmat × 魔法スキル係数 - 敵キャラのmdf) × (1 + 乱数変動係数)
* 能力名 = HP、攻撃、防御、魔攻、魔防、素早さ、運
* 属性名 = なし、炎、氷、水、電気、風、土、光、闇
* 良い状態 = 不死身、状態異常無効、<属性名>耐性<N>%アップ、<能力名><N>%アップ、命中率<N>%アップ、回避率<N>%アップ、魔法回避率<N>%アップ、反撃率<N>%アップ、魔法反射率<N>%アップ、毎ターン<N>再生、毎ターンTP<N>再生、狙われ率<N>%アップ、狙われ率<N>%ダウン、防御効果率<N>%アップ、回復効果率<N>%アップ、薬効果率<N>%アップ、TPチャージ率<N>%アップ、物理ダメージ<N>%アップ、魔法ダメージ<N>%アップ、攻撃時<属性名>属性付与、攻撃時<状態異常名>付与、攻撃<N>回追加、身代わり、防御(、その他自由に作成してください)
  * <N>には自然数を入れること
* 状態異常 = 毒、暗闇、沈黙、激昂、混乱、魅了、睡眠、麻痺、スタン、状態異常確率アップ、<属性名>耐性ダウン、<能力名><N>%ダウン(、その他自由に作成してください)
  * <N>には自然数を入れること

このブロックではスキル詳細を決定する上での前提条件を入れています。

作るゲームによって、ダメージ計算式や属性名、状態名などをカスタマイズして使います。

ダメージ計算式

* 通常攻撃ダメージ = (攻撃キャラのatk × 2 - 敵キャラのdef) × (1 + 乱数変動係数)
* 物理スキルダメージ = (攻撃キャラのatk × 物理スキル係数 - 敵キャラのdef) × (1 + 乱数変動係数
* 魔法スキルダメージ = (攻撃キャラのmat × 魔法スキル係数 - 敵キャラのmdf) × (1 + 乱数変動係数)

ここはダメージ計算式を定義しています。ChatGPTがスキルのダメージを計算するときの参考にしてもらいます。

能力、属性の定義

* 能力名 = HP、攻撃、防御、魔攻、魔防、素早さ、運
* 属性名 = なし、炎、氷、水、電気、風、土、光、闇

ここは能力や属性の名前です。スキルによって能力が上がったり、攻撃に属性が乗ったりするためここで定義しています。

良い状態、状態異常の定義

* 良い状態 = 不死身、状態異常無効、<属性名>耐性<N>%アップ、<能力名><N>%アップ、命中率<N>%アップ、回避率<N>%アップ、魔法回避率<N>%アップ、反撃率<N>%アップ、魔法反射率<N>%アップ、毎ターン<N>再生、毎ターンTP<N>再生、狙われ率<N>%アップ、狙われ率<N>%ダウン、防御効果率<N>%アップ、回復効果率<N>%アップ、薬効果率<N>%アップ、TPチャージ率<N>%アップ、物理ダメージ<N>%アップ、魔法ダメージ<N>%アップ、攻撃時<属性名>属性付与、攻撃時<状態異常名>付与、攻撃<N>回追加、身代わり、防御(、その他自由に作成してください)
  * <N>には自然数を入れること
* 状態異常 = 毒、暗闇、沈黙、激昂、混乱、魅了、睡眠、麻痺、スタン、状態異常確率アップ、<属性名>耐性ダウン、<能力名><N>%ダウン(、その他自由に作成してください)
  * <N>には自然数を入れること

ここはよい状態や状態異常を定義しています。能力アップであったり属性に耐性が付く場合は全ての項目を書くのは大変なので、<能力名>や<属性名>などプレースホルダー表記しています。

出力形式

[出力形式] JSON形式(JSONのキーは以下の通り、必ずすべてのキーを付けてください)
* name:スキル名
* description:説明文(日本語)
* tp:消費TP(消費TPの1の位は1~4,6~9も設定すること、TPは初回ターン10,最大値100,通常攻撃10回復,防御20回復)
* type:物理、魔法、スキルのどれか
* scope:自分、敵単体、敵全体、敵ランダム、味方単体、味方全体のどれか
* effect_type:なし、HPダメージ、TPダメージ、HP回復、TP回復、TP付与、HP吸収、TP吸収、全回復のどれか
* effect_rate:スキル係数
* distributed:乱数変動係数 単位%(例:10)
* repeats:効果を発動する回数
* formula:基本のダメージ計算式(atk,def,mat,mdf,agi,luk 例: user.atk*effect_rate-target.def)
* element:スキルの属性名
* target_add_state:対象者に付与する良い状態または状態異常の配列
* target_add_state_rate:対象者に良い状態または状態異常を付与する確率
* icon_index:アイコンの種類の数字(毒:2, 暗闇:3, 混乱:6, 睡眠:8, 麻痺:9, スタン:11, バリア:81, 物理:76, 炎:64, 氷:65, 雷:66, 水:67, 土:68, 風:69, 光:70, 闇:71, アップ:73, ダウン:74, 魔法:79, ハート:84, 短剣:96, 剣:97, 斧:99, 杖:101, 弓:102, 槍:107, 帽子:130, 兜:132, 服:135, 鎧:137, 小型盾:129, 盾:128, 手袋:142, 装飾品:146)
* animation:スキルのアニメーション(Absorb、ArrowSpecial、BallsOfLight、Bind、Blind、Bodyslam、Breath、ClawEffect、ClawFire、ClawIce、ClawPhysical、ClawSpecial、ClawThunder、Confusion、CureAll1、CureAll2、CureOne1、CureOne2、DarknessAll1、DarknessAll2、DarknessAll3、DarknessOne1、DarknessOne2、Death、EarthAll1、EarthAll2、EarthAll3、EarthOne1、EarthOne2、FireAll1、FireAll2、FireAll3、FireOne1、FireOne2、Flash、Fog、GeneralSpecial1、GeneralSpecial2、HealAll1、HealAll2、HealOne1、HealOne2、HitEffect、HitFire、HitIce、HitPhysical、HitSpecial1、HitSpecial2、HitThunder、IceAll1、IceAll2、IceAll3、IceOne1、IceOne2、LaserAll、LaserOne、LightAll1、LightAll2、LightAll3、LightOne1、LightOne2、LightPillar1、LightPillar2、NeutralAll1、NeutralAll2、NeutralAll3、NeutralOne1、NeutralOne2、Paralyze、PierceEffect、PierceFire、PierceIce、PiercePhysical、PierceSpecial1、PierceSpecial2、PierceThunder、Poison、Pollen、Powerdown1、Powerdown2、Powerdown3、Powerup1、Powerup2、Powerup3、Radiation、Revive1、Revive2、ShootAll、ShootBarrage、ShootNormal、ShootSpecial、Shout、Silence、SlashEffect、SlashFire、SlashIce、SlashPhysical、SlashSpecial1、SlashSpecial2、SlashSpecial3、SlashThunder、Sleep、Song、SonicWave、Sweep、ThunderAll1、ThunderAll2、ThunderAll3、ThunderOne1、ThunderOne2、WaterAll1、WaterAll2、WaterAll3、WaterOne1、WaterOne2、WindAll1、WindAll2、WindAll3、WindOne1、WindOne2のどれか)

ここではChatGPTが決めたスキル詳細をどのように出力してほしいかを入力しています。詳しく見ていきます。

消費TP

* tp:消費TP(消費TPの1の位は1~4,6~9も設定すること、TPは初回ターン10,最大値100,通常攻撃10回復,防御20回復)

今回のRPGはMP消費ではなくTP消費にしたかったのでtpとしています。普通にMPを使う場合はmpで良いです。

また、1の位を細かく指定しないと20や35など切りのいい数しか出力されなかったため「1の位は1~4,6~9も設定すること」と条件を入れています。

状態付与

* target_add_state:対象者に付与する良い状態または状態異常の配列
* target_add_state_rate:対象者に良い状態または状態異常を付与する確率

使用者や対象者に付与する状態や確率を定義しています。付与する状態は複数になりうるので配列で出力されます。したがって、以下のような回答がChatGPTから返ってくることを想定しています。

{
    "target_add_state": ["麻痺", "毒", "混乱"],
    "target_add_state_rate": 30
}

アイコン

* icon_index:アイコンの種類の数字(毒:2, 暗闇:3, 混乱:6, 睡眠:8, 麻痺:9, スタン:11, バリア:81, 物理:76, 炎:64, 氷:65, 雷:66, 水:67, 土:68, 風:69, 光:70, 闇:71, アップ:73, ダウン:74, 魔法:79, ハート:84, 短剣:96, 剣:97, 斧:99, 杖:101, 弓:102, 槍:107, 帽子:130, 兜:132, 服:135, 鎧:137, 小型盾:129, 盾:128, 手袋:142, 装飾品:146)

スキルにはアイコンが存在します。

ここでは、RPGツクールMZデフォルトのアイコンの種類とアイコン番号(「物理」の場合76)をChatGPTに教えることで、icon_indexをChatGPTに振ってもらっています。

アニメーション

* animation:スキルのアニメーション(Absorb、ArrowSpecial、BallsOfLight、Bind、Blind、Bodyslam、Breath、ClawEffect、ClawFire、ClawIce、ClawPhysical、ClawSpecial、ClawThunder、Confusion、CureAll1、CureAll2、CureOne1、CureOne2、DarknessAll1、DarknessAll2、DarknessAll3、DarknessOne1、DarknessOne2、Death、EarthAll1、EarthAll2、EarthAll3、EarthOne1、EarthOne2、FireAll1、FireAll2、FireAll3、FireOne1、FireOne2、Flash、Fog、GeneralSpecial1、GeneralSpecial2、HealAll1、HealAll2、HealOne1、HealOne2、HitEffect、HitFire、HitIce、HitPhysical、HitSpecial1、HitSpecial2、HitThunder、IceAll1、IceAll2、IceAll3、IceOne1、IceOne2、LaserAll、LaserOne、LightAll1、LightAll2、LightAll3、LightOne1、LightOne2、LightPillar1、LightPillar2、NeutralAll1、NeutralAll2、NeutralAll3、NeutralOne1、NeutralOne2、Paralyze、PierceEffect、PierceFire、PierceIce、PiercePhysical、PierceSpecial1、PierceSpecial2、PierceThunder、Poison、Pollen、Powerdown1、Powerdown2、Powerdown3、Powerup1、Powerup2、Powerup3、Radiation、Revive1、Revive2、ShootAll、ShootBarrage、ShootNormal、ShootSpecial、Shout、Silence、SlashEffect、SlashFire、SlashIce、SlashPhysical、SlashSpecial1、SlashSpecial2、SlashSpecial3、SlashThunder、Sleep、Song、SonicWave、Sweep、ThunderAll1、ThunderAll2、ThunderAll3、ThunderOne1、ThunderOne2、WaterAll1、WaterAll2、WaterAll3、WaterOne1、WaterOne2、WindAll1、WindAll2、WindAll3、WindOne1、WindOne2のどれか)

最後の1文

1回ですべてJSON出力できない場合は分けて出力してOKですので、省略はしないでください。

100人分の職業のスキルは当然1回のChatGPTとのやり取りではすべて出力できません。最後の文章を入れないと省略されたり、GPTが手を抜いたJSONが出力されてしまうので、この文章を入れています。

この文章を入れることで、だいたい1回のやり取りで1職業分のスキル詳細が作成されるので、ChatGPTで出力されたら、

次の職業のスキルものこの形式で出力してください。

と次に入力することで、次の職業のスキル詳細が順番に出力されていきます。

まとめ

今回は職業ごとのスキル詳細(スキルの効果量や状態付与など)を詳細にChatGPTを使って出力していく過程を説明しました。

全体で見たとき、
①アクター作成⇒②スキル作成⇒③RPGツクールMZで使えるファイルに変換
の2番目のプロセスになります。

あとは①②で作ったJSONファイルをRPGツクールMZで使える形に変換すれば実際にデータを扱えるようになります。もうひと手間かかるので、この後の記事で解説していきます。

追記(スキル名修正)

最初は気づかなかったのですが、スキル名を作る時にChatGPTに手を抜かれることがあります。

前半はユニークかつばらけた名前を付けていたのですが、後半は戦闘スキル名の構造がほぼ同じでした。100人のうちの後半は「〇〇ストライク、〇〇アタック、〇〇シールド、〇〇ブラスト」これの繰り返しでした。さすがにもう少しパターンのある名前にしたいのでスキル名は作り直します。

だいぶ苦労しましたが、以下のやり取りでだいぶ名前の付け方が分散されるようになりました。

以下の職業がRPGに出た時のスキル名を条件付きで作成してください。

[出力形式]
・改行無しの文字列配列

[条件]
・「〇〇アタック」「〇〇シールド」「〇〇の魔法」など後ろの単語が重ならないようにすること
・「〇〇者」のように職業自体を言葉にするのではなく、RPGの技名のようにすること
・職業ごとに特徴を出すこと
・一般名詞ではなく固有名詞ぽくすること
・スキル名にはカタカナだけでなく、ひらがなや漢字をまんべんなく使うこと

[職業]
・ウェブセキュリティアナリスト
・トレンドマスター
・フードスタイリスト
・スペースアレンジャー
・アニマルコーチ

ウェブセキュリティアナリスト、トレンドマスター、フードスタイリスト、スペースアレンジャー、アニマルコーチの各職業に対するRPG風の固有名詞スキル名を作成し、指定された条件に従って改行無しの文字列配列で提供します。

ウェブセキュリティアナリスト:

["サイバーセーフガード", "データプロテクトウェーブ", "エンクリプションリボルト", "ネットウォッチャーブロック"]

トレンドマスター:

["ファッションストーム", "スタイルイノベーション", "トレンドセンサー", "カルチャーウェーブラッシュ"]

フードスタイリスト:

["デリシャスエクスプレス", "ガストロナミックイリュージョン", "テイストオブエレガンス", "キュイジーヌクラフト"]

スペースアレンジャー:

["インテリアフュージョン", "ルームリフレクション", "デザインエスケープ", "ハーモニックスペースシフト"]

アニマルコーチ:

["ビーストハーモニー", "アニマルエンパワー", "ペットキネティクス", "クリーチャーカリスマ"]

タイトルとURLをコピーしました