ゲームデータ用の「バイナリXML」?


17

私は、データをXMLとして保存するレベル編集ツールに取り組んでいます。

これは、データ形式を少し変更するだけで簡単であり、ツリーのようなデータでもうまく機能するため、開発中に理想的です。

ただし、欠点は、主にタグ名と属性名が重複しているため、XMLファイルがかなり肥大化することです。また、数値データがネイティブデータ型を使用するよりもかなり多くのスペースを使用するためです。小さいレベルでは、1Mb +になります。特に、メモリが比較的限られているiPhoneやその他のデバイスでゲームにシステムを使用する場合は、これらのサイズを大幅に小さくしたいと思います。

メモリとパフォーマンスの最適なソリューションは、XMLをバイナリレベルの形式に変換することです。しかし、私はこれをしたくありません。フォーマットをかなり柔軟に保ちたい。XMLを使用すると、オブジェクトに新しい属性を簡単に追加でき、古いバージョンのデータが読み込まれた場合はデフォルト値をオブジェクトに設定できます。そのため、属性を名前と値のペアとして、ノードの階層を維持したいと思います。

しかし、これをよりコンパクトな形式で保存する必要があります-タグ/属性名の大量の重複を削除するためです。ネイティブタイプの属性を指定することもあります。たとえば、浮動小数点データは、テキスト文字列としてではなく、フロートあたり4バイトとして格納されます。

Google / Wikipediaは、「バイナリXML」はほとんど新しい問題ではないことを明らかにしています-すでに何度も解決されています。ここに誰かが既存のシステム/標準のいずれかで経験を持っていますか?-ゲームの使用に理想的なものはありますか?-無料の軽量でクロスプラットフォームのパーサー/ローダーライブラリ(C / C ++)が利用可能ですか?

それとも、自分でこのホイールを再発明すべきですか?

または、理想を忘れて、生の.xmlデータを圧縮するだけで(zipのような圧縮でうまく圧縮する必要があります)、ロード時にメモリ/パフォーマンスヒットを取得する方が良いでしょうか?


1
XMLはgzipなどを使用して非常にうまく圧縮できます。
シーフマスター

回答:


18

Superman Returns:The VideogameにバイナリXMLを多用しました。私たちは何千ものファイルを話しています。うまくいきましたが、正直なところ、努力する価値はありませんでした。ロード時間のかなりの部分を使い果たし、XMLの「柔軟性」は拡大しませんでした。しばらくして、データファイルには奇妙な識別子、同期を維持する必要がある外部参照、および実際に人間が編集できるようにするためのその他の奇妙な要件が多すぎました。

また、XMLは実際にはマークアップ形式であり、データ形式ではありません。時折タグを使用して多くのテキストに最適化されています。完全に構造化されたデータには適していません。それは私の呼び出しではありませんでしたが、もしそうであり、私が今知っていることを知っていれば、おそらくJSONまたはYAMLを実行したでしょう。どちらも圧縮を必要としないほど簡潔で、テキストではなくデータを表すために最適化されています


1
BSONと呼ばれるJSONのバイナリバージョンがあります。
フィリップ

12

レベルを通常のXMLとして保存および編集しますが、ロード中にゲームエンジンでバイナリXMLにレイジーベイク処理し、バイナリXMLをディスクに保存して次回ロードできるようにします(未加工のXMLが変更されていない場合) 。

このようなもの:

data loadXml(xmlFile)
{
    if (xmlFile has changed OR binFile doesn't exist)
    {
        binFile = convertToBinary(xmlFile)
        save(binFile)
    }
    return loadBinaryXml(binFile)
}

そうすれば、両方の長所を最大限に活用できます。リリース時には、すべてのバイナリファイルがそこにあることを確認する必要があります。


5

Google Protocol Buffersが最適な方法のように見えますが、私自身は使用していません。
http://code.google.com/p/protobuf/

ファイル形式を記述する.protoファイルを定義します。

message Person {
  required int32 id = 1;
  required string name = 2;
  optional string email = 3;
}

これは、C / C ++クラスを生成するコマンドラインツールでコンパイルされ、以前に定義されたデータ形式でバイナリデータファイルを記述および解析します。さまざまなプログラミング言語用の拡張機能もいくつかあります。

ProtocolBufferの欠点は、プレーンテキスト形式ではないことです。それらを生成、読み取り、編集するにはツールが必要です。ただし、ゲームエディタとゲーム間でデータを交換するためだけに使用している場合、これは問題になりません。私は設定ファイルを定義するためにそれを使用しません;)

生のxmlファイルの圧縮も機能するはずです。どんなゲームを作っていますか?レベルベースの場合、レベルのロード時に必要なすべてのリソースを一度だけロードする必要があります。

更新: ProtocolBufferで動作するC#などの他の言語のプロジェクトがいくつかあります:http :
//code.google.com/p/protobuf/wiki/ThirdPartyAddOns


シリアライザーはそのような問題に適応していませんか?そうではないと思いますが、明確な違いは見当たりません。しかし、私にはこの答えが適切だと思われます。しかし、xmlファイルをtar / gzipするとサイズが大幅に小さくなります(テキストであるため、xmlでも機能すると思います)。これが「簡単な」ソリューションかもしれません。とにかくXMLは簡単な言語ですが、構文解析/メモリの使用という点では非常に高価です。XMLを使用するときは、できるだけ少ない回数で読み取り/書き込みを行う必要があります。
-jokoon

これは興味深いオプションですが、パイプラインのどこでもXMLを使用するための完全な代替手段のように見えます。正直なところ、私は生成されたコードについてあまり熱心ではありませんが、別の複雑な点は、ツールの側面にC#を使用していることです(ツールが大きな.XMLファイルを引き続き使用できることを嬉しく思います)。XML-> PBコンバーターはオプションかもしれませんが、特定の「バイナリレベルデータ」を焼く方法ではなく、「より汎用的なバイナリXML」を探しています効率的)
-bluescrn

「ツールの側面にC#を使用しています」c#にはいくつかのプロジェクトがあります。私の答えを更新しました。
スティーブン

@bluescrn、生成されたコードについてはあまり心配しません。Googleは、C ++、Java、およびPythonに第1クラスのサポートを提供します。彼らはそれを内部的に広範囲に使用しています。生成されたコードは非常に堅牢です。PBの大きな利点の1つは、.protoファイルに対するツールプログラムであり、誤通信の問題をほぼ排除します。xmlスキーマを使用する規律(および時間)さえある場合、プロトはxmlスキーマよりも読み取り/保守がはるかに簡単です。
-deft_code

4

JSON形式はどうですか?

http://www.json.org/xml.html


XMLより若干コンパクトに見えますが、それでも属性名の重複という主な問題があります。ファイルに「XPosition」、「YPosition」、および「Scale」属性を持つゲームオブジェクトのリストが含まれている場合、ストリング「XPosition」/「YPosition」/「Scale」はすべてのゲームオブジェクトに対して複製されます。これが私が現時点で「圧縮」することを目指している主なものです
-bluescrn

1
@bluescrn:いいえ、問題はありません。オブジェクトは1つの構造です。また、配列[this、just、look、like、this]を使用することもできます。これは、車の名前とプロパティを保存するために、このようなものになることを意味します。"cars":{"ford":[8C,FA,BC,2A,384FFFFF],"holden":[00,00,04,FF,04FF54A9]}「cars」識別子を省略して、carsフィールドの場所がわかっている場合は、配列に直接進むこともできます。そのデータを保存する必要がない場合は、「ford」および「holden」の名前を省略することもできます[...,[[8C,FA,BC,2A,384FFFFF],[00,00,04,FF,04FF54A9]]]。もっとコンパクトになりますか?
-doppelgreener

1
@Axidos:マークアップを読めず、構造化されていないものにする場合は、単にバイナリにすることもできます。それとは別に、実行時に非圧縮データを解析している場合(この場合、おそらくとにかくねじ込まれている)、または解析中に何らかの理由で数百バイトの文字列メモリに制限されていない限り、それは誤った節約です電子レンジではありません)。

@Joe:bluescrnは、重複した名前を持たない読み取り可能な形式を検索しているようです。私はまさにそれを提供するJSONの能力を示していました。ある時点で、なぜこのようなマークアップに悩まされているのか不思議に思うかもしれませんが、私は完全に同意します。
-doppelgreener

4

JSONを使用します。

(Munificentの対応に基づいており、主に他の場所で表明された懸念に対応しています)

JSONには、XMLなどのスペース命名要素を浪費する問題があるという懸念に言及しました。そうではありません。

JSONは、名前/値のペア(オブジェクト)と順序付けられた値のリスト(配列)の2つの構造で構築されています。XMLは、名前と値のペアでのみ構築されます。

JSONが、自己記述的で人間が読み取れるように構築されたJSONを読んでいるオブジェクトに依存していると思う場合は、次のようにします(1バイトを表すために8進数のペアを使用):

{
    "some": ...,
    "data": ...,
    "fields": ...,
    "cars": [
        {"name":"greg","cost":8C,"speed":FA,"age":04,"driverID":384FFFFF},
        {"name":"ole rustbucket","cost":00,"speed":00,"age":2A,"driverID":04FF54A9}
    ]
}

ただし、すべてがどこにあるかを知っている限り、このように書くオプションもあります(したがって、車のリストを取得するために、オブジェクト "cars"ではなくインデックス4を探すことができます)。

{
    [
        ...,
        ..., 
        ...,
        [["greg",8C,FA,04,384FFFFF],["ole rustbucket",00,00,2A,04FF54A9]],
        ...,
    ]
}

それだけで持つよりも簡潔を取得し[],と自分の価値観?

まあ、純粋なバイナリストリームにどんどん近づいていきたいと思っているなら、そうなります。

"cars":{"names":["greg","ole rustbucket"],"stream":8CFA04384FFFFF00002A04FF54A9}
or
[["greg","ole rustbucket"],8CFA04384FFFFF00002A04FF54A9]

最適化をしすぎて自分の足を撃たないでください。


2

回答を受け入れたことは承知していますが、Googleは「高速インフォセット」(バイナリXML)とvtd-xmlの両方を提供しています。

後者(VTD)はXMLの使用に関する圧縮の側面を解決しないかもしれませんが、大きなファイルにわたるノードアクセスを大幅に高速化する可能性があります(ノードにジャンプするためにバイナリオフセット「辞書」を使用し、各ノードのオブジェクトを作成しません)、代わりに元のXML文字列で動作します)。したがって、XMLルックアップは高速であると言われており、XMLドキュメントへのアクセス/操作にインプロセスメモリをそれほど必要としません。

上記の両方には、一般的な言語(C#を含む)のバインディングがあります。

乾杯

リッチ


1

Karvoniteを試すことができます。アジャイルになるはずです。これは永続的なフレームワークであり、データの変更にかなりよく適応します(バイナリを自分で処理するのに比べて便利です)。実際にデータがどのように構造化されているかはわかりませんが、ファイルはxmlの肥大化したファイルよりもずっと小さいです。(私はそれがxmlのようなテキストの代わりにバイナリ形式でデータを保存すると仮定しています)

私がこれについて考えることができる唯一の短所は、データが破損したり、Karvoniteが気に入らない方法で何らかの混乱を起こした場合、その構造がデータが動作します。

データを保存/ロードする方法を指定する方法は、永続性エディターを開き、すべてのデータオブジェクトを含むアセンブリをインポートし、いくつかのチェックボックスをオンにして、サポートするオブジェクトと保存するフィールド/プロパティを表示することです。

試してみる価値があるかもしれません。C#を使用しているため、XNA(Windows、Xbox360、およびWindows Phone 7で動作するので、これはあなたの言語にぴったりです。iPhoneについて言及してから興味がありますか?)

編集:ツールにC#のみを使用していることに気付きました。これはおそらくあなたのワークフローにはあまり合いません。何らかの理由で、私の頭の中にXNAがありました。

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