It is vital for any game to be bug free for optimal experience for the users. It is also vital for bugs discovered in the game to be reported to the developers, so that we can act on it as soon as possible and provide an update.
Keeping this in mind, I came up with the idea of having a simple bug report system for our game, Split, which is user facing, so that people who are playing can report bugs. These bugs are then categorized and assigned to developers.
It works in the following way.
Firstly when the user presses the Bug report button (Which is mapped to D-Pad on the controller), we take a screenshot. I then populate a widget using that screenshot along with a text box for the user to enter the bug details. Once the user clicks submit, I save the screenshot as PNG and the text box as a text file. To save them on the disk, the current method that i’m employing is to create separate folders for each bug report and then save the corresponding PNG and text file in them.
We are updating this to include SQL Server, where in we will save the PNG as a BLOB and the text in a table in a database. I’m also planning on creating a WPF application using C# which will basically work as a gallery for these reports for our producers to look at and assign to respective people. I am planning on improving this system by not only including screenshots, but also store video of previous 5 seconds of gameplay.
We are also planning on extending the bug reporting system into a complete telemetry system, where in we will be logging various parts of the players progress to better serve them.
How I’m doing it in unreal:
Unreal has built in tools to take a screenshot of the game. It has a screenshot and a high res screenshot functions to do this job. I am using the screenshot function in my implementation.
First I bind a function to handle the delegate.
GetWorld->GetGameViewport()->OnScreenshotCaptured().AddUObject(this, &ALevelManager::BugReportHelper);
This is the function declaration that I use.
void BugReportHelper(int32 sizeX, int32 sizeY, const TArray<FColor>& i_Bitmap);
Then we use the Request screenshot function to get the screenshot
FScreenshotRequest::RequestScreenshot(false);
After the screenshot is taken, I create a texture with the bitmap data. I was using FImageUtils::CreateTexture2D but found out that this function does not work with packaged builds for console. So below is the code I am using to create the texture.
UTexture2D* tempTexture = UTexture2D::CreateTransient(sizeX, sizeY); if (tempTexture) { tempTexture->SRGB = 0; FTexture2DMipMap& Mip = tempTexture->PlatformData->Mips[0]; void* Data = Mip.BulkData.Lock(LOCK_READ_WRITE); int32 stride = (int32)(sizeof(uint8) * 4); FMemory::Memcpy(Data, i_Bitmap.GetData(), tempTexture->PlatformData->SizeX * tempTexture->PlatformData->SizeY * stride); Mip.BulkData.Unlock(); tempTexture->UpdateResource(); }
I populate this texture on an Image that we show in the UI. I created a Widget that extends from the UUserWidget class. I use this class as a base class for the blueprint version of the widget. After the user enter the bug report and hits submit, I call a function in the widget which is then used to store the data as shown below.
FHighResScreenshotConfig& hConfig = GetHighResScreenshotConfig(); hConfig.SaveImage(imageFileName, bitMapData, FIntPoint(X, Y), &resultPath);
Where bitmap data is the data from the screenshot and X, Y are the dimensions of the screenshot. If the dimensions that are passed and the dimensions in the bitmap data are not the same, then the image will not be saved.