再起動しないテストワールドを実装する方法


23

次のことを行う方法についてのアイデアを探しています。Javaで単純な「世界」を書きたいです。既存のオブジェクト間のさまざまな動作をシミュレート/観察するために、後から新しいオブジェクトを開始してから追加できるもの。その後、古いオブジェクトをしばらく見てから新しいオブジェクトをコーディングし、それらを既存の世界にロード/ドロップします。問題は、一度世界を開始または停止して再起動したくない、数週間実行したいが、オブジェクトをドロップして、やり直し/書き換え/削除/作成/変更する機能が必要なことです再起動を必要とせずに時間をかけて。世界は、世界を視覚的に表すタイルマップGUIを使用して、X / Yロケーションの100 x 100配列のようにシンプルにすることができます。オブジェクトを監視し、それぞれに「行動するチャンス」を与えるために、何らかの種類のティックタイマープロセスが必要であることを知っています

例:月曜日にWorld.javaをコーディングし、実行したままにします。それから火曜日に、Rock.javaと呼ばれる新しいクラスを作成します(動かない)。次に、既に実行中のワールドにロード/ドロップします(ワールドアレイ内のランダムな場所にドロップし、移動することはありません)。それから水曜日にCat.javaという新しいクラスを作成し、再びランダムに配置して世界にドロップしますが、この新しいオブジェクトは(時間単位で)世界中を移動でき、木曜日にDogというクラスを作成します。また、移動しますが、隣の場所にある場合は別のオブジェクトに「作用」することができ、逆もまた同様です。

ここにあります。将来の(および現在存在しない)オブジェクトを検出/ロード/追跡する方法を知るために、実際のワールドクラスをコーディングするのにどのような構造/設計が必要かはわかりません。

Javaを使用してこのようなことをどのように行うかについてのアイデアはありますか?


2
ホットスワッピングによく似ています。おそらく、これに関する参考資料がいくつかあります。とにかく、非常に興味深い質問です。+1…
コンラッドルドルフ

回答:


5

基本的に探しているのは、ホットプラグ可能なシステムです。メインアプリケーションを実行してから、実行時にイベントループに統合されるプラグインを追加します。まず、あなたの世界がゲームエンティティに何を期待しているかについて考え始めます。例(説明に基づいて):

interface Entity {
   void init(World world);
   // Called when loaded for the first time in the world and adds itself
   // to the world (correct position in the array, scheduler for updates)

   void update(World world);
   // Called when scheduler fires (allows the entity to think about its
   // next move)

   Image getImage();
   // Called by the GUI when it is time to draw the entity on the screen
}

もちろん、必要と思われる他のメソッドを追加できます。2つの関連するメソッドを持つWorldパラメーターに注意してください。これにより、新しいエンティティは、設定または更新時に世界を考慮することができます。たとえば、Dogクラスでは、近所のすべての猫を世界に尋ねることができます。次に、このインターフェイスと、Javaコードを動的にコンパイルおよびロードするシステムで動作するワールドを作成します。この例はここにあります

void injectEntity(String filename, World world) {
    // Load the class as described in the mentioned link
    Entity e = (Entity) loadClass(filename);
    e.init(world);
}

World GUIからこのメソッドを呼び出して、新しいエンティティを追加します。Worldの実装に応じて、Entity init関数は次のようになります。

void init(World world) {
   // Register entity with world for easy access
   world.register(this, "RockImpl A");

   // Place the entity on the world map
   Point initialLocation = Point(10,5);
   world.place(this, initialLocation);

   // Schedule its update method for every 5 seconds
   world.schedule(this, 5);
}

1
Googleへのキーワード:「IoCコンテナー」、「制御の反転」、「依存性注入」。これらは、実行時にコンポーネントを検出してロードできる、一般的なホットプラグ可能なシステムの技術です。
ネバマインド

16

我々はスタンダールで襲撃のためにそのようなことをしました。

再起動を完全に回避することを目指していませんでした。したがって、クライアント/サーバー通信などのコアインフラストラクチャサービスを変更するには、再起動が必要です。ただし、エンティティ、クリーチャー、NPCの追加、および既存のオブジェクトの変更は機能します。(ああ、時にはライブバグ修正、リフレクションはプライベートフィールドでさえ操作するために使用できます)。

新しいデータ(別のスキンなど)に基づく新しいオブジェクトが必要なだけでなく、新しい動作を追加するため、worldプログラムは新しいクラスファイルロードできる必要があります。これらは「スクリプト」と呼ばれますが、実際にコンパイルされたJavaクラスです。これらのクラスはScript.javaインターフェースを実装します。

Maria.javaは簡単な例です。彼女は飲み物や食べ物をプレイヤーに販売する新しいNPCです。ここでも非常に複雑なオブジェクトを定義できます。

新しいクラスは次の方法でロードされます。

// create a new class loader, with the script folder as classpath.
final File file = new File("./data/script");
final ClassLoader loader = new URLClassLoader(new URL[]{file.toURI().toURL()});

// load class through new loader
final Class< ? > aClass = loader.loadClass(classname);
script = (Script) aClass.newInstance();

一意の名前を確保でき、クラスをアンロードしたくない場合は、低レベルのもので完了です。

ただし、アンロードは非常に重要なようです。それを実現するためには、新しいコードを挿入するたびに新しいクラスローダーをインスタンス化する必要があります。そのため、GCは、そのコードへの最後の参照がクリアされた後に作業を行うことができます。

我々は持っている/アンロードコマンドスクリプトがクリーンアップを行うことができるように私たちのインターフェイスでアンロードメソッドを呼び出します。実際のアンロードは、GCによって自動的に行われます。

レイド中に多くの一時オブジェクトを作成することがよくあります。そして、襲撃が終了した後、それらすべてを削除したいです。たとえば、目に見えない管理者の近くに多数のノームを生成するノームレイドでは、次のコードを使用します:GnomeRaid.java extends CreateRaid.java

スクリプトは(最初の例が示すように)ワールドに直接アクセスし、unload()メソッドで独自のクリーンアップを実行できます。ただし、Javaコーダーはクリーンアップに使用されず、面倒です。そこで、スクリプトが使用できるサンドボックスを作成しました。アンロードすると、Sandboxクラスを介してワールドに追加されたすべてのオブジェクトが削除されます。


3

世界(しゃれを意図しない)とそのすべての状態(位置、速度、すべての変数)を保存します。

  • プログラムを閉じる。
  • 変更を実装します(保存との後方互換性を確保します)。
  • プログラムを再コンパイルします。
  • プログラムを再起動します。
  • ワールドとステートをロードします。
  • 繰り返す

これは一般的な解決策ですが、あなたが望むようにコードブロックとクラスを動的に実装できるかどうかを知るためのJava固有のものはありません...

オプション2は、オンザフライでロードできるスクリプト言語をバインドすることです。


スクリプト言語の場合は+1。Javaに縛られていない場合は、LPCベースのMUDドライバーとmudlibも試してください。
マーティンソーカ

1

Javaに必要なのは、OSG​​iプラットフォームのみです。それにより、モジュールやアプリケーションのホットスワップが簡単になり、リモート管理や部分的なアップグレードを行うことさえできます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.