Skip to content

feat(camera): implement async base64 screenshot capture #70

Open
IlyaChichkov wants to merge 3 commits intodevelopfrom
feat/add-screenshot-capture
Open

feat(camera): implement async base64 screenshot capture #70
IlyaChichkov wants to merge 3 commits intodevelopfrom
feat/add-screenshot-capture

Conversation

@IlyaChichkov
Copy link
Copy Markdown
Owner

Closes #69

Description

This PR implements the requested feature to capture the live in-game screen and return it directly as a Base64 image payload, without requiring saving to disk.

The implementation required a careful architectural upgrade to bridge the asynchronous HTTP background threads with RimWorld's synchronous Unity Main Thread.

Key Changes:

  • MakeScreenshotAsync Endpoint: Captures the live game view and returns a CameraScreenshotResponseDto containing the Base64 Data URI.
  • GameThreadDispatcher: Implemented a new core persistent Unity MonoBehaviour with a thread-safe ConcurrentQueue. This allows background HTTP threads to safely await operations that must run on the main thread.
  • UI Control: Added support for cleanly hiding the RimWorld UI (HideUI) before capturing the screen buffer.
  • Dynamic Resizing: Built dynamic image resizing via temporary RenderTexture and Graphics.Blit to support custom width/height API requests.
  • Memory Safety: Implemented strict GPU memory cleanup (Object.Destroy, RenderTexture.ReleaseTemporary) inside try/finally blocks to prevent texture memory leaks.
  • Model Restructuring: Renamed CameraStreamDto and created CameraDto for better domain isolation.
  • Testing: Added new Bruno .yml test configurations for both native file and base64 screenshot endpoints.

- Created `GameThreadDispatcher.cs` as a persistent Unity `MonoBehaviour`.
- Implemented a thread-safe `ConcurrentQueue<Action>` to bridge background HTTP threads and the synchronous Unity Main Thread.
- Added `InvokeAsync` wrappers utilizing `TaskCompletionSource` so controllers can seamlessly `await` Main Thread operations (like capturing textures or interacting with UI components).
- Updated `RIMAPI_Mod` constructor to generate an invisible GameObject (`DontDestroyOnLoad`) and attach the dispatcher component during mod initialization.
…resizing

- Introduced `MakeScreenshotAsync` to capture the live game view and return it directly to the API client as a Base64 Data URI.
- Added support for cleanly hiding the RimWorld UI (`HideUI`) by yielding to `WaitForEndOfFrame` before reading the screen buffer.
- Built dynamic image resizing via temporary `RenderTexture` and `Graphics.Blit` to support custom width/height requests.
- Implemented strict GPU memory cleanup (`Object.Destroy`, `RenderTexture.ReleaseTemporary`) inside try/finally blocks to prevent texture memory leaks.
- Reorganized camera models (renamed `CameraStreamDto` and created `CameraDto`) for better domain isolation.
- Added 3 distinct Bruno (.yml) test configurations for the /api/v1/game/start endpoint:
  1. Standard Auto
  2. Hardcore Randy
  3. Exact Seed & Tile
- Converted all JSON request payload keys from PascalCase to standard REST snake_case.
@IlyaChichkov IlyaChichkov changed the base branch from master to develop April 4, 2026 15:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Add in-game screenshot capture for RimWorld

1 participant