खेल डेटा के लिए 'बाइनरी एक्सएमएल'?


17

मैं एक स्तर के संपादन उपकरण पर काम कर रहा हूं जो XML के रूप में अपने डेटा को बचाता है।

यह विकास के दौरान आदर्श है, क्योंकि यह डेटा प्रारूप में छोटे बदलाव करने के लिए दर्द रहित है, और यह पेड़ जैसे डेटा के साथ अच्छी तरह से काम करता है।

हालांकि, नकारात्मक पक्ष यह है कि एक्सएमएल फाइलें बल्कि फूला हुआ है, ज्यादातर टैग और विशेषता नामों के दोहराव के कारण है। इसके अलावा संख्यात्मक डेटा के कारण देशी डेटाटिप्स का उपयोग करने की तुलना में काफी अधिक जगह ले रहा है। एक छोटा स्तर आसानी से 1Mb + के रूप में समाप्त हो सकता है। मैं इन आकारों को महत्वपूर्ण रूप से कम करना चाहता हूं, खासकर अगर सिस्टम को आईफोन या किसी अन्य डिवाइस पर अपेक्षाकृत सीमित मेमोरी वाले गेम के लिए उपयोग किया जाना है।

स्मृति और प्रदर्शन के लिए इष्टतम समाधान, XML को बाइनरी स्तर प्रारूप में परिवर्तित करना होगा। लेकिन मैं ऐसा नहीं करना चाहता। मैं प्रारूप को काफी लचीला रखना चाहता हूं। XML को ऑब्जेक्ट में नई विशेषताओं को जोड़ना बहुत आसान बनाता है, और यदि डेटा का एक पुराना संस्करण लोड किया गया है, तो उन्हें डिफ़ॉल्ट मान दें। इसलिए मैं नाम-मूल्य जोड़े के रूप में विशेषताओं के साथ नोड्स के पदानुक्रम को रखना चाहता हूं।

लेकिन मुझे टैग / विशेषता नामों के बड़े पैमाने पर दोहराव को हटाने के लिए इसे और अधिक कॉम्पैक्ट प्रारूप में संग्रहीत करने की आवश्यकता है। हो सकता है कि विशेषताओं को मूल प्रकार देने के लिए भी, इसलिए, उदाहरण के लिए फ्लोटिंग-पॉइंट डेटा को 4 बाइट प्रति फ्लोट के रूप में संग्रहीत किया जाता है, न कि टेक्स्ट स्ट्रिंग के रूप में।

Google / विकिपीडिया बताते हैं कि 'बाइनरी एक्सएमएल' शायद ही कोई नई समस्या है - यह पहले ही कई बार हल हो चुकी है। यहाँ किसी को भी मौजूदा सिस्टम / मानकों में से किसी के साथ अनुभव मिला है? - खेल के उपयोग के लिए कोई आदर्श हैं - एक नि: शुल्क, हल्के और क्रॉस-प्लेटफॉर्म पार्सर / लोडर लाइब्रेरी (C / C ++) के साथ उपलब्ध हैं?

या मैं खुद ही इस पहिये को सुदृढ़ करूं?

या क्या मैं आदर्श को भूल जाना बेहतर हूं, और बस अपने कच्चे .xml डेटा को संपीड़ित कर रहा हूं (इसे जिप-जैसे संपीड़न के साथ अच्छी तरह से पैक करना चाहिए), और बस मेमोरी / प्रदर्शन को हिट-लोड पर ले जा रहा है?


1
XML को बहुत अच्छी तरह से gzip et al का उपयोग करके संपीड़ित किया जा सकता है ।
ThiefMaster

जवाबों:


18

हमने सुपरमैन रिटर्न्स: द विडियोगेम के लिए बाइनरी एक्सएमएल का भारी उपयोग किया । हम हजारों और हजारों फाइलों में बात कर रहे हैं। यह ठीक काम किया, लेकिन ईमानदारी से प्रयास के लायक नहीं था। यह हमारे लोडिंग समय के एक ध्यान देने योग्य अंश को खा गया, और एक्सएमएल के "लचीलेपन" ने कोई पैमाना नहीं बनाया। थोड़ी देर के बाद, हमारी डेटा फ़ाइलों में बहुत अधिक अजीब पहचानकर्ता थे, बाहरी संदर्भ जिन्हें सिंक में रखने की आवश्यकता थी, और उनके लिए अन्य अजीब आवश्यकताएं वास्तव में संभवतया मानव-संपादित की जानी चाहिए।

इसके अलावा, XML वास्तव में एक मार्कअप प्रारूप है, और डेटा प्रारूप नहीं है। यह कभी-कभार टैग के साथ बहुत सारे पाठ के लिए अनुकूलित है। यह पूरी तरह से संरचित डेटा के लिए बहुत अच्छा नहीं है। यह मेरी कॉल नहीं थी, लेकिन अगर ऐसा होता और मुझे पता होता तो मैं अब जो जानता, मैं शायद JSON या YAML कर लेता। वे दोनों के लिए पर्याप्त नहीं हैं संघनन की आवश्यकता है, और डेटा का प्रतिनिधित्व करने के लिए अनुकूलित कर रहे हैं , पाठ नहीं ।


1
JSON का एक बाइनरी संस्करण है जिसे BSON कहा जाता है ।
फिलीपिंस

12

अपने स्तरों को सामान्य XML के रूप में संग्रहीत और संपादित करें, लेकिन क्या आपके गेम इंजन ने इसे लोड करने के दौरान बाइनरी एक्सएमएल में बेक किया है, और बाइनरी एक्सएमएल को डिस्क पर वापस सहेजें ताकि यह अगली बार लोड हो सके (यदि कच्चा एक्सएमएल बदल नहीं गया है) ।

कुछ इस तरह:

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

इस तरह आप दोनों दुनियाओं में सर्वश्रेष्ठ हो जाते हैं। रिलीज होने पर, आपको बस यह सुनिश्चित करने की आवश्यकता है कि सभी बाइनरी फाइलें हैं।


5

Google प्रोटोकॉल बफ़र जाने का तरीका लगता है, लेकिन मैंने खुद उनका उपयोग नहीं किया है।
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 फ़ाइलों को संपीड़ित करने के लिए भी काम करना चाहिए। आप किस प्रकार का खेल बना रहे हैं? यदि यह स्तर-आधारित है तो आपको सभी आवश्यक संसाधनों को केवल एक बार लोड किया जाना चाहिए जब स्तर लोड हो।

अद्यतन: प्रोटोकॉल के साथ काम करने के लिए C # जैसी अन्य भाषाओं के लिए कई परियोजनाएं हैं:
http://code.google.com/p/protobuf/wiki/ThirdPartyAddOns


क्या कोई धारावाहिक उस तरह की समस्या के अनुकूल नहीं है? मुझे लगता है कि नहीं, लेकिन मुझे स्पष्ट अंतर दिखाई नहीं दे रहा है। लेकिन मेरे लिए यह उत्तर उचित प्रतीत होता है। लेकिन xml फ़ाइलों को टार् / gzip भी करने से उनका आकार बहुत कम हो जाएगा (क्योंकि यह पाठ है, लेकिन मुझे लगता है कि यह xml के लिए भी काम करेगा), ताकि "आसान" समाधान हो सके। किसी भी तरह एक्सएमएल एक आसान भाषा है, लेकिन इसका उपयोग करके पार्सिंग / मेमोरी की अवधि में बहुत महंगा है: जब आप एक्सएमएल का उपयोग करते हैं तो आपको जितनी बार संभव हो पढ़ना / लिखना चाहिए।
१६:०६ पर जोकून

यह एक दिलचस्प विकल्प है, लेकिन पाइपलाइन में कहीं भी XML का उपयोग करने के लिए एक पूर्ण विकल्प की तरह दिखता है। ईमानदार होने के लिए, मैं उत्पन्न कोड के बारे में बहुत उत्साही हूं, हालांकि - और एक और जटिलता यह है कि मैं चीजों के टूल साइड के लिए C # का उपयोग कर रहा हूं (मैं बड़ी .XML फ़ाइलों के साथ काम करना जारी रखने के लिए टूल के लिए खुश हूं। )। एक XML-> PB कनवर्टर एक विकल्प हो सकता है, हालांकि मुझे लगता है कि मैं अभी भी कुछ ऐसी चीज तलाश रहा हूं जो विशिष्ट 'बाइनरी लेवल डेटा' को सेंकने के तरीकों के बजाय 'सामान्य उद्देश्य बाइनरी एक्सएमएल' अधिक हो, भले ही वह थोड़ा अधिक हो। कुशल)
ब्लूस्क्रान

"मैं चीजों के टूल साइड के लिए C # का उपयोग कर रहा हूं" c # के लिए कई प्रोजेक्ट हैं। मेरे जवाब को अपडेट किया।
स्टीफन

@bluescrn, मैं उत्पन्न कोड के बारे में बहुत चिंतित नहीं होगा। Google C ++, Java और पायथन को प्रथम श्रेणी का समर्थन देता है। वे बड़े पैमाने पर आंतरिक रूप से इसका उपयोग करते हैं; उत्पन्न कोड काफी मजबूत है। PB के साथ एक बड़ा फायदा, एक .protoफ़ाइल के खिलाफ आपका टूल प्रोग्राम है , जो लगभग गलत संचार समस्याओं को दूर करता है। यदि आप एक्सएमएल स्कीमा का उपयोग करने के लिए अनुशासन (और समय) भी रखते हैं, तो एक एक्सएमएल स्कीमा की तुलना में प्रोटोज को पढ़ना / बनाए रखना बहुत आसान है।
deft_code

4

JSON- प्रारूप के बारे में क्या?

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


यह XML की तुलना में थोड़ा अधिक कॉम्पैक्ट दिखता है, लेकिन अभी भी डुप्लिकेट विशेषता नाम का मुख्य मुद्दा है। यदि फ़ाइल में 'XPosition', 'YPosition', और 'Scale' विशेषताओं के साथ गेम ऑब्जेक्ट्स की सूची होती है, तो स्ट्रिंग्स 'XPosition' / 'YPosition' / 'Scale' को हर एक गेम ऑब्जेक्ट के लिए डुप्लिकेट किया जाएगा। यह मुख्य बात है कि मैं इस समय 'सेक' करने का लक्ष्य बना रहा हूं
ब्लूज़क्रान

1
@bluescrn: नहीं, यह मुद्दा नहीं है। वस्तुएं एक संरचना हैं; तुम भी सरणियों का उपयोग कर सकते हैं [जो, बस, देखो, जैसे, यह]। इसका मतलब है कि आप कारों के नाम और गुणों को संग्रहीत करने के लिए कुछ इस तरह से समाप्त कर सकते हैं: "cars":{"ford":[8C,FA,BC,2A,384FFFFF],"holden":[00,00,04,FF,04FF54A9]}आप "कारों" पहचानकर्ता को भी छोड़ सकते हैं और बस एक सरणी में सीधे जा सकते हैं यदि आप जानते हैं कि कारों का क्षेत्र कहाँ होगा। आप "ford" और "होल्डन" नामों को भी छोड़ सकते हैं यदि आपको उस डेटा को सहेजने की आवश्यकता नहीं है, तो आपको छोड़ कर [...,[[8C,FA,BC,2A,384FFFFF],[00,00,04,FF,04FF54A9]]]:। क्या यह अधिक कॉम्पैक्ट है?
doppelgreener

1
@ एक्सीडोस: यदि आप मार्कअप बनाने जा रहे हैं जो अपठनीय और असंरचित है, तो आप इसे केवल बाइनरी बना सकते हैं। इसके अलावा, यह एक झूठी बचत है, जब तक कि आप रनटाइम के दौरान असम्पीडित डेटा को पार्स नहीं कर रहे हैं (जिस स्थिति में, आप शायद वैसे भी खराब हैं), या किसी भी तरह से पार्सिंग के दौरान स्ट्रिंग मेमोरी के कुछ सौ बाइट्स के लिए विवश हैं (जब तक कि आप चालू न हों एक माइक्रोवेव, तुम नहीं हो)।

@ जो: ब्लूज़क्रान एक पठनीय प्रारूप की खोज कर रहा है जिसमें डुप्लिकेट नाम नहीं हैं। मैं सिर्फ प्रस्ताव देने के लिए JSON की क्षमता का चित्रण कर रहा था। मैं पूरी तरह से सहमत हूं, हालांकि एक निश्चित बिंदु पर आप बस आश्चर्यचकित हो सकते हैं कि आप इस तरह मार्कअप के साथ भी परेशान क्यों हैं।
doppelgreener

4

JSON का उपयोग करें।

(मुनस्यारी की प्रतिक्रिया पर निर्माण, और काफी हद तक आपकी चिंताओं के जवाब में)

आपने चिंता व्यक्त की है कि जेएसएन में एक्सएमएल की तरह अंतरिक्ष के नामकरण तत्वों को बर्बाद करने का मुद्दा है। यह नहीं है

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 दोनों "फास्ट इन्फोसिट" (बाइनरी एक्सएमएल) और वीडीटी-एक्सएमएल।

हालाँकि बाद वाला (VTD) आप XML उपयोग के संपीड़न पहलू को हल नहीं कर सकता है, यह बड़ी फ़ाइलों में नोड एक्सेस की गति बढ़ा सकता है, काफी (यह बाइनरी ऑफ़सेट्स 'डिक्शनरी' का उपयोग करके नोड्स में जा सकता है, और) प्रत्येक नोड के लिए ऑब्जेक्ट नहीं बनाता है। , बजाय मूल XML स्ट्रिंग पर काम)। इसलिए, यह XML लुकअप है [कहा जाता है] दोनों तेज हैं और इसे XML डॉक्स तक पहुंचने / हेरफेर करने के लिए ज्यादा इन-प्रोसेस मेमोरी की आवश्यकता नहीं है।

उपरोक्त दोनों की लोकप्रिय भाषाओं में बाइंडिंग है (जिसमें C # शामिल है)।

चियर्स

धनी


1

आप Karvonite की कोशिश कर सकते हैं । यह चुस्त होना चाहिए। यह एक दृढ़ता की रूपरेखा है जो आपके डेटा में परिवर्तनों को काफी अच्छी तरह से अनुकूल करेगा (जो कि आपके स्वयं के बाइनरी को संभालने की तुलना में अच्छा है)। मुझे वास्तव में यकीन नहीं है कि डेटा कैसे संरचित है, लेकिन फ़ाइलें xml फूला हुआ फ़ाइलों की तुलना में बहुत छोटी हैं। (मुझे लगता है कि यह xml की तरह पाठ के बजाय एक द्विआधारी प्रारूप में डेटा बचाता है)

इसके साथ मैं केवल यह सोच सकता हूं कि यदि आपका डेटा दूषित हो जाता है या कुछ इस तरह से गड़बड़ हो जाता है कि कार्वोनाइट इसे पसंद नहीं करता है, तो यह आपकी तरह की रचनाकारों की दया पर है जब तक आप यह पता नहीं लगाते कि मैं कैसे संरचना डेटा काम करता है।

जिस तरह से आप अपने डेटा को बचाने / लोड करने के तरीके को निर्दिष्ट करते हैं, क्या आप उनके दृढ़ता संपादक को खोलते हैं, अपनी विधानसभा को सभी डेटा ऑब्जेक्ट्स के साथ आयात करते हैं और कुछ चेक बॉक्स दिखाते हैं कि आप किन वस्तुओं का समर्थन करना चाहते हैं और किन फ़ील्ड / गुणों को सहेजना चाहते हैं।

इसे कोशिश करने में लाभ हो सकता है। जब से आप C # का उपयोग कर रहे हैं, यह आपकी भाषा के साथ सही बैठता है क्योंकि यह XNA (Windows, Xbox360, और Windows Phone 7) के साथ काम करता है, जो मुझे लगता है कि जब से आपने iPhone का उल्लेख किया है, तो आपकी दिलचस्पी क्या है?)।

संपादित करें: टूल के लिए बस अपने # C का उपयोग करके देखा। यह शायद आपके वर्कफ़्लो में बहुत अच्छी तरह से फिट नहीं होगा। किसी कारण से मेरे सिर में XNA था।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.