How to save and load a text mode game - c++

I went in late in a project of gamedev of a simple text game in C++.I studied the project and I think I know how to do everything but i get stuck on a thing:how to save and load the game as proposed.I don't want to have the thing done for me,only you show me a way to do it.

Well the simplest way I can think of is to have a structure/class which represents the whole games "state." And on save you simply write this entire structure from memory to disk. Loading would be the opposite.
What format it is on disk is entirely up to you, if your state consists entirely of simple data types, you may just want to write a binary blob. Or you might want to go with something more versatile such as serializing it to XML, it's really up to you.

I've only taken a quick look at the post but here's my suggestion:
You game state might consist of a couple of structures and a few arrays of data. The structures would define the player(name, health, money, whatever), a weapon (attack, chance, etc), armor etc and so on...
First you would write the player's state by saving his structure. Next would would be the number of weapons owned by the player, followed by an array of weapon structures, the same for armor...
The file format would then be
STRUCT player
INT num_of_weapons
STRUCT weapon
STRUCT weapon
STRUCT weapon
INT num_of_armor
STRUCT armor
STRUCT armor
It can be easily done using fstream.

The process you are describing is known as "serialization"- that is, taking an in-memory object and converting it into some form that can be saved to disk. It could be as simple as a raw memory dump, or something complicated like XML.
I suggest taking a look at the wikipedia article on this subject: http://en.wikipedia.org/wiki/Serialization

I didn't read the website you linked to, but you'll probably want to write code that reads/writes to a basic text file in order to load/save your game.
First, figure out how to format your text file. For example, if I'm writing a pacman game that allows the player to save games, the text file might look something like this:
5
54700
3
I would write my code to read the file one line at a time:
Line 1: the level the player is on.
Line 2: the number of points the player has.
Line 3: the number of lives the player has.
Do a Google search for C++ file input/output to figure out how to write the actual code.

XML serialization seems the easiest solution. With small lightweight libraries such as TinyXML it's even easier. As for making the files unreadable you can use simple XOR obfuscation with a short key. Or you could try JSON.

It all depends on how complex your save files would be. If it's just a few integers than it's probably pretty easy to simply write a couple of functions that would write those values to a file in a specified order and then load them in the same order that they're written. If it needs to be more complex and handle saving the values of multiple objects than serialization is your best bet. If you're looking for a human readable save format I would suggest XML Serialization, otherwise you may want to look up some non-human readable formats.

Related

Any ideas on how to create a file only readable by my program?

So I noticed when I want to write external data for my program I have to use and that inserts my data I want into a notepad. What Im wondering is, say I wanted to write to a file that my users couldn't edit, like a file that would hold scores and such for a game that I dont want players to be able to edit manually. Would such a thing be possible through c++ standard library alone, or would I need some other library? And I understand some programs may be able to read it, but Im more oriented towards wether people can read it by simply looking at the notepad.
You say you just want to prevent people from easily using notepad.exe to see and edit the file content. That can be done by writing the data as binary rather than text:
std::ofstream out("score.dat", std::ios::binary);
std::uint32_t score = 12000;
out.write(reinterpret_cast<char*>(&score), sizeof score);
However it's still trivial for users to see and modify the data using a hex editor.
You could make it require a bit more work by encrypting the data first, but given that the program must have all the information necessary to read and write the file it's still pretty easy to get around.

how to save and load story-flow nodes in file?

I want to make an interactive fiction game editor, in this type of games a story has many story-lines where each gamer can finish the game with a different story. For each section of a game story we need a node that tells the story and interacts with player.
I will make an editor for drawing story sections (nodes), that every node can link to minimum one node and maybe many, also each node has some properties (like text, photo, sound, ...) and variables (like gold on the ground, HP reducer, ...) that must be used in the game story.
What's the best way for saving this story-line (nodes) in a file for loading with my game player?
If you can write a code example in C++, Pascal or PHP it is better for me.
You want to do a couple of things:
Figure out what you need to reconstruct a saved node completely enough to use it again.
Prepare all that data you need.
Look into file i/o. There are loads of tutorials online, search for "c++ file i/o" or something similar.
Now you implement file saving/loading.
I'd guess you'll end up with something like this for saving.
write number of nodes
for node in node_list:
write node info
And then for loading
read number of nodes
for i in range(0, number_of_nodes)
read node info
If you run into a specific problem ask a new question.
I think you should take a look to xml.
There are a lot of libraries to work with it, personally in c++ I prefer pugi but you can take a look to libxml2, xerces, etc...
Pugi XML
If you don't want user interaction you can always encrypt the xml before save it.

is there any reference/resource about how to design the structure of a data file? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What are important points when designing a (binary) file format?
I am going to develop a program which will store data in file.
The file can be big. The data in the file is basically made up with variable length records. And I need random access to the records.
I just want to read some resouces/books about how to design the structure of a data file. But I can't find any yet.
Any suggestion is much appreciated.
You might find http://decoy.iki.fi/texts/filefd/filefd useful. It's a general starting point to the techniques to consider.
Also look at this question here on SO: What are important points when designing a (binary) file format?
The problem you describe is a central theme of Database Theory.
Any decent text on the subject should give you some good ideas. The standard text from uni was:
Fundamentals of Database Systems- Elmasari & Nava (PDF) (Amazon)
Another approach is to use a memory mapped array of structs, take a look at my bountied answer to a similar question
Yet another approach is to use a binary protocol like Google protobuf and "send" your data to the file when writing and "receive" it when writing.
If the answer you're looking for is "what book to read" I can't help.
If "how do to that" may be good for you as well I've some suggestions.
One good solution is the one suggested by Srykar; I would just add that I'd use SQLite instead of MySQL. It's an open source C library that you can embed in your program. It lets you store data in a DB just the way you'd do with SQL statement, but calling the library C functions instead. In your case you may keep everything in memory and then save the data to disk at proper time.
Reference:
http://www.sqlite.org
Another option is the old "do it yourself way". I mean: there's nothing very complicated about storing your data to a file (unless your data is very very structured, but I'd go with option nr. 1 in this case).
You write down a plan of how you want the structure of your file to be. And you follow that plan both when writing the file to disk and when reading it re-storing the data into memory.
If you have n records. Write n to disk, then write each record.
If each record has variable lenght, then write the length of each record before writing the record.
You talk about "random access" in your question. Probably you mean that the file is very big and at access time you want to read from disk only the portion you're interested in.
If so plan to build an index; that index will tell the offset of each element in bytes from the beginning of the file. Store the index at the beginning of the file and then store the data.
When you read the file you start reading the index, get the offset to the data you need, and read that portion of file.
These are very basic examples, just to get the idea...
Hope they helps!
Is there any reason you are not considering putting this data in a persistent DB store like mysql? these system are built to deal with random data access with proper indexes to speeden you data retrieval. Plus while reading from a file, you would have to read the entire file to get what you want as there are no indexes and no query language.
Added to this they have systems in place to make sure multiple running processes can access the same data without data getting corrupted. It provided data recovery incase of inconsistencies.
So just storing is the simple part, it does not end there. You would have to provide all the other solutions eventually. Better use whats available.

Writing to the middle of the file (without overwriting data)

In windows is it possible through an API to write to the middle of a file without overwriting any data and without having to rewrite everything after that?
If it's possible then I believe it will obviously fragment the file; how many times can I do it before it becomes a serious problem?
If it's not possible what approach/workaround is usually taken? Re-writing everything after the insertion point becomes prohibitive really quickly with big (ie, gigabytes) files.
Note: I can't avoid having to write to the middle. Think of the application as a text editor for huge files where the user types stuff and then saves. I also can't split the files in several smaller ones.
I'm unaware of any way to do this if the interim result you need is a flat file that can be used by other applications other than the editor. If you want a flat file to be produced, you will have to update it from the change point to the end of file, since it's really just a sequential file.
But the italics are there for good reason. If you can control the file format, you have some options. Some versions of MS Word had a quick-save feature where they didn't rewrite the entire document, rather they appended a delta record to the end of the file. Then, when re-reading the file, it applied all the deltas in order so that what you ended up with was the right file. This obviously won't work if the saved file has to be usable immediately to another application that doesn't understand the file format.
What I'm proposing there is to not store the file as text. Use an intermediate form that you can efficiently edit and save, then have a step which converts that to a usable text file infrequently (e.g., on editor exit). That way, the user can save as much as they want but the time-expensive operation won't have as much of an impact.
Beyond that, there are some other possibilities.
Memory-mapping (rather than loading) the file may provide efficiences which would speed things up. You'd probably still have to rewrite to the end of the file but it would be happening at a lower level in the OS.
If the primary reason you want fast save is to start letting the user keep working (rather than having the file available to another application), you could farm the save operation out to a separate thread and return control to the user immediately. Then you would need synchronisation between the two threads to prevent the user modifying data yet to be saved to disk.
The realistic answer is no. Your only real choices are to rewrite from the point of the modification, or build a more complex format that uses something like an index to tell how to arrange records into their intended order.
From a purely theoretical viewpoint, you could sort of do it under just the right circumstances. Using FAT (for example, but most other file systems have at least some degree of similarity) you could go in and directly manipulate the FAT. The FAT is basically a linked list of clusters that make up a file. You could modify that linked list to add a new cluster in the middle of a file, and then write your new data to that cluster you added.
Please note that I said purely theoretical. Doing this kind of manipulation under a complete unprotected system like MS-DOS would have been difficult but bordering on reasonable. With most newer systems, doing the modification at all would generally be pretty difficult. Most modern file systems are also (considerably) more complex than FAT, which would add further difficulty to the implementation. In theory it's still possible -- in fact, it's now thoroughly insane to even contemplate, where it was once almost reasonable.
I'm not sure about the format of your file but you could make it 'record' based.
Write your data in chunks and give each chunk an id.
Id could be data offset in file.
At the start of the file you could
have a header with a list of ids so
that you can read records in
order.
At the end of 'list of ids' you could point to another location in the file (and id/offset) that stores another list of ids
Something similar to filesystem.
To add new data you append them at the end and update index (add id to the list).
You have to figure out how to handle delete record and update.
If records are of the same size then to delete you can just mark it empty and next time reuse it with appropriate updates to index table.
Probably the most efficient way to do this (if you really want to do it) is to call ReadFileScatter() to read the chunks before and after the insertion point, insert the new data in the middle of the FILE_SEGMENT_ELEMENT[3] list, and call WriteFileGather(). Yes, this involves moving bytes on disk. But you leave the hard parts to the OS.
If using .NET 4 try a memory-mapped file if you have an editor-like application - might jsut be the ticket. Something like this (I didn't type it into VS so not sure if I got the syntax right):
MemoryMappedFile bigFile = MemoryMappedFile.CreateFromFile(
new FileStream(#"C:\bigfile.dat", FileMode.Create),
"BigFileMemMapped",
1024 * 1024,
MemoryMappedFileAccess.ReadWrite);
MemoryMappedViewAccessor view = MemoryMapped.CreateViewAccessor();
int offset = 1000000000;
view.Write<ObjectType>(offset, ref MyObject);
I noted both paxdiablo's answer on dealing with other applications, and Matteo Italia's comment on Installable File Systems. That made me realize there's another non-trivial solution.
Using reparse points, you can create a "virtual" file from a base file plus deltas. Any application unaware of this method will see a continuous range of bytes, as the deltas are applied on the fly by a file system filter. For small deltas (total <16 KB), the delta information can be stored in the reparse point itself; larger deltas can be placed in an alternative data stream. Non-trivial of course.
I know that this question is marked "Windows", but I'll still add my $0.05 and say that on Linux it is possible to both insert or remove a lump of data to/from the middle of a file without either leaving a hole or copying the second half forward/backward:
fallocate(fd, FALLOC_FL_COLLAPSE_RANGE, offset, len)
fallocate(fd, FALLOC_FL_INSERT_RANGE, offset, len)
Again, I know that this probably won't help the OP but I personally landed here searching for a Linix-specific answer. (There is no "Windows" word in the question, so web search engine saw no problem with sending me here.

Game Programming: .DAT file?

I've seen a lot of games use something similar to a .DAT file or a specific file type that the game has for itself. I'm just beginning with C++ and DirectX and I was interested in keeping my information in something similar to a .DAT.
My initial conception was that it would hold information on the files you wanted to store within the .DAT file. Something similar to a .RAR file. Unfortunately, my googleing skills did not help me in finding the answers.
Right now I'm simply loading textures and sound files from a folder called Data.
EDIT: While I understand that .DAT is short for data, and I've found that a .DAT file generally contains any assortment of information, I'm still unsure about how to go about doing something as packing images and sound files into any type of file and being able to read them.
I'm not sure about using fstreams to achieve my task, however I will look into streams related to storing data and how to properly read from that data. Meanwhile if anyone has another answer to offer based on this new information, it would be appreciated.
EDIT: Thanks to the answers, I stumbled across a similar question on stackoverflow and felt I'd share it here. Combining resources into a single binary file
I don't think there is really such thing as .dat file format. It's short for "data," and different applications just put in some proprietary stuff in it and call it ".dat." You can read up on fstream classes to do file IO in C++. See Input/Output with files.
What you then do is make up your own file format. For example, first 4 byte is int that indicates the number of blocks in the .dat and for each block, you have 4 byte indicating the length of each block, 4 byte indicating the type of the block, the variable length data itself .. something like that.
DAT obviously stands for data, and there is no real or de facto standard on what that extension actually refers to. Your decisions on the best file formats should be based on technical considerations, not pointless attempts at security through obscurity.
Professional games use a technique where they put all the needed resources (models, textures, sounds, ai, config, etc) zipped/packed into a single file thus making it faster to manage, harder to change (some even make use of a virtual filing system from what's inside the data file). Now, for what's inside the file is different depending on the needs of the game and the data structures that you use.
If you're just starting into gamedev, i recommend you stick with keeping all you assets separate and don't bother too much about packing them into a single file.
Now if you really want to start using a packed format here's a good pointer:
Creating a PAK File Format
Here's a link which claims that .dat is a movie format, 'DAT' being short for Digital Audio Tape.
I'm not sure I believe the link, but I do remember something about a Microsoft supported format called DAT, from long ago, when I used an earlier version of Windows.
It makes more sense as a logical extension for a DATA file of some kind.
.dat, as others have said, is literally just a data file. In reality, the file extension means nothing other than association with a program. For example, I could make a word processor that saves all the documents with the .mp3 file extension. These files wouldn't be playable in any media software, but the software might try. File extensions are used to help programs know what types of files they can and cannot open--however those rules don't have to be followed.
Anyway, you can dump any sort of information to a file. Programmers/software writers will often choose .dat as the extension of that file because it has become the standard to signify 'this file just holds a ton of data' and that the data doesn't necessarily hold any standardized headers, footers, or formatting.
A dat file could really contain anything. It might be as simple as a zip archive with the extension changed, or it could be a completely custom file type. If you're just starting out, you probably don't want to write your own file format, although doing so can be fun and educational. If you want to encapsulate your data files into some kind of container, you should probably go with a zip, paq, or maybe tar.gz.