Building a UNIX-like terminal in Unity with a virtual filesystem

So this is a doozy of a problem I’m having. I’m working on a stealth game where the player has to secretly access various computers and retrieve files/perform other operations without being caught. The stealth elements were easy enough to implement, but now I’m stuck with the slight problem of having to build a filesystem in Unity.

What I first tried doing was the following:

using UnityEngine;
using System.Collections;

[System.Serializable]
public class FileElement {

    public string fileName;
    public string permissions;
    public int owner;
    public string contents;
    public int executes;
    public FileElement[] folderDepth;

}

But it turns out that doing this makes it so I can’t properly serialize and save it to a custom asset? Basically, I’m completely at a loss as to how I’m going to make a file system for this game at all.

I am not going into details in here but I would use JSON or XML to store directory structure, file names and other relevant properties in them. The actual files could be stored somewhere else and JSON/XML could have path to those files.

-hp

Okay, except I don’t know how to generate the directory structure in the first place and I’d really prefer doing this with Unity’s built-in serialization.

Then you should take a look at ScriptableObject. It is like MonoBehaviour but instead of attaching it to a GameObject you can create asset out of it which contains your custom data.

There is a Unity tutorial about ScriptableObject here Introduction to Scriptable Objects - Unity Learn

I am aware of this. This does not help solve how I’m supposed to structure the data without running into serialization depth limits.

You can’t have a class that contains a field of its own type (unless that type inherits from UnityEngine.Object in some manner, such as MonoBehaviour).

This is because unity serializes by just copying the object, no references are preserved at all. Furthermore unity always instantiates a field, even if null. So thusly, if you have a type that references its own type, you get an infinitely recursing loop when serializing.

Now you technically don’t actually have this, since you have an array. This means you can get a 0 length array. But unity still fires off the exception when ever it does a depth check. It appears the serializer sees the ref to its own type, despite it being array, and throws off the message preemptively.

Anyways, yeah, I agree I wouldn’t bother using unity’s serialization for this, or even having this kind of structure for it.

Use some xml, or json, to describe the structure. So much easier to write and maintain. Then you can just reference the resource directly in your script.

If you want to stick with Unity’s serialization, you could implement a closer approximation of a real filesystem by using inode tables and data block tables (let’s just call those fileElements). Maybe something like:

public class Filesystem : ScriptableObject {
    public INode[] iNodeTable;
    public FileElement[] fileElements;
}

[Serializable]
public class INode {
    public string filename;
    public string permissions;
    public int owner;
    public int executes;
    public int[] subdirectories; // <-- indices into filesystem's iNodeTable[] array
    public int fileElementIndex; //<-- index into filesystem's fileElements[] array
}

[Serializable]
public class FileElement {
    public string contents;
}

Really, for your needs it sounds like you don’t need data blocks. You could just move contents into INode. The key is that it serializes int indices into iNodeTable[ ] and fileElements[ ] instead of references to other objects. (Also, I know technically filenames don’t belong in inodes. :slight_smile: )