dragoncoder047’s blog

random thoughts about nonrandom things

A Very Confusing Data Model

← Previous: Well, I Got Something... Next: Manual Memory Management Madness
Posted
By dragoncoder047

For the past week or two I have been working on a few things simultaneously. I keep prototype code that I’m developing but not quite ready to release yet in private GitHub repositories, and publish them when I’m ready. Lately I’ve been working on two different and completely unrelated things.

The first is the programming language I started in my previous post, PICKLE (which I think will be the final name). I got the garbage collector to work, and I also implemented hashmaps capable of looking up object attributes. I also got the parser to generate an abstract syntax tree from the code, which is a lot farther than I got with my other failed attempt at creating a programming language, TEHSSL.

The other thing I am working on is at the request of a friend. He is currently working on a (cringey) interactive fiction game, currently using Twine. But he wants to use a text-based engine, and none of the major ones have features he wants, so I have been asked to make one.

As-is, it’s very much a concept.

I’m very much tailoring the engine to fit my friend’s game, but I do want it to be able to be used for any generic type of game. So I have to do two things: 1) make it usable by a person who has never done programming before (although I do know my friend from computer science class) and 2) be story-agnostic, so it can be used for a fantasy story as easily as for a horror story or a science fiction story.

Number 2 necessitates abstracting the common characteristics of story elements into simple base classes, and then allowing the user to extend them to create the objects in the game.

After a lot of thinking (and consulting the Interactive Fiction Wiki) I came up with a simple method of defining objects based on a few simple attributes:

(Wait… did I just say “a few?” I sinceeeerely apologizeeee........)

From this, special objects can be made with sentinel value of zero or infinity:

Rooms additionally can reference each other (to implement passages) directly or through a door. Doors also have flags indicating if they are locked and closed.

Every object can also respond to events, which the vast majority of verbs is simply the verb. For example, typing push the button would invoke the push event on the button.

The difficulty with this data model is the ability to refer to any object from anywhere in the object tree. The engine has to account for the paradoxical possibility of a reference cycle, so the tree acts more like a doubly-linked list and the management of the nodes gets very confusing very fast and I haven’t implemented any of it yet.

The second, unrelated problem I have is how to describe the game. I want to avoid the use of real Python code as much as possible, but to allow for anything to be modified in any way desired during the course of the game. I did find a simple description of using YAML (and by extension, JSON) as a templating language (this), but it’s not Turing-complete, and it’s a templating language anyway (the constructs were designed without any side-effects in mind).

I have had several ideas over the course of thought:

  1. Use Tcl embedded into Python to create a domain-specific language. This has the disadvantage in that it can’t be run in the Web using Pyodide because Pyodide doesn’t have access to libtcl.
  2. Write my own Tcl-like parser in Python. This is conceptually easy (all it really needs to do is be able to balance brackets) but extremely difficult in practice.
  3. Just give up and use Python, but make it really easy by using a decorator syntax, and naming conventions similar to the do_X standard expected by the Python cmd module.
  4. Use YAML, and embed commands into the strings somehow. Blocks could be implemented by one-keypair dictionaries.

The approach I think I’m going to use is probably a mix of 3 and 4. For some reason I like Lisp, so I might end up using Hy as the expression syntax. A trivial fizzbuzz example would probably look like this:

- for x (range 1 11):
  - if (= 0 (% x 15)):
    - print FizzBuzz
    elif (= 0 (% x 5)):
    - print Fizz
    elif (= 0 (% x 3)):
    - print Buzz
    else:
    - print {x}
  - inc x

Who knows. If you’re interested in the outcome of this, monitor my GitHub repositories list for the appearance of something described as a Python text-based game engine. I don’t even have a name for it yet!


Related Posts