アットウィキロゴ
bbc_mc @ moddingメモ
掲示板 掲示板 ページ検索 ページ検索 メニュー メニュー

bbc_mc @ moddingメモ

SMP coding guideline

最終更新:

bbc_mc

- view
管理者のみ編集可

SMP Coding Guideline 勝手な和訳

以下ページの勝手な和訳です。
http://www.minecraftforge.net/wiki/SMP_Coding_Guidelines

2013/09/09 訳終了

目次


編集

はじめに In general

Minecraft のサーバ (もしくは、その他の一般的なゲームサーバ) がどのように動いているか、考えてみて下さい。
基本的にクライアントとサーバでは同じゲームが動いていますが、サーバはあなたが何をすることが出来て何をすることが出来ないかの判定を受け持っているため、クライアント側で何が起きているかの更新を受け取り続ける必要があります。 Minecraft のサーバは非常に柔軟であり、(特にplayerの動きについては) 鷹揚に受け入れてしまいます。そのため、「一段の段差を登れるようにする」ような簡単な動作を行う mod であれば、サーバ側に変更を加えることなく動作させることが出来ます。 しかし、これには限度があります。default では、明白に飛んでいるような動作や異常な移動速度は kick されます。 Minecraft の同期の仕組みは "おおざっぱ" であり、Block や Entity の位置情報は数秒に一回程度しかクライアントへ送信されません。そのため、クライアントの動作はサーバ側と極力同じように動作する必要があるのです。

Consider how Minecraft servers (or any game servers) work.
Basically, both your client and the server are running the same game, but the server has authority over what you can or cannot do, and because of that, needs to be kept updated about what your client does.
The Minecraft server is very flexible when it comes to allowing things (especially player movement), so simple clientside mods like stepping over 1 height blocks are possible without changing anything on the server.
However, it does by default make sure you cannot fly too obviously, and does only allow you to move so fast before kicking.
Minecraft synchronizes very lazyily, Blocks and Entity Positions only get sent every couple seconds to a client, so your clientside needs to do pretty much the same as your serverside.

「…で、SMP 用のコードはどう書けばいいの?」って?
では何が必要か見ていきましょう。

So how do I code now for SMP? Let's clarify what needs to be networked:

編集

ブロックの配置/破壊 Blocks setting/breaking

特に通常の Modding と変わりません。
あなたは Block を変更する Mod を作る場合、クライアントとサーバのどちらにあるかを区別する必要はありません。 クライアント側のワールドを構成するブロックは数秒ごとに更新されますし、クライアント側での World.setBlock はサーバ側へ影響を及ぼしません。

No.
You do not have to change anything to have a Block-changing mod work on server, you do not have to think about distinguishing client/server, the clientside "Block ID at World XYZ" is synchronized every couple seconds, and a clientside World.setBlock wont do anything on a server.
( It will only make your client already presume the new Block, which means you will have no glitch until the server sends you the new data )

Tile Entities

変更点があります。
すべての Inventory や Container はクライアント側とサーバ側の双方で保存されますが、もし差異が生じた場合、サーバ側のデータによってクライアント側のデータが上書きされます。 Forge の IGuiHandler クラスや、MinecraftForge.registerGuiHandler 関数のコードを参照すれば、利用方法のアイデアが浮かぶと思います。
Strong Hint:
EntityPlayer.openGui をクライアント/サーバのどちらでも利用するのがお勧めです。

Yes.
Any Inventory/Container is stored both client and serverside, but if they differ, the server will always override (and overwrite) your client's inventory.
Read the Forge IGuiHandler and MinecraftForge.registerGuiHandler source to get an idea of how to accomplish networking here.
Strong Hint: Use EntityPlayer.openGui both client and server, in which case you don't even need to have differing client/server sources.
Check out existing Forge Mods on how to pull it off.

編集

Items

特に変更点はありません。
アイテムを使用する関数はクライアント/サーバの双方で呼び出されますが、SMP で機能するようにするためにあなたが変更を加えなければならない部分はありません。
Note: ただし! Entity を発生されるアイテムについては注意が必要です。"Entity" の項目を参照してください。
Note2: 地面に落ちているアイテムは含みません。落ちているアイテムは EntityItem のインスタンスですが、これについて何かしなくてはならない事はありません。

No.
The item usage methods are called both on client and server, which generally means you don't have to change anything to keep your Item working in SMP.
NOTE: This does not include an Item that spawns Entities of any kind! See "Entities".
NOTE #2: This does not include dropped Items.
Dropped anything is an instance of EntityItem, which generally does not need any actions on your part.

編集

Entity (EntityItem 以外) Entities (that aren't EntityItem)

対応が必要です。
少なくとも、クライアントが Entity の発生を伝える Packet を受け取れるように Forge に EntityTracker を登録する必要があります。 あなたの Mod が Entity を発生させる時は、実施するワールドがリモートであることを確認してください。( worldObj.isRemote == false) もし間違えると、見た目だけのにせものの Entity が発生します。

Yes.
At the very least, you need to tell Forge to register an EntityTracker for clients to receive spawn packets about your Entities.
Whenever your mod spawns an Entity, make sure the World is not a remote World (so worldObj.isRemote must be false), or you will have a dummy dupe Entity.

あなたは通常必要です network field の値をサーバからクライアントへ
バニラの DataWatchers のコードを読んでみてください。狼のテイムに関するコードは、教材として非常に良いものです。 できる限り、DataWatchers を使用するようにしてください。 あなたの DataWatcher 用に値を選択する場合、Overclasses DataWatcher value のために空きを残すようにしたほうが良いです。 それらが、いつ・より多くの数字を占有しようとするかわからないからです。


Hint: クライアント側で dataWatchers を変更しないようにしてください。もし変更した場合、サーバ側からの更新との仁義なき戦いが待っています。

You will usually need to network field values from server to client (prominent vanilla example being taming).
Read the vanilla code on DataWatchers, the Wolf taming code is an excellent learning example.
Use DataWatchers whenever possible.
When selecting a value for your DataWatcher better leave space to the Overclasses DataWatcher values - you never know if and when they decide to occupy more numbers.
Hint: Make sure the client cannot *write* to dataWatchers or there will be a merciless update battle.

あなたがしようとしていることによっては、dataWatchers では達成できないかもしれません。
特に迅速な反応が必要な場合には、Forge Packets のコードを読んで、利用してみてください。

For stuff you absolutely cannot do through dataWatchers, perhaps because response time is critical, read up on Forge Packets and how to use them.

もしあなたが Forge ISpawnHandler Interface を実装した場合、新たに発生した Entity には追加の ByteStream が用意されるため、好きなものをやり取りすることができます。

If you implement the Forge ISpawnHandler Interface, it will automatically pass an additional ByteStream to newly spawned Entities of yours, and you can put anything you desire and need into that stream.


注意:あなたのクライアントは、基本的にはサーバと同じコードで Entity を処理しています。しかし、そのためにはサーバと同じ情報が必要です。あなたの Entity が World に変化を生じさせる場合は、クライアント側がそれを知る方法を準備する必要があります。

Remember:
 Your client simulates any given Entity with basically the same code the server is running.
 But it needs to have the same data! So if your World changes something in your Entity, make sure the client gets notified about it!

編集

Graphics/Models/Rendering/Sound

音声・描画に関する事柄は、完全にすべてクライアント側にあります。

もしブロックや Entity が音を生じるようにした場合、クライアント側のクラスはクライアント側とサーバ側の両方の world でそれが起こるようにしなくてはなりません。 もしどのような音が生じるかを決めるために何かのデータが必要な場合は、Forge Packets を読んで、サーバからクライアントへデータパケットを送るようにする必要があります。

テクスチャについても同様です。 もしクライアントのデフォルト設定から何か変更があった場合、クライアント側へどうにかして伝える必要があります。 もしなにもなければ、特になにもする必要はありません。

Anything audiovisual is completely clientside.
If your Blocks or Entities create sounds, make sure the clientside classes will create those in both client and server worlds.
If you need any data to decide what sounds need to be played - read up on Forge Packets and send Packets with that data from sever to client.
Same for textures.
If they change from the client default at any moment in time, you need to notify clients about it somehow.
If not, you need not do anything.

「何も教えてくれてないじゃないか!」
その通り!
手取り足取りでは、modding が出来るようにならない、と私は考えています。
バニラのコードを読んでください。
他の人々が作成した SMP版 mod のコードを読んでください。


そして、観察し、学んでください。

基本的なコンセプトを理解しさえすれば、それは難しい事ではありません。 詳細について知りたければ、IRC で質問をするという方法もあるのですから。

「You still havent told me anything!!」
Correct! I do not believe holding someone's hand will make any decent modder out of him.
Read the vanilla source, read other people's SMP mods source, OBSERVE AND LEARN.
It's not particularly hard once you get the concepts.
And you can always ask in the IRC channels for specifics.

一般的なポイントをあといくつか挙げておきます。

Some more pointers for coding in general
  • すべきこと Do
    • あなたのコードにコメントを書きましょう。また、名前をつける時は意味のある名前にしましょう
      • あなた自身や誰かが数ヵ月後にそのコードを見たときに、関数のことを「何かしているヤツ」と呼ぶ羽目になります。
    • Notch のクラスから継承しているあなたのクラスの全ての関数には、@Override アノテーションをつけましょう
      • MCP が関数名のマッピングを変更した場合、すぐに知ることが出来ます。
    • World に変化を及ぼす「すべての」関数は、現在の World (そして必要なら player)を引数として渡すようにしましょう
      • サーバ側から見ると、多くの world と多くの player が居るのです。
    • Minecraft のコードやクラスを出来るだけ利用しましょう
      • 利用したほうが作業が減りますし、Minecraft との親和性も増します。
    • World.isRemote を利用して、modが動作している world がクライアントかサーバかを判別しましょう。そして、明確なコードを書きましょう
      • コード上のその場所で何をしているかを明確にすることで、厄介なバグを取り除く作業が後々楽になります。
    • MinecraftForge のクラスをいろいろと見てみてください
      • 特に、ModLoader.getMinecraftServerInstance.configManager が何をしているかを見てみてください。
comment your code, and give everything meaningful names.
  If you or someone else looks at it months later, you will curse the guy who called this method "doStuff"
put @Override annotations on every method your custom classes inherit from Notch classes.
  If MCP changes mappings, you will know immediatly.
make sure *any* World interaction methods always pass the current World as argument, and the player if one is concerned.
  A server has multiple Worlds and many players.
use MC code and -classes wherever possible.
  It saves work and makes your mod comply better with Minecraft.
use World.isRemote to decide if a world is client or serverside, and act accordingly write clean, legible code.
  It makes the pesky bug hunting later a lot easier if you can actually comprehend what you did there.
check out the MinecraftForge class on what it has to offer you
  also check out ModLoader.getMinecraftServerInstance.configManager on what it offers (in particular, sending Packets to players) 
  • すべきではないこと Don't
    • 絶対確実にクライアント側であることが保証できないが、ModLoader.getMinecraftInstance.theWorld や ModLoader.getMinecraftInstance.thePlayer を使用する
      • これらの関数は、サーバ側では決して動作しません。
    • 2 行の変更のために、minecraft のクラスをまるごとコピーする
      • extends や @Override を利用して、変更したい部分だけを変更しましょう。
    • World.isRemote が true の時(サーバ側ではない)に、World.spawnEntity を使う
      • やめましょう。
    • 特に方針や方向性は決まってないが、とりあえずコードを書いてみる
      • 後になってコードを修正しようとしたときに、少なくとも 3 倍以上の労力が必要となるでしょう
use ModLoader.getMinecraftInstance.theWorld and ModLoader.getMinecraftInstance.thePlayer in anything that isn't strictly client.
  This will NEVER work on a server.
copy entire minecraft classes only to change 2 lines.
  Use "extends" and "@Override" on what you need changed!
use World.spawnEntity when World.isRemote is true.
  Never.
code without a plan.
  If you have to unscrew your code later, you will do the triple amount of work at least.

編集


記事メニュー
最近更新されたスレッド
ウィキ募集バナー