OrangeNBT更新等06/10

更新しました。

fix
ListChunkCoordがマジメになった
IChunkManagerのContainsが追加されました。やりました!

add
Dataの方にIGameDataProviderとかいうわけわからないやつが追加された

次ぐらいで.nbt/structure対応できるかと思います。
以上

OrangeNBT20160610

OrangeNBT.Bedrockっていう名前でいこうと思ってるんだけど、ほかに良い案あったら教えてください。
OrangeNBT.PEやOrangeNBT.BEなんかもありかなと思ってますけど。

(メモ)VisualStudioでコンパイルできるmojangのleveldbの奴のリンク
https://github.com/jocopa3/leveldb-mcpe

.NETのLevelDBのライブラリについて考える

OrangeNBTの実装に向けての検証とテスト等

LevelDBはgoogleが開発したSQLiteみたいなデータベースです。MinecraftのBedrock版でワールドの保存に使われてます。C#で実装しなおすのは極めて車輪の再発明です。ライブラリがどれがいいのか考えるだけの記事です。

LevelDBはCでの実装が公式に公開されてます。https://github.com/google/leveldb
.NETでは動きません。DLLImport等使えば動くと思いますけど……。

理想のライブラリの条件を上げましょう
・追加のDLLいらない。NativeDLLもできればいらない。
・ソースコードのまま導入できる。いわばオープンソース
・.NET Standardで動いてほしい。動かなくても改造可なら改造する。
・ライセンスにソースコードの開示を求める条項がないこと。このライブラリの利用者もおそらく継承されるため
・別に高機能は求めてない。低レベルでもいい。うごけばそれでいい。

ざっとググってみた限り以下のライブラリを見つけたので検証していきます。
LevelDB.NET
https://github.com/neo-project/leveldb
ライセンス:BSD-3。(可)
githubを見る限りcppファイル等しかない。下記のReactiveExtensionのことでしょうか?

LevelDB sharp
https://github.com/meebey/leveldb-sharp
ライセンス:BSD-3。(可)
ネイティブDLLの使用:あり(unix等で動かないっぽい?)

ReactiveExtension LevelDB
https://github.com/Reactive-Extensions/LevelDB
ライセンス:Apache License, Version 2.0(可)
ネイティブDLLの使用:あり(厳しい)

IronLevelDB
https://github.com/tg123/IronLeveldb
ライセンス:MIT(可)
ネイティブDLLの使用:なし
しかし、githubのREADMEをよく読むと、「This project is still under hard working」このプロジェクトはまだ作業中みたいなこと書いてあるし、読み込み関数しかまだ書いてないぜ見たいこと書いてある……。むむむこれに期待したいけど……厳しい。

Nugetの上位のそれっぽいやつもリンク切れてたり。ライセンスがよくわからなかったり……

そもそもMOJANGのLevelDBは若干改造されたやつである。圧縮方法がどうも違うらしい。
https://github.com/Mojang/leveldb-mcpe

うううむ……どうしようか。
.NET Standardにするとやはり、ネイティブDLLはない方がいいわけで。(うざい・使いにくい・各自コンパイル面倒くさい64bit/32bitでも変わる)

やはり……車輪の再発明しちゃう?

OrangeNBT 修正等06/03

もはやデイリーアップデート状態。

-修正
AnvilChunkManagerの破棄がたまに失敗する問題
ディメンションの新規作成時にフォルダが完全に空だと失敗する問題
ChunkCoordのコンストラクタの引数がxyだった問題

-追加
ChunkCoordがToStringできる
IChunkManagerに ListAllCoordsという謎の関数を追加した。
AnvilWorldにAddDimensionというよくわからない関数を追加した。(仮)

OrangeNBT20180603

以上!

OrangeNBT 修正等06/02

Cuboid/BlockPosにてOverFlowする問題を解決。

null非許容型がほしい。ください。

SNLはまだ直してません。

OrangeNBTはオープンソースで自分でビルドもできるので、バグを見つけたらぜひ、解決策も示していただけるとめっちゃはかどる。(自分でやれ)

https://github.com/noto0648/OrangeNBT

OrangeNBT20180602

TODO:
BE対応
Chunk破損でリスト失敗→チャンクコードのみを吐く関数を提供
ChunkCoordのコンストラクタの引数がx,y
ChunkCoordのToString書く。

OrangeNBT 修正等 06/01

OrangeNBT

schematic追加しました。
World.Loadが使えないバグを修正しました。
Json関連も修正しました。

一部ネームスペースが変更となっています。Worldに含まれてたもので共通化したいものをDataの方へ移動させました。

ダウンロード:
OrangeNBT20180601

git:
https://github.com/noto0648/OrangeNBT

Readmeかかねば。

XamarinでVisualStudioがエラー出た

標記通り。

Xamarinでアプリ作ってるんですが、ソリューションエクスプローラーのところから、新規追加でコンテンツページの追加を押すと、ちょっと固まってから、System.Exceptionが発生しましたって出た。なんだこれ。

xamlとxaml.csファイルどっちもできているようですが、xamlのリンクができてないので、InitializeComponentが赤線になってた。あるあるですね。

現状、projitemsを編集して xamlとリンクさせてるんですがとても面倒くさいですね。

プロジェクトのリビルドすればまあ治ると思うのですが……。

ところで、最近ついにSSDに変えたんですが、音がしなさ過ぎてちょっと不安になります。すごく早いですけど。僕はまだHDDでいいや。データ消えるのもちょっと怖い

OrangeNBT使い方1

Schematic/Structureの実装に悩んでます。どうも。

SNLでNBTTagなんたらはOrangeNBT.NBTにあります。

・初期化など

var tag = new TagCompound()
{
new TagInt("DataVersion", 1),
new TagCompound("Level")
{
new TagInt("xPos", _coord.X),
new TagInt("zPos", _coord.Z),
new TagLong("LastUpdate", DateTime.Now.Ticks),
new TagByte("V", 1),
new TagByte("TerrainPopulated", (byte)(_isTerrainPopulated? 1 : 0)),
new TagByte("LightPopulated", (byte)(_isLightPopulated? 1 : 0)),
new TagIntArray("HeightMap", _heights),
new TagByteArray("Biomes", _biomes)
}
};

TagCompoundのクラスにはAdd(val)関数は実装されていません。
using OrangeNBT.Helper;
ってやるといろいろ追加されます。拡張メソッドで定義されています


using OrangeNBT.Helper;
c._heights = level.GetIntArray("HeightMap");
c._isTerrainPopulated = level.GetBool("TerrainPopulated");
c._isLightPopulated = level.GetBool("LightPopulated");

ところで、アルファ版というかDev版は破壊的変更し放題ですね。最高。ネームスペースが突然変わったり引数が増えたり減ったりします。

LongArrayもあるので使ってね!(いつから追加されたのだろう)(使い用途不明)(コマンド用?)

https://github.com/noto0648/OrangeNBT

Githubに上がってます。気になったところは教えてください。
ちなみにいつになってもgit苦手です。つらい。
またひと段落したらPushします

バイナリは前記事よりDLしてください。

bedrock版では、どうも1.4になってしまったようですね。よさそう。建築したいです。

OrangeNBT

OrangeNBTはなぜ生み出されたのか。
OrangeNBTの発表自体今からだいたい2年前くらいに発表しました。
しかし、1年ぐらい放置してました。

SNLの代わりになるものを目指してるわけではありません。
汎用のNBTライブラリを目指して作られています。

OrangeNBTの改善点!
SNLはそもそもぼくのNBTエディタの内部コードをもとに作られたライブラリです。したがって数年前の産物でありコードが汚い。読めない。それをつぎはぎして改善してきたためとてつもなくわけのわからないコードを生み出してしまった。
おまけに僕はソースコードにコメントを書かない主義なので読むのに時間がかかる。(コメントなくても読みやすいコードを目指していた)
しかし、保守するのには限界がきた。僕にもわけのわからないバグもたくさん生み出されてきた。
そこで読みやすい保守しやすいコードを生み出すためにOrangeNBTという1から書き直しを行うことにした。

OrangeNBTのよいところ

  • .net Standard 2.0で書かれてる
  • 読みやすい
  • オープンソース(予定)
  • Bedrock Editionのデータ対応予定
  • ネームスペースわけがきれい

まだダメなところ

  • デバッグが完全ではないため動かないコード多数
  • まだ未実装のコード多数
  • まだSNLより機能が少ない
  • ワールドライティング未対応
  • Schematic/.nbtファイル未対応
  • TagCompoundのヘルパー機能がほぼない

課題

  • 現状dllが分かれているため統合するか検討中
  • ブロックデータアイテムデータ等の導入。ゲームのアップデートに追いつくのが大変

    OrangeNBTは一応最低限のNBTライブラリを目標にしているためSNLで実装されていた多くの機能は削る可能性があります。

    一人ではデバッグするのめんどい大変なため一応バイナリを公開します。
    ゆっくりまったりと開発を行います。

    OrangeNBT

    バイナリはデバッグコンパイルです。

Minecraftの地形生成を考える【2】

Minecraftの地形生成を考える【2】

前回、一応基本となる地形生成のパーリンノイズについて一応書きましたので、今回はBeta1.8以降のバイオームわけについて。

バイオーム拡大法
バイオームを拡大していく方法です。
ゆえにMinecraftの地形生成は時間がかかります。

簡単な仕組みは
16×16(チャンク)を生成するために、もっと小さいブロックの四角形(例:4×4)を拡大・補完することで無限の生成を可能にしています。
無限といってもint値やlong値には最大が有るわけですから、その最大のなかのちょっとを何回も拡大することで擬似的に無限世界を生成することができるのです。
一番最初は固定シード値によってランダムに点をばらまくだけです。

拡大・補完の仕方
2×2ならば3×3に拡大します。(n x n => (2n – 1) x (2n – 1))

A B
C D

一番最初の拡大のときは下記のように拡大して補完します

A A or B B
A or C A, B, C or D B or D
C C or D D

この処理の際、シード値を常に座標から計算するなどして一定にしておかないと次のチャンクとの補完結果がずれる場合があります。また隣のチャンクとの差異吸収のために16×16は補完後18×18になるようにしてそこから16×16を取り出すことで次の拡大に影響が出ないようにします。

それ以降の拡大時には大陸や海をちゃんとつなげていくために上下または左右の最頻値をとって補完していきます。
ただし全て異なる場合などは上記同様ランダムに決定していきます
例:

A B
A A

これを、

A A B
A A B
A A A

これをもう一回拡大すると

A A A B B
A A A A B
A A A B B
A A A A A
A A A A A

この拡大処理を十分に繰り返し、あるていどの大きさになったところで終了します。
このようにバイオームのあの複雑なバイオームの境界線を生み出すことができるのです。

Minecraftの地形生成を考える【1】

Minecraftの地形生成を考える【1】
最初はずっと2D世界の話をしていきます。
Minecraftでいうと上からみた世界みたいな感じです。

Minecraftはどこまで行ってもワールドが続きます。
つまり……無限の生成を考えるということである。

有限の生成は実は結構簡単であったりする。
例えば64×64みたいな奴
実装方法としては64×64の世界に、海と陸のブロックをばら撒きランダムで結合したりばらしていったりする。
まあここでは省略しますが。
ランダムが重要になってきます。

しかし無限となると初回で全部ワールドを生成してしまうわけには行きません。
何らかの手段でなめらかに地形を繋げる必要があります。

コレを見てください。Googleでy=2xのグラフです。

この画像の範囲外を想像することはできますか?きっと容易だと思います。
なぜなら数式が与えられている=関数が与えられているからです。
ずっと同じ角度で直線が続いていきます。

もう一つ、プログラム上での乱数は擬似乱数。つまり関数です。
つまり、この疑似乱数を使っている時点で次にくる値が明らかだということ。

javaデフォルトのランダムで同じシード値を与えて初期化すれば、実行するたびに同じ値が出力されるはずです。

Minecraft Beta1.7、使われてるのがパーリンノイズ。同じシード値を与えれば常に同じ値が出ます。

パーリンノイズの周期を調整して2~4つ重ねることでそれっぽい地形を無限で生成することができます。

バイオームを分けるのは難しいです。
簡単にできる方法としてはボロノイノイズを使うのが良いですが、直線的になってしまいます。

しかし、Beta1.8以降はかなり複雑です。海沿いにビーチバイオームなどがあり、生成の基準がバイオームになっています。
これは今度解説することにします。