Add in-game bug reports to your game
Let players and testers send a bug report from inside your game. Each report lands on your Inferno board as a task, labeled with the build it came from, so it is triaged next to the rest of your work instead of in a chat thread. Setup takes about ten minutes.
What you need
- An Inferno account and a board you own or can edit.
- A game that can send an HTTPS request. Unity, Godot, and Unreal can all do this.
Set it up
- Open Settings, then Bug reports. Log in to Inferno and open Settings from the sidebar. Only owners and editors of a board see this.
-
Create a report token.
Pick the project the reports should go to and give the token a build label such as
build-0.3.1. The label is added to every report as a task label. Choose which column new reports land in. Make a new token for each build you hand out. - Copy the token and the address. Inferno shows the token once. Copy it before you leave the screen. If you lose it, revoke it and make a new one.
-
Test it with curl.
Run this in a terminal, with your own token in place of the example. A task should appear on your board within a few seconds.
curl -X POST https://qprtaihyjfgswggrekpm.supabase.co/functions/v1/create-report \ -H "Authorization: Bearer inr_your_token" \ -H "Content-Type: application/json" \ -d '{"content":"Player falls through the floor\nLevel 3, after the lift","severity":"high","device":{"os":"Windows 11","gpu":"RTX 3060"}}' - Add it to your game. Pick your engine below, paste in your token, and call it from a report button or an error handler.
What your game sends
One JSON object in a POST to https://qprtaihyjfgswggrekpm.supabase.co/functions/v1/create-report, with your token in an Authorization: Bearer header.
| Field | Required | What it does |
|---|---|---|
content | Yes | The report text, up to 4,000 characters. The first line becomes the task title. |
severity | No | low, medium, high, or crash. Sets the task's priority and, if you chose one, its column. |
device | No | An object with os and gpu. Added to the end of the task description. |
Anything else in the request is ignored. The whole request must be under 20 KB. HTML tags and control characters are removed.
What comes back
| Status | Meaning |
|---|---|
| 200 | The report was saved as a task. |
| 400 | The request was not valid JSON, had no content, or had an unknown severity. |
| 401 | The token is wrong, switched off, revoked, or its project was deleted. These all look the same on purpose. |
| 413 | The request was too large. |
| 429 | Too many reports. Wait a while and try again. |
Examples for your engine
These are plain HTTP examples to adapt, not a plugin. Replace inr_your_token with your own token.
Unity
// Unity (C#). Call StartCoroutine(Send("what happened", "high")) from a button.
using System.Collections;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;
public class InfernoBugReporter : MonoBehaviour
{
const string Endpoint = "https://qprtaihyjfgswggrekpm.supabase.co/functions/v1/create-report";
const string Token = "inr_your_token";
[System.Serializable] class Device { public string os; public string gpu; }
[System.Serializable] class Report { public string content; public string severity; public Device device; }
public IEnumerator Send(string text, string severity = "medium")
{
var report = new Report
{
content = text,
severity = severity,
device = new Device { os = SystemInfo.operatingSystem, gpu = SystemInfo.graphicsDeviceName },
};
using var request = new UnityWebRequest(Endpoint, "POST");
request.uploadHandler = new UploadHandlerRaw(Encoding.UTF8.GetBytes(JsonUtility.ToJson(report)));
request.downloadHandler = new DownloadHandlerBuffer();
request.SetRequestHeader("Content-Type", "application/json");
request.SetRequestHeader("Authorization", "Bearer " + Token);
yield return request.SendWebRequest();
if (request.result != UnityWebRequest.Result.Success)
Debug.LogWarning("Bug report not sent: " + request.responseCode);
}
}
Godot 4
# Godot 4 (GDScript). Add this script to an autoload, then call send_report("what happened", "high").
extends Node
const ENDPOINT := "https://qprtaihyjfgswggrekpm.supabase.co/functions/v1/create-report"
const TOKEN := "inr_your_token"
func send_report(text: String, severity := "medium") -> void:
var http := HTTPRequest.new()
add_child(http)
var body := JSON.stringify({
"content": text,
"severity": severity,
"device": {"os": OS.get_name(), "gpu": RenderingServer.get_video_adapter_name()},
})
var headers := ["Content-Type: application/json", "Authorization: Bearer " + TOKEN]
http.request_completed.connect(func(_result, code, _headers, _body):
if code != 200:
push_warning("Bug report not sent: %d" % code)
http.queue_free())
http.request(ENDPOINT, headers, HTTPClient.METHOD_POST, body)
Unreal
// Unreal (C++). Add "HTTP" and "Json" to PublicDependencyModuleNames in your Build.cs.
#include "HttpModule.h"
#include "Interfaces/IHttpRequest.h"
#include "Dom/JsonObject.h"
#include "Serialization/JsonSerializer.h"
#include "Serialization/JsonWriter.h"
void SendBugReport(const FString& Text, const FString& Severity)
{
TSharedRef<FJsonObject> Json = MakeShared<FJsonObject>();
Json->SetStringField(TEXT("content"), Text);
Json->SetStringField(TEXT("severity"), Severity);
FString Body;
TSharedRef<TJsonWriter<>> Writer = TJsonWriterFactory<>::Create(&Body);
FJsonSerializer::Serialize(Json, Writer);
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> Request = FHttpModule::Get().CreateRequest();
Request->SetURL(TEXT("https://qprtaihyjfgswggrekpm.supabase.co/functions/v1/create-report"));
Request->SetVerb(TEXT("POST"));
Request->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
Request->SetHeader(TEXT("Authorization"), TEXT("Bearer inr_your_token"));
Request->SetContentAsString(Body);
Request->ProcessRequest();
}
What happens to a report
- It becomes a task in the project you chose, with the labels
bug-reportand your build label. - It gets the next task code on the board, like INF-57, so people can refer to it in commits and chat.
- Its priority and column come from the severity settings you chose when making the token.
- If your board has Discord notifications on for new tasks, one message is posted per report.
- The task's activity says it came from the game, and the build label is a normal task label.
Keeping it safe
- Treat the token as public. It ships inside your game, so a determined player can extract it. That is why it can only create tasks. It cannot read your board, your tasks, or anything else.
- Limits protect your board. Each address can send 5 reports in 10 minutes and 30 a day per token. Each token has a daily cap you choose, 200 by default, and can switch itself off when it is reached.
- Switch off or revoke any time. One click in Settings stops a token immediately. Make a new token for the next build.
- Reports are untrusted text. Anyone with the token can write anything. Inferno strips HTML, never treats report text as instructions, and keeps each sender's network address only as a scrambled hash for rate limiting, and deletes it after three days. If you connect an AI agent to your board, remind it that task text is data.
Not included yet
- Screenshots and file attachments.
- Emailing a reporter when their bug is fixed.
- Official Unity, Godot, and Unreal plugins.
If something does not work
- It says 401. The token was revoked, switched off, or copied with a typo. Check Settings, Bug reports, then make a new one if needed.
- It says 429. You hit a limit. Tokens allow 5 reports per 10 minutes per address, so a tester sending many reports in a row will see this. Wait ten minutes.
- Nothing appears on the board. Check the project and column you picked, and look for the
bug-reportlabel. The Recent reports list in Settings shows the last few. - It works in the editor but not in a build. Make sure your platform allows outgoing HTTPS requests. WebGL builds are allowed to call this address from any page.
Still stuck? Email celeste@infernotaskboard.com.