Epic Gamesが開発中のプログラミング言語「Verse」って知ってる?編集部員が感じる2つの特徴「ロールバック」「非同期処理」などを解説

2024.06.12
注目記事ルールをつくるしくみをつくるUEFNプログラム
この記事をシェア!
Twitter Facebook LINE B!
Twitter Facebook LINE B!

ゲームメーカーズ編集部の神谷です。本記事では、Epic Gamesが開発するプログラミング言語「Verse」について紹介します。

Verseは個人開発で使っており、モダンだし自分の好みと合うしと魅力を感じています。使用環境が限定されているため人口は少ないのですが、将来性も感じる言語です。もっとたくさんの方に触ってもらえるよう、筆を執りました。

Verseが持つ2つの大きな特徴のほか、私が感じているUnreal Engine 5(以下、UE5)におけるブループリントとの相違点を説明します。

TEXT / 神谷 優斗

EDIT / 藤縄 優佑

目次

※ 本記事は、2024年6月12日時点での情報に基づいて執筆しています

Verseとは

Verseとは、命令型オブジェクト指向関数型の思想を取り入れた静的型付け言語です。『フォートナイト』上で動作するゲーム制作ツール「Unreal Editor for Fortnite(以下、UEFN)」で利用できます。

Verseには、オープンワールドかつマルチプレイヤーのゲームを実行できる高いパフォーマンスなどが設計思想として掲げられています。

記事執筆時点ではUEFN上でのみ使用できますが、2024年後半には、UEFNに依存せずスタンドアローンで動作するVerse(開発内部では「MaxVerse」と呼ばれている)のリリースが予定されています。

関連記事
UE6にはフォートナイト用の言語「Verse」が導入される?GDC 2024のVerse講演から見るアンリアルエンジンの今後
2024.04.22

Verseの構文

まずは、Verseの構文についての基本を解説します。

Verseにおいては、クラスや変数、関数の宣言・定義は以下のように記述します。

sample_class<public>:= class(sample_abstract_class, sample_interface):
    ImmutableVariableA<public>: string
    var MutableVariableB<private>: int = 1

    SampleFunc<public>(HogeArg: int, FugaArg: float): void=
        Print("This is sample text")

一行目に書かれているのはクラスの宣言です。Verseでは基本的に「クラス名:= class(親クラス):」の形でクラスを宣言します。

変数宣言と定義は、「変数名: 変数の型 = 初期値」で記述します。初期値を指定せず、宣言のみの記述も可能です。

変数は基本的に不変。可変変数にする場合は、変数名の前にvarを付ける。詳細は本記事の「そのほかの特徴」を参照

関数は、「関数名(引数): 戻り値=」で記述します。

Verseでは、関数に「エフェクト」が付与されます。エフェクトとは、関数の特性のようなイメージです。

例えば、<transacts>エフェクトのついた関数は、関数で実行される処理がすべてロールバック可能であることを示します(本記事の「特徴1. ロールバック」を参照)。また、<computes>引数が同じであれば常に同じ結果を返す(参照透過性を持つ)関数であることを示します。

<transacts>がついているため、この関数はロールバックできる。ちなみに、Verseでは暗黙的な戻り値が許可される

特徴1. ロールバック

Verseの大きな特徴の1つは、処理のロールバック(巻き戻し)を言語仕様として組み込んでいることです。

ロールバックを導入する理由には、プログラムの処理は失敗する可能性があることが挙げられます。配列が空であれば要素を取り出すことはできませんし、ネットワークに依存する処理は失敗するかもしれません。

このような処理の失敗・例外に対して、ほかの言語ではtry-catchResult型などを使って対処していますが、Verseではロールバックを用いています。

RustのResult型(画像はRust By Example 日本語版より引用)

ロールバックが起こると、例外の起きた処理をなかったことにできます。失敗する可能性のある処理に関連した、変数の代入などの一連の処理(トランザクション)も行われなかったことになるため、不正な状態が生まれない利点があります。

Verseでは、ロールバックできる関数には<transacts>エフェクトを付与します。また、失敗する可能性のある関数には<decides>を付ける必要があります

下の関数では、playerの配列([]player)からランダムなplayerを返す<decides>関数を呼んでいる。配列が空であれば失敗するため、この関数にも<decides>を付けている。なお、<decides>関数は当然<transacts>だ

<decides>の付いた関数(以下、<decides>関数と呼称)は、同じ<decides>関数内か、if文の中でのみ処理できます。if文内で<decides>関数を扱った際は、成功した場合(then節)と失敗した場合(else節)に何を行うかを選択します。

<decides>関数を呼び出す際は()ではなく[]を使う必要がある。これにより、呼び出し元は関数が<decides>であることを認識できる

UE5のブループリントで例外を処理するには、関数の戻り値を使う必要があります。しかし、この方法では関数の呼び出し元が戻り値を適切に処理せず、不正な値を使って処理を続行する可能性を排除できません

ブループリントでは、処理が成功したかどうかを呼び出し元で確認する

しかし、Verseの<decides>関数はif文の中でしか使えず、戻り値もthen節でしか使えないように制限されるため、より安全に処理を設計することが可能です。

特徴2. 非同期処理

もうひとつの特徴は、簡潔に非同期処理が記述できる点です。

C#のasync/awaitにおけるasyncの付いた関数のように、<suspends>エフェクトを付与した関数(以下、<suspends>関数と呼称)は非同期で実行されます

<suspends>関数は<suspends>関数内か、spawn式でtaskとして生成することによってのみ実行できます。spawnした<suspends>関数のtaskインスタンスは、.Await()することで関数の終了を待ち受けます。

例えば、カウントダウンするタイマーは以下の画像のように記述できます。

for文を使ったカウントダウンタイマー。各ループごとに1秒間待機し、UIを更新して次のループに移る

従来のコールバックを使う手法では処理が散らかりがちで可読性が悪くなっていましたが、Verseでは一連の非同期処理を1つの関数として記述できるため処理の流れを直感的に理解できます。

また、非同期処理の並行処理も簡潔に記述できます。複数の非同期処理を並行して実行し、どれかひとつが完了したらほかの処理をキャンセルする「race」式や、実行した非同期処理の完了を待たずに次の関数に進む「branch」式など、並行処理フローを記述するための式がいくつか用意されています。

race式。先に完了した関数の戻り値がWinnerに代入される。そして、もう一方の関数は実行が強制的に終了する

branch式。キャンセルイベントが呼ばれるまでランダムなターゲットを攻撃するタレットを実装している

ブループリントでも、Latent Actionによって非同期処理を簡潔に記述できます。しかし、並行処理処理のキャンセルなど、Verseの方がより柔軟に処理を組み立てることが可能です。

「タイム フローと並列処理」UEFN公式ドキュメント

そのほかの特徴

以上に加え、そのほかのVerseの特徴についても説明します。

変数はImmutableが基本

C++やブループリントでは、変数はデフォルトで可変(Mutable。書き換え可能)になっています。一方で、Verseの変数はデフォルトで不変(Immutable。書き換え不可)です。

可変変数はいつ状態が変わるか分からず、関数の呼び出しタイミングによって結果が変わる危険性を持っています。変数を不変にするここで、その危険性を排除しています。

可変変数を定義する際は、変数名の前にvarを付けます。

可変変数には「set」で変数の再代入を行う。なお、再代入はロールバック可能だ

forやifが結果を返す

Verseにおいて、すべての文は値を返す式として扱われます。それはforやifも例外ではありません。

if式(if文)では、then節(else節)の最後に書かれた式が返す値がif式の戻り値となります。三項演算子のような感覚が近いでしょう。

条件によって代入する値を決定する。なお、elseを書かない場合はvoidが返る

for式(for文)では、ループ処理の最後に書かれた式が返す値を集めた配列がfor式の戻り値となります。

for式に、失敗する可能性のある式をフィルターとして追加することも可能です。その場合、フィルターとなる式が成功した要素のみが配列に入ります。

プレイヤーの配列から、現在ダウン状態でないプレイヤーのみをフィルターするfor式

そのほか、パラメーター多相を実現する「パラメトリック型」(C++のテンプレートのようなもの)や、関数が第一級オブジェクトであることに起因する機能「型マクロ」(C++ではstd::functionが近い)ことなども特徴です。

ブループリントとの違い

ここで、私個人が考えるブループリントとVerseのメリット・デメリットを挙げます。

【Verseのメリット】

  • 実行時の安全性が高い
  • 非同期処理が柔軟に作れる
  • 静的解析が強力
  • 関数が第一級オブジェクトである
  • パラメーター多相(C++のテンプレート)に対応
  • option型(C++のstd::optional)に対応
  • 初期値のないメンバ変数が作れる
  • タプルが使える

 

【Verseのデメリット】

  • コードで記述する
  • 「失敗する可能性のある式」など、独特の概念
  • テストフレームワークデバッガなどがない

【ブループリントのメリット】

  • ノードベースで直感的に記述できる
  • コメントが書きやすい、フローが分かりやすいなど、可読性が高い
  • C++との強い連携
  • アニメーションやUIエディタとの高い親和性
  • 学習しやすい
  • 情報が入手しやすい

 

【ブループリントのデメリット】

  • 設計に関する機能の不足
  • 非同期処理の柔軟性が低い
  • 実行時の安全性が低い

Verseを使ってみよう!

以上の内容でVerseに興味を持った方は、UEFNを使って実際にコーディングしてみてはいかがでしょうか。

初めてVerseのコーディングを行う際は、以下の公式ドキュメントに沿って行うのがおすすめです。

「初めての Verse プログラムを変更して実行する」UEFN公式ドキュメント「Verse でのコードの書き方の基本を学ぶ」UEFN公式ドキュメント

また、Verseの詳細な情報は以下の公式ドキュメントにまとめられています。

「Verse 言語のリファレンス」UEFN公式ドキュメント

UEFNの更新に伴い、Verseもアップデートされています。UEFNのリリースノートなどをチェックすれば、Verseのアップデート情報も自然と追えるようになります。

「Unreal Editor for Fortnite の最新情報」UEFN公式ドキュメント

今後MaxVerseがリリースされる予定もありますし、ぜひVerseを試して、その思想に触れていただけるとうれしいです!

神谷 優斗

コーヒーがゲームデザインと同じくらい好きです

関連記事

フォートナイトとUEFNがv33.10にアップデート。一人称視点カメラを使ったゲームの公開が解禁
2024.12.11
フォートナイトとUEFNがv33.00にアップデート。経験値によるレベルアップや独自通貨をVerseなしで実装できるようになった
2024.12.02
C++の最新動向と展望をチェック。C++の日本語リファレンスサイト「cpprefjp」メンバーの講演を、ゲームエンジン開発者がレポート&補足してみた【CEDEC2024】
2024.11.27
フォートナイトとUEFNがv32.00にアップデート。NPCとの会話イベントを作れる仕掛けが登場
2024.11.05
UE/Unity/DCCツールなどで使えるコンテンツが並ぶ。Epic Games、統合コンテンツマーケットプレイス「Fab」をリリース
2024.10.23
フォートナイトとUEFNがv31.30にアップデート。装備中の武器モデルも画面内に映る「一人称視点」の仕掛けが実験的に導入された
2024.10.02

注目記事ランキング

2024.12.05 - 2024.12.12
VIEW MORE

連載・特集ピックアップ

イベントカレンダー

VIEW MORE

今日の用語

ブレンド(Blend)
ブレンド 2つ以上のものを混ぜ合わせることを意味する英単語。 ゲーム制作においても、2つ以上の要素を特定の割合によって合成することを示す。
VIEW MORE

Xで最新情報をチェック!