Level scripting in My Memory of Us: Game Actions

Posted: 09/07/2018

Today we want to give you a general look at how we are making our game and the engine that powers most of the interactions - Game Action System. We know that we could be slightly more creative when picking up the name for it, but hey, it works.

We're making My Memory of Us (MMoU in short) in Unity, using C# as our scripting language. This is pretty standard and offers a ton of control over how things are done. But what was most important to us during the prototype phase was to get the levels up and running as fast as possible. My Memory of Us is a content-driven game. We knew that as for gameplay-wise we do not have to deal with a lot of typical game stuff, like jumping, shooting (which came later) or making sure that power-ups are working like intended. We needed to start fleshing out the levels, mainly to verify what possible dangers could be hiding in our story - and how many ideas in it will have to be altered.

To achieve high-speed content prototyping, we decided to separate programmer and level designer work almost entirely. From a design perspective, we work with a bunch of big LEGO bricks, allowing us to have a working level prototype in a matter of a few days. Because of the nature of our game, we do not have a lot of repeatable interactions - most of them are hand-tailored for the best effect. Those crude prototypes allow quick idea testing and, more importantly, find the right proportions, composition, and pacing of our levels. As you know, we're quite serious about how My Memory of Us looks, so having a know-how about the works in relation to each other was extremely useful.

If you wonder how it is presented before adding graphics to the mix - here is a snapshot of an unused prototype stage of one of our levels:

Those marked spots are places where interactions happen. As mentioned before, they are powered by Game Actions, that can form long interaction chains. We have slightly more than 200 of these, but a lot of them are used only in a few places, and they do fairly specific things. However, this one here does a lot of everyday heavy lifting - introducing GA_Move_Object!

This bad boy has seen it all. Submitted in the initial commit for the system, it is the oldest Game Action. It does literally what it says. Takes a Unity GameObject as a Target and moves it from point A to point B. That should be it, shouldn't it?

We didn't expect it to stay that way, of course, it was the prototype of a prototype. GA_Move_Object went through a lot of changes. Some of these include pretty handy features: drawing gizmos, choice of a reference point (world/local to Game Action object/local to Target), constant refresh for the following stuff around, breaks and finally, integration of iTween to all of this stuff looks pretty. It also allows us now to fade the camera in and out if we are moving our characters between parts of the scenery. All of this comes with a price. Programmers have spent many hours on reworking the script constantly according to new design needs. A lot of this stuff could be resolved on the design side using a lower-level scripting system like Blueprints for UE4 or Bolt for Unity. But it would not look as pretty as it does now:


In conclusion, the most significant advantage of building the Game Action System is the speed of content creation. It matters a lot. It allowed us to make more iterations so we could spend more hours on polishing graphics, animations, and other stuff. Second thing, it is pretty easy to debug in the engine now. There is a finite amount of things that can go wrong with such a block. Most of the time, Game Actions happen one after another, so we just look for the one that shows weird behavior. Fixing it is usually a matter of changing its configuration, without the need to go into the code, which is quite handy. On the other hand, we arrived at this point after more than a year of creating these blocks and making sure that they do not interact with each other in unforeseen ways (actually, they still do, but that's another story ;) ). Our programmers put enormous work into making that happen. Thanks to them, we have a stable code-base that we can build upon in the future...


Radosław Smyk