2026 CEDEC 2026 講演資料
宝可梦战斗系统基础设计
宗像快 × 小幡敏宏
从《太阳・月亮》到《剑・盾》,宝可梦战斗系统如何重构以应对复杂化。
摘要
宝可梦战斗系统随系列扩展而复杂化,在开发效率、可维护性与扩展性上遇到瓶颈。讲者介绍以 Section 结构化游戏逻辑、以 Event/EventHandler 分离个别规格的重构方案,并分享在《剑・盾》中的运用案例。
まずポケモンバトルに関して紹介させていただきます ポケモンのバトルには3つの特徴があると考えています 1つ目は、設定データが多く、バトルシステム内で扱う情報量が多い所です ポケモンだけでも1000種類以上あり、技や特性、バトル用の道具も合わせると2400種類以上のデータがあります 新しいシリーズが出る度に、ポケモンや技等が合計200種類以上追加されていきます この膨大なデータ量が、ポケモンバトルの楽しさを生み出していますが、バトルシステムで扱う情報量も多くなり、品質の維持が大変です
首先,请允许我介绍一下宝可梦对战。 我们认为宝可梦对战有三个特征。 第一个特征是,设定数据繁多,对战系统内需要处理的信息量巨大。 仅宝可梦就有1000种以上,再加上招式、特性和对战用道具,数据种类超过2400种。 每当新系列推出时,宝可梦和招式等合计会追加200种以上。 这庞大的数据量造就了宝可梦对战的乐趣,但对战系统需要处理的信息量也随之增大,品质维持十分艰难。
2つ目は、パッシブスキルです 能動的にプレイヤーが発動させるのではなく、条件を満たすと自動で発動するスキルの実装は、ポケモンバトルでは単純な割り込み処理ではなく、場合によっては再帰的な計算が発生するため、複雑な処理順序の制御が必要です パッシブスキルの一例として、特性「いかく」の動画をご覧ください。 特性「いかく」は発動条件が、バトル場に出てきた時で、発動効果としては、敵の攻撃ランクを1段階下げるものになっています
第二个特征是,被动技能。 这类技能并非由玩家主动发动,而是在满足条件时自动发动;在宝可梦对战中,其实现并非单纯的插队处理,有时还会产生递归计算,因此需要复杂的处理顺序控制。 作为被动技能的一个例子,请观看特性「威吓」的动画。 特性「威吓」的发动条件是出场到对战场上时,发动效果则是使对手的攻击等级下降1级。
3つ目は、バトル中のパラメータ変化です 1ターン中に扱うパラメータがほとんどの場合、動的に変化します。 実際の動画をご覧ください。 ゲッコウガは、通常みずタイプとあくタイプです。 特性「へんげんじざい」の発動条件が、技を打つ直前で、発動効果は、打とうとしている技と同じタイプに変化となっています これにより、ゲッコウガは、ひこうタイプに変わります。 このようにバトルの状況に応じて、パラメータが変化し続けます
第三个特征是,对战中的参数变化。 一个回合中处理的参数,在绝大多数情况下都会动态变化。 请观看实际动画。 甲贺忍蛙通常为水属性和恶属性。 特性「变幻自如」的发动条件是出招直前,发动效果是变为即将使出的招式相同的属性。 由此,甲贺忍蛙变为飞行属性。 像这样,参数会随着对战状况不断变化。
この3つの要素が、組み合わさり、相互に影響し合う非常に複雑なシステムが、ポケモンのバトルシステムです この非常に複雑なシステムを各シリーズ毎に個別開発していては、組み合わせの考慮が困難になり、品質の担保が難しくなるため、私たちが所属するポケモン・バトルシステムチームがあります 私たちのチームは、全てのポケモンプロジェクトに参加し、バトルやポケモン部分の実装サポートを行い、品質の担保に努めています このセッションでは、我々の知見の一部を共有させていただき、皆様のゲーム開発・運用の参考になれば幸いです。
这三个要素相互组合、相互影响,构成了极为复杂的系统,这就是宝可梦的对战系统。 若每个系列都单独开发这套极为复杂的系统,组合的考量会变得困难,品质也难以保证,因此才有了我们所属的宝可梦对战系统团队。 我们的团队参与所有宝可梦项目,为对战及宝可梦部分的实现提供支持,致力于保证品质。 本次演讲中,我们希望能分享部分经验,为各位的游戏开发与运营提供参考。
宝可梦对战系统的基础设计
ここからは、ポケモンバトルシステムの基盤設計について説明します。
接下来,说明宝可梦对战系统的基础设计。
最初に、本セッションで紹介するバトルシステムとは何か、について説明します。 まずは動画をご覧ください。 ※動画を再生
首先,说明本次演讲所介绍的对战系统是什么。 请先观看动画。 ※播放动画
先ほどの動画では、プレイヤーが「ほのおのパンチ」を選択し、リザードンが技を放ちました。 ★ほのおのパンチは、ほのおタイプの攻撃技で、10%の確率で相手を「や けど」状態にする効果があります。 リザードンが「ほのおのパンチ」を撃った結果、 ★相手のピカチュウはダメージを受け、 ★「やけど」状態になりました。
刚才的动画中,玩家选择了「火焰拳」,喷火龙使出了招式。 ★火焰拳是火属性的攻击招式,有10%的概率使对手陷入「灼伤」状态。 喷火龙使出「火焰拳」的结果是, ★对手的皮卡丘受到了伤害, ★并陷入了「灼伤」状态。
もう少し複雑なケースを見てみましょう。 ★リザードンに「クラボのみ」という道具を持たせてみます。 ★そして、ピカチュウには「せいでんき」という特性を持たせます。 ★さらに、フィールドの天気を「晴れ」にしてみましょう。 ★この状況で「ほのおのパンチ」を撃つと、何が起こるでしょうか?
让我们看一个稍微复杂一点的案例。 ★让喷火龙携带「樱子果」这个道具。 ★然后,让皮卡丘拥有「静电」这个特性。 ★进一步,把场地的天气设为「晴」。 ★在这种情况下打出「火焰拳」,会发生什么呢?
では、実際の動画をご覧ください。 ※動画を再生 先ほどの動画とは、異なる結果になったことがお判りいただけたと思います。 このように、同じ「ほのおのパンチ」であっても、ポケモンのパラメータやバトル場の状況によって異なる事象が発生することが分かります。
那么,请观看实际的视频。 ※播放视频 我想大家能看出,结果与刚才的视频不同。 像这样,即使是同样的「火焰拳」,根据宝可梦的参数和对战场的状况,也会发生不同的事件。
本セッションで紹介するバトルシステムとは、バトルにおいて発生する事象を決定するシステムです。 ★バトルシステムは入力として、各ポケモンの行動データを受け取ります 。 つまり「誰が、何をするか」という情報です。 ★そして、バトルシステムの出力は、その行動の結果として「何が起こっ たか」を表す情報です。 つまり、バトルシステムとは、「だれが、何をする」という入力データをもとに、「なにが起こるのか?」を計算するシステムとなります。
本环节介绍的战斗系统,是决定对战中发生的事件的系统。 ★战斗系统作为输入,接收各宝可梦的行动数据。 也就是说,是「谁、做什么」这一信息。 ★然后,战斗系统的输出,是表示该行动结果「发生了什么」的信息。 也就是说,战斗系统是基于「谁、做什么」这一输入数据,计算「会发生什么?」的系统。
先ほどの動画に当てはめてみましょう。 ★入力は『リザードンが「ほのおのパンチ」を撃つ』という行動データで す。 バトルシステムは、この入力から発生する事象を計算します。 ★まず、ピカチュウがダメージを受けます。 ★このとき、天気の効果によりダメージが増加しています。 天気「晴れ」には、「ほのお」タイプの技の威力を1.5倍にする効果があります。 ★次に、ピカチュウが「やけど」状態になります。 ★そのあと、ピカチュウの特性「せいでんき」が発動しました。 ★「せいでんき」とは、攻撃を受けたときに、相手に「まひ」の状態異常 を与える特性です。 ★ピカチュウの「せいでんき」の効果により、リザードンが「まひ」状態 になります。 ★ここで、リザードンの「クラボのみ」が発動します。 ★「クラボのみ」という道具は、「まひ」状態になったときに自動的に発 動し、「まひ」状態を治す道具です。
让我们套用到刚才的视频中。 ★输入是『喷火龙打出「火焰拳」』这一行动数据。 战斗系统根据该输入计算发生的事件。 ★首先,皮卡丘受到伤害。 ★此时,由于天气的效果,伤害增加了。 天气「晴」具有将「火」属性招式的威力变为1.5倍的效果。 ★接着,皮卡丘进入「灼伤」状态。 ★之后,皮卡丘的特性「静电」发动了。 ★「静电」是受到攻击时,给予对方「麻痹」异常状态的特性的。 ★由于皮卡丘的「静电」效果,喷火龙进入「麻痹」状态。 ★此时,喷火龙的「樱子果」发动了。 ★「樱子果」这个道具在进入「麻痹」状态时自动发动,是治愈「麻痹」状态的道具。
★「クラボのみ」が発動した結果、リザードンの「まひ」状態が治りました。 ★一番最初に見ていただいた動画と比較すると、 ★天気「晴れ」の効果により、「ほのおのパンチ」のダメージが増加しています 。 ★また、ピカチュウの特性「せいでんき」の発動と、 ★リザードンの道具「クラボのみ」の発動が追加されました。 このように、選択した行動が同じでも、持ち物などの状況によって発生する事象や計算結果は変化します。
★由于「樱子果」发动,喷火龙的「麻痹」状态被治愈了。 ★与最初观看的视频相比, ★由于天气「晴」的效果,「火焰拳」的伤害增加了。 ★此外,皮卡丘的特性「静电」的发动,以及 ★喷火龙的道具「樱子果」的发动被追加了。 像这样,即使选择的行动相同,根据持有物等状况,发生的事件和计算结果也会变化。
繰り返しになりますが、ユーザーが選択した行動から、特性や道具、天気などの状況を加味したうえで、発生する事象を決定することがバトルシステムの役割です。 ★先ほど見ていただいた通り、状況によって計算結果が変化するという性 質を持っています。 ★加えて、実際のバトルでは、相手の行動、バフ、デバフなども介入する ことにより、より複雑な事象に発展します。 ★さらに、技・特性・道具はシリーズを重ねるごとに増加しますが、過去 で登場した仕様は後続タイトルでも同じ挙動を担保する必要があります 。 ★このような状況において、ポケモンシリーズのバトルロジックには、シ リーズを通して、バトルの品質と整合性を担保することが求められます 。 ここからは、その実現のための基盤設計について、課題解決の事例とともに紹介していきます。
重复一下,根据用户选择的行动,在考虑特性、道具、天气等状况的基础上,决定发生的事件,这就是战斗系统的作用。 ★如刚才所见,它具有计算结果会随状况变化的性质。 ★此外,在实际对战中,对方的行动、增益、减益等也会介入,从而发展为更复杂的事件。 ★而且,招式、特性、道具会随着系列累积而增加,但过去登场的规格需要在后续作品中保证相同的行为。 ★在这种情况下,宝可梦系列的战斗逻辑要求在整个系列中保证对战的质量和一致性。 接下来,将结合课题解决的案例,介绍实现这一目标的基础设计。
これからバトルシステムの設計思想を紹介するのですが、設計の話に入る前に、当時のバトル開発の背景をお話しします。 この背景こそが、設計思想に大きく影響しているためです。
接下来将介绍战斗系统的设计思想,但在进入设计话题之前,先谈谈当时战斗开发的背景。 因为这个背景对设计思想产生了很大影响。
簡単にですが、ポケモンバトルの進化の歴史を簡単に振り返ります。 まず初代、赤緑では、特性や道具のない、非常にシンプルなバトルでした。 ★金銀ではタイプや天気が追加され、 ★ルビー・サファイアでは特性とダブルバトルが登場しました。 ★★★以降もトリプルバトルやメガシンカなど、多様なバトル仕様が追加 されてきました。 ★このように進化してきたポケモンバトルでしたが、 これらは実装の観点で見ると、既存システムの拡張の範囲内でした。
简单回顾一下宝可梦对战的进化历史。 首先初代红绿,是没有特性和道具的非常简单的对战。 ★金/银中追加了属性和天气, ★红宝石/蓝宝石中登场了特性和双打对战。 ★★★此后也追加了三打对战、超级进化等多种对战规格。 ★宝可梦对战虽然如此进化, 但从实现的角度来看,这些都在既有系统的扩展范围内。
転機となったのは、2016年の『ポケットモンスターサン・ムーン』でした。 サン・ムーンで登場した「バトルロイヤル」という特殊なバトルを皮切りに、従来の枠組みでは対応しきれない、多様なバトルルールの実装が求められるようになります。
转折点是2016年的《宝可梦 太阳・月亮》。 以太阳・月亮中登场的「皇家对战」这一特殊对战为开端,游戏开始需要实现以往框架无法应对的多样化对战规则。
このように、シリーズを重ねるごとに進化してきたポケモンバトルです が、それに伴い、プログラムも追加と拡張が繰り返し行われ、複雑化していました。 スライドに記載の通り、ファイルの肥大化、クラス責務の過多、密な結合、巨大な関数などが絡み合い、新しい仕様を安全に追加することが困難な状態でした。 ★つまり、当時のバトルシステムは、保守性と拡張性に深刻な課題を抱え ていました。 サン・ムーンの開発終了時、このままでは今後のバトルの進化に対応できないと感じました。 また、「今後のバトルの進化を加速させるには、現行システムの課題を解決し、明快で柔軟な構造に作り替える必要がある」と判断しました。 そこでポケモンバトルチームを結成し、システムの再構築に踏み切った、という背景があります。
如上所述,宝可梦对战随着系列不断进化, 但与此同时,程序也反复进行追加和扩展,变得复杂化。 如幻灯片所述,文件肥大化、类职责过多、紧密耦合、巨大函数等问题相互交织,导致难以安全地追加新规格。 ★也就是说,当时的对战系统在可维护性和可扩展性上存在严重问题。 在太阳・月亮的开发结束时,我们感到这样下去无法应对今后的对战进化。 此外,我们判断「为了加速今后的对战进化,必须解决现行系统的问题,将其重构为清晰灵活的结构」。 于是我们组建了宝可梦对战队伍,决定着手重构系统,这就是当时的背景。
これから紹介するシステムは、『ポケットモンスターソード・シールド』の開発時に行った再構築の成果になります。
接下来介绍的系统,是在《宝可梦 剑・盾》开发时进行重构的成果。
对战系统的设计思想
ここからは、バトルシステムの設計思想を紹介していきます。
接下来,介绍对战系统的设计思想。
先ほど紹介した課題を解消すべく、新しいバトルシステムには、図に示した4つの要件を定義しました。 ★1つ目は「構造化」。クラスの役割分担を明確にし、誰が実装しても同 じ構造になる設計を目指しました。 ★2つ目は「拡張性」。新しい技や特性を、既存コードを変更せずに追加 できることを目指しました。 ★3つ目は「柔軟性」。頻繁な仕様変更に、少ない修正で対応できること を指します。 ★4つ目は「保守性」。理解しやすく、修正、デバッグしやすいことを指 します。 ★本セッションでは、構造化と拡張性に焦点を当てます。 柔軟性と保守性は、この2つを実現した結果として達成される部分が多いため、説明の中で適宜触れていきます。
为了解决刚才介绍的问题,我们为新对战系统定义了图中所示的4项要件。 ★第1项是「结构化」。明确类的职责分担,目标是无论谁来实现都能形成相同的结构。 ★第2项是「扩展性」。目标是在不修改现有代码的情况下追加新招式和特性。 ★第3项是「灵活性」。指能够以较少的修改应对频繁的规格变更。 ★第4项是「可维护性」。指易于理解、修改和调试。 ★本环节将聚焦于结构化和扩展性。 灵活性和可维护性在很多情况下是实现这两项后的结果,因此会在说明中适当提及。
では、具体的な設計について紹介していきます。
那么,接下来介绍具体的设计。
まず着手したのは、ゲームロジックの構造化です。
首先着手的是游戏逻辑的结构化。
ゲームロジックを簡潔に表すための設計として、Sectionという機構を導入しました。
为了简洁地表达游戏逻辑,我们引入了名为 Section 的机制。
ゲームロジックの構造化について、具体例で説明します。 リザードンの「ほのおのパンチ」の処理を例に見てみましょう。 おおまかな処理の流れは図のようになります。 ★まず、ダメージ計算のための攻撃力、防御力を決定します。 このとき、天気「晴れ」を考慮して、リザードンの攻撃力を1.5倍にします。 ★次に、ダメージの数値を計算し、 ★その分だけHPを減少させます。 この一連のゲームロジックは非常にシンプルですが、 ★実際には「ほのおのパンチ」だけでなく、たくさんの技や特性、道具な どの処理を実装する必要があります。 ★そのため、これらを素直に実装していくと、ゲームロジックがどんどん 複雑になっていくことは明白です。
关于游戏逻辑的结构化,我们用具体例子来说明。 以喷火龙的「火焰拳」处理为例来看。 大致的处理流程如图所示。 ★首先,决定用于伤害计算的攻击力、防御力。 此时,考虑天气「晴」,将喷火龙的攻击力变为 1.5 倍。 ★接着,计算伤害数值, ★并相应地减少 HP。 这一系列游戏逻辑非常简单, ★但实际上不仅需要实现「火焰拳」,还需要实现大量招式、特性、道具等 的处理。 ★因此,如果直接实现这些内容,游戏逻辑会不断变得复杂,这是显而易见的。
そこで、処理の「種類」に着目し、 ★図のように「ゲームロジック」と「個別仕様」に分類します。★ ここでいうゲームロジックとは、「何を、どの順番で計算するか」という処理の流れを定義する部分を指します。 また、個別仕様とは、技・特性・道具などの個別の実装を指します。 この例においては、天気「晴れ」の効果が該当します。
于是,着眼于处理的「种类」, ★如图所示,将其分类为「游戏逻辑」与「个别规格」。★ 这里所说的游戏逻辑,指的是定义「计算什么、以何种顺序计算」这一处理流程的部分。 此外,个别规格指的是招式、特性、道具等个别实现。 在此例中,天气「晴」的效果即属于此类。
そして、これらのゲームロジックの最小単位を ★「Section」と名付けました。 攻撃力を決定するSection、防御力を決定するSectionというように、ゲームロジックをSectionの繋がりで表現できるようになりました。 ここで重要なのは、 ★攻撃力決定Sectionに「天気を加味して1.5倍」という個別仕様の実装を 含めない、ということです。 Sectionはあくまでゲームロジックの流れを定義するものであり、細かい個別仕様の実装はSectionから排除する、というルールを敷いています。 このように役割とルールを明確にすることで、Sectionの複雑化を回避するとともに、実装者による実装方法のブレを抑えることができます。 ちなみに個別仕様の部分は、のちほど「拡張性」の話で詳しく説明します。 説明の都合上、いったん、Section以外の部分は隠します。
然后,我们将这些游戏逻辑的最小单位 ★命名为「Section」。 如决定攻击力的 Section、决定防御力的 Section 这样,游戏逻辑可以用 Section 的连接来表达。 这里重要的是, ★不在攻击力决定 Section 中包含「考虑天气变为 1.5 倍」这一 个别规格的实现。 Section 终究只是定义游戏逻辑流程的东西,我们制定了将细部个别规格的实现从 Section 中排除的规则。 通过这样明确角色与规则,可以避免 Section 的复杂化,同时抑制实现者之间实现方式的偏差。 顺带一提,个别规格的部分将在之后「扩展性」的话题中详细说明。 出于说明的方便,暂时隐藏 Section 以外的部分。
そして、Sectionの話に戻ります。
那么,回到 Section 的话题。
Sectionは階層構造を持つことができます。 たとえば、 ★攻撃力決定、防御力決定、ダメージ算出という一連の流れは、ダメージ 計算Sectionとしてまとめることができます。 ダメージ計算Sectionの内訳として、攻撃力決定、防御力決定、ダメージ計算Sectionが存在する、という構造になります。
Section 可以具有层级结构。 例如, ★攻击力决定、防御力决定、伤害算出这一系列流程,可以归纳为伤害 计算 Section。 其结构为:作为伤害计算 Section 的内部构成,存在攻击力决定、防御力决定、伤害计算 Section。
次に、ダメージ計算、HP減少の処理、 ★つまり、この処理全体は、ダメージを与える処理なので、ダメージ付与 Sectionとしてまとめることができます。
接着,伤害计算、HP 减少的处理, ★也就是说,这整个处理是造成伤害的处理,因此可以归纳为伤害赋予 Section。
さらに、 ★この全体の流れは、 「ほのおのパンチ」という技の効果を計算する処理なので、「技効果Section」と名付けることができます。
进一步地, ★这整个流程是 计算「火焰拳」这一招式效果的处理,因此可以命名为「招式效果 Section」。
これで、「ほのおのパンチ」でダメージを与える処理のゲームロジックが完成しました。
至此,用「火焰拳」造成伤害处理的游戏逻辑就完成了。
しかし、 ★「ほのおのパンチ」は追加効果で状態異常を付与する技です。 これを実装するために、 ★技効果Sectionの中に、 ★状態異常付与Sectionを追加します。
但是, ★「火焰拳」是通过追加效果赋予状态异常的招式。 为了实现这一点, ★在招式效果 Section 中, ★追加状态异常赋予 Section。
これで、「ほのおのパンチ」のゲームロジックを整理することができました。 このように、ゲームロジックを再利用可能な単位で分割し、適切な名前を付けていく。 これにより、ゲームロジックの本筋が理解しやすい形に整理できます。 また、ゲームロジックの構造化において大切なのは、「役割とルールを明確化する」ということです。 個別仕様をSectionから除外することで、Sectionの複雑化を抑え、ゲームロジック全体の見通しを良くしています。
至此,我们成功整理了「火焰拳」的游戏逻辑。 像这样,将游戏逻辑拆分为可复用的单位,并赋予恰当的名称。 由此,可以将游戏逻辑的主线整理成易于理解的形式。 此外,在游戏逻辑的结构化中,重要的是「明确职责与规则」。 通过将个别规格从 Section 中排除,抑制了 Section 的复杂化,改善了游戏逻辑整体的可读性。
次に拡張性について説明します。 ポケモンのバトルシステムにおける拡張性とは、既存のコードを変更せずに、技や特性を追加できること、また、不要な仕様をビルドから削除できること、と定義しています。 ポケモンはシリーズを重ねるごとに技・特性・道具が追加されます。 技や特性が追加されるほど、組み合わせの考慮が必要となり、ゲームロジックは複雑化します。 そのため、ゲームロジックが継続的な拡張に耐えうる設計であることは、非常に重要です。
接下来说明扩展性。 在宝可梦的对战系统中,扩展性被定义为:无需修改既有代码即可追加招式与特性,并且可以从构建中删除不需要的规格。 宝可梦随着系列不断推出,招式、特性和道具会不断增加。 招式与特性增加得越多,就越需要考虑组合,游戏逻辑也会变得复杂。 因此,游戏逻辑能够承受持续扩展的设计是非常重要的。
この課題に対応するため、「Event」と「EventHandler」という機構を設計しました。
为了应对这一课题,我们设计了「Event」和「EventHandler」这一机制。
EventとEventHandlerを説明するために、「ほのおのパンチ」のゲームフローに戻ります。 ★この、攻撃力決定Sectionに着目します。
为了说明 Event 和 EventHandler,我们回到「火焰拳」的游戏流程。 ★关注这个攻击力决定 Section。
例えば「攻撃力を決定するSection」では、 ★天気・特性・道具など、多くの仕様を考慮する必要があります。 天気による攻撃力上昇のほか、特性「もうか、ちからもち、こんじょう」、道具「こだわりハチマキ、でんきだま、ふといほね」など、攻撃力を補正する仕様を挙げると、きりがありません。 これらを愚直に実装すると、攻撃力決定Sectionに処理をどんどん追加することになります。 この方法では、Sectionの実装が複雑になり、保守性が低下します。 また、特性や道具はシリーズを重ねるごとに増えますので、Sectionがどんどん複雑になっていくことは明らかです。 そこで、技・特性・道具などの個別仕様を実装する仕組みとして、EventとEventHandlerを導入しました。
例如在「决定攻击力的 Section」中, ★需要考虑天气、特性、道具等诸多规格。 除了天气带来的攻击力提升外,特性「猛火、大力士、毅力」、道具「讲究头带、电气球、粗骨头」等修正攻击力的规格,列举起来没完没了。 如果直接实现这些,就会不断向攻击力决定 Section 中追加处理。 这种方法会使 Section 的实现变得复杂,降低可维护性。 而且,特性和道具会随着系列不断增多,Section 变得越来越复杂是显而易见的。 因此,我们引入了 Event 和 EventHandler,作为实现招式、特性、道具等个别规格的机制。
EventとEventHandlerについて説明します。 ★まず、SectionがEventを発火します★ Eventは、個別仕様がSectionの計算に介入できるポイントです。 ★このEventにEventHandlerが反応し、 ★Sectionが行う計算の結果に影響を与える、という関係になります。 この構造により、個別仕様の実装がSectionから分離されます。 その結果として、ゲームロジック本体を変更せずに、個別仕様を追加することを可能としています。
说明 Event 和 EventHandler。 ★首先,Section 触发 Event★ Event 是个别规格能够介入 Section 计算的切入点。 ★EventHandler 响应该 Event, ★对 Section 进行的计算结果产生影响,就是这样的关系。 通过这种结构,个别规格的实现从 Section 中分离出来。 其结果是,使得在不修改游戏逻辑本体的情况下追加个别规格成为可能。
例えば、攻撃力を決定するSectionに当てはめてみます。 ★まずSectionが、攻撃力を補正するためのEventを発火します。 ★このEventに対し、天気「晴れ」のEventHandlerが反応することで、攻撃 力を1.5倍に補正します。 ★さらに、特性「もうか」や ★道具「こだわりハチマキ」など、 それぞれのEventHandlerも、必要に応じて攻撃力を補正することができます。 もちろん、重ね掛けも発生します。 このように、複数の要因による補正を加味して、最終的な攻撃力を決定する、という構造になります。
例如,试着套用到决定攻击力的 Section 上。 ★首先,Section 会触发用于补正攻击力的 Event。 ★针对这个 Event,天气「晴天」的 EventHandler 作出反应,从而将攻击力补正为 1.5 倍。 ★此外,特性「猛火」或 ★道具「讲究头带」等, 各自的 EventHandler 也可以根据需要补正攻击力。 当然,也会发生叠加。 像这样,将多个因素带来的补正一并纳入考量,最终决定攻击力,就是这样的结构。
「ほのおのパンチ」の例に当てはめてみます。
试着套用到「火焰拳」这个例子上。
さきほど紹介したように、 ★攻撃力決定Sectionから攻撃力補正Eventが発行され、 ★天気「晴れ」のEventHandlerが攻撃力を1.5倍にします。
正如刚才介绍的, ★从攻击力决定 Section 发出攻击力补正 Event, ★天气「晴天」的 EventHandler 将攻击力变为 1.5 倍。
また、実際には、 ★たくさんのEventHandlerが存在しています。 ちなみに、 ★他のSectionにも、たくさんのEventHandlerが存在しています。 これらを全てSectionで実装すると、Sectionがどんどん肥大化することは明らかですね。
另外,实际上, ★存在着大量的 EventHandler。 顺带一提, ★其他 Section 中也存在着大量的 EventHandler。 如果把这些全部在 Section 中实现,Section 显然会不断膨胀。
また、同じHandlerは複数のEventに反応することができます。 たとえば、 ★天気「晴れ」は、 ★「ほのおタイプの技の威力を1.5倍にする」という効果と、 ★「みずタイプから受けるダメージを0.5倍にする」という、複数の効果 を持ち合わせています。 ★そのため、「晴れ」のEventHandlerは、攻撃力補正Eventと防御力補正 Eventの両方に反応するわけです。 もし、この実装をSection側で行った場合、「晴れ」に関する実装が複数のSectionに散らばることになります。 しかし、EventHandlerに両方の実装が集約されることで、実装が一か所に集約され、保守性の向上に貢献します。
此外,同一个 Handler 可以响应多个 Event。 例如, ★天气「晴天」拥有 ★「将火属性招式的威力变为 1.5 倍」这一效果,以及 ★「将受到的水属性伤害变为 0.5 倍」这一效果, ★具备多个效果。 ★因此,「晴天」的 EventHandler 会同时响应攻击力补正 Event 和防御力补正 Event。 如果把这个实现放在 Section 侧进行,与「晴天」相关的实现就会分散到多个 Section 中。 但是,通过将两方面的实现都汇集到 EventHandler 中,实现就能集中在一处,有助于提升可维护性。
まとめると、EventとEventHandlerには、次の3つの利点があります。 ★1つ目は、メインロジックを変更せずに個別仕様を追加できること。 ★2つ目は、不要な仕様をビルドから除外できること。 タイトルに登場しない技・特性・道具は、EventHandlerを登録しないようにするだけで、簡単にゲームから除外することができます。 ★3つ目は、タイトル固有の仕様の実装を分離できることです。 例えば、メガシンカやテラスタルといった大型仕様は、シリーズを通して登場する仕様ではありません。 これらもEventHandlerとして実装することで、ゲームロジック本体を変更せずに実装することを可能とします。
总结来说,Event 与 EventHandler 有以下 3 个优点。 ★第一,可以在不修改主逻辑的情况下追加个别规格。 ★第二,可以将不需要的规格从构建中排除。 对于未在标题中登场的招式、特性、道具,只要不注册 EventHandler,就能简单地将其从游戏中排除。 ★第三,可以将标题固有规格的实现分离出来。 例如,超级进化、太晶化这类大型规格,并非贯穿整个系列都会登场的规格。 通过将这些也作为 EventHandler 实现,就能在不修改游戏逻辑本体的情况下完成实现。
さらに、このEvent/EventHandlerの仕組みには、もう1つ重要な機能があります。 それは、ポケモンバトル特有の「割り込み」と「連鎖」の実現です。
而且,这个 Event/EventHandler 机制还有另一个重要功能。 那就是实现宝可梦对战特有的「插入」与「连锁」。
ここで、割り込み、連鎖とは何か説明します。 もう一度、動画を見てみましょう。 ※動画を流す 割り込みと連鎖とは何かというと、この例における「せいでんき」と「クラボのみ」の発動を指します。 リザードンの「ほのおのパンチ」の処理に対し、ピカチュウの「せいでんき」が割り込んで発動しています。 また、ピカチュウの「せいでんき」に反応して、リザードンの「クラボのみ」の発動が連鎖しています。 これらをどのように実現しているのか、説明します。
在这里,说明一下什么是插入、连锁。 再看一次视频。 ※播放视频 所谓插入与连锁,指的是这个例子中「静电」与「樱子果」的发动。 针对喷火龙的「火焰拳」处理,皮卡丘的「静电」插入并发动。 此外,响应皮卡丘的「静电」,喷火龙的「樱子果」的发动发生了连锁。 下面说明这些是如何实现的。
「ほのおのパンチ」のゲームロジックに戻ります。 ★ここに、ピカチュウの「せいでんき」を実装することを考えてみます。 いったん、説明に不要なSectionを消します。
回到「火焰拳」的游戏逻辑。 ★在这里,考虑实现皮卡丘的「静电」。 暂时删除说明中不需要的 Section。
「せいでんき」でリザードンを「まひ」にする処理を追加したいのです が、これを素直に実装すると、 ★既存のゲームフローに「状態異常付与Section」の呼び出しをもう1つ追 加する必要があります。 ★しかし、この方法ではゲームロジックの拡張が必要になります。 技・特性・道具は増え続けるため、ゲームフローの複雑化に歯止めがかかりません。 いったん、ゲームフローをリセットします。
想要追加通过「静电」使喷火龙陷入「麻痹」的处理, 但如果直接实现, ★就需要在既有游戏流程中再添加一个「状态异常赋予 Section」的调用。 ★然而,这种方法需要扩展游戏逻辑。 由于招式、特性和道具会不断增加,游戏流程的复杂化将无法遏制。 暂时重置游戏流程。
そこで、EventHandlerに、任意のSectionを呼び出せる機能を追加しました 。 これにより、EventHandlerは計算結果への介入だけでなく、新たな事象を発生させることができるようになりました。 ★「せいでんき」を実現するために、技効果Sectionの最後に、技効果後処 理のSectionを追加します。 ★そして、技効果後処理Sectionからは、リアクションEventというEventを 発火するようにします。 これまで説明してきたEventHandlerは、Sectionの計算結果に影響を与えるだけでしたが、新たなゲームフローを発生させる機能を持たせることにより、 ★リアクションEventに反応した「せいでんき」のEventHandlerが状態異常 付与Sectionを呼ぶ、という方法でゲームロジックの拡張を行います。 ★結果として、リザードンが「まひ」状態になります。
因此,我们为 EventHandler 添加了可调用任意 Section 的功能。 由此,EventHandler 不仅能介入计算结果,还能引发新的事件。 ★为了实现「静电」,在招式效果 Section 的最后,添加招式效果后处理 Section。 ★然后,从招式效果后处理 Section 触发名为 Reaction Event 的 Event。 此前说明的 EventHandler 仅影响 Section 的计算结果,但通过赋予其引发新游戏流程的功能, ★由响应 Reaction Event 的「静电」EventHandler 调用状态异常赋予 Section,以此方式扩展游戏逻辑。 ★结果,喷火龙陷入「麻痹」状态。
さらに、リザードンが持つ「クラボのみ」の発動まで見てみましょう。 クラボのみは、「まひ」状態になったとき自動的に発動して、「まひ」 を回復する道具です。 ★状態異常付与Sectionから状態異常Eventを発火し、 ★「クラボのみ」EventHandlerを反応させます。 ★「クラボのみ」EventHandlerは、状態異常回復Sectionを呼ぶことで、 ★所有者であるリザードンの「まひ」を治す、という流れになります。 このように「Section → Event → EventHandler → Section」という再帰的な構造により、ポケモンバトル特有の複雑な割り込みと連鎖を、整理された形で実現しています。 メインフローを変更せずにゲームフローを拡張でき、EventHandlerの有無でタイトルごとのカスタマイズも可能としています。
进一步,看看喷火龙持有的「樱子果」的发动。 樱子果是在陷入「麻痹」状态时自动发动、治愈「麻痹」的道具。 ★从状态异常赋予 Section 触发状态异常 Event, ★让「樱子果」EventHandler 响应。 ★「樱子果」EventHandler 调用状态异常回复 Section, ★从而治愈持有者喷火龙的「麻痹」,形成这样的流程。 如此,通过「Section → Event → EventHandler → Section」的递归结构,以整理后的形式实现了宝可梦对战特有的复杂插入与连锁。 可以在不修改主流程的情况下扩展游戏流程,并且通过 EventHandler 的有无,也能实现各作品的定制。
ここでポイントとなるのは、この一連の流れの中で同じSectionが再帰的に呼ばれ得る、ということです。 たとえば、 ★「状態異常付与Section」は、 「ほのおのパンチ」でピカチュウが「やけど」になるときに呼ばれます し、 ★「せいでんき」でリザードンが「まひ」になるときにも呼ばれます。★ ★ただし、最初の状態異常Eventでは「クラボのみ」は発動しません。 これは、最初のEvent時点ではリザードンが状態異常でないため、つまり、「クラボのみ」の発動条件を満たしていないためです。 このように、EventHandlerにはそれぞれ発動条件を設定することができますが、逆に言うと、発動条件を満たしさえすれば、いくらでもSectionがつながり得るということになります。 この構造こそが、ポケモンバトルのパッシブスキルによる割り込み、および連鎖の挙動を実現しています。
这里的要点是,在这一系列流程中,同一个 Section 可能被递归调用。 例如, ★「状态异常赋予 Section」在 「火焰拳」使皮卡丘陷入「灼伤」时会被调用, ★在「静电」使喷火龙陷入「麻痹」时也会被调用。★ ★不过,在最初的状态异常 Event 中「樱子果」不会发动。 这是因为在最初的 Event 时点喷火龙并非状态异常,也就是说,不满足「樱子果」的发动条件。 如此,EventHandler 可以分别设置发动条件,但反过来说,只要满足发动条件,Section 就可以无限连接下去。 正是这种结构,实现了宝可梦对战中被动技能带来的插入与连锁行为。
以上で、リザードンの「ほのおのパンチ」の実行フローを図のように整理できました。 ★「ほのおのパンチ」の処理は「技効果Section」であり、 ★その内訳は、ダメージ付与Section、状態異常付与Section、技効果後処理 Sectionのように、Sectionのつながりで表現されます。 ★また、ゲームロジックがSectionで表現されるのに対し、個別仕様は EventHandlerという形で実装されていて、Sectionの計算結果に影響を与える、という構造を紹介しました。 ★さらに、EventHandlerの重要な機能として、任意のSectionを呼び出せる ことを説明しました。 この構造により、メインとなるゲームロジックを変更することなく、様々な事象を連鎖させ、ゲームロジックを拡張することができることを紹介しました。
以上,喷火龙的「火焰拳」执行流程可以如图整理。 ★「火焰拳」的处理是「招式效果 Section」, ★其内部由伤害赋予 Section、状态异常赋予 Section、招式效果后处理 Section 等 Section 的连接来表示。 ★此外,游戏逻辑由 Section 表示,而个别规格以 EventHandler 的形式实现,并影响 Section 的计算结果,介绍了这样的结构。 ★并且,说明了 EventHandler 的重要功能:可以调用任意 Section。 通过这种结构,介绍了可以在不修改主游戏逻辑的情况下,使各种事象连锁并扩展游戏逻辑。
ここまでに紹介した設計についてまとめます。 ★まず、ゲームロジックを機能単位で分割し、「Section」として階層構造 で表現しました。 これにより、ゲームロジックの見通しが良くなり、構造化を実現しました。 ★次に、「Event」と「EventHandler」により、個別仕様をゲームロジック 本体から分離しました。 これにより、既存コードを変更せずに技・特性・道具を追加でき、拡張性を実現しました。 さらに、EventHandlerからSectionを呼び出せる構造により、ポケモンバトル特有の割り込みと連鎖を整理された形で実現しています 。 ★これらの設計により、シリーズを通してバトルの品質と整合性を担保す る基盤を構築しました。 では、このバトルシステムをどのように活用、発展させてきたのか、
总结目前为止介绍的设计。 ★首先,将游戏逻辑按功能单位分割,并以「Section」的形式表现为层级结构。 由此,游戏逻辑的可见性变好,实现了结构化。 ★其次,通过「Event」和「EventHandler」,将个别规格从游戏逻辑本体中分离。 由此,可以在不修改既有代码的情况下添加招式、特性和道具,实现了扩展性。 并且,通过 EventHandler 可调用 Section 的结构,以整理后的形式实现了宝可梦对战特有的插入与连锁。 ★通过这些设计,构建了在整个系列中保障对战质量与一致性的基础。 那么,这个对战系统是如何被活用和发展的,
これまでの運用事例とともに紹介します
将结合此前的运用案例进行介绍
ここからは、発売済みタイトルでの運用事例に関して説明させていただきます 今回は構造化と拡張性がどのように役立ったか、『Pokémon LEGENDS Z-A』(以下、ZA)のバトルを例に説明したいと思います まずZAはどのようなバトルだったか?を知っていただくため、動画を御覧ください技によって届く距離や範囲が違うため、繰り出すタイミングやポジションが勝敗を左右します パートナーのポケモンを導き、攻撃を避けたり、時には交代しながらチャンスを見つけて技を仕掛けるバトルです ZAのバトルは今までのターン制バトルとは異なり、リアルタイム制バトルでした 結論から先に言いますと、異なるバトル形式でも同じバトルシステムを使っています どのようにして同じバトルシステムを使ったのか、説明させていただきます
接下来,我将说明已发售作品中的运用案例 这次想以《Pokémon LEGENDS Z-A》(以下简称ZA)的对战为例,说明结构化与扩展性是如何发挥作用的 首先,为了让大家了解ZA是怎样的对战,请观看视频。不同招式可触及的距离和范围不同,因此出招的时机和位置会左右胜负 这是一场引导伙伴宝可梦、躲避攻击、有时通过替换来寻找机会施展招式的对战 ZA的对战与以往的回合制对战不同,是实时制对战 先说结论:即使是不同的对战形式,我们也使用了相同的对战系统 下面说明我们是如何使用相同对战系统的
まずは構造化がどのように役だったのか説明させていただきます 同じバトルシステムを使ったということで、ソード・シールドやスカーレット・バイオレットで使われていたターン制バトルシステムのセクションの階層構造をざっくり説明させてください ★ターン制バトルでは、行動実行セクションという1ターン分の行動をま とめて入力としてもらい、出力として、1ターン中に起きる全ての事象を返すゲームロジックがあります ★ポケモンバトルの行動には、技を使う、別のポケモンに交代する等があ りますが、今回の例は技を選択したパターンになります 行動実行セクションは、行動選択の結果を受け取り、行動処理を動かします 技を選択した行動の場合、技効果セクションが動きます ★技効果セクション内では、発動判定セクション、★命中判定セクション 、★ダメージ付与セクションが順番に動きます 発動判定セクションでは、こおり状態で動けない等のチェック処理を行っています
首先说明结构化是如何发挥作用的 既然使用了相同的对战系统,请允许我大致说明在《剑/盾》和《朱/紫》中使用的回合制对战系统的区段(section)层级结构 ★在回合制对战中,有一个行动执行区段,它接收一回合份的行动作为输入,并作为输出返回一回合中发生的所有事件,这是游戏逻辑 ★宝可梦对战的行动包括使用招式、替换为其他宝可梦等,本次示例为选择招式的模式 行动执行区段接收行动选择的结果,并驱动行动处理 在选择招式的行动中,招式效果区段会运行 ★在招式效果区段内,发动判定区段、★命中判定区段、★伤害赋予区段会依次运行 发动判定区段会进行诸如因冰冻状态而无法行动等检查处理
命中判定セクションでは、技の命中率、対象の回避率等を元に命中するかの計算処理を行っています ダメージ付与セクションでは、タイプ相性を加味したダメージ計算を行っています ターン制バトルの肝となる行動実行セクションは、出力として、1ターン中に起きる全ての事象を返す必要があるため、本スライドでは簡略化しておりますが、実際は多くのセクションが実行されています
命中判定区段会根据招式命中率、目标闪避率等进行是否命中的计算处理 伤害赋予区段会进行考虑属性相性的伤害计算 作为回合制对战核心的行动执行区段,需要作为输出返回一回合中发生的所有事件,因此本页幻灯片中做了简化,但实际上会执行许多区段
続きましてZAのバトルを説明させていただきます リアルタイム制バトルは、時間と共に状況が刻々と変わっていくため、行動実行セクションや技効果セクションは、処理の粒度が大きく、不要なセクションと判断しました★また命中判定セクションにおいては、リアルタイム制バトルに合わせて、コリジョン同士の衝突判定に変える必要がありました★発動判定セクションやダメージ付与セクションは、リアルタイム制バトルにおいても、仕様は変わらず、再利用可能なセクションでした このようにセクション視点で見ると、ターン制バトルで使っていたセクションの中にも再利用可能なものが沢山あり、全く異なるバトルとは言えませんでした 仕様に合わせて、セクションの呼び出し順番や中身の処理を変えたり、取捨選択が出来るのは、基盤設計の構造化のおかげになります
接下来说明ZA的对战 实时制对战中,状况会随时间不断变化,因此行动执行区段和招式效果区段的处理粒度过大,被判断为不需要的区段。★另外,在命中判定区段中,需要配合实时制对战改为碰撞体之间的碰撞判定。★发动判定区段和伤害赋予区段在实时制对战中规格不变,是可以复用的区段 这样从区段的视角来看,回合制对战中使用的区段里也有许多可以复用的,因此不能说完全是不同的对战 能够根据规格改变区段的调用顺序和内部处理,或进行取舍选择,这得益于基础设计的结构化
ZAバトルでどのようにセクションが使われたのか、具体的に説明させていただきます では改めて実際のZAバトルをご覧ください
我将具体说明ZA对战中区段是如何被使用的 那么请再次观看实际的ZA对战
このバトルでは、技のボタンが押されると技発動できるか判定セクションが呼ばれます★その後は、判定結果に応じたリアクションを行います 技発動が可能となった場合は、ポケモンが技を出します★命中判定セクションではなく、コリジョン同士の衝突判定により、命中判定がされます★ ★命中した場合、★ダメージ付与セクションが呼ばれ、ダメージ反映がさ れます このような感じでZAバトルでは、ゲーム挙動に合う形に発動判定セクションとダメージ付与セクションをバトルシステムから切り出し、使いました
在这场对战中,当按下招式按钮时,会调用判定招式能否发动的区段。★之后根据判定结果进行相应的反应 如果招式可以发动,宝可梦就会出招。★此时不是通过命中判定区段,而是通过碰撞体之间的碰撞判定来进行命中判定 ★命中时,会调用★伤害赋予区段,并反映伤害 像这样,在ZA对战中,我们将发动判定区段和伤害赋予区段从对战系统中切分出来,以符合游戏行为的形式加以使用
続いては、拡張性がどのように役だったのか説明させていただきます 拡張性は先ほど小幡から説明した通りのことをやっているだけですので、実用例を簡単に説明したいと思います ZAバトルはターン処理が存在しないバトルでした そのため、ターン処理を前提に組まれた技効果を変える必要がありました ZAバトルで技効果を変えた技をご覧ください。 ターン制バトルの「まもる」は、ターンの間、相手の技を受けない仕様でしたが、ZAでは、一定時間「まもる」状態となり、相手の技を受けない仕様でした
接着说明扩展性是如何发挥作用的 扩展性只是做了刚才小幡说明过的事情,因此我想简单说明实际案例 ZA对战是不存在回合处理的对战 因此,需要改变以回合处理为前提构建的招式效果 请看ZA对战中改变了招式效果的招式。 回合制对战中的“守住”是在一回合内不受到对手招式攻击的规格,但在ZA中,是变为一定时间的“守住”状态,不受到对手招式攻击的规格
ターン制のまもるハンドラは、発動判定セクションで呼ばれるイベントに反応し、発動を失敗させる処理でしたが ★ZAのバトルでは、ターン制のハンドラは不要なため、★削除し、 代わりに★ダメージ付与セクションで呼ばれるイベントに反応し、ダメージを0にするまもるハンドラを作成しました★このように技効果を変える場合は、基本的に不要なイベントハンドラを削除し、必要に応じて新しい仕様のイベントハンドラを作成するだけで済みます これは基盤設計の拡張性のおかげになります また一度作った効果のイベントハンドラは、再利用することが出来るのも利点です
回合制的守住处理器,是响应发动判定区段中调用的事件,使发动失败的处理, ★但在ZA对战中,回合制的处理器不需要,因此★将其删除, 取而代之,创建了响应★伤害赋予区段中调用的事件、将伤害变为0的守住处理器。★像这样改变招式效果时,基本上只需删除不需要的事件处理器,并根据需要创建新规格的事件处理器即可 这得益于基础设计的扩展性 此外,一旦创建的效果事件处理器可以复用,这也是一个优点
運用事例のまとめです 構造化と拡張性を軸にした基盤設計により、共通のバトルシステムで、ターン制からリアルタイム制まで、多様なバトルに対応できました 複雑性の高いシステムほど、コードの再利用性を高めることで保守性と安定性の向上につながります 共通のバトルシステム上で異なるバトルを構築できたことが開発効率と品質の安定化に貢献したと考えています
运用案例总结 以结构化和扩展性为核心的基盘设计,使得通过共通的战斗系统,能够应对从回合制到实时制的多种战斗 系统越复杂,越应通过提高代码复用性来提升可维护性与稳定性 我们认为,能够在共通战斗系统上构建不同的战斗,为开发效率与质量稳定化做出了贡献
さいごに、本セッションのまとめです ポイントは2つです。
- ゲームロジックを「再利用可能な単位」で分割すること2. 個別仕様を「メインロジックから分離」することこの2点を意識することで、保守性と拡張性を両立できます。 本セッションで紹介したSectionとEvent/EventHandlerの設計は、ポケモンに限らず、複雑化し続けるゲームロジック全般に適用できる考え方です。 皆様のゲーム開発の参考になれば幸いです。
最后,本场会议的总结 要点有两个。
- 将游戏逻辑分割为「可复用的单位」2. 将个别规格「从主逻辑中分离」有意识地做到这两点,即可兼顾可维护性与扩展性。 本场会议介绍的 Section 与 Event/EventHandler 设计,不仅适用于宝可梦,也适用于不断复杂化的游戏逻辑整体。 希望能为各位的游戏开发提供参考。