User Guide for the editor and the GAME_DATA JSON file
TerminalLog is a micro-engine for creating small games in a
retro terminal style + graphic viewport. The player interacts
by typing commands (e.g. look, scan, listen) and moving between
textual “rooms”, while the viewport shows an image or animated tileset
(to simulate cameras, scanners, etc.).
As a developer, you don’t need to write JavaScript: you just edit a JSON
object called GAME_DATA. The editor helps you to:
Make sure you have these files in the same folder:
editor.htmleditor.csseditor.jsTo get started:
editor.html in a modern browser (Chrome, Firefox, Edge).Left side
Right side
Load horror demo – reloads a working example.Apply JSON & Restart – applies changes and restarts the preview.Validate JSON – checks that the JSON is valid (no syntax errors).+ Add Room – automatically adds a new room to the JSON.+ Add Event – automatically adds a new global event to the JSON.Export runtime ZIP – generates a ZIP file with a ready-to-use game.In the Terminal Preview panel (on the left) you can test your game as a player would. The basic available commands are:
help – shows the list of base commands.look – describes the current room (uses the room’s desc field).scan – shows the room’s scan text.n, s, e, w (or north/south etc.) – moves between rooms using exits.move north, move south, etc. – alternative movement syntax.whereami – shows the ID of the current room.flags – shows the current value of all global flags.clear or cls – clears the terminal screen.
Besides these, you can type local actions defined in the JSON (e.g. listen,
restore power, use terminal, etc.) when you are in the appropriate room.
The JSON in the GAME_DATA JSON box defines the entire game. The basic structure is:
{
"title": "My Horror Game",
"startRoom": "airlock",
"viewport": { ... },
"flags": { ... },
"rooms": { ... },
"events": [ ... ]
}
title – game title (shown at startup).startRoom – ID of the room where the player starts.viewport – settings for the graphic viewport.flags – global variables (game state).rooms – list of rooms (locations).events – list of global events (based on commands or timers).
Each time you modify the JSON, press
Apply JSON & Restart to see the changes in the preview.
The viewport section controls the image or tileset shown in the upper-left
part of the editor (and of the exported game).
"viewport": {
"image": "assets/viewport_idle.png",
"frameWidth": 160,
"frameHeight": 90,
"fps": 6,
"mode": "tileset"
}
image – path to the image or tileset (e.g. assets/camera1.png).frameWidth – width of a single frame if you use a horizontal tileset.frameHeight – height of a single frame.fps – animation speed (frames per second) if mode is "tileset".mode – can be:
"tileset" – the image is animated by scrolling multiple frames horizontally."still" – only the first frame is shown (static image).
Note: in the editor you can also use a locally loaded image for testing, but
in the exported game you must make sure that the path (e.g. "assets/viewport_idle.png")
matches a real file in the assets/ folder.
flags are global variables representing the state of the game world.
"flags": {
"power_online": false,
"creature_alert": 0
}
true/false, numbers, or strings.conditions and modified with flag actions.power_online controls whether the power/light is on.creature_alert measures how close the monster is.
Each room in the game is defined inside rooms. Example:
"rooms": {
"airlock": {
"name": "Outer Airlock",
"desc": "Frost covers the inner hatch.",
"scan": "Atmosphere: THIN. Movement: NONE.",
"exits": {
"north": "main_corridor"
},
"actions": {
"listen": "You hear a faint knocking sound."
},
"onEnter": [
{ "type": "log", "text": "You dock with the outpost." }
]
}
}
Main fields:
name – human-readable name of the room.desc – description shown when the player types look.scan – text shown when the player types scan.exits – connections to other rooms, for example:
"north": "main_corridor" – typing n or north moves to room main_corridor.actions – special commands available only in that room.onEnter – list of actions automatically executed when you enter the room.
When you click + Add Room, the editor:
hallway).name, desc, scan, exits, actions, onEnter.restartGameFromEditor().You can then manually customize the content of the new room directly in the JSON.
Inside a room’s actions, you can define commands that the player
can type when they are in that room. Example:
"actions": {
"listen": {
"text": "You hold your breath.",
"conditions": ["flags.power_online === false"],
"actions": [
{ "type": "log", "text": "Something moves in the dark above you." },
{ "type": "flag", "add": { "creature_alert": 1 } }
],
"onFail": [
{ "type": "warn", "text": "You hear only the hum of active systems." }
]
}
}
Field meanings:
"listen" – the command the player must type.text – main message shown when the action starts.conditions – array of conditions (strings) that must be true for the action to proceed.actions – list of actions executed if the conditions are satisfied.onFail – list of actions executed if the conditions are NOT satisfied.Global events react to:
trigger: "onCommand" – a typed command (global).trigger: "timer" – a timer (in seconds).{
"trigger": "onCommand",
"command": "scan",
"conditions": ["flags.power_online === false"],
"actions": [
{ "type": "warn", "text": "Scan is degraded. Power is offline." }
]
}
Here, each time the player types scan, if the conditions are true, this
list of extra actions is executed.
{
"trigger": "timer",
"delay": 20,
"repeat": true,
"conditions": ["flags.creature_alert >= 1"],
"actions": [
{ "type": "log", "text": "You hear something drag itself a little closer." },
{ "type": "flag", "add": { "creature_alert": 1 } }
]
}
Every 20 seconds, if the condition is true, the engine executes these actions.
If repeat is true, the timer keeps repeating.
When you click + Add Event, the editor:
onCommand or timer.onCommand, it asks which command (e.g. scan).timer, it asks for the delay in seconds.events section.Inside actions, onEnter and events, you can use objects like:
{ "type": "log", "text": "..." } – shows standard text.{ "type": "sys", "text": "..." } – system-style text.{ "type": "warn", "text": "..." } – yellow text (warning).{ "type": "err", "text": "..." } – red text (error).{ "type": "flag", "set": {...}, "add": {...}, "toggle": "flagName" } – modifies flags.{ "type": "move", "to": "room_id", "log": "..." } – moves the player to another room.{ "type": "setViewport", "image": "...", "fps": 8, ... } – changes the viewport image or animation.{ "type": "jumpscare", "image": "...", "duration": 400, "text": "..." } – shows a “jumpscare” image for a few ms, then restores the previous one.{ "type": "timer", "delay": 5, "actions": [ ... ] } – creates a local timer that runs actions after some seconds.{ "type": "end", "text": "..." } – ends the game (disables input).Conditions are strings containing small JavaScript expressions. The engine evaluates them with predefined variables:
flags – object containing all global flags.roomId – ID of the current room.room – object of the current room.state – contains currentRoomId and flags.Examples:
"conditions": [ "flags.power_online === true", "flags.creature_alert >= 2", "roomId === 'lab'" ]
If ANY of these expressions is false, the whole condition set fails. In that case,
if you define onFail, it will be executed.
If you are unsure about the JSON, click Validate JSON. Possible errors:
"...".// or /* ... */.
If the JSON is valid, you can click Apply JSON & Restart to reload the game.
When you are satisfied:
Export runtime ZIP.Derelict_Outpost_A_13.zip.index.html style.css engine.js game_data.js assets/
assets/ folder (with the same names used in viewport.image and in setViewport/jumpscare actions).index.html locally.desc, scan, log).+ Add Room.flags only for a few things (e.g. power on/off, monster near/far).look to read descriptionsflags to see if values change as expectedstartRoom points to an existing roomexits point to valid IDsTerminalLog Engine is designed to be simple but expressive: you can create small horror games, mysteries, and technical logs using only text + a graphic viewport.
Take your time to explore the JSON, duplicate rooms, change texts, and add events. Even if you are a hobby or inexperienced dev, with a bit of trial and error you will be able to build complete, publishable experiences.
If something doesn’t work, double-check the JSON, quotes, commas, and room IDs.