What is a Console?
The concept of a console is important when writing games for modern game engines. In this article we will examine the concept in light of solving the blocking input problem in modern game engines and langauges like JavaScript.
In JavaScript, for example, your code is placed on the UI thread. This means that whenever a user presses a key, it does not register during the execution of your code. When your code is finished, then the browser will add any keypress events to an events buffer, and you will be able to check them on your next run. The net effect of this is that blocking for input is impossible. You cannot block for input because input is handled as an event on the same thread your own program runs.
Why is this a problem?
This is such a problem because it means your game code cannot wait for the user to press a key and it cannot perform string input. You will notice that the only way to perform string input in JavaScript is to type it on the console or in a special pop-up window — a window which you cannot style, because it is provided by the browser. This is a problem because it breaks the immersion of a game by preventing you from giving the user a consistent user interface. This is ultimately the result of poorly designed languages and game engines, but there is a workaround.
Simulating a Multithreaded Game Engine
The ideal solution would be to have multiple threads, such as the UI thread, and then, the game thread. Imagine two threads — one thread catches characters, such that the game thread can block if required, while it waits for input. This is what we want.
To simulate this in the world of event-driven JavaScript, we have to subvert the event queue and turn our game loop into a second-order event processing program. Then, when we want to enter a string, a flag is toggled which makes the game act as a terminal simulator. Finally, when the user presses enter, the ‘string’ he typed gets added to the command in our game’s event stack. This makes it look to the game as if we asked the user for a string and then called a function such as “setname”. In reality, we added “setname” to the event stack first, then entered terminal mode, and appended the string the user typed in terminal mode to the word ‘setname’.
Upon exiting the terminal mode (input mode) simulator, the event is triggered as “setname <Richard>” (etc).
If you wanted to ask multiple questions in a row, you can do that by adding multiple input mode commands to the game’s question event queue. This “question event queue” is called the console. Or rather, a game’s console is in fact a mode of operation which allows the user to type a string and have it added, wholesale, to the game’s event queue. This is how the console in games like Half Life 2, Fallout 4, or Starfield works.
A Console is an Event Queue
So essentially when you process a key, you don’t take the action there. You just add the command (for example, to move north) to the console command queue. Then later the game engine will process it.
This simple yet powerful idea opens up worlds of possibilities beyond simulating string input.
We could go as far as creating a custom scripting language and having the game coded partially in that language. It could be like an interactive fiction command processing engine. It could be like a bytecode. It could be a simple, or as complex, as you wish.
You could also have multiple queues. One could be a main queue, and one could be a priority queue which must be processed before anything in the main queue. You could have different queues for different kinds of events. This is a design paradigm you can explore, and that brings back a lot of memories I had writing my first games in BASIC.
What originally looked like a kludge to get around a badly designed game engine (LibGDX), turned into a way to bypass the limitations in a badly designed programming language (JavaScript) and ended up actually being the only way to do certain things. A kludge no more.
Filed under: Javascript,Programming - @ November 13, 2023 12:55 am