'Binary XML' สำหรับข้อมูลเกม?


17

ฉันกำลังทำงานกับเครื่องมือแก้ไขระดับที่บันทึกข้อมูลเป็น XML

สิ่งนี้เหมาะอย่างยิ่งในระหว่างการพัฒนาเนื่องจากไม่เจ็บปวดที่จะทำการเปลี่ยนแปลงรูปแบบข้อมูลเล็กน้อยและทำงานได้ดีกับข้อมูลที่มีลักษณะคล้ายต้นไม้

ข้อเสียคือไฟล์ XML นั้นค่อนข้างป่องส่วนใหญ่เกิดจากการทำซ้ำชื่อแท็กและแอตทริบิวต์ นอกจากนี้เนื่องจากข้อมูลตัวเลขที่ใช้พื้นที่มากกว่าการใช้ประเภทข้อมูลดั้งเดิม ระดับเล็กสามารถจบได้อย่างง่ายดายด้วย 1Mb + ฉันต้องการลดขนาดเหล่านี้ลงอย่างมากโดยเฉพาะอย่างยิ่งหากจะใช้ระบบสำหรับเกมบน iPhone หรืออุปกรณ์อื่นที่มีหน่วยความจำค่อนข้าง จำกัด

ทางออกที่ดีที่สุดสำหรับหน่วยความจำและประสิทธิภาพคือการแปลง XML เป็นรูปแบบระดับไบนารี แต่ฉันไม่ต้องการทำสิ่งนี้ ฉันต้องการให้รูปแบบมีความยืดหยุ่นพอสมควร XML ทำให้ง่ายต่อการเพิ่มคุณสมบัติใหม่ให้กับวัตถุและให้เป็นค่าเริ่มต้นหากมีการโหลดข้อมูลรุ่นเก่า ดังนั้นฉันต้องการที่จะรักษาลำดับชั้นของโหนดที่มีคุณลักษณะเป็นคู่ค่าชื่อ

แต่ฉันต้องเก็บสิ่งนี้ในรูปแบบที่กะทัดรัดยิ่งขึ้น - เพื่อลบการซ้ำซ้อนของชื่อแท็ก / แอตทริบิวต์ อาจจะให้แอตทริบิวต์ประเภทดั้งเดิมดังนั้นเช่นข้อมูลจุดลอยตัวจะถูกเก็บไว้ที่ 4 ไบต์ต่อลอยไม่เป็นสตริงข้อความ

Google / Wikipedia เปิดเผยว่า 'binary XML' เป็นปัญหาใหม่แทบจะไม่ได้รับการแก้ไขมาหลายครั้งแล้ว มีใครบ้างที่เคยมีประสบการณ์กับระบบ / มาตรฐานที่มีอยู่บ้างไหม? - เหมาะสำหรับการเล่นเกมหรือไม่ - ด้วยตัวแยกวิเคราะห์ / ตัวโหลดข้ามแพลตฟอร์ม (C / C ++) ที่ให้บริการฟรีน้ำหนักเบาและข้ามแพลตฟอร์ม

หรือฉันควรบูรณาการล้อนี้ด้วยตัวเอง?

หรือฉันดีกว่าลืมอุดมคติและเพียงแค่บีบอัดข้อมูล. xml ดิบของฉัน (มันควรอัดแน่นด้วยการบีบอัดแบบ zip) และเพียงแค่ใช้หน่วยความจำ / ประสิทธิภาพการทำงานที่โหลด


1
XML สามารถบีบอัดได้โดยใช้ gzip และเป็นอย่างดี
ThiefMaster

คำตอบ:


18

เราใช้ XML ไบนารีอย่างหนักเรื่อง Superman Returns: วีดีโอ เรากำลังพูดถึงไฟล์หลายพันไฟล์ มันใช้ได้ดี แต่จริงๆแล้วดูเหมือนจะไม่คุ้มค่ากับความพยายาม มันกินส่วนที่เห็นได้ชัดเจนของเวลาโหลดของเราและ "ความยืดหยุ่น" ของ XML ไม่ได้เพิ่มขึ้น หลังจากนั้นครู่หนึ่งไฟล์ข้อมูลของเรามีตัวระบุแปลก ๆ มากเกินไปการอ้างอิงภายนอกที่จำเป็นต้องได้รับการซิงค์และความต้องการแปลก ๆ อื่น ๆ

นอกจากนี้ XML เป็นรูปแบบมาร์กอัปจริงๆและไม่ใช่รูปแบบข้อมูล มันเหมาะสำหรับข้อความจำนวนมากที่มีแท็กเป็นครั้งคราว มันไม่ดีสำหรับข้อมูลที่มีโครงสร้างอย่างสมบูรณ์ มันไม่ใช่สายของฉัน แต่ถ้ามันเป็นและฉันรู้แล้วสิ่งที่ฉันรู้ตอนนี้ฉันอาจจะทำ JSON หรือ YAML พวกเขาทั้งสองพอสั้นจะไม่จำเป็นต้องมีการบดอัดและเหมาะสำหรับเป็นตัวแทนของข้อมูลที่ไม่ข้อความ


1
มีรุ่นไบนารีของ JSON เรียกว่าเป็นBSON
Philipp

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 แบบ raw ควรใช้งานได้เช่นกัน คุณทำเกมประเภทใด หากเป็นระดับที่คุณควรโหลดทรัพยากรที่จำเป็นทั้งหมดเพียงครั้งเดียวเมื่อโหลดระดับ

อัปเดต: มีหลายโครงการสำหรับภาษาอื่นเช่น C # เพื่อทำงานกับ ProtocolBuffers:
http://code.google.com/p/protobuf/wiki/ThirdPartyAddOns


Serializer ไม่ได้ปรับให้เข้ากับปัญหาแบบนั้นหรือ ฉันเดาไม่ได้ แต่ฉันไม่เห็นความแตกต่างที่ชัดเจน แต่สำหรับฉันคำตอบนี้ดูเหมือนจะเหมาะสม แต่ด้วย tar / gzip ไฟล์ xml จะลดขนาดของมันลงอย่างมาก (เนื่องจากมันเป็นข้อความ แต่ฉันเดาว่ามันจะใช้ได้กับ xml ด้วย) ดังนั้นนั่นอาจเป็นทางออกที่ "ง่ายขึ้น" อย่างไรก็ตาม XML เป็นภาษาที่ง่าย แต่มีราคาแพงมากในการแยกวิเคราะห์ / หน่วยความจำโดยใช้: เมื่อคุณใช้ XML คุณควรอ่าน / เขียนกี่ครั้งเท่าที่จะทำได้
jokoon

มันเป็นตัวเลือกที่น่าสนใจ แต่ดูเหมือนจะเป็นทางเลือกที่สมบูรณ์ยิ่งขึ้นในการใช้ XML ได้ทุกที่ในไปป์ไลน์ พูดตามตรงฉันไม่กระตือรือร้นมากเกี่ยวกับรหัสที่สร้างแม้ว่า - และสิ่งที่ซับซ้อนอีกอย่างคือฉันใช้ C # สำหรับด้านเครื่องมือของสิ่งต่าง ๆ (ฉันยินดีที่เครื่องมือสำหรับทำงานกับไฟล์. XML ขนาดใหญ่ต่อไป ) XML-> PB converter อาจเป็นตัวเลือกถึงแม้ว่าฉันคิดว่าฉันยังคงมองหาบางสิ่งที่มีมากกว่า 'binary XML วัตถุประสงค์ทั่วไป' แทนที่จะใช้วิธีการอบเฉพาะ 'ข้อมูลระดับไบนารี' (แม้ว่าจะมากกว่านี้ก็ตาม มีประสิทธิภาพ)
bluescrn

"ฉันใช้ C # สำหรับเครื่องมือด้านสิ่งต่าง ๆ " มีหลายโครงการสำหรับ c # อัปเดตคำตอบของฉัน
สตีเฟ่น

@bluescrn ฉันจะไม่กังวลเกินไปเกี่ยวกับรหัสที่สร้างขึ้น Google ให้การสนับสนุนชั้นหนึ่งแก่ C ++, Java และ Python พวกเขาใช้มันอย่างกว้างขวางภายใน รหัสที่สร้างขึ้นค่อนข้างแข็งแกร่ง ข้อดีอย่างหนึ่งของ PB คือโปรแกรมเครื่องมือของคุณเทียบกับ.protoไฟล์ซึ่งเกือบกำจัดปัญหาการสื่อสารผิดพลาด Protos นั้นง่ายต่อการอ่าน / ดูแลรักษามากกว่าสกีมา xml หากคุณมีวินัย (และเวลา) ในการใช้สกีมา xml
deft_code

4

รูปแบบ JSON เป็นอย่างไร

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


ดูเหมือนกะทัดรัดกว่า XML เล็กน้อย แต่ก็ยังมีปัญหาหลักของชื่อแอตทริบิวต์ที่ซ้ำกัน หากไฟล์มีรายการของเกมวัตถุที่มีคุณลักษณะ 'XPosition', 'YPosition' และ 'Scale' สตริง 'XPosition' / 'YPosition' / 'Scale' จะถูกทำซ้ำสำหรับวัตถุทุกเกม นี่คือสิ่งสำคัญที่ฉันตั้งใจจะ 'บีบอัด' ในขณะนี้
bluescrn

1
@bluescrn: ไม่ไม่มีปัญหานั้น วัตถุเป็นโครงสร้างเดียว คุณยังสามารถใช้อาร์เรย์ [ซึ่งเพียงแค่มองแบบนี้] นั่นหมายความว่าคุณสามารถจบลงด้วยสิ่งนี้เพื่อจัดเก็บชื่อและคุณสมบัติของรถยนต์: "cars":{"ford":[8C,FA,BC,2A,384FFFFF],"holden":[00,00,04,FF,04FF54A9]}คุณสามารถเว้นตัวระบุ "รถยนต์" และตรงเข้าไปในอาร์เรย์ถ้าคุณรู้ว่าจะต้องใช้ที่ใด คุณสามารถละเว้นชื่อ "ฟอร์ด" และ "โฮลเดน" ได้หากคุณไม่ต้องการบันทึกข้อมูล[...,[[8C,FA,BC,2A,384FFFFF],[00,00,04,FF,04FF54A9]]]ดังกล่าว มันกะทัดรัดขึ้นหรือไม่?
doppelgreener

1
@Axidos: ถ้าคุณจะทำมาร์กอัปที่ไม่สามารถอ่านได้และไม่มีโครงสร้างคุณก็อาจทำให้มันเป็นเลขฐานสอง นอกจากนั้นมันเป็นการประหยัดที่ผิดพลาดเว้นแต่คุณจะวิเคราะห์ข้อมูลที่ไม่มีการบีบอัดระหว่างรันไทม์ (ซึ่งในกรณีนี้คุณอาจเมาแล้ว) หรืออย่างใดอย่างหนึ่งถูก จำกัด สำหรับหน่วยความจำสตริงสองสามร้อยไบต์ระหว่างการแยกวิเคราะห์ ไมโครเวฟคุณไม่ได้)

@Joe: ดูเหมือนว่า bluescrn กำลังค้นหารูปแบบที่อ่านได้ซึ่งไม่มีชื่อซ้ำ ฉันแสดงให้เห็นถึงความสามารถของ JSON ในการเสนอสิ่งนั้น ฉันเห็นด้วยอย่างสมบูรณ์ว่าถึงจุดหนึ่งคุณอาจสงสัยว่าทำไมคุณถึงต้องกังวลกับมาร์กอัปเช่นนี้
doppelgreener

4

ใช้ JSON

(การสร้างการตอบสนองของ Munificent และส่วนใหญ่เป็นการตอบสนองต่อข้อกังวลของคุณที่แสดงไว้ที่อื่น)

คุณได้กล่าวถึงความกังวลว่า JSON มีปัญหาเรื่ององค์ประกอบการตั้งชื่อเสียพื้นที่เช่น XML มันไม่ได้

JSON สร้างขึ้นด้วยสองโครงสร้าง: คู่ชื่อ / ค่า ( วัตถุ ) และรายการค่าสั่งซื้อ ( อาร์เรย์ ) XML ที่ถูกสร้างขึ้นเพียงชื่อ / คู่ค่า

หากคุณคิดว่า JSON อาศัยวัตถุที่คุณกำลังอ่าน JSON นั้นสร้างขึ้นเพื่อให้สามารถอธิบายตัวเองและมนุษย์อ่านได้เช่นนี้ (โดยใช้เลขฐานแปดแปดหลักแทนไบต์เดียว):

{
    "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}
    ]
}

อย่างไรก็ตามคุณยังมีตัวเลือกในการเขียนเช่นนี้ตราบใดที่คุณรู้ว่าทุกสิ่งจะอยู่ที่ไหน (และสามารถค้นหาดัชนี 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 ทั้ง "Fast Infoset" (ไบนารี XML) และ vtd-xml

แม้ว่าหลัง (VTD) อาจไม่สามารถแก้ไขลักษณะการบีบอัดของการใช้งาน XML ของคุณ แต่อาจเพิ่มความเร็วในการเข้าถึงโหนดในไฟล์ขนาดใหญ่ได้อย่างมาก (ใช้ 'offset' พจนานุกรมไบนารีเพื่อข้ามไปยังโหนดและไม่สร้างวัตถุสำหรับแต่ละโหนด ทำงานแทนสตริง XML ต้นฉบับ) ดังนั้นการค้นหา XML จึงเร็วขึ้นและไม่จำเป็นต้องใช้หน่วยความจำในกระบวนการมากในการเข้าถึง / จัดการกับเอกสาร XML

ทั้งสองข้อข้างต้นมีการเชื่อมโยงในภาษายอดนิยม (ซึ่งรวมถึง C #)

ไชโย

รวย


1

คุณอาจจะลองKarvonite มันควรจะว่องไว เป็นกรอบการคงอยู่ที่จะปรับให้เข้ากับการเปลี่ยนแปลงในข้อมูลของคุณค่อนข้างดี (ซึ่งดีเมื่อเทียบกับการจัดการไบนารีของคุณเอง) ฉันไม่แน่ใจจริงๆว่าข้อมูลมีโครงสร้างอย่างไร แต่ไฟล์มีขนาดเล็กกว่าไฟล์ bloated xml มาก (ฉันสมมติว่ามันบันทึกข้อมูลในรูปแบบไบนารีแทนข้อความเช่น xml)

สิ่งเดียวที่ฉันคิดได้ก็คือถ้าข้อมูลของคุณได้รับความเสียหายหรือบางสิ่งที่ยุ่งเหยิงในแบบที่ Karvonite ไม่ชอบคุณก็จะได้รับความเมตตาจากผู้สร้างมันเว้นแต่คุณจะเข้าใจว่าโครงสร้างของ ข้อมูลทำงาน

วิธีที่คุณระบุวิธีการบันทึก / โหลดข้อมูลของคุณคือคุณเพียงแค่เปิดตัวแก้ไขการคงอยู่ของพวกเขานำเข้าแอสเซมบลีของคุณด้วยวัตถุข้อมูลทั้งหมดและทำเครื่องหมายในกล่องกาเครื่องหมายเพื่อแสดงวัตถุที่คุณต้องการสนับสนุน

มันอาจจะคุ้มค่าที่จะลอง เมื่อคุณใช้ C # มันเหมาะกับภาษาของคุณเพราะมันใช้งานได้กับ XNA (Windows, Xbox360 และ Windows Phone 7 ที่ฉันคิดว่าคุณสนใจเพราะคุณพูดถึง iPhone?)

แก้ไข: เพิ่งสังเกตเห็นคุณเพียงใช้ C # สำหรับเครื่องมือ นี่อาจไม่เหมาะสมกับขั้นตอนการทำงานของคุณ ด้วยเหตุผลบางอย่างฉันมี XNA ในหัวของฉัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.