マイクラModdingの基礎知識(BlockとMetaDataとTileEntityの関係について)
この記事の目的
この記事は、Java初心者かつModding初心者であるhevohevoが、ネット上に落ちている情報を拾い読みしたり、公開されているソースコードを読んで、自分なりに理解したことをまとめたものです。
当然ながら、間違いが含まれている可能性が高いです。記事を100%信用してはいけません。
この記事はつまり、間違っているであろう自分の知識をわざと公言することで、心優しい識者の方から教えをいただけないだろうかという期待を元に公開しています。
識者の方は、やさしくご指摘いただけると助かります。
- 前回のModding関連の記事
はじめに
以下の内容は、Minecraft1.7.10およびForge#1180を対象にしています。それ以前のバージョンでは異なる可能性があるのでご注意ください。
また、マルチプレイヤー環境ではなくシングルプレイヤー環境を想定しています。マルチプレイヤー環境独自のmoddingなど、そこまでまだ理解が進んでいません。
以下の記述中で、アルファベット大文字からはじまる単語はJavaのクラス名を指します(Block、TileEntityなど)。あるクラスから、newして作ったオブジェクトをここではインスタンスと呼びます。
ブロックは1種類につき1個しか存在しない
マイクラ世界は数え切れないほど多くのブロックから成り立っています。
ゲームをやったことがある人なら、経験的に石ブロックを一番多くみかけることでしょう。次によく見るのは土ブロックでしょうか?
実は、何もない空間は全て透明の空気ブロックで埋め尽くされています。地表面が高度63だとすると、高度限界は256なので、差し引き193個の空気ブロックが存在することになります。圧倒的ですね。
では、ゲーム内でもっとも多く存在するブロックは空気ブロックなのでしょうか?
いえ実は、「システム的には」違います。
システム的には(内部実装としては)、ブロックは1種類につき1個しか存在しません。
厳密に言うと、Blockクラス(およびそれをextendsした独自クラス)のインスタンスは、1種類につき1個しか作成(new)されません。
たとえば石ブロックのインスタンスは、ゲーム開始時に1個だけ作成されて、GameRegistryに記憶されます。
後は原則として、それを使いまわすのです。
たとえば、ワールド上のあらゆるところで石ブロックを見かけます。狭い範囲でもおそらく数万、数十万という単位で石ブロックは存在するように思われます。
仮に、その石ブロック1つ1つがインスタンスとして存在しているとしたらどうでしょうか、newを数万回実行する? そんなバカな。PCがチンでしまいます。
実はワールド上のどの座標にどのブロックがあるかという情報は、マッピングデータとしてゲーム内で管理されているのです。
具体的には、ワールドオブジェクト(Worldクラスのインスタンス)ごとに、座標(x,y,z)とGameRegistryに保存されているブロックインスタンスを結びつける形で情報を記録しています。
そのため、とあるワールドのとある座標にどんなブロックがあるかを調べるには、以下のようにコードを書けばよいのです。
Block myBlock = world.getBlock(x,y,z);
ここで注意したいのは、同じ種類のブロックであれば、マッピングデータ上では同じブロックインスタンスを指し示すということです。
つまり、異なる座標であったとしても、そこに存在するブロックが同じ種類のブロックであれば、その指し示すブロックインスタンスは同じなのです。
つまり以下のように。
Block myBlock1 = world.getBlock(x1,y1,z1); Block myBlock2 = world.getBlock(x2,y2,z2); if(myBlock1 == myBlock2){ System.out.println("同じインスタンス!"); }
ここで、おやっと思いませんでした?
もしそうだとするならば、 同じ種類のブロックであったとしても、原木や階段のように向きが違ったり、羊毛のように色が違ったり、チェストやカマドのように中に異なるものが詰まっているブロックはどうやって表現されているのでしょうか。
答えは、「それは別データとして保持している」です。
ブロック個別のデータをどうやって保存・管理しているのか
別データとは言いますが、ブロックはその保存したいデータの大きさによって2つの保存方法が用意されています。
それはMetaData(メタ値)という形でデータを直接保存する方法と、TileEntityを利用して間接的にデータを保持・管理する方法です。
ともに、ワールドごとに座標をキーとして保存します。ブロックではありません。「座標をキー」にです。
たとえば、とあるワールドのとある座標に(繰り返しますがブロックではありませんよ)保存されているMetaDataを取り出したいのならば、以下のコードを書きます。
(ここではメタ値をint型として取り出しています)
int myMetaData = world.getBlockMetadata(x,y,z);
また、とあるワールドのとある座標に(繰り返しますがブロックでは・・・略)保存されているTileEntityは次のように取り出します。
(TileEntityオブジェクトが得られます)
TileEntity myTileEntity = world.getTileEntity(x,y,z);
それではこの2種類の方法、どのような違いがあり、どのように使い分ければよいのでしょうか。
MetaDataの特徴
まず、とても小さなデータはMetaData(メタ値)として保存できます。
MetaDataは容量が4bit(10進数で言うと0-15)しかありませんが、処理が高速かつ取り扱いが簡単です。
たとえばゲーム内では、羊毛の色はMetaDataによって変えています。
ワールドに色違いの羊毛ブロックが複数置いてあるとき、world.getBlock(x,y,z)によって得られるブロックインスタンスはどの羊毛ブロックも共通です。
しかし、world.getBlockMetaData(x,y,z)によって得られるメタ値はそれぞれ色によって異なるのです。
ゲーム内でとある羊毛ブロックを視界に入れたとき、システムはそのブロックと同じ座標に保存されているMetaDataを自動的に参照し、そのMetaDataの違いによって表示するテクスチャを変えているのです*1。
またたとえば、Modderが設置方向が重要となる新しいブロックを追加するとしましょう(参考としたソースコード)。
まるでバニラのカマドのように、設置するとプレイヤーキャラクタと向き合う形でブロックの正面方向が決定され、その正面方向だけ他の方向とは異なるテクスチャが使われるケースです。
この正面方向はワールド内のどの方向*2であるかという情報を保存するのに、MetaDataを使うことができます。
たとえば、ブロックをワールドに設置したときにプレイヤーの向いている方向を元にブロックの正面がどちらかという情報をMetaDataに記録させます。
具体的には、ブロック設置したときに必ず呼び出されるonBlockPlacedBy()メソッドを@Overrrideして、この中でworld.setBlockMetadataWithNotify()メソッドを使ってMetaDataを記録します。
あとは、画面表示のときに呼び出されるgetIcon()メソッド*3を@Overrideして、その中でMetaDataを呼び出しつつその値によって返すテクスチャ(IIconクラス)を切り替える処理を記述すればよいのです。
MetaDataはint型なので保存できるデータ量が限られてしまうという欠点がありますが、実値なので呼び出しが高速であり、ゲームを再開したときなど画面描写が早いという利点があります。
たとえば様々な色の羊毛ブロックが視界内に大量に設置されていても、そこまで負荷は大きくないですよね。
TileEntityの特徴
実値であるMetaDataに対して、TileEntityはクラスなので、いくらでも好きなデータを保持することができます。
さらに言うならば、様々なメソッドがクラス内で定義されておりそれらを@Overrideすることで新しい機能を付け加えることも可能ですし、保存データを用いた新しい処理メソッドを追加することもできます。
その意味でTileEntityは、ブロックのデータ保存方法という範疇を軽く超えており、ブロックのデータ管理基盤とも言うべき特殊なクラスです。
いまいちイメージがつかめない人には、以下のたとえ話はどうでしょう。
- Block+MetaData=羊毛ブロックの色を変える程度の能力。
- Block+TileEntity=工業Modの機械のように、中にデータを保持するだけでなくそれらデータを使った特殊な機能を実装する程度の能力。
(補足)なお、TileEntityを使うときには、Blockクラスを使うよりもBlockクラスを拡張したBlockContainerクラスを使ったほうが機能がいろいろとそろっているので楽です。つまり、BlockContainer+TileEntityの組み合わせ。
TileEntityがどのくらい高機能か例を挙げると、以下のような処理ができるデータおよびメソッドがTileEntityクラスに標準で含まれています。ね?高機能でしょう?
- Blockの座標データを保持(xCood, yCood, zCood)
- 保持されているBlock座標データを使って、MetaDataを呼び出せる(getBlockMetadata())
- 自分の座標から特定座標までの距離を計算できる(getDistanceFrom(x,y,z))
- などなど。以上は標準で実装されている機能のごく一部です。
しかもこれは、標準のTileEntityクラスのお話です。
TileEntityをextendsして新しいMyTileEntityクラスを定義するなら、なんでもやりたい放題ですね!
とはいえ欠点が無いわけではありません。
高機能であるがゆえにいくつかの問題も抱えています。
ここでは初心者の僕程度でも気づくことができた、明確な欠点を2つ挙げましょう
欠点1)高機能なため重い
MetaDataは実値なので、素直にGameRegistoryの中に値が保存されています。ゲーム再開時にも保存された値を呼び出すだけなので、羊毛などの個別ブロックの描写もさほど負荷はかかりません。
しかしTileEntityは違います。ワールドの位置情報でマッピングされる形で、個別のTileEntity(およびそれをextendsしたクラス)インスタンスが保持されています。
たとえば、プレイヤーの直近に100個の機械ブロックがあってそれが全部稼働中ならば、それら100個のTileEntityインスタンスがメモリ中に保持されるわけですね。ヒィッ!*4
そりゃ、1チャンク内に工業Mod機械をぎっしり詰め込んだら重いはずですわ。
ついでなので、ここでTileEntityインスタンスのライフサイクルを簡単に記述しておきましょう。
- 新しくブロックをワールドに設置したときに、その設置ブロックのTileEntityインスタンスが新しく生成(new)される。
- Block*5の
createNewTileEntity()メソッドが呼び出される。 - TileEntityを使いたいときにはあらかじめこのメソッドを@OverrideしてTileEntityのインスタンスを返すようにしておかなければならない。
- Block*5の
- 生成されたTileEntityインスタンスは、ワールド上に座標をキーにマッピングされる。
- 設置ブロックとそのTileEntityインスタンスに記述された内容ごとにいろいろな処理。
- ゲーム終了時に、TileEntityの
一部データのみがセーブファイルに保存される- なおBlockのマッピングデータやMetaDataなどは自動でセーブファイルに保存される。
- ゲーム再開時、Blockごとに新しくTileEntityインスタンスを生成、セーブファイルから保存されたデータを取り出してTileEntityインスタンスにセット。
- 2へと進む。
(なお、TileEntityのデータがセーブされるタイミングは他にもあるかもしれないので、識者のつっこみ待ち。たとえばMekanismの機械は撤去しても内部データを保持しているので、撤去時に特殊な処理を行っているのかな?)
欠点2)独自に拡張可能 → どのデータを実際にセーブするかは自分で書いて
TileEntityのライフサイクルの中で、「ゲーム終了時に、TileEntityの一部データのみがセーブファイルに保存される」と説明しました。
具体的に言うと、TileEntityインスタンスの中でも、座標情報しかファイルにセーブされません。
そのため、機械ブロック作業中にゲームを再起動すると、中の処理が中に入れた材料ごとリセット・・・これはひどい。
明示的にどのデータを保存するか記述しましょう。記述する方法はいくつかあるようです。
(以下、識者のつっこみ待ち。NBTを直接読み書きするような低レベルのメソッドではなくもっと高レベルのメソッドで書けよ!等の突込みが欲しいのです。また、マルチプレイヤー環境で動くようなModを実装するときのpacket関連をフックするような書き方があるんじゃないかなぁと個人的には疑っています。このソースコードをみてもっと勉強しろ等の叱咤でもOKです。お願いします)
一番シンプルなのは、TileEntityクラスのreadFromNBT()メソッドとwriteToNBT()メソッドを@Overrideすることだと思います。
実際、デフォルトの状態では、ここで座標(とブロックID?)くらしか読み書きしていないのですよね。
ここで、内部インベントリの状態ですとか、作業の進行状況などを明示的に読み書きしてあげれば、ゲーム再開時でもTileEntityの状態を中断時の状態に戻すことができるはずです。
ちなみに、NBTとは何だ! という質問には、「僕も不勉強なもので・・・」としか答えられません。今わかっていることは以下くらい。
- NBTとは
- 上記の参考ページを読んでの理解
- Minecraftにおけるデータ保存方式。原則として、NBTTagCompoundをハンドルとして、データをTagと対にして保管。
- NBTに保存したデータは、セーブファイルとして保存される(?)
- データタイプ(String等)は厳密に管理されており、データタイプごとに保管メソッド、読み込みメソッドを変えなくてはならない。
- (上記とは別ソースですが)文字列データには、容量の上限はないのではという噂。
ここまでのまとめ
- Block(をextendsした独自Block)クラスのインスタンスはゲーム内に1種類につき1つしか存在しない
- ワールド内の特定座標にブロックが設置されているという情報は、位置をキーとして上記インスタンスをマッピングする形で保存されている
- そのため、Blockという単位(枠組み)では、ブロックに個別情報を保存できない。
- ブロックの個別情報を保存する方法として、MetaDataとして保存する方法と、TileEntityを経由して任意のデータを保存する方法の2つがある
- MetaDataとは
- ワールド上に設置された個別のブロックに結び付けられたブロックデータ保存形式
- 保存できるデータ量は4bitと小さい。でもお手軽で読み込みも早い
- Blockクラスから直接利用できる。
- http://www.minecraftforge.net/wiki/Metadata_Based_Subblocks
- TileEntity とは、
- ワールド上に設置された個別のブロックに結び付けられたブロックデータ管理基盤。
- どんなデータでも保存できる。ついでにそれらデータを取り扱うメソッドも追加できる。
- 通常は、BlockクラスをextendsしたBlockContainerクラスから利用する(楽だし)
- ブロックを新しく設置するたびにTileEntityは新しく生成され、ワールドに位置をキーとして保存される
- Blockマッピングデータとは異なりTileEntityマッピングデータには個別のTileEntityインスタンスが保存されているので、インスタンス内に独自データを自由に保存できる。
- ただし、ブロック再設置、ゲーム再起動などでインスタンスは再生成されるので、残しておきたいデータはNBTを読み書きするメソッドを@Overrideして明示的に保存するよう記述しなくてはならない
次回について
次は、ItemとItemContainerとDamgeValueとNBTの関係についてまとめたいところ。
なお、ItemBlockについては以下のページがとてもわかりやすくまとめており参考になるので、ここでまとめる必要はないですよね。
個人的なメモ帳
*1:もしかしたらテクスチャ切り替えではなく色乗算で変えているかも?ここは識者の指摘待ち
*2:ゲーム内では、上:0、下:1、北:2、南:3、西:4、東:5のようにint型で表現されていますが、わかりづらいので ForgeDirection.NORTHのようなヘルパークラスを使うことが多いようです。
*3:ワールドに設置したときに呼ばれるものと、インベントリ内にあるItemBlockを表示するときに呼ばれるものの2種類があることに注意
*4:これは特殊な負荷軽減処理を行わない場合のお話で、もしかすると負荷軽減のための特殊な機能があるかもしれず、初心者の僕ではそこまでの知識がないので識者の突っ込み待ち
*5:一般的にはBlockContainerクラスを使う
マイクラModdingの基礎知識(Modの初期化処理について)
はじめに
以下の内容は、Java初心者であるhevohevoが調べた内容なので、
間違いが含まれている可能性が高いです。
その場合は、優しくご指摘いただけると助かります。
また、以下はMinecraft1.7.10およびForge#1180をターゲットに調査した内容です。
これよりも古いバージョンでは異なる可能性があるのでご注意ください。
Forgeを用いたModdingの基礎知識
自作Modを作るには、まず自分のModで初期化処理を書かなくてはならない。
たとえば、設定ファイルを読み込んだり、ブロックを追加したり、独自レシピを追加したり、他のModとの連携処理を書いたりなどなど。
Forge(厳密に言うとForgeModLoader、以下FMLと呼称)は、初期化処理のフレームワークを以下のように定めている。
FMLにおけるMod初期化処理の書き方
基礎知識・・・FMLはイベント駆動
FMLは、○○○というイベントメッセージが来たらあらかじめ登録してある処理を実行する、というイベント駆動型で実装されている。
FMLにおけるMod初期化処理は、以下の3つのイベントにより3段階に分かれており、1から3まで順番に実行される。
- FMLPreInitializationEvent イベント
- FMLInitializationEvent イベント
- FMLPostInitializationEvent イベント
Modを作成するときには、適切なイベントに適切な初期化処理を登録しなくてはならない。
なお、10個のModがあったらFMLは次のように初期化処理を進める。
- "FMLPreInitializationEvent"イベントメッセージ来た
- 有効なModリストを作成。今回は10個。
- 10個のModそれぞれについて、このイベントに対応する初期化処理を実行する
- "FMLInitializationEvent"イベントメッセージ来た
- 10個のModそれぞれについて、このイベントに対応する初期化処理を実行する
- "FMLPostInitializationEvent"メッセージ来た
- 10個のModそれぞれについて、このイベントに対応する初期化処理を実行する
特に、他のModと連携するModを書くときには、初期化の順序を意識する必要がある。
初期化処理を登録する方法
ModのメインとなるClassに@EventHandlerアノテーションを宣言しつつ、初期化用メソッドを追加する。
このとき、適切な初期化イベント(クラス)を引数として選択すること。
@EventHandler アノテーションの使い方
書式は以下の通り。
@EventHandler public XXXX(YYYY event){ // 具体的な初期化処理 }
- XXXXは任意のメソッド名、YYYYは3種類ある初期化イベントクラスのどれか
- FMLPreInitializationEvent クラス
- FMLInitializationEvent クラス
- FMLPostInitializationEvent クラス
ここで注意事項
好きなメソッド名を登録できるが、可読性のために、以下のメソッド名にすることがModderの間では推奨されている。
以下、またそれぞれの初期化イベントでどのような初期化処理を書くべきかの目安も記述。
1. FMLPreInitializationEvent イベント
一般的には、設定ファイルの読み込みやブロックなどの登録。事前の初期化作業に使う。
@EventHandler public void preInit(FMLPreInitializationEvent event) { // 具体的な処理 }
2. FMLInitializationEvent イベント
レシピの追加やこのMod用の各種データ設定など。メソッド名は load()を使っている人も多い模様。
@EventHandler public void init(FMLInitializationEvent event) { // 具体的な処理 }
3. FMLPostInitializationEvent イベント
本当に後に回したい初期化処理など? 他のModとの連携はここで書くらしい。
@EventHandler public void postInit(FMLPostInitializationEvent event) { // 具体的な処理 }
(補足事項)やってしまいがちなミス。経験者は語る
任意の初期化メソッドを登録できるのだが、これには大きな罠がある。
たとえば、1つのクラスの中で、同じイベントに対して複数の初期化メソッドを登録することができる(できてしまう)。
具体的には以下のように、"FMLInitializationEvent"を指定した別の名前のメソッドを複数登録できてしまう。
// 名前の異なる3つの初期化メソッドを、同じFMLInitializationEventに登録 @EventHandler public hoge(FMLInitializationEvent event){処理の中身}; @EventHandler public init(FMLInitializationEvent event){処理の中身}; @EventHandler public load(FMLInitializationEvent event){処理の中身};
しかしこれは混乱の元なので避けたい。なぜならば、同じイベントに登録された複数のメソッドは実行順序が不定(環境依存)になってしまうためである*1。
混乱を避けるために、1つの初期化イベントに対して1つだけ初期化メソッドを登録するのが無難だろう。少なくとも初心者モダーにとっては・・・。*2
他のモダーのコードを眺めてみる
他のモダーが、初期化処理をどのイベント段階で記述しているか、調べてみました。
日本Modder界の重鎮、reginnさんのコード。マイクラ1.7系のチュートリアルを大量に公開されているので、ありがたい。- Mekanismはアイテム登録どころか設定ファイルの読み込みまで全部initでやってる ^q^ というかコードが長いよw
- Modder界のK&R、cpw氏のIronChest*3では、preInitでブロック登録まで、init(loadを使ってる)でレシピ追加など他全部、postInitは何もしない
FMLの @EventHandlerのJavaDoc
cpw.mods.fml.common.Mod より抜粋
/**
* Marks the associated method as handling an FML lifecycle event.
* The method must have a single parameter, one of the following types. This annotation
* replaces the multiple different annotations that previously were used.
*
* Current event classes. This first section is standard lifecycle events. They are dispatched
* at various phases as the game starts. Each event should have information useful to that
* phase of the lifecycle. They are fired in this order.
*
* These suggestions are mostly just suggestions on what to do in each event.
* <ul>
* <li> {@link FMLPreInitializationEvent} : Run before anything else. Read your config, create blocks,
* items, etc, and register them with the {@link GameRegistry}.</li>
* <li> {@link FMLInitializationEvent} : Do your mod setup. Build whatever data structures you care about. Register recipes,
* send {@link FMLInterModComms} messages to other mods.</li>
* <li> {@link FMLPostInitializationEvent} : Handle interaction with other mods, complete your setup based on this.</li>
* </ul>
* <p>These are the server lifecycle events. They are fired whenever a server is running, or about to run. Each time a server
* starts they will be fired in this sequence.
* <ul>
* <li> {@link FMLServerAboutToStartEvent} : Use if you need to handle something before the server has even been created.</li>
* <li> {@link FMLServerStartingEvent} : Do stuff you need to do to set up the server. register commands, tweak the server.</li>
* <li> {@link FMLServerStartedEvent} : Do what you need to with the running server.</li>
* <li> {@link FMLServerStoppingEvent} : Do what you need to before the server has started it's shutdown sequence.</li>
* <li> {@link FMLServerStoppedEvent} : Do whatever cleanup you need once the server has shutdown. Generally only useful
* on the integrated server.</li>
* </ul>
* The second set of events are more specialized, for receiving notification of specific
* information.
* <ul>
* <li> {@link FMLFingerprintViolationEvent} : Sent just before {@link FMLPreInitializationEvent}
* if something is wrong with your mod signature</li>
* <li> {@link IMCEvent} : Sent just after {@link FMLInitializationEvent} if you have IMC messages waiting
* from other mods</li>
* </ul>
*
* @author cpw
*
*/
Google Guava EventBusについて参考にしたページ
- googleさんの提供するイベント駆動基盤
- 日本語で解説 http://cco.hatenablog.jp/entry/20111210/1323509513
@Subscribeアノテーションを使うことでevent handlerとなる公開メソッドを実装することができます。イベントである引数は必ず1つのみであることに注意が必要です。
- 日本語で解説 http://blog.kengo-toda.jp/entry/20111006/1317907239
リスナーはどのようなクラスでもよく、メソッドを@Subscribeアノテーションで修飾するだけで使えます。リスナーが@Subscribeで修飾されたメソッドを複数個持っている場合、これらが実行される順番は環境依存となります。
調査内容を書きなぐったメモ書き(現在進行中)
http://codeshare.io/5Xx5E ・・・FMLとBlockとTileEntityとTileEntitySpecialRendererについて http://codeshare.io/4KSk6 ・・・上記が重くなってきたので増設。ItemとNBTについて調査
- Codeshare なので、どなたでも、誤り指摘や修正など直接やっていただいてかまいません。
- ただし、このメモ書きに書いた内容を定期的に記事にまとめてアップします。この点、ご了承ください。
- 定期的にバックアップはとっていますが、荒らしはご勘弁ください。
「FunTurtles」プロジェクト発動のお知らせ(マイクラModdingはじめました)
はじめに
「ぐぎぎぎ・・・」
その魅力的なキャラクターと万能性で人々に愛されてきたタートルでですが、最近になってその人気に影が差してきました。
そう、強力なライバルの出現です。
OpenComputersのロボット、BuildCraft6.1のロボット。そしてMekanismのホモォ。
便利でお手軽という機能面でタートルを大きく上回っています(OCだけは少し違いますが)。
また、工業系Modだけではありません。魔術系Modでもゴーレムというライバルが次第に力をつけ始めています。機能だけでなくかわいいという点でも強力なライバルです。
「このままではいけない」
危機感を覚えたタートルは、自らの人気の底上げのために、機能強化を検討し始めました。
とはいえ、ただ便利な機能を付け加えただけではすぐに飽きられてしまうことは明白です。
そこで、プログラミング可能という自らの最大の長所を生かし、「プログラミングが楽しくなる」機能強化を目指すことにしました。
ただ機能を強化するだけでなくその機能を実行するLua関数を追加したり、周辺機器を追加したとしても、その機能を実現するためには専用のAPIを使いこなさなければならなかったり。
ただ高機能を与えるのではなくその高機能を実現するための断片的な機能をユーザーの皆さんに提供する予定です。
つまり、タートルの出番が増えCCプログラミングが楽しくなるような機能追加(Modの作成)を目指すプロジェクトが、この「Functional Turtles」(通称、FunTurtle)プロジェクトの目的です。
・・・さあ、それではどこの企業に新しい周辺機器を発注しましょうか。・・・グレッグ社かな?
というわけで
Javaの勉強も兼ねて、MinecraftのModdingを始めました。
Java自体がほとんど初心者に近いので手探り状態ですが、新しいことに挑戦するというのはとても楽しいですね。
このサイトは、ComputerCraftのファンサイトですが、同時にCCとの連携Modの開発もすすめて行こうと思います。
つまり今までのCC中心の記事構成に加えて、Moddingに関する情報も発信していこうかと。
と言いましても、JavaもModdingも初心者なので、間違えた情報を発信することも多々あるかと思います。そのときはアホなこと言っているなぁと生暖かい目で見ていただけるとありがたいです。
また同時に、こっそりご指摘していただけると喜びます。
それでは今後ともこのサイトをよろしくお願いします。
作成予定
基本的にはマイクラ1.7系統をターゲットにするつもりです。
- 周辺機器
- タートルが、
push()と命令すると1mだけ押すことができるブロック(正式名称募集中) - タートルが、
lift()と命令すると上に乗っているプレイヤーごと真上に1m上昇するブロック(エレベーターブロック?) - IC2の支柱から採取できる機能(Minecraft1.7.10ではできません><)
- その他、アイデア募集中
- タートルが、
- 追加タートル
- アクティブソナータートル。直線状に(見えない)音波を発信することで、直線状、何メートル先にブロックがあるかを調べることができる。ただしブロック種類まではわからず、有効射程距離を伸ばすために燃料を消費する。
- 作る予定がないもの
- 便利すぎる機能、強力すぎる機能は実装しません
- 例)自分のインベントリにあるアイテムの名称やIDを直に調べることができる機能
- 作ってみたいけれど、技術力が足りなすぎてまだ夢でしかないもの
- タートルと会話できるシステム
- 文字単位ではなく、ドット単位で詳細な描画ができる高解像度の外部モニタ
- 日本語の表示できるターミナル画面、外部モニタ
補足
CC関連の連載記事がまだ途中ですが、これは今週末にでも更新の予定です。
一応、ソースコードは出来上がっていますので、もし興味があればどうぞ。