Even in a game engine like Unity, where a lot of the difficulties of mobile development have been obviated, working on such games presents its own set of frustrations, particularly when bug fixing. After all, the way we interact with a computer is far different than how we interact with a mobile device, so despite all of Unity’s conveniences, there are classes of issues and considerations that only show up while the game is running on a device.
In such cases, the typical edit-compile-test loop can be frustrating. Unity itself is designed for on-the-fly editing, so why shouldn’t we be able to do that on devices?
Consider the following scenarios:
- The game is in a broken state and we’d like to see why. These sorts of bugs are often logic issues, so we don’t have nice error messages to go by.
- The game is working, but we’d like to tweak things (accelerometer sensitivity, dimensions of objects, etc.) on the device while the game is running.
When running in the editor, we can use the inspector to do all those things to some degree, but when a device is deployed, we have to look elsewhere:
- Logging is often a workable solution for examining the game’s state, but can get tedious when there’s a lot to log or the cause of the issue isn’t clear.
- Developers can create buttons and other controls that can be adjusted in-game, though that can be a time sink as well.
- Ultimately, one could simply guess and check (Hm, 1.5 is too much, let’s try 1.45!), but that’s not really tenable when you’re working with projects with long compile times and it gets boring very quickly.
For these cases, a REPL (Read, Eval, Print, Loop) would be ideal. While it’s not as convenient for non-developers, it allows us to have all the functionality of a programming language available at runtime, so we can edit and examine to our hearts’ content. Early on in the development cycle, it would allow us to work interactively with the games, finding what works well, what doesn’t, and what we need to change to resolve issues that arise. Projects like Light Table (and the Lisp environments which preceded them) show some of the potential of this kind of interactivity.
With this in mind, we decided to create our own REPL framework for Unity!
Mono has a compiler library (Mono.CSharp) which provides the bulk of the functionality needed for a REPL. This was an easy choice, as it was freely available and easy to use. The documentation for the library is rather poor and occasionally inconsistent, though there are a few well-written and comprehensive samples in the Mono runtime source.
However, an issue was quickly apparent: How should we interact with the REPL? While we could create a text field in the game and allow users to type commands using the on-screen keyboard, it would be tedious (particularly because of all the symbols we would need to type) and the REPL itself would take up an unnecessary amount of space on a mobile screen.
As such, instead of trying to make a REPL that worked well on mobile and on the desktop, we decided to control it over the network. This would make the REPL as unobtrusive as possible, and would also allow developers to type using full-size keyboards.
We have the REPL server read data in a secondary thread (so we don’t get in the way of the game’s execution), and execute the commands in the main one. (Most of the Unity functions are not thread-safe and even error out if called from another thread). This gives us a great deal of flexibility in what we can do from the REPL without affecting game performance.
Stay tuned for a future blog post, where we introduce our new match-three infinite-runner Angry-Birds-clone, where users must use the REPL to hack the game itself to win!
If you have any questions or comments on this post, please feel free to message me firstname.lastname@example.org