Resource Counter Device UEFN × Verse
← Back to Blog

タイクーンを解剖して
オリジナルデバイスを生み出した話
Wood専用だったカウンターが、セッション終わりには「インベントリシステム」になっていた

PROLOGUE

「タイクーンを作りたい」から始まった

そもそも、わたしはゲームというジャンル自体があまりわからない。色々調べていたところ、最近「タイクーン」というジャンルのゲームが流行っているという情報にたどり着いた。「タイクーンって何ぞや?」——UEFNでタイクーン型ゲームを作ろうと思い立った日は、そこからのスタートだった。

まず最初にした選択が「作り始める前に仕組みを理解する」だった。

タイクーンというゲームジャンルは、見た目よりずっと多くのデバイスが複雑に絡み合っている。公式ドキュメントを読み、既存のタイクーンマップを分解し、コミュニティの情報を照合しながら、そのサイクルを整理した。

結果として見えてきた骨格はシンプルだった。「素材を集め → 一定数貯まったら建設ボタンを押せるようになり → エリアが解放される」。これがタイクーンの基本ループ。

ただ、このループを実装しようとしたとき、ひとつの壁にぶつかった。UEFNには「素材の数を数えてUIに表示する」標準デバイスが存在しないのだ。

DISCOVERY

「プロップの世界」と「アイテムの世界」

UEFN × Verseを触っていると、ある根本的な構造の違いに気づく瞬間がある。

木材(Wood)はマップ上に置かれたプロップ(prop)として扱われる。プレイヤーが攻撃して破壊するとイベントが発生し、Verseのコードがその信号を拾うことができる。一方、コインやV-Bucksといったアイテムはフォートナイトのインベントリシステムに管理されていて、Verseから直接読み書きすることはできない。

これは最初は不思議に見えるが、理屈は明快だ。プロップはUEFNが管理する「ゲームの世界」の住人で、アイテムはフォートナイト本体が管理する「経済システム」の住人なのだ。

Verseが触れるのは「プロップの世界」だけ。
フォートナイトが持つ「アイテムの世界」には、素直な方法では届かない。

この境界を理解してから、設計の方針が一気に定まった。木材カウンターはVerseで作れる。コイン管理はデバイスに任せる。それぞれの世界のルールに従えばいい。

BUILD

まずはWood専用のカウンターを作る

方針が決まれば実装は速い。木材のプロップに prop_manipulator_device を紐付け、プレイヤーが攻撃するたびに発火する DamagedEvent を購読する。

// プロップが攻撃されるたびにカウントを1増やす PropManipulator.DamagedEvent.Subscribe(OnPropDamaged) OnPropDamaged(Agent:agent):void= set ResourceCount += 1 UICount.SetText(TextForCount(ResourceCount))

UIはシンプルに。アイコン画像を中心に置いて、その右上に素材名、右下にカウント数を重ねて表示する。Verseの overlay ウィジェットを使えば、複数の要素をひとつのキャンバス上に積み重ねることができる。

消費ボタン(建設トリガー)は conditional_button_device のActivatedEventを購読し、ストックが足りるときだけカウントを減らす。基本的な仕組みはこれだけだ。

TROUBLE

行き詰まりと、それぞれの突破口

TROUBLE 01
texture型の @editable にデフォルト値が設定できない
アイコン画像を外部から設定できるようにしようとして、@editable ResourceIcon : texture と書いたところでエラーが出た。Verseのtexture型は初期値なしでは宣言できない構造になっている。

解決策:オプショナル型(?texture)にして、デフォルトを false(未設定)とした。UIを描画する際に if(Icon := ResourceIcon?) でアンラップし、アイコンが設定されていないときはUIを作らない、という設計にした。コードを「動かす」のではなく「設計として正しく」書けた瞬間だった。
TROUBLE 02
Verseのcolor型にアルファチャンネル(透明度)がない
テキストブロックの色を半透明にしようとして、colorにA(アルファ)パラメータがないことに気づいた。RGBの3値しかない。

解決策:透明度は color_block の DefaultOpacity プロパティで別途設定する。色と透明度を分離して管理する方式に切り替えた。「ないから諦める」ではなく「別の場所に用意されている」という発想の切り替えが大事だった。
TROUBLE 03
ライブラリが古くて color_block が見つからない
EdenCode のローカルに保存していた Verse ライブラリで color_blockoverlay を検索しても見つからなかった。

解決策:UEFNがVS Codeを起動したとき、AppData以下に自動生成される公式ライブラリ(Fortnite.digest.verse)を参照することで解決。EdenCodeのライブラリはやや古いバージョンで、AppData側が常に最新。ライブラリの「住所」を把握していることが、こういうときに直接効いてくる。
DESIGN

Wood専用を「どの素材でも動く」に変える

Wood専用のカウンターが動くようになったとき、ふと思った。「同じロジックで石や金属のカウンターも作れるんじゃないか?」と。

そのとき採った設計方針が、このデバイスの核心になった。@editable を徹底的に使って、すべての設定値をUEFNのエディタから変更できるようにする、というものだ。

// ★ 汎用化の核心 — 全設定をエディタから変更できる @editable PropManipulator : prop_manipulator_device = prop_manipulator_device{} @editable ResourceIcon : ?texture = false # アイコン(未設定時はUI非表示) @editable ConsumeButtons : []conditional_button_device = array{} @editable UIBasePosition : vector2 = vector2{X := 0.05, Y := 0.9} @editable ResourceName : string = "Resource" @editable ConsumeAmount : int = 5

素材の種類(Wood / Stone / Metal)を変えたいなら ResourceName を変える。アイコン画像を変えたいなら ResourceIcon に別の画像を指定する。UIの表示位置を変えたいなら UIBasePosition を動かす。

コードは1行も変えない。エディタの設定を変えるだけで、別の素材のカウンターができあがる。

消費ボタンは複数対応にした。「ボタンが1個しか置けない」という制限は、タイクーンの設計を大きく縛る。for ループで配列を一括購読することで、エディタから好きな数のボタンを登録できるようにした。

// for ループで複数ボタンをまとめて購読 for(Button : ConsumeButtons): Button.ActivatedEvent.Subscribe(OnConsumeButtonActivated)

「1個だけ動く」ではなく「何個でも動く」にする。この差が、後の拡張性を決める。

INSIGHT

「これ、インベントリじゃん」

デバイスの汎用化が完成したとき、もうひとつの気づきが来た。

「同じデバイスを複数配置して、UIBasePositionをそれぞれずらしたら——
縦に並んだオリジナルのインベントリUIが完成するんじゃないか?」

そのとおりだった。ResourceCounter_device を Wood 用・Stone 用・Metal 用として3つ配置し、それぞれの UIBasePosition を少しずつずらすだけで、フォートナイト標準UIを完全に置き換えたカスタムインベントリが出来上がる。

1日の目標は「タイクーンのリソースカウンターを作る」だった。でもセッションの終わりには、再利用可能なインベントリシステムのコンポーネントが手元にあった。

プログラミングの面白さって、こういう「思ってたより遠くまで来てた」という感覚だと思う。

NOTE

Claude Codeで変わった開発体験

以前はChatGPTでVerseを書いていた。コードを貼り付けて、エラーが出たら貼り直して、修正案をコピーして、またUEFNに戻って……このループを1つのコードで20〜30回繰り返すことも普通にあった。

Claude Codeはファイルを直接読み書きするため、このループが劇的に短くなった。エラーが出たらそのファイルを直接確認して即修正する。UEFNとエディタを往復する回数が減ると、思考の流れが切れにくくなる。

ツールが変わると、作れるものの「深さ」が変わる。

SUMMARY

Wood専用だったカウンターが、セッションの終わりには木・石・金属どれにでも使える汎用デバイスになっていた。鍵になったのは @editable の徹底活用——コードを変えずに「素材テンプレート」として使い回せる設計にしたこと。そしてそのデバイスを並べるだけで カスタムインベントリシステム が完成することに気づいたとき、「タイクーンを学ぶ」という出発点から想像していたより遥かに遠くに来ていた。

Verseが触れるのは「プロップの世界」だけ、という境界を理解したこともまた大きかった。何をVerseで書くべきか、何はデバイスに任せるか——この判断軸が手に入ったことで、これからの設計がもっと速く、もっと意図的になる。

ALL UEFN × Verse Level Craft Asset Design Artwork