Working with files

From Spheriki

Jump to: navigation, search


Tutorial: Working With Files by Steax, last update 19th Jan 2007 Level: Intermediate Requirements: Understanding of variables, functions, and objects Suggested: Understanding of basic file handling

One of sphere's greatest abilities is it's capability to directly access, read, and manipulate external files of any kind. Numerous useful functions can be delivered from this feature, such as loading your game's item data from a file, creating a custom save system that saves every variable you want, or even make your own image editor from sphere! This tutorial is to teach you about how sphere handles files and how we can use them, plus some tips and tricks.

Contents

How Sphere Handles Files

Sphere in its own right can handle any file you give it. It has 3 types of in-engine "file" objects, which are standard Files, RawFiles, and Logs. They have different uses, and thus different child functions.

Note about filetypes: Sphere has no dependency of filetypes it can open. In other words, you can have files called tiny.bla or boom.skew or anything. And in any directory as well, as you can always navigate to them via the "up one level" command, ../. Each file object type has its own default directory, which is always under the game dir, so doing "../myfiles/file.pif" will go to "game_directory/myfiles/file.pif". Yes, this means you can also open your own scripts, maps, or spritesets.

File Object (SaveFile)

This is the basic object and the simplest to use. These Files, which I will call SaveFiles, which is what they are usually for, are for the basic string-saving needs. And you can have a lot of strings in one file. Here's what they usually look like:

charname=kite
money=1000
score=50

As you can see, they take the simple form of key=value. They can be split via newlines to declare a new key and value, but if you save files from Sphere, the separator between value sets will be shown as an unrecognizable character (when opened in a text editor). Don't worry, this is how it's supposed to be.

First off, what's good about SaveFiles:

  • Simple save method. No messing around with a ton of functions.
  • Are easy to read from out of sphere.

As for its negative points:

  • Players can easily open them too.
  • It's easy to modify & search for keys.

So use these when you have information people are unlikely to tamper with. Lets start.

Opening A SaveFile

We use the OpenFile(filename) function here. By default, this is the "game_directory/save/" folder (which is why they're called SaveFiles anyway). Code:

var myfile = OpenFile("sphere.dat"); //Open sphere.dat from the /save/ folder.

Specific Characteristic: If the file doesn't exist, sphere will create a whole new blank file. This is the only way to make a new file in sphere. Later on we will exploit this.

It doesn't matter if the file doesn't exist yet, as sphere will make a new one, and now the variable myfile will contain your newly opened file (as a SaveFile object). We can manipulate myfile now.

Reading From A SaveFile

To obtain a value from the file, we use the read(key,default) function from the file's containing variable.

var version = myfile.read("version","1.0"); //Read the key that starts as version=... or return "1.0" if it doesn't exist

Remember the format "key=value"? Well, here we use it. Sphere will search through the file's loaded data (it will not read from the file again, but rather read the file's data in the variable), and look for "version=..." and return the string that follows. If it can't find a key called "version", then Sphere will give us the default we set in the function. So in this case, if we can't find the "version" key, the variable version will be equal to "1.0", otherwise it'll be filled with whatever value the key held in sphere.dat.

Writing To A SaveFile

Aside from reading files, we should also be able to save things to them. So lets do that! For this we need the write(key, value) function from the SaveFile object.

myfile.write("latestversion","1.13"); //Create or overwrite the key called "latestversion" and set it to "1.13"

The SaveFile object contained in myfile now contains the key "latestversion" with the value "1.13". If the key had existed before, it would be overwritten, otherwise sphere will add this key to the bottom of the file. Remember that this information is saved in the variable, not the file yet, so we need to flush the variable's contents into the real file!

So lets flush it

Yeah, we need to literally write the variable to the real file. So yeah, we flush it. With, of course, the flush() function.

myfile.flush() //Save the SaveFile object's data into the real sphere.dat file 

Now the sphere.dat file, which was the original file we loaded into "myfile" has all new updated keys and values we might have added via write() functions. A SaveFile object should be saved using this method (it can also be automatically saved later, but this is unreliable) for immediate saving.

We're done, lets Close the SaveFile

So we're done with the file, we've read all that we want and saved everything. We want to close the link to that file! So, obviously, we close() it. Simple as that.

myfile.close() //Close the myfile SaveFile object.

The variable "myfile" is now closed and useless. There's no point referring to it now, and the file is officially out of Sphere's reach. All SaveFiles should be closed when you're done using them.

Techniques with SaveFiles

SaveFiles can be used for quick and easy file manipulation. There are only a few functions and they are simple to use (you can compare this to the RawFiles coming up next). The following are some useful tricks:

Simple Save-From-Tampering

Sphere has the function HashFromFile(file), which creates an MD5 hash (or "fingerprint") of the file. The fingerprint of each file is different depending on the data it contains. Different data means different hashes. This means we've got a clean way to secure our SaveFiles from amateur cheating attempts - just save the hashes (created when we save the file) elsewhere, and hash the file again when we try to load it - if they don't match, that means that the file's data has change, and we just can't accept it.

String Tables

String tables are an effective way to use the same game engine while allowing multiple languages. They are basically files containing all information about strings in the game, and the engine can call them. Here's the step-by-step explanation:

  1. Select a string file
  2. Load all keys and values from that file
  3. Send those strings into an array
  4. Use the array whenever calling a string

Code:

var myStringTable = CreateStringTable() //The table must be a global variable

function CreateStringTable(filename){
  var st = []
  var file = OpenFile(filename); // Open file
  var keys = file.getNumKeys(); // Get number of keys
  for(i=0;i<keys.length;i++){
    st[file.getKey(i)] = file.read(file.getKey(i), "Stringtable error!");
  }
  return st;
}

// To call a string...
Abort(myStringTable["StringValue"]);

(This code can be turned into a more sophisticated object, for more functions, but is safe the way it is.)

RawFile Object

Rawfiles are different from SaveFiles - they aren't directly read as the strings they contain. Instead, Rawfiles are read as the bytes they're made of. This level of control allows us to modify the actual bytes, via all sorts of logical methods.

Personal tools