ゲーム好きな豚のしっぽ

筆者の下手の横好きなゲーム日記、情報メモです。主にプレイするのはtrophymanager、WoT、WoWS、洋モノSLGなどの予定。

net.minecraft.client.renderer.entity.Render

注意事項

このリファレンスは筆者が記述した時点での拙い知識で翻訳、解釈したもののメモです。
誤訳や理解不足の可能性を多分に含みます。ご覧になる際はご注意ください。
ソースは1.8.9 - 11.15.1.1722のものを使用しています。

net.minecraft.client.renderer.entity.Render

レンダリングの仕組みを理解するために解析。
基本的にはRenderは同じ仕組みで動いているはずなのでRenderの実装クラスを作るときはこれと実装するEntityと類似したクラスの記述を参考に作ることにする。

クラス宣言
@SideOnly(Side.CLIENT)
public abstract class Render<T extends Entity>
フィールド
private static final ResourceLocation shadowTextures

影のテクスチャ

protected final RenderManager renderManager

レンダリングの多くを委譲されるインスタンス。内部に各クラスのレンダラをマップしており、随時呼び出してレンダリングする模様

protected float shadowSize

影のサイズ? 指定方法がわからない

protected float shadowOpaque

影の濃さを決定します。大きい数字ほど濃くなります。

コンストラクタ
protected Render(RenderManager renderManager)

protectedのため実装クラスからしか呼べない。実装クラスのコンストラクタRenderManagerからのみ呼ばれる。MODがこの辺りを操作することはない模様。

メソッド
public boolean shouldRender(T livingEntity, ICamera camera, double camX, double camY, double camZ)

エンティティをレンダリングするかどうかを返す。オーバーライドしているのはRenderGuardianのみ。

public void doRender(T entity, double x, double y, double z, float entityYaw, float partialTicks)

実際にレンダリングを行います。実際にはこのメソッドは合成メソッドで、引数をダウンキャストして実際に作業をするメソッドに引き継ぎます。
何かと思ったら共変戻り値の説明だったので以下略。要するにエンティティに適したレンダラをコンパイラが選択して適切に処理できるということ。

protected void renderName(T entity, double x, double y, double z)

必要であれば名前をレンダリングする。

protected boolean canRenderName(T entity)

名前をレンダリングするかどうかを返す。

protected void renderOffsetLivingLabel(T entityIn, double x, double y, double z, String str, float p_177069_9_, double p_177069_10_)

名前の表示位置を調整してレンダリングする。適切にクラスを継承していれば基本的にオーバーライドは不要。ただし、特殊な装備品や姿勢を実装している時は条件分岐で適切な位置に調整してあげる必要がある。

protected abstract ResourceLocation getEntityTexture(T entity);

エンティティのResourceLocationを返します。bindEntityTexture(T entity)を呼ばない限りなにも見えません。
動的にテクスチャを変更しない限りはstatic finalで宣言したResourceLocationを返せばよい。
エンティティを引数に受け取るので、受け取ったエンティティの属性によってテクスチャを変更するのは難しくない。

protected boolean bindEntityTexture(T entity)

getEntityTexture(T entity)を試みて成功したらtrueを返す。

public void bindTexture(ResourceLocation location)

指定された位置にあるテクスチャをレンダラに割り当てる

private void renderEntityOnFire(Entity entity, double x, double y, double z, float partialTicks)

エンティティの上に炎を描画する

private void renderShadow(Entity entityIn, double x, double y, double z, float shadowAlpha, float partialTicks)

エンティティの影を描写する

private World getWorldFromRenderManager()

RenderManagerが保有しているWorldオブジェクトを返す。
クライアント側のワールドが返る

public static void renderOffsetAABB(AxisAlignedBB boundingBox, double x, double y, double z)

指定された範囲を白い箱で置き換える
範囲内の描画のリセット

public void doRenderShadowAndFire(Entity entityIn, double x, double y, double z, float yaw, float partialTicks)

エンティティの影と炎(もし燃えていたら)を描画する
オーバーライドなし

public FontRenderer getFontRendererFromRenderManager()

レンダーマネージャーにセットされているフォントレンダーを返す

protected void renderLivingLabel(T entityIn, String str, double x, double y, double z, int maxDistance)

エンティティの頭上に名前をレンダリングする
実際の描画処理。

public RenderManager getRenderManager()

レンダーマネージャーを返す

net.minecraftforge.common.capabilities.Capability

注意事項

このリファレンスは筆者が記述した時点での拙い知識で翻訳、解釈したもののメモです。
誤訳や理解不足の可能性を多分に含みます。ご覧になる際はご注意ください。
ソースは1.8.9 - 11.15.1.1722のものを使用しています。

net.minecraftforge.common.capabilities.Capability

Forgeが追加する、NBTでの永続化が可能なオブジェクトのホルダ。おそらくは、ある機能を実現するオブジェクトをクラスの拡張や書き換えを行わずに動的に追加するための機構。有効な使い道がぱっとは浮かんでこない。

クラス宣言
public class Capability<T>
内部インターフェイス
public static interface IStorage<T>

T型を保存するためのインターフェイス。Capabilityクラスしか使用しないとはいえ拡張しないと使えないものを内部で宣言する理由はない。

IStorageのメソッド
NBTBase writeNBT(Capability<T> capability, T instance, EnumFacing side)
void readNBT(Capability<T> capability, T instance, EnumFacing side, NBTBase nbt)

CapabilityインスタンスをNBTTagにシリアライズ、デシリアライズします。
これをデータセーブのセントラル実装にすることができます。

重要な注意点として、Capabilityにどのようなインスタンス値が必須であるかはそのAPI定義次第です。
インターフェイスは利用できるメソッドを定義するだけなのでそのインスタンスのフィールドについては保証できない。
Capability自体はあくまでも情報伝搬の手段で、機能そのものはT型のオブジェクトの実装による。
T型オブジェクトの実装が変更されてもその情報を読み書きするためのインターフェイスは保障されるため、Capabilityは安全に機能する(はず)という思想かと思われる。

内部のデータを操作する可能性を考えると、「とある実装」は「デフォルト実装」のインスタンスを含んでいる必要があるかもしれません。
よくわかりません

メソッド
public String getName()

Capabilityの一意な名前を返します。一般的にはこれはターゲットになるインターフェイスの完全修飾名です。

public IStorage<T> getStorage()

デフォルトのストレージハンドラのインスタンスを返します。あなたはこれをあなたのNBTのデフォルト実装として安全に使用できます。

public T getDefaultInstance()

デフォルト実装のインスタンスを返します。デフォルトのストレージを使用したい場合、この正確に実装されたデフォルトを使用する必要があることが注意点です。
問題となるCapabilityの所有するAPIを参照してください。
どのみちT型の中身を把握していないと「デフォルトではない実装」を使用できないはずなので、正確に実装しろよという警告

コンストラクタ
Capability(String name, IStorage<T> storage, Callable<? extends T> factory)

フィールドをすべて外部から受け取る潔い設計。java8では第3引数のfactoryは関数インターフェイスに置き換えできる。

net.minecraft.entity.Entity

注意事項

このリファレンスは筆者が記述した時点での拙い知識で翻訳、解釈したもののメモです。
誤訳や理解不足の可能性を多分に含みます。ご覧になる際はご注意ください。
ソースは1.8.9 - 11.15.1.1722のものを使用しています。

net.minecraft.entity.Entity

すべてのエンティティの基底クラス。
前方互換を維持するためか、他のクラスと見比べるとフラグやフィールドの管理が統一されていない。
フィールドの多くがpublicだが、MinecraftやForgeの仕様変更に対応するためにもアクセサを通してアクセスし、オーバーライド等で柔軟に対応できるようにしたほうが良い。

クラス宣言
public abstract class Entity implements ICommandSender, ICapabilitySerializable<NBTTagCompound>

チャットからコマンドを送信するICommandSenderとシリアライズできるCapabilityを表すICapabilitySerializableを実装する。

フィールド
private static final AxisAlignedBB ZERO_AABB

大きさゼロのバウンディングボックス。初期化用?

private static int nextEntityID

次に発行されるエンティティのID算出用

private int entityId

エンティティのID

public double renderDistanceWeight

エンティティが描画される範囲の調整

public boolean preventEntitySpawning

このEntityが他のBlockやEntityのスポーンを防ぐかどうかを表す

public Entity riddenByEntity

このEntityに騎乗しているEntity

public Entity ridingEntity

このエンティティが騎乗しているエンティティ

public boolean forceSpawn

他の条件にかかわらずスポーンさせるかどうか

public World worldObj

Worldオブジェクトへの参照

public double prevPosX;
public double prevPosY;
public double prevPosZ;

直前のティックでの座標

public double posX;
public double posY;
public double posZ;

エンティティの現在の座標

public double motionX;
public double motionY;
public double motionZ;

おそらくエンティティの移動増分

public float rotationYaw;
public float rotationPitch;
public float prevRotationYaw;
public float prevRotationPitch;

エンティティの水平方向と垂直方向

private AxisAlignedBB boundingBox

軸並行バウンディングボックス
おもに衝突判定に使用される箱型範囲

public boolean onGround

エンティティが接地しているかどうか?

public boolean isCollidedHorizonally

移動後に水平方向から何かに衝突した場合true

public boolean isCollidedVerticaly

移動後に垂直方向から何かに衝突した場合true

public boolean isCollidead

水平、垂直にかかわらず移動後に何かに衝突した場合true

public boolean velocityChanged

速度変化が起きたかどうか? 攻撃されたときにtrueになる

protected boolean isInWeb

蜘蛛の巣にいるかどうか

private boolean isOutsideBorder

世界の果て(WorldBorder)を越えた位置にいるかどうか

public boolean isDead

setEntityDead()でセットされるため、これは死亡しているかどうかのフラグでなくてはならない(「非アクティブ」にするのがより良い呼び方だろう)
生物的に死んでいるということではなく、オブジェクトとして破棄されるという意味。publicだがアクセサで操作すること

public float width
public float height

設定上の高さと幅
衝突判定とは別に簡便な値として高さと幅を持つ。主にレンダリング時の座標計算に使われる

public float prevDistanceWalkedModified

直前のティックで歩いた距離に0.6を掛けたもの
0.6の由来は不明。

public float distanceWalkedModified

歩いた距離に0.6を掛けたもの

public float distanceWalkedModified;
public float distanceWalkedOnStepModified;

移動距離と歩数

public float fallDistance

落下中のとき落下距離が入ると思われる

private int nextStepDistance

onEntityWalkingイベントを起動して足音を鳴らすまでの距離

public double lastTickPosX
public double lastTickPosY
public double lastTickPosZ

直前のティックでの座標(レンダリングに使用される)

public float stepHeight

エンティティが乗り越えることのできる段差の高さ(必ずしもこの数値通りとはならない)

public boolean noClip

エンティティが衝突に制限されるかどうか(重力の影響がなくなるわけではない)

public float entityCollisionReduction

エンティティが衝突で失う速度のパーセント表記

protected Random rand

乱数発生装置

public int ticksExisted

エンティティが存在し始めてからの時間

public int fireResistance

エンティティが炎にあぶられて燃焼状態になるまでのティック数

private int fire

燃えている時の残り燃焼時間

protected boolean inWater

エンティティが水の中にいるかどうか

public int hurtResistantTime

エンティティがダメージによる影響を受けるまでの時間
いわゆる無敵時間?

protected boolean firstUpdate

エンティティが生成されてから初めてアップデートされるまでのマーカー

protected boolean isImmuneToFire

炎に無敵かどうか

protected DataWatcher dataWatcher

サーバーと同期される監視対象データが入るオブジェクト。別記事も参照。

private double entityRiderPitchDelta
private double entityRiderYawDelta

このエンティティに騎乗しているエンティティの方向の差分?

public boolean addedToChunk

エンティティがチャンクに追加されているかどうか

public int chunkCoordX
public int chunkCoordY
public int chunkCoordZ

エンティティの存在するチャンク座標

@SideOnly(Side.CLIENT)
public int serverPosX
@SideOnly(Side.CLIENT)
public int serverPosY
@SideOnly(Side.CLIENT)
public int serverPosZ

サーバーが保持するエンティティの座標。イベントハンドラからセットされてその値をsetPositionAndRotation2(double x, double y, double z, float yaw, float pitch, int posRotationIncrements, boolean p_180426_10_)で同期している模様。

public boolean ignoreFrustumCheck

エンティティがカメラの描画範囲外でもレンダリングされるかどうか。現在はEntityFishのみtrue

public boolean isAirBorne

エンティティが空中にあるかどうか。原因は問わない。

public int timeUntilPortal

次にポータルが利用できるまでの残り時間

protected boolean inPortal

ポータル内にいるかどうか

protected int portalCounter

ポータル内にいる時間(転送開始までのカウント)

public int dimension

エンティティがどの次元にいるか(-1=ネザー、0=通常世界)

protected BlockPos field_181016_an;
protected Vec3 field_181017_ao;
protected EnumFacing field_181018_ap;

プレイヤーの座標と方向の模様

private boolean invulnerable

攻撃を無効にするかどうか

protected UUID entityUniqueID

UUID

private final CommandResultStats cmdResultStats

コマンドの実行結果が保存される?

private NBTTagCompound customEntityData

カスタムデータの保存を行う

public boolean captureDrops
public java.util.ArrayList<EntityItem> capturedDrops

ドロップされた際にひとまとめになるかどうかと、まとめられたアイテムのリスト

private net.minecraftforge.common.capabilities.CapabilityDispatcher capabilities

Capabilityの受け皿。

コンストラクタ
public Entity(World worldIn)

シンプル。

メソッド
public int getEntityId()
public void setEntityId(int id)

IDへのアクセサ

public void onKillCommand()

"/kill"コマンドが実行されると呼び出されます

protected abstract void entityInit()

実装クラス固有の初期化処理。super.entityInit()の実行後にDateWacherの追加を行う。

@SideOnly(Side.CLIENT)
protected void preparePlayerToSpawn()

エンティティがスポーン可能な位置まで高さを上げる(実際のところプレイヤーにも使用)

public void setDead()

次のティックに破壊されます

protected void setSize(float width, float height)

エンティティのサイズ(高さ、幅)をセットします

protected void setRotation(float yaw, float pitch)

エンティティの回転(首振り角度、仰俯角)をセットします

public void setPosition(double x, double y, double z)

エンティティの座標をセットします。バウンディングボックスもセットされます

@SideOnly(Side.CLIENT)
public void setAngles(float yaw, float pitch)

エンティティの首ふり角を15%増やし、仰俯角を15%減らします。pitchは-90から90に制限されます。いずれの引数も角度で指定します。
レンダリングで内部的に使用されている様子

public void onUpdate()

エンティティの位置やロジックを更新するために呼び出されます

public void onEntityUpdate()

ティックごとに呼び出されるエンティティの基礎処理です。

public int getMaxInPortalTime()

ポータルに入ってから実際に転送されるまでの時間を返します。

protected void setOnFireFromLava()

エンティティが溶岩の中を移動している間呼び出されます
ダメージ量と燃焼時間がセットされる

public void setFire(int seconds)

エンティティの燃焼時間をセットします。既に燃えている時はこのメソッドで既存の燃焼時間を短くすることはできません

public void extinguish()

消火します

protected void kill()

死亡フラグを立てます

public boolean isOffsetPositionInLiquid(double x, double y, double z)

エンティティから指定の差分移動した座標が液体かどうかを返します

private boolean isLiquidPresentInAABB(AxisAlignedBB bb)

指定のバウンディングボックス内に水が存在するかを返します。

public void moveEntity(double x, double y, double z)

エンティティを渡された座標へ移動させようと試みます
障害物があるときや落下が発生すると指定の座標にたどり着けるとは限らない

private void resetPositionToBB()

エンティティの位置をバウンディングボックスの中央、ボトムへ調整する

protected String getSwimSound()

泳いでいる時の効果音のリソース名

protected void doBlockCollisions()

ブロックとの衝突処理を行う

protected void playStepSound(BlockPos pos, Block blockIn)

指定座標で足音を鳴らす。踏んだブロックで足音が変わる

public void playSound(String name, float volume, float pitch)

効果音を鳴らす

public boolean isSilent()

エンティティが音を鳴らさないときtrue

public void setSilent(boolean isSilent)

音を鳴らさないときtrueをセットします

protected boolean canTriggerWalking()

エンティティがブロックに対してOnEntityWalking()を起動する場合はtrueを返します。蜘蛛やオオカミが作物を踏み荒らさないなどに使用されます

protected void updateFallState(double y, boolean onGroundIn, Block blockIn, BlockPos pos)

落下距離ステータスを更新している。通常はオーバーライドの必要なしと思われる

public AxisAlignedBB getCollisionBoundingBox()

当たり判定用のボックスを返します

protected void dealFireDamage(int amount)

エンティティに対し炎によるダメージを与えます

public final boolean isImmuneToFire()

エンティティが炎無効かを返す

public void fall(float distance, float damageMultiplier)

距離とダメージ倍率を与えて落下処理を行います
エンティティに騎乗しているエンティティも落下する。ここではダメージ処理などは行っていない。
落下の処理中にブロックへ到達するとブロックの側からダメージを発生させる様子

public boolean isWet()

エンティティが濡れているかを返します。オオカミの身震いなどに使用されています
水中にいるかと雷が落ちるか≒雨が降っているかで判定している模様

public boolean isInWater()

水中にいるかどうかを返します(trueのとき水流の影響をうけます)

public boolean handleWaterMovement()

エンティティが水中にいることによる速度の変化を受けているかを返します。

protected void resetHeight()

寝た後や死んだあとにエンティティの高さをリセットします
コメントとは異なり、Entityの中では実際には水中の処理しか行っていない。
飛沫のパーティクルを発生させている

public void spawnRunningParticles()
protected void createRunningParticles()

ダッシュしていてかつ水中にいない時にパーティクルを生成させます

protected String getSplashSound()

水に入った時の効果音のリソース名

public boolean isInsideOfMaterial(Material materialIn)

指定されたMaterialの中にいるかを返します
固形ブロックの中には入れない前提なので液体に対する判定がメインの模様。
液体の充填度で水位を計算してそれが目線よりも上かどうかで判定している

public boolean isInLava()

溶岩の中にいるかを返す

public void moveFlying(float strafe, float forward, float friction)

飛んでいる、あるいは水中にいるエンティティの移動に使用します
水平移動、前進、抵抗(摩擦)が引数で方向転換しないで移動する模様

@SideOnly(Side.CLIENT)
public int getBrightnessForRender(float partialTicks)

レンダー用の明るさを返す

public float getBrightness(float partialTicks)

エンティティの明るさを返します。
この二つはMODから触れることはなさそう

public void setWorld(World worldIn)

Worldをセットします

public void setPositionAndRotation(double x, double y, double z, float yaw, float pitch)

エンティティの位置と方向をセットします

public void moveToBlockPosAndAngles(BlockPos pos, float rotationYawIn, float rotationPitchIn)

エンティティの位置と方向をBlockPosから変換してセット

public void setLocationAndAngles(double x, double y, double z, float yaw, float pitch)

エンティティの位置と方向をセットします
通常はsetLocationAndAnglesを使う模様

public float getDistanceToEntity(Entity entityIn)
public double getDistanceSq(double x, double y, double z)
public double getDistanceSq(BlockPos pos)
public double getDistanceSqToCenter(BlockPos pos)
public double getDistance(double x, double y, double z)
public double getDistanceSqToEntity(Entity entityIn)

エンティティとの直線距離を返します
精度と平方根を取っているかいないか、対象となる座標を指定する引数の違い

public void onCollideWithPlayer(EntityPlayer entityIn)

プレイヤーがエンティティと衝突したときに呼ばれます
アイテムなら拾われる処理など。通常は何もしない

public void applyEntityCollision(Entity entityIn)

エンティティ同士が衝突したときの速度変化を行います

public void addVelocity(double x, double y, double z)

速度を変化させます
攻撃を受けた時のノックバック、カートがアクティベーターを通過したときにしか呼ばれないため、空中フラグもたてているものと思われる。
メソッド名が内容と合っておらずよくない。

protected void setBeenAttacked()

エンティティが攻撃されたときに呼ばれます
速度変化のフラグを立てているだけ

public boolean attackEntityFrom(DamageSource source, float amount)

エンティティが攻撃されたときに呼ばれます
ダメージ処理もされていないため継承クラスではsuper()とオーバーライド必須。カートなら揺れて乗っているエンティティを落とす、ゾンビなら仲間を召還する、などの特殊処理もここ

public Vec3 getLook(float partialTicks)

視線(ベクター)の補正を行います
指定されたティック後の視線の位置を返している?

protected final Vec3 getVectorForRotation(float pitch, float yaw)

エンティティの回転を表すベクトルを生成します
ヘルパーなので直接呼んだりオーバーライドするは必要ないと思われる

@SideOnly(Side.CLIENT)
public Vec3 getPositionEyes(float partialTicks)

視線を取得するメソッドの亜種。レンダリング用?

@SideOnly(Side.CLIENT)
public MovingObjectPosition rayTrace(double blockReachDistance, float partialTicks)

視線が当たった場所の情報を返す。レンダリングで使用されている模様。
しかしながら遠距離武器の射線確認や動線予測にも使えそうな予感。

public boolean canBeCollidedWith()

エンティティが他のエンティティの通過を妨げるかどうかを返します
生物ならisDeadがfalseならtrueが定型

public boolean canBePushed()

エンティティが他のエンティティに押されることができるかを返します
生物は基本true、移動しない無生物はfalse

public void addToPlayerScore(Entity entityIn, int amount)

プレイヤースコアを加算します。
プレイヤースコア=経験値なので、Mobに成長を実装するなら使えるかも。プレイヤーの実装を参照

@SideOnly(Side.CLIENT)
public boolean isInRangeToRender3d(double x, double y, double z)
@SideOnly(Side.CLIENT)
public boolean isInRangeToRenderDist(double distance)

エンティティが描画される範囲かどうかを返します
エンティティの大きさや特殊効果を持つアイテムのときisInRangeToRenderDistをオーバーライド
フィールドのrenderDistanceWeightを増やせば遠くでも描写されるはずだがこれはシステムのオプションからしか変更できない?

public boolean writeMountToNBT(NBTTagCompound tagCompund)
public boolean writeToNBTOptional(NBTTagCompound tagCompund)

エンティティのNBTを記録し、trueを返します。保存する情報がなかったときfalseを返します
騎乗されているエンティティはwriteMountToNBTを使って乗っているエンティティが記録を行う。
二つの差は騎乗のチェックを行うかどうか。騎乗する側は呼び出すメソッドを間違わないように注意が必要。

public void writeToNBT(NBTTagCompound tagCompund)
public void readFromNBT(NBTTagCompound tagCompund)

NBTを読み書きするヘルパーです

protected boolean shouldSetPosAfterLoading()

NBTの読み込み後に位置を設定するべきかを返す。
絵画や額縁はfalse、区別がわからない

protected final String getEntityString()

エンティティのクラスの識別子を返します

protected abstract void readEntityFromNBT(NBTTagCompound tagCompund);
protected abstract void writeEntityToNBT(NBTTagCompound tagCompound);

サブクラスがNBTの読み書きを行うための抽象メソッドです
スーパークラスメソッドを呼ぶこと、データ長の指定ミス、丸め込みの処理漏れ等バグに注意が必要

public void onChunkLoad()

チャンクが読み込まれたときに呼び出される
実装クラスなし

protected NBTTagList newDoubleNBTList(double... numbers)
protected NBTTagList newFloatNBTList(float... numbers)

引数の値を持つNBTTagListを生成する
コーディングの観点ではNBTTagListコンストラクタになっているべきメソッド
座標などの保存に使うらしい。

public EntityItem dropItem(Item itemIn, int size)
public EntityItem dropItemWithOffset(Item itemIn, int size, float offsetY)
public EntityItem entityDropItem(ItemStack itemStackIn, float offsetY)

アイテムをドロップします
ドロップする可能性のあるアイテムをエンティティから引き出し、最終的にWorldオブジェクトに追加(スポーン)させるという流れ

public boolean isEntityAlive()

エンティティが生きているかを返します
isDeadの否定を返しているだけ

public boolean isEntityInsideOpaqueBlock()

エンティティが「不透過ブロック」の中にいるかどうかを返す
窒息するかどうかだと思えばおおよそ正しい

public boolean interactFirst(EntityPlayer playerIn)

プレイヤーに右クリックされたときに呼び出され、フラグを返す
trueとfalseの条件がわからない。おそらくクリックイベントを消費したかどうか

public AxisAlignedBB getCollisionBox(Entity entityIn)

衝突判定用のAABBを返します。カートやボートのように接触時に移動する動作に使用できます。

public void updateRidden()

騎乗されている間のデータ更新を行います

public void updateRiderPosition()

騎乗しているエンティティの座標を更新します

public double getYOffset()

上下位置の補正値を返します
成長などでモデルの大きさに補正が入る場合(子どもゾンビ)などで使用

public double getMountedYOffset()

このエンティティに騎乗しているエンティティに対する高さ補正を返します
騎乗しているエンティティの底面(座っているとは限らない)の高さに使用される

public void mountEntity(Entity entityIn)

エンティティが騎乗されたときに呼ばれます。
乗り降り両方の動作をトグルしている

@SideOnly(Side.CLIENT)
public void setPositionAndRotation2(double x, double y, double z, float yaw, float pitch, int posRotationIncrements, boolean p_180426_10_)

エンティティの位置と方向をセットします
サーバーからの通信でクライアント側のエンティティの位置をセットするときに呼ばれる。基本的に引数をそのままフィールドに代入する。
Entityでの宣言とオーバーライドしているクラスで処理がまちまちで、表示系のバグの温床になりそうなメソッド

public float getCollisionBorderSize()

当たり判定の厚さ?を返す
基本的に0.1F。炎の玉1.0、炎0.0

public Vec3 getLookVec()
protected final Vec3 getVectorForRotation(float pitch, float yaw)

正規化した視線を返します
生物以外はnullを返す。生物は1ティック分の視線?を返す

public void setPortal(BlockPos p_181015_1_)

エンティティがポータルに入ったことをマークします

public int getPortalCooldown()

エンティティがポータルを再利用できるようになるまでのティック数を返します
プレイヤーは10、それ以外は300

@SideOnly(Side.CLIENT)
public void setVelocity(double x, double y, double z)

エンティティの速度を設定します
クラスによっては速度を表すフィールドが異なっているため使用時にはオーバーライドの必要がないか確認が必須

public void handleStatusUpdate(byte id)

サーバから通信を受けてエンティティのステータス更新を行う
送られてくるステータスidの詳細が分からないため実装できない

@SideOnly(Side.CLIENT)
public void performHurtAnimation()

サーバから通信を受けてダメージを受けた時のアニメの初期化を行う
通常はオーバーライドの必要なし。カートとボートがオーバーライドしている

public ItemStack[] getInventory()

エンティティのインベントリ(ItemStackの配列)を返す
実際には装備品の配列を返す。運搬物としてのインベントリではない

public void setCurrentItemOrArmor(int slotIn, ItemStack stack)

エンティティの装備品を返す
0が手持ち、1~4が防具だが1.9で変更されること間違いなし。オーバーライド必須

public boolean isBurning()

エンティティが燃えている時にtrueを返す。レンダリングで炎上のエフェクトを追加するために使用される

public boolean isSneaking()
public boolean isRiding()
public boolean isSprinting()
public boolean isEating()
public boolean isInvisible()

エンティティの状態管理フラグを返す。セッターもある

public boolean isInvisibleToPlayer(EntityPlayer player)

EntityLivingのレンダーに使用される。falseを返すと半透明に表示される

protected boolean getFlag(int flag)
protected void setFlag(int flag, boolean set)

エンティティの状態管理フラグのアクセサ
触らないほうが良さそう

public int getAir()
public void setAir(int air)

無呼吸時間の残りをセットまたはゲットする(水中の息止めなど?)

public void onStruckByLightning(EntityLightningBolt lightningBolt)

エンティティが雷に撃たれたときに呼ばれる
豚のゾンビ豚化などで上書きされている

public void onKillEntity(EntityLivingBase entityLivingIn)

エンティティが生物を殺した時に呼ばれます。
生物が殺されたときに、相手のこのメソッドを自分を引数として呼び出す。私殺されたけど何か?
ゾンビのクラスが村人のゾンビ化処理を行っている

protected boolean pushOutOfBlocks(double x, double y, double z)

ブロックへ向かって移動したときの衝突判定と移動処理。
通常はオーバーライドの必要なしのはずだが、半ブロックで埋まるなどの原因はこのメソッドにありそうな気がする

public void setInWeb()

蜘蛛の巣に引っかかっているフラグを立てます
BlockWeb(蜘蛛の巣クラス)しかこのメソッドを呼ばない

public String getName()

エンティティの名前を返します。
※名づけされている時はcustumNameTagを返す。色や毛並で名前が異なる場合NBTなどのデータから文字列を合成してローカライズしてから返す。

public Entity[] getParts()

複合パーツのエンティティのときそれぞれのパーツを配列で返す
ドラゴンなど大型Mobに使用する模様

public boolean isEntityEqual(Entity entityIn)

エンティティが同じかを返します
単純な==比較

public float getRotationYawHead()
public void setRotationYawHead(float rotation)

首の向きのアクセサ

public void func_181013_g(float p_181013_1_)

おそらくsetRenderYawOffsetがメソッド名。どういう作用があるかは不明

public boolean canAttackWithItem()

このエンティティが他のエンティティからダメージを受けるかどうか
falseを返すのは視覚効果系と矢のみ

public boolean hitByEntity(Entity entityIn)

エンティティが攻撃されたとき呼び出されます
trueを返すと処理が完了とみなされる模様。イベントが消費されたかどうかのフラグ

public boolean isEntityInvulnerable(DamageSource source)

エンティティがDamageSourceからダメージを受けるかを返す。
現在のところ一定のルールでfalseが返る。特殊なケースを除いてオーバーライドの必要なし

public void copyLocationAndAnglesFrom(Entity entityIn)

与えられたエンティティの位置と角度をコピーします
村人のゾンビ化、ゾンビの治療で使用

public void copyDataFromOld(Entity entityIn)

古いディメンションのエンティティからNBTをコピーして新しいディメンションのエンティティの準備をします
それ以外の用途でもNTBのコピーが必要なら使えるはず

public void travelToDimension(int dimensionId)

エンティティを指定されたディメンションへ移動させます

public float getExplosionResistance(Explosion explosionIn, World worldIn, BlockPos pos, IBlockState blockStateIn)

爆発耐性を返します
エンティティの耐性はエンティティのいる位置のブロックに由来するらしい

public boolean verifyExplosion(Explosion explosionIn, World worldIn, BlockPos pos, IBlockState blockStateIn, float p_174816_5_)

基本的にtrueを返す。MinecartTNTのみ独自で実装している

public int getMaxFallHeight()

ジャンプの最大の高さ。経路探索に使用される
頭の頂点の高さでデフォルトは3、体力が減るにつれて減少する。クリーパーのみ敵をターゲットしていると体力-1分ジャンプ力が増す(怖い)

public Vec3 func_181014_aG()
public EnumFacing func_181012_aH()

おそらくゲッター いずれもエンティティの方向(yaw)を示すものと思われる

public boolean doesEntityNotTriggerPressurePlate()

感圧版に反応しない時true
コウモリだけtrue

public void addEntityCrashInfo(CrashReportCategory category)

クラッシュ時にレポートに情報を追加する
当然ながらcatch節で使用される

@SideOnly(Side.CLIENT)
public boolean canRenderOnFire()

燃えている描写をするかを返す

public UUID getUniqueID()

UUIDを返す

public boolean isPushedByWater()

水に押し流されるかを返す
レンダリングや移動の情報ではなくエンティティとしての属性。飛んでいるプレイヤーと水棲MOBはfalse(でもイカは流されていた気がする…)

getDisplayName()

チャット用にフォーマットされたユーザーネームを含むIChatComponentを返す

public void setCustomNameTag(String name)
public String getCustomNameTag()

カスタムネームタグのアクセサ

public boolean hasCustomName()

カスタムネームを持っていればtrueを返す

public void setAlwaysRenderNameTag(boolean alwaysRenderNameTag)
public boolean getAlwaysRenderNameTag()
@SideOnly(Side.CLIENT)
public boolean getAlwaysRenderNameTagForRender()

名前を常時レンダリングするかどうかのフラグへのアクセサ
TagForRender()はレンダラ用のラッパー

public void setPositionAndUpdate(double x, double y, double z)

「最後に」与えられた変数をもとに位置のセットと更新をおこないます
アップデートのタイミングによっては必ずしもここで与えられた数値通りの位置に表示されるとは限らない ということか?

public void onDataWatcherUpdate(int dataID)

DataWatcherが更新を検知したときに呼ばれる

public EnumFacing getHorizontalFacing()

エンティティの向いている方角を返す

protected HoverEvent getHoverEvent()

チャット表示用のクリックできる文字(HTMLでいうリンク)を作る?
オーバーライドの必要なし

public boolean isSpectatedByPlayer(EntityPlayerMP player)

プレイヤーがスペクテイターモードかを返す

public AxisAlignedBB getEntityBoundingBox()
public void setEntityBoundingBox(AxisAlignedBB bb)

バウンディングボックスへのアクセサ

public float getEyeHeight()

目線の高さを返す。
モデルの見た目に合わせて随時オーバーライドが必要。

public boolean isOutsideBorder()
public void setOutsideBorder(boolean outsideBorder)

isOutsideBorderフラグへのアクセサ
衝突判定で呼ばれているが詳細がわからない。オーバーライドは不要の様子

public boolean replaceItemInInventory(int inventorySlot, ItemStack itemStackIn)

指定されたインベントリのスロットにアイテムを配置しようと試みて、成功したときtrueを返す
防具やエンダーチェストのときは本来存在しないスロットidを指定して加減算して調整している模様。
タブ切り替えやスクロールできるような大容量インベントリを実装するときは誤動作しやすいと思われる。
将来的な拡張や1.9でのアップデートを考えると装備品のインベントリと所持品のインベントリはあらかじめ分けて考えるべき

public void addChatMessage(IChatComponent component)

チャットメッセージを送信する
通常のエンティティなら不要? 実装してるのはプレイヤーのみ

public boolean canCommandSenderUseCommand(int permLevel, String commandName)

trueならコマンドの送信ができる
これもプレイヤーのみオーバーライド

public BlockPos getPosition()

BlockPositionを返す。nullを返してはいけない。もしも世界に存在しないことを表したいなら(0,0,0)を返すこと

public Vec3 getPositionVector()

ベクターで位置を返す。getPosition()と同じ制約

public World getEntityWorld()

ワールドを返す。もしも世界に存在しないらoverworldを返すこと
overworldについては詳細不明

public Entity getCommandSenderEntity()

CommandSenderと結びついているEntityを返す。おそらくnull
といいつつ自分自身を返している。本来プレイヤー以外に実装する意味のないインターフェイスじゃないのかな
以下コマンド系統のメソッド数個省略

public NBTTagCompound getNBTTagCompound()

持っているNBTTagを返す
実装クラスなし

@SideOnly(Side.CLIENT)
public void clientUpdateEntityNBT(NBTTagCompound compound)

クライアントがサーバーからNBTの更新を受信したときに呼ばれる
呼び出しているメッセージはS49PacketUpdateEntityNBT
実装クラスなしだが重要そう。
独自に同期の必要のあるデータ構造を実装する場合は使用できると思われる。

public boolean interactAt(EntityPlayer player, Vec3 targetVec3)

プレイヤーがターゲットしている場所が正確に把握できるinteractWithの新バージョンです
前方互換性を考える以外ではこちらを使うべき

public boolean isImmuneToExplosions()

爆発無効かどうかを返す
実装クラスは新しいエンティティのEntityArmorStandだけだが、オブジェクトとしての「爆発」はこのメソッドで相手のチェックを行っている

protected void applyEnchantments(EntityLivingBase entityLivingBaseIn, Entity entityIn)


エンチャントの処理を行うハンドラ
内部的にはエンチャントの処理を行うヘルパに投げているが、オーバーライドで弱点を作ったりできるはず

Forge拡張

Forgeの拡張メソッドなのでバニラとの互換性を考えるなら使用できない。公式がMOD用のAPIを発表するとも思えないので依存を避ける理由はあまりない。

public NBTTagCompound getEntityData()

拡張のエンティティデータを返します。
getNBTTagCompound()に対応する拡張。仕様変更を避けるために独自に設定したものと思われる。

public boolean shouldRiderSit()

このエンティティに乗ったエンティティのモデルに対し「座位」をレンダリングするかを決定します。

public ItemStack getPickedResult(MovingObjectPosition target)

このエンティティを対象にpick blockボタン(デフォルトではホイール押し下げ)を押したときに呼ばれます。

クリエイティブモードのいわゆるスポイト操作。
操作系のイベントハンドラなのでよほど特殊なエンティティ―でなければオーバーライドの必要なし

public UUID getPersistentID()

UUIDを返します。

public final void resetEntityId()

エンティティIDを再設定します。MODのコードから呼び出してはいけません。

public boolean shouldRenderInPass(int pass)

レンダリングの順序などの制御を行っている模様。触れないほうが良さそう

public boolean isCreatureType(EnumCreatureType type, boolean forSpawnCount)

エンティティがEnumCretureTypeで規定されているタイプならtrueを返します。
スポーンのコントロールに使用される模様。

public String registerExtendedProperties(String identifier, IExtendedEntityProperties properties)
public IExtendedEntityProperties getExtendedProperties(String identifier)

IExtendedPropertiesに対するアクセサ。IExtendedProperties自体が廃止が検討されているようなので使用しないほうが良い

public boolean canRiderInteract()

このエンティティに騎乗しているエンティティがこのエンティティに対し右クリックできるかどうか
通常はfalse。
宇宙船のような乗り物で特殊なUIを実装したいときはオーバーライドする、とか

public boolean shouldDismountInWater(Entity rider)

このエンティティが水中にいるとき騎乗が解除されるかどうか
生物ならtrue。特殊な設定をしたいならオーバーライド。

public boolean hasCapability(Capability<?> capability, EnumFacing facing)
public <T> T getCapability(Capability<T> capability, EnumFacing facing)

Capabilityに対応していればそれを返す。利用側はnullチェックを怠ってはいけない

public void deserializeNBT(NBTTagCompound nbt)
public NBTTagCompound serializeNBT()

INBTSilializableインターフェイスの実装。Forgeはこのメソッドを呼んでエンティティを永続化する

net.minecraft.client.model.ModelBiped

注意事項

この記事はforge-1.8.9-11.15.1.1722のソースを筆者が記述した時点での拙い知識で解釈したもののメモです。
誤訳や理解不足の可能性を多分に含みます。ご覧になる際はご注意ください。

ModelBiped

二足歩行のLivingEntityのモデルの親クラス。
人型のモデルを作るならこれを基本にするので調べておく。

クラス宣言
@SideOnly(Side.CLIENT)
public class ModelBiped extends ModelBase

ModelBaseを拡張している。

フィールド
public ModelRenderer bipedHead;
public ModelRenderer bipedHeadwear;
public ModelRenderer bipedBody;
public ModelRenderer bipedRightArm;
public ModelRenderer bipedLeftArm;
public ModelRenderer bipedRightLeg;
public ModelRenderer bipedLeftLeg;

モデルの各パーツとなるレンダラ。ModelBipedでは非常にシンプルで一つのパーツに一つのレンダラ、一つのボックスしかない。

public int heldItemLeft;
public int heldItemRight;

左右の手にブロックを持っている時にそれがレンダリングするべきかどうかを記録する。
呼び出し階層で追いかけるとアイテムを手に持っている時に可能な行動であるEnumActionで判別しており、それをswitch文でintに置き換えて保持している。大変古いコードの名残と思われるが、よくないコーディングスタイル。

メソッド
public void render(Entity entityIn, float p_78088_2_, float p_78088_3_, float p_78088_4_, float p_78088_5_, float p_78088_6_, float scale)

実際にモデルをレンダリングするメソッド。ここでは子どもではないかとスニークしているかで処理を分けている。継承したクラスでは(スティーブ氏と同じ体系、動作でよい場合を除いて)完全に上書きする必要がある。

public void setRotationAngles(float p_78087_1_, float p_78087_2_, float p_78087_3_, float p_78087_4_, float p_78087_5_, float p_78087_6_, Entity entityIn)

各パーツの角度を決める。モデルが取る可能性のあるポーズをすべてこの中で処理するため、メソッドが長くなる傾向がある。
継承したクラスではこのメソッドを参考にしながら完全に上書きする必要がある。理想でいえばポーズや状態ごとにそれ用の角度設定メソッドを用意して、このメソッド内では分岐条件を判断してそれを呼ぶだけにしたい。
ModelBipedで行っている処理は
1.初期化
2.騎乗している時
3.両手のアイテムによる調整
4.歩行時の腕振り角度
5.スニーク時とそれ以外のときの体と頭の角度
6.弓で狙う動作
の流れ。
継承したモデルではこれらについてすべて調整したうえで、独自の動作があればその処理を追加しなくてはならない。

public void setModelAttributes(ModelBase model)

別のモデルから状態(動作のフラグなど)をコピーする。メソッドではこれのみがsuperを呼び出している。

public void setInvisible(boolean invisible)

不可視状態を設定する

public void postRenderArm(float scale)

コメントとソースの追跡によると右腕をレンダリング実行後に角度を変化させている。効果は不明。

net.minecraft.client.model.ModelRenderer

注意事項

この記事はforge-1.8.9-11.15.1.1722のソースを筆者が記述した時点での拙い知識で解釈したもののメモです。
誤訳や理解不足の可能性を多分に含みます。ご覧になる際はご注意ください。

ModelRenderer

モデルのレンダリングを実際に引き受けているクラス。
基本的には1つのMedelRendererに一つの四角とテクスチャ。
3Dグラフィックに触れたことがないので不明点が多い。

フィールド
public float textureWidth;
public float textureHeight;

テクスチャ画像の幅と高さ。単位はピクセル。

private int textureOffsetX;
private int textureOffsetY;

テクスチャ画像のうち実際に使用する範囲の始点。単位はピクセル

public float rotationPointX;
public float rotationPointY;
public float rotationPointZ;

回転処理の始点座標

public float rotateAngleX;
public float rotateAngleY;
public float rotateAngleZ;

モデルの方向(角度)

private boolean compiled;
private int displayList;

OpenGLの機能であるdisplayListとそれ用の描画情報がコンパイル済かのフラグ

public boolean showModel;
public boolean isHidden;

名前からして表示非表示の切り替えだと思われるが使いわけ方が不明。

public List<ModelBox> cubeList;

レンダラが持つModelBoxのリスト。基本的に同じテクスチャ画像をオフセット指定で使いまわす。

public List<ModelRenderer> childModels;

子のレンダラ。こちらはModelRendererなのでそれぞれにテクスチャを指定できる。

public final String boxName;

レンダラの名前。

private ModelBase baseModel;

レンダラの親となるモデル。テクスチャのオフセットを得るために使用している模様

public float offsetX;
public float offsetY;
public float offsetZ;

座標のオフセット。どこを原点にしてのオフセットなのか不明

コンストラクタ
    public ModelRenderer(ModelBase model, String boxNameIn)
    {
        this.textureWidth = 64.0F;
        this.textureHeight = 32.0F;
        this.showModel = true;
        this.cubeList = Lists.<ModelBox>newArrayList();
        this.baseModel = model;
        model.boxList.add(this);
        this.boxName = boxNameIn;
        this.setTextureSize(model.textureWidth, model.textureHeight);
    }

一番詳細なコンストラクタ。別のコンストラクタはboxNameをnullで転送する。また、このコンストラクタはtexturOffsetを受け取らず、受け取るコンストラクタは別途setTextureOffsetを自分で呼び出す。

メソッド
public void addChild(ModelRenderer renderer)

現在のボックスの回転位置と回転角度を他のボックスへセットする
別のレンダラをこのレンダラと連動するようにする。

public ModelRenderer setTextureOffset(int x, int y)

テクスチャのオフセットのセッター

public void addBox(float p_78790_1_, float p_78790_2_, float p_78790_3_, int width, int height, int depth, float scaleFactor)

テクスチャ付きのボックスを追加する。引数はX,Y,Z,幅、高さ、奥行き、スケール倍率。
唯一コメントのついているaddBox。
他のaddBoxと見比べると、名前指定をするタイプのaddBoxの時は親Modelの持つMapからテクスチャのオフセットを取得してテクスチャを部分使用する。
それ以外はまったく同じテクスチャを使いまわすと思われる。

public void setRotationPoint(float rotationPointXIn, float rotationPointYIn, float rotationPointZIn)

回転処理の中心座標をセットする。

net.minecraft.client.model.ModelBase

注意事項

この記事はforge1.9-12.16.0.1797-1.9-snapshotのソースを筆者が記述した時点での拙い知識で解釈したもののメモです。
誤訳や理解不足の可能性を多分に含みます。ご覧になる際はご注意ください。

ModelBase

すべてのエンティティモデルの基底クラス。意外なほどフィールドやメソッドは少ない。
mod制作の中でも比較的大きな比重を占めるモデルづくりの根底なのできちんと調べておく。

クラス宣言
public abstract class ModelBase

基底クラスだけにいたってシンプル。

フィールド
public float swingProgress;

通常アニメーションのサイクルカウント用

public boolean isRiding;

騎乗状態か

public boolean isChild = true;

子供か(なんでridingは初期化してないのにこっちはしてるのか)

public List<ModelRenderer> boxList = Lists.<ModelRenderer>newArrayList();

実際にモデルをレンダリングするModelRendererのリスト。1パーツに1つ?

private Map<String, TextureOffset> modelTextureMap = Maps.<String, TextureOffset>newHashMap();

パーツごとのテクスチャ画像の始点位置のMap

public int textureWidth = 64;

テクスチャ画像の幅

public int textureHeight = 32;

テクスチャ画像の高さ

メソッド
public void render(Entity entityIn, float p_78088_2_, float limbSwing, float ageInTicks, float netHeadYaw, float headPitch, float scale)

モデルの様々な角度を設定してからレンダリングを行う
引数はレンダリングされるエンティティ、(bipedの実装によると)手足の前後の振りのパーセンテージ、手足の振りの最大がどれだけ遠いか、ティック数のカウント?、頭の水平方向、頭の仰俯角、スケール倍率

public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entityIn)

モデルの様々な角度を設定する。
renderの角度設定部分の実装

public void setLivingAnimations(EntityLivingBase entitylivingbaseIn, float p_78086_2_, float p_78086_3_, float partialTickTime)

エンティティに固有なアニメーションの追加を容易にする。第二、第三の引数はSetRotationAnglesと同じ。
実はそこが一番簡単じゃない。

public ModelRenderer getRandomModelBox(Random rand)

モデルに追加されているパーツ(ボックス)から一つをランダムで取得する。ダメージなどのアニメーションに利用できる。

protected void setTextureOffset(String partName, int x, int y)

指定したパーツにテクスチャ画像の始点を指定する。

public TextureOffset getTextureOffset(String partName)

指定したパーツのテクスチャの始点を取得する。

public static void copyModelAngles(ModelRenderer source, ModelRenderer dest)

あるオブジェクトの角度を別のオブジェクトへコピーする。頭と髪の毛のように、互いが同じ方向を向くオブジェクトに利用できる。

public void setModelAttributes(ModelBase model)

与えられたモデルが持っている属性を受け取ったモデルへコピーする。

これだけでモデルが動いてくれれば苦労しないな…

The Capability System

注意事項

この記事は
Capabilities - Forge Documentation
の記事を筆者が記述した時点での拙い知識で解釈したもののメモです。
誤訳や理解不足の可能性を多分に含みます。ご覧になる際はご注意ください。

Capability システム

Capabilityは、手数をかけてインターフェイスを実装することなく、様々な機能を動的に、柔軟に公開するための手法です。
一般的には、Capabilityはデフォルトの実装に要求される機能を満たすインターフェイスと、少なくともこのデフォルトの実装に対するストレージハンドラを提供します。
このストレージハンドラはほかの実装をサポートすることもありますが、これはCapabilityの実装者次第ですので、デフォルトのストレージと(Capabilityの)デフォルトではない実装の使用に挑戦する前に、ドキュメントを参照するようにしましょう。
Foegeはあなたが実装した、Capabilityメソッドをオーバーライドしているか、イベントを通じて公開されているTileEntity,Entity,ItemStackにCapabilityのサポートを追加します。これについては続くセクションで説明します。

Foegeが提供するCapability

元の記事の執筆時点でFoegeは IItemHandler 1つだけのCapabilityを提供します。

このCapabilityはインベントリのスロットに対するハンドリングのインターフェースを公開します。これはTileEntity(チェスト、機械装置など)、Entity(プレイヤー、mobクリーチャーのインベントリやバッグ)、ItemStack(バックパックなど)に適用できます。これはかつてのIInventoryISidedInventoryを自動的なシステムに置き換えます。

既存のCapabilityを利用する

先に軽く触れたように、TileEntity,Entity,ItemStackは、ICapabilityProviderインターフェイスを実装してCapabilityの機能を提供しています。このインターフェイスhasCapabilitygetCapabilityの二つのメソッドを追加し、そのオブジェクトでCapabilityが使用できるかを照会できるようにします。
Capabilityを取得するには、そのインスタンスの参照が必要になります。ItemHandlerの場合、そのCapabilityは基本的にCapabilityItemHandler.ITEM_HANDLER_CAPABILITYに保存されていますが、@CapabilityInjectアノテーションを利用することで、他のインスタンスでも参照することができるようになります。

@CapabilityInject(IItemHandler.class)
static Capability<IItemHandler> ITEM_HANDLER_CAPABILITY = null;

このアノテーションはフィールドとメソッドに適用できます。フィールドに適用したときは、Capabilityが登録された際に、(アノテーションを適用されているすべてのフィールドに同一の)インスタンスが割り当てられます。もしもCapabilityが登録されていない場合はnullが割り当てられます。ローカルなstaticフィールドへのアクセスは高速ですので、Capabilityを使用するオブジェクトには上記のソースのようにローカルなコピーを保持しておくことをお勧めします。このアノテーションメソッドに適用された場合は、Capabilityが登録された際の通知を特定の条件下でのみ有効にするために使用することができます。

hasCapabilitygetCapabilityのどちらも、2つ目のパラメータにEnumFacingをとります。これによって特定の方向を向いたインスタンスだけを照会できます。もしもnullが渡された場合は、ブロックの中であるとか、異世界のように方向が意味をなさないどこかが指定されていると仮定されます。この場合は、リクエストは方向を気にしない一般的なCapabilityのインスタンスに入れ替えられます。getCapabilityは、メソッドに渡されたCapabilityに宣言されている型を返します。ItemHandler Capabilityが返す型はやはりIItemHandlerです。

Capabilityの公開

Capabilityを公開するためには、Capabilityの基礎となる型のインスタンスが必要になります。Capabilityのインスタンスはおそらくほかのオブジェクトの内部に結び付けられるので、各オブジェクトに別々のCapabilityのインスタンスを割り当てる必要があることに注意してください。
こうしたインスタンスを取得するには、二つの方法があります。Capability自身を通じて取得するか、それを実装するオブジェクトを明示的にインスタンス化するかです。最初の方法は、デフォルトの実装を使用するように設計されています。これは、デフォルトの値が有用であれば便利です。ItemHandlerのCapabilityの場合、デフォルトの実装は一つのスロットを持つインベントリを公開します。これはおそらくあなたの希望するものではないでしょう。
二つ目の方法は、独自の実装を提供することです。IItemHandlerの場合、デフォルトの実装はItemStackHandlerクラスを使用し、このコンストラクタはオプションの引数にスロットの数をとります。しかしながら、Capabilityのシステムの目的の一つがロード時のエラーを防止ことにありますから、こうしたデフォルトの実装に依存することなく、インスタンス化はCapabilityが登録されているかのチェックを行った後に保護されるべきです。(前節の@CapabilityInjectアノテーションについて参照してください。)
Capabilityインターフェイスインスタンスを取得したら、ユーザーにCapabilityを公開するためにシステムの通知を送ることになります。これにはhasCapabilityメソッドをオーバーライドして、インスタンスがあなたの公開したCapabilityと一致するか比較します。もしもあなたの実装したクラスが方向によって別々なスロットを持つようなものであるなら、facingパラメータを利用することができます。EntityとItemStackではこのパラメータは無視されますが、プレイヤーの防具スロット(top=>頭スロット?)や、インベントリのブロック(西=>左のスロット?)などのようにコンテキストから方向を再現することは可能です。
忘れてはならないのは、親クラスのhasCapabilityへのフォールバックです。さもないと、Capabilityは機能を停止してしまいます。

@Override
public boolean hasCapability(Capability<?> capability, EnumFacing facing) {
  if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
    return true;
  }
  return super.hasCapability(capability, facing);
}

同様に、リクエストによってCapabilityのインスタンスへの参照を渡す時も、親クラスへのフォールバックを忘れてはいけません。

@Override
public <T> T getCapability(Capability<T> capability, EnumFacing facing) {
  if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
    return (T) inventory;
  }
  return super.getCapability(capability, facing);
}

Capabilityが毎tickごとに多くのオブジェクトを捜査し、ゲームの遅延を起こすことを可能な限り避けるために、Mapなどのデータ構造に依存せず、直接Capabilityをチェックすることが強く提示されています。

Capabilityの付加

軽く触れたように、Entity,ItemstackはAttachCapabilityEventを通じてCapabilityが付与されています。このイベントは粒度の異なる3つのイベントからなります。

  • AttachCapabilityEvent.Entity:Entityでのみ発火する
  • AttachCapabilityEvent.TileEntity:TileEntityでのみ発火する
  • AttachCapabilityEvent.Item:ItemStackでのみ発火する

いずれの場合でも、対象のオブジェクトにCapabilityを付与するためのaddCapabilityメソッドを持っています。これらをリストに加える代わりに、サーバかクライアントかの必要なサイドでのみCapabilityを返すCapability プロバイダを加えることが可能です。プロバイダはICapabilityProviderのみを実装する必要がありますが、もしも持続的にデータを保存しておきたいのであれば、ICapabilitySerializable<T extends NBTBase>を上乗せすれば、NBTの保存、読み込みの機能を提供することができます。

IcapabilityProviderの実装方法についての情報はCapabilityの公開を参照してください。

独自Capabilityの制作

一般的には、Capabilityの宣言と登録はCapabilityManager.INSTANCE.Register()の呼び出しを通じて行われます。Cpabilityクラスに専用のstaticメソッドregister()を作る方法も考えられますが、これではCapabilityシステムに組み込むことができません。匿名クラスを作成するというのも選択肢ではありますが、このドキュメントの目的でもありますのでクラスを記述しましょう。

CapabilityManager.INSTANCE.register(capability interface class, storage, default implementation factory);
このメソッドの最初の引数はCapabilityの型となります。ここではIExampleCapability.classとしましょう。

二つ目の引数はCapability.IStorage<T>を実装したクラスのインスタンスとなります。ここでのTは第一引数で指定したものと同じになります。このストレージクラスはデフォルト実装の読み書きを補助し、他の実装をサポートすることも可能です。

private static class Storage
    implements Capability.IStorage<IExampleCapability> {

  @Override
  public NBTBase writeNBT(Capability<IExampleCapability> capability, IExampleCapability instance, EnumFacing side) {
    // return an NBT tag
  }

  @Override
  public void readNBT(Capability<IExampleCapability> capability, IExampleCapability instance, EnumFacing side, NBTBase nbt) {
    // load from the NBT tag
  }
}

そして最後の引数はデフォルト実装の新しいインスタンスを返すファクトリとなります。

private static class Factory implements Callable<IExampleCapability> {

  @Override
  public IExampleCapability call() throws Exception {
    return new Implementation();
  }
}

最後に、このファクトリがインスタンス化できるようにデフォルト動作の実装が必要です。このクラスの設計はあなた次第ですが、少なくとも、このクラスを使用する人々が自身ですべての実装を行わなくても、機能のテストを行うことができるような骨格を提供する必要があります。

クライアントとのデータ同期

デフォルトでは、Capabilityのデータはクライアントへは送信されません。これを変更するにはmodがパケット通信で同期を管理する必要があります。

あなたが同期を行いたくなるようなシチュエーションは、下記の3つでしょう。

  1. エンティティがワールドにスポーンした、あるいは、ブロックが設置された。これらの初期化情報をクライアントに共有させたくなる。
  2. 保存されているデータが変更された。あなたはそれを監視しているクライアントに通知を送りたくなる。
  3. 新しいクライアントがエンティティやブロックを表示し始めた。あなたは存在しているデータを通知したくなる。
パケット通信の詳細な情報についてはNetworking後日訳しますを参照してください。

プレイヤーの死をまたぐ永続性

デフォルトでは、Capabilityのデータはプレイヤーの死後に永続しません。これを変更するためには、プレイヤーが死亡してリスポーンする際に手動でデータをコピーする必要があります。

これについては、PlayerEvent.Cloneイベントをハンドリングして、オリジナルのエンティティからデータを読み取り、新しいエンティティに割り当てを行うことで実現できます。このイベントの中で、wasDeadフィールドはエンド世界から帰還するとき実のところエンドに限らずディメンションの移動時は全部と死んでリスポーンするときを区別するために使用できます。エンドから帰還するときにはすでにデータが存在しているので、それを重複させてしまわないようにするために、これは重要なことです。

記事全体的に、使用法についてともうちょっと具体的な例がないとピンとこないですね…

4/12追記:元記事にForge1.9向けの記事追加されていました(IEEPがDuprecatedになったため)

IExtendedEntityPropertiesからの移行

CapabilityはIExtendedEntityProperties(IEEP)が行っていた以上のすべてを行うことができますが、二つの概念のすべてが1:1でマッチするわけではありません。

IEEPの機能:同等なCapabilityの機能早見

  • Property name/id(String):Capability key(ResourceLocation)
  • Registration(EntityConstracting):Attaching(AttachCapalityEvent.Entity)、実際のCapabilityの登録はPre-initの間に発生する
  • NBTの読み書きメソッド:自動的には発生しない。ICapabilitySerializableをイベントに接続して、serializeNBT/deserializeNBTを呼び出す。

(IEEPを内部的にのみ使用していたのなら)おそらく必要のない機能

  • Capabilityシステムは第三者の利用者が容易に使用できるデフォルト実装を提供しますが、これがIPEEを置き換えるために内部的に使用されるCapabilityの場合、あまり意味を持ちません。もしもCapabilityを内部的にのみ使用するのであれば、あなたはファクトリから安全にnullを返すこともできます。
    逆説的にはCapabilityを第三者も使用するAPIとして公開する場合にはファクトリがnullを返すのは望ましくない、ということ
  • Capabilityシステムはデフォルト実装のデータの読み書きを可能にするISorageを提供します。もしもデフォルト実装を提供しないことを選択したのであれば、IStorageは呼び出されることがないので、空白のまま残すこともできます。


以下のステップは、あなたがここまでの文章を読んで、Capabilityのコンセプトを理解していると仮定しています。

変換手順:
1.IEEPのkey/idの文字列をResourceLoacationに置き換える。(これはあなたのMODIDであり、ドメインです)
2.あなたのハンドラクラス(Capabilityインターフェイスの実装ではなく)にCapabilityのインスタンスを保持するフィールドを作成する。
3.EntityConstructingイベントをAttachCapabilityEventに変更する。IEEPに問い合わせを行う代わりに、ICapabilityProvider(おそらくNBTからの読み書きをできるICapabilitySerializableを持ったもの)に接続する。
4.(IEEPのイベントハンドラで使用していたはずですが)もしも作っていないのなら登録用メソッドを作成してCapabilityの登録メソッドを呼び出します。