はじめに
私は現在ファイナルファンタジーXIV(FF14)というゲームをプレイしており、特に極や零式レイド等の高難易度の攻略を楽しんでいます。しかし、複雑な高難易度コンテンツにおいて、パーティでの進捗管理やフェーズごとの攻略メモをしっかり残す方法がなかなか見つからず、いつも苦労していました。Discordでメモを残したりと試行錯誤する中で、「FF14のための攻略進捗管理ツールがあれば便利なのに」という思いから、自分で作成しようと考えました。
開発環境と技術選定
本アプリケーションはJava/Spring Bootをバックエンド、ThymeleafをテンプレートエンジンとしたWebアプリケーションとして設計しました。データベースはPostgreSQLをメインに使用し、メディアファイル(スクリーンショットや攻略動画)はMongoDBに格納する構成にしました。
また、最初は汎用的なゲームトラッカーとして設計を始めましたが、途中でFF14専用に特化させる決断をしたことで、より使いやすいツールにすることができました。
苦労した点とそこから学んだこと
Thymeleafとの格闘
開発中、最も苦労したのはThymeleafのレイアウト処理でした。特に変数名の衝突問題は頭を悩ませました。「content」という変数名をモデル属性として使っていたところ、Thymeleafのレイアウトフラグメントでも同じ変数名が使われており、このエラーメッセージに何時間も悩まされました。
Property or field 'name' cannot be found on object of type 'org.thymeleaf.standard.expression.Fragment'
このエラーを解決するために変数名を「ff14Content」に変更する必要がありましたが、この問題解決過程でテンプレートエンジンの仕組みをより深く理解することができました。変数のスコープや名前空間について学ぶ良い機会となり、結果的に私のプログラミングスキル向上に繋がりました。
シンプルなページネーション実装
コンテンツ数が増えるにつれ、一覧画面の読み込みが遅くなるという問題が発生しました。すべてのコンテンツを一度に表示するのではなく、ページネーションを実装することにしました。
html<nav aria-label="ページネーション">
<ul class="pagination">
<li class="page-item" th:classappend="${currentPage == 0} ? 'disabled'">
<a class="page-link" th:href="@{/ff14/contents(page=0)}">« 最初</a>
</li>
<li class="page-item" th:each="i : ${#numbers.sequence(1, totalPages)}"
th:classappend="${currentPage == i-1} ? 'active'">
<a class="page-link" th:href="@{/ff14/contents(page=${i-1})}" th:text="${i}"></a>
</li>
<li class="page-item" th:classappend="${currentPage == totalPages-1} ? 'disabled'">
<a class="page-link" th:href="@{/ff14/contents(page=${totalPages-1})}">最後 »</a>
</li>
</ul>
</nav>
この単純なページネーション実装により、一覧画面の読み込み時間が大幅に短縮され、ユーザー体験が向上しました。この経験から「パフォーマンスはシンプルな解決策から取り組むべき」ことを学びました。複雑なキャッシュ戦略や最適化の前に、基本的なページネーションのような解決策を検討することの重要性を実感しました。
モバイル対応のレスポンシブデザイン
当初はデスクトップブラウザでの使用を想定していましたが、スマホでも攻略の情報を確認できるようにモバイル対応に取り組みました。特に苦労したのは、複雑なフェーズ進捗テーブルをスマホの小さな画面でも見やすく表示することでした。
<!-- レスポンシブ対応のテーブル -->
<div class="table-responsive">
<table class="table table-sm table-hover">
<!-- 省略 -->
</table>
</div>
<!-- スマホサイズでは別のレイアウトに切り替え -->
<div class="d-md-none">
<div class="card mb-2" th:each="progress : ${progressEntries}">
<div class="card-header d-flex justify-content-between">
<span th:text="${progress.phaseName}">フェーズ</span>
<span class="badge" th:text="${progress.status.displayName}">状態</span>
</div>
<div class="card-body">
<!-- モバイル用のコンパクト表示 -->
</div>
</div>
</div>
この経験から「レスポンシブデザインの重要性」と「使用コンテキストによるUI要件の変化」について学びました。ユーザーがどのような状況でアプリを使うかを想像することの大切さを実感しました。
こだわったポイント
フェーズ別進捗状態の視覚化
FF14の高難易度コンテンツは複数のフェーズで構成されており、攻略の進行状況を正確に把握することが重要です。そこで最もこだわったのは、フェーズごとの進行状況を視覚的に表現するステータスシステムです。「未着手」「練習中」「攻略中」「エンレイジ到達(時間切れ)」「クリア済み」「周回中」といった状態を色分けされたバッジで表示し、一目でチームの進捗状況が把握できるようにしました。
<span class="badge bg-secondary">未着手</span>
<span class="badge bg-info">練習中</span>
<span class="badge bg-warning">攻略中</span>
<span class="badge bg-danger">エンレイジ</span>
<span class="badge bg-success">クリア済</span>
<span class="badge bg-primary">周回中</span>
特に「エンレイジ到達」状態を独立して設けたのは、FF14の攻略において「あと少し」という状況を明確に記録したいプレイヤー心理を反映したものです。実際の攻略では「エンレイジまで見えているが、クリアはまだ」という状況が長く続くことも多く、その微妙な進捗状況を表現できるよう配慮しました。
エクスパンション別コンテンツ管理
FF14は長い歴史を持つゲームであり、多くのエクスパンションと膨大なコンテンツが存在します。そこで、エクスパンションごとにコンテンツを分類し、さらにコンテンツタイプ(零式レイド、絶レイド、極討滅戦など)でフィルタリングできる機能を実装しました。
メカニクス説明のテキストエディタ
各フェーズのメカニクス説明を詳細に記録できる専用テキストエディタを実装しました。単純なテキスト入力欄ではなく、フォーマットを保持したまま情報を記録できるよう、改行やインデントを正確に保存する仕組みを取り入れました。
<pre class="description-text" th:text="${progress.mechanics}">メカニクス説明</pre>
特にFF14の複雑なギミック説明では図式化された情報が重要になるため、ASCII図形(□■↑↓←→
など)を使った位置表現も綺麗に表示されるよう、等幅フォントでの表示を基本としています。これにより、Discord等で共有されている既存の攻略情報をコピー&ペーストしても崩れずに保存できる利便性を実現しました。
今後の展望
長時間レイド動画のストリーミング対応
現在のアプリケーションでは動画ファイルのサイズ制限があり、長時間のレイド動画をアップロードすることができません。今後は、YouTubeなどの動画プラットフォームとの連携機能を追加し、動画URLを登録するだけでアプリ内で再生できるようにします。これにより、ストレージコストを抑えつつ動画共有が可能になります。
マクロ管理機能
FF14のレイド攻略では、ゲーム内マクロを使って戦略を共有することが一般的です。各フェーズに対応するマクロを保存・管理できる機能があれば、ゲーム内で素早くマクロを展開できます。
例/p 【基本散開】
/p D3 MT D4
/p H1 ● H2
/p D1 ST D2
このようなマクロ(上記は短いが通常使用するマクロはもっと長いです)をワンクリックでクリップボードにコピーできる機能は、パーティ募集を立てる際やフレンドと過去のコンテンツを遊ぶ際にすぐマクロを確認できるようになるのでもっと便利になります。
余談:FF14の好きなところ
FF14の一番の魅力は、誰でも自分のペースで楽しめるところだと思います。難しいレイドに挑戦するのも、お洒落な家具で部屋を飾るのも、ただ友達とおしゃべりしたり、また、オシャレをしてスクリーンショットを撮るといった自分の好きな遊び方で遊んでいけるのが魅力的です。私は、戦闘ものんびり過ごすのも好きなので、全部やっていますが笑
また、FF14のストーリーもとてもおもしろいです。中でも私は、漆黒の反逆者(ヴィランズ)のストーリーが好きで、どこが好きかはネタバレになるので伏せますが、ストーリーがとてもおもしろくこの漆黒という拡張パッチから戦闘の難易度も上がって楽しくなるのでぜひプレイしてみてください!
利用著作物 ©SQUARE ENIX
コメント