Pracuję nad narzędziem do edycji poziomu, które zapisuje dane w formacie XML.
Jest to idealne rozwiązanie podczas programowania, ponieważ wprowadzanie drobnych zmian w formacie danych jest bezbolesne i działa dobrze z danymi drzewiastymi.
Minusem jest jednak to, że pliki XML są raczej rozdęte, głównie z powodu powielania nazw znaczników i atrybutów. Również z powodu danych numerycznych zajmujących znacznie więcej miejsca niż przy użyciu rodzimych typów danych. Mały poziom może łatwo skończyć jako 1Mb +. Chcę znacznie zmniejszyć te rozmiary, zwłaszcza jeśli system ma być używany do gry na iPhonie lub innych urządzeniach o stosunkowo ograniczonej pamięci.
Optymalnym rozwiązaniem dla pamięci i wydajności byłoby przekonwertowanie XML na format binarny. Ale nie chcę tego robić. Chcę, aby format był dość elastyczny. XML bardzo ułatwia dodawanie nowych atrybutów do obiektów i nadawanie im wartości domyślnej, jeśli załadowana jest stara wersja danych. Chcę więc zachować hierarchię węzłów, z atrybutami jako parami nazwa-wartość.
Ale muszę przechowywać to w bardziej zwartym formacie - aby usunąć masowe powielanie nazw znaczników / atrybutów. Może także nadać atrybutom typy rodzime, więc na przykład dane zmiennoprzecinkowe są przechowywane jako 4 bajty na zmiennoprzecinkowe, a nie jako ciąg tekstowy.
Google / Wikipedia ujawniają, że „binarny XML” nie jest nowym problemem - został już rozwiązany wiele razy. Czy ktoś tu ma doświadczenie w zakresie istniejących systemów / standardów? - czy są idealne do użytku w grach - z bezpłatną, lekką i wieloplatformową biblioteką parsera / modułu ładującego (C / C ++)?
Czy powinienem sam odkryć to koło?
A może lepiej zapomnieć o ideale i po prostu kompresować swoje nieprzetworzone dane .xml (powinno się dobrze spakować z kompresją typu zip) i po prostu wziąć obciążenie pamięci / wydajność po załadowaniu?
źródło
Odpowiedzi:
Często używaliśmy binarnego XML-a do Superman Returns: The Videogame . Mówimy o tysiącach plików. Działało OK, ale szczerze mówiąc nie wydawało się warte wysiłku. Zjadł zauważalną część naszego czasu ładowania, a „elastyczność” XML nie wzrosła. Po pewnym czasie nasze pliki danych miały zbyt wiele dziwnych identyfikatorów, referencje zewnętrzne, które musiały być zsynchronizowane, i inne dziwne wymagania, aby mogły być naprawdę edytowane przez człowieka.
Ponadto XML jest tak naprawdę formatem znaczników, a nie formatem danych. Jest zoptymalizowany pod kątem dużej ilości tekstu z okazjonalnymi tagami. Nie nadaje się do danych o pełnej strukturze. To nie był mój telefon, ale gdyby tak było i wiedziałbym wtedy, co wiem teraz, prawdopodobnie zrobiłbym JSON lub YAML. Oba są na tyle zwięzłe, że nie wymagają kompaktowania, i są zoptymalizowane do reprezentowania danych , a nie tekstu .
źródło
Przechowuj i edytuj swoje poziomy jako normalne XML, ale silnik gry leniwie upiecz je w binarnym XML podczas ładowania i zapisz binarny XML z powrotem na dysku, aby mógł załadować go następnym razem (jeśli surowy XML nie zmienił się) .
Coś takiego:
W ten sposób uzyskasz to, co najlepsze z obu światów. Po wydaniu musisz tylko upewnić się, że wszystkie pliki binarne tam są.
źródło
Bufory protokołów Google wydają się właściwą drogą, ale sam ich nie używałem.
http://code.google.com/p/protobuf/
Definiujesz plik .proto, który opisuje format pliku:
Jest to następnie kompilowane za pomocą narzędzia wiersza poleceń, które generuje klasy C / C ++ do zapisywania i analizowania plików danych binarnych w uprzednio zdefiniowanym formacie danych. Istnieje również kilka rozszerzeń dla różnych języków programowania.
Minusem protokołu ProtocolBuffer jest to, że nie są one formatem zwykłego tekstu. Potrzebujesz narzędzia do ich generowania, czytania i edycji. Nie powinno to jednak stanowić problemu, jeśli używasz ich tylko do wymiany danych między edytorem gier a grą. Nie użyłbym tego do definiowania plików konfiguracyjnych;)
Kompresowanie nieprzetworzonych plików XML powinno również działać. Jakiego rodzaju grę tworzysz? Jeśli jest oparty na poziomie, wszystkie niezbędne zasoby należy załadować tylko raz, gdy poziom jest załadowany.
aktualizacja: Istnieje kilka projektów dla innych języków, takich jak C # do współpracy z ProtocolBuffers:
http://code.google.com/p/protobuf/wiki/ThirdPartyAddOns
źródło
.proto
plikowi, który prawie eliminuje problemy z błędną komunikacją. Prototypy są znacznie łatwiejsze do odczytania / utrzymania niż schemat xml, jeśli masz dyscyplinę (i czas), aby używać schematów xml.Co z formatem JSON?
http://www.json.org/xml.html
źródło
"cars":{"ford":[8C,FA,BC,2A,384FFFFF],"holden":[00,00,04,FF,04FF54A9]}
możesz nawet pominąć identyfikator „samochodów” i po prostu przejść bezpośrednio do tablicy, jeśli wiesz, gdzie będzie pole samochodów. Można nawet pominąć „Ford” i „gospodarstwo” nazwy, jeśli nie ma potrzeby zapisywania tych danych, dzięki czemu można z:[...,[[8C,FA,BC,2A,384FFFFF],[00,00,04,FF,04FF54A9]]]
. Czy robi się bardziej kompaktowy?Użyj JSON.
(Opierając się na odpowiedzi Munificent i głównie w odpowiedzi na twoje obawy wyrażone gdzie indziej)
Wspomniałeś o obawie, że JSON ma problem z marnowaniem elementów nazewnictwa przestrzeni, takich jak XML. Tak nie jest.
JSON jest zbudowany na dwóch strukturach: parach nazwa / wartość ( obiekty ) i uporządkowanych listach wartości ( tablice ). XML jest zbudowany tylko na parach nazwa / wartość.
Jeśli uważasz, że JSON opiera się na obiektach, które czytasz JSON, które są zbudowane tak, aby były samoopisujące i czytelne dla człowieka, jak to poniżej (używając liczb ósemkowych do reprezentowania pojedynczych bajtów):
Masz jednak możliwość napisania tego w ten sposób, o ile wiesz, gdzie wszystko będzie (i możesz poszukać indeksu 4, a nie obiektu „samochody”, aby uzyskać listę samochodów):
Robi się bardziej zwięzły niż tylko o
[
,]
,,
i swoich wartości?Dzieje się tak, jeśli chcesz zbliżyć się do czystego strumienia binarnego.
Po prostu nie strzelaj sobie w nogę, optymalizując zbyt wiele.
źródło
Wiem, że zaakceptowałeś odpowiedź, ale Google zarówno „Fast Infoset” (binarny XML), jak i vtd-xml.
Chociaż ten ostatni (VTD) może nie rozwiązać aspektu kompresji użycia XML, może znacznie przyspieszyć dostęp do węzłów w dużych plikach (znacznie używa „słownika” przesunięć binarnych do przeskakiwania do węzłów i nie tworzy obiektów dla każdego węzła , zamiast tego działa na oryginalny ciąg XML). Dlatego jego wyszukiwanie XML jest [podobno] zarówno szybsze, jak i nie wymaga tak dużo pamięci w trakcie przetwarzania, aby uzyskać dostęp do dokumentu XML lub nim manipulować.
Oba powyższe mają powiązania w popularnych językach (w tym C #).
Twoje zdrowie
Bogaty
źródło
Możesz spróbować Karvonite . To ma być zwinne. Jest to struktura utrwalania, która dość dobrze dostosuje się do zmian w twoich danych (co jest miłe w porównaniu do obsługi binarnej twojej jaźni). Właściwie nie jestem pewien, w jaki sposób dane są ustrukturyzowane, ale pliki są znacznie mniejsze niż rozdęte pliki XML. (Zakładam, że zapisuje dane w formacie binarnym zamiast tekstu takiego jak xml)
Jedynym mankamentem, jaki mogę tutaj wymyślić, jest to, że jeśli twoje dane zostaną uszkodzone lub w jakiś sposób popsuty w taki sposób, że Karvonite go nie lubi, jesteś na łasce jego twórców, chyba że zorientujesz się, jak struktura dane działają.
Sposób, w jaki określasz sposób zapisywania / ładowania danych, polega na otwarciu ich edytora trwałości, zaimportowaniu zestawu ze wszystkimi obiektami danych i zaznaczeniu niektórych pól wyboru, aby pokazać, które obiekty mają być obsługiwane i jakie pola / właściwości zapisać.
Może warto spróbować. Odkąd używasz C #, to pasuje do twojego języka, ponieważ działa z XNA (Windows, Xbox360 i Windows Phone 7, który moim zdaniem jest zainteresowany odkąd wspomniałeś o iPhonie?).
Edycja: Właśnie zauważyłem, że używasz tylko C # dla narzędzi. Prawdopodobnie nie pasowałoby to zbyt dobrze do Twojego przepływu pracy. Z jakiegoś powodu miałem XNA w głowie.
źródło