ForgeCraftPLUGIN WIKISDocumentationSupport ↗
Web console

ForgeGuard player-enabled screen capture

ForgeGuard · 0.6.0-alpha.2

Integrated screenshots

The modern plugin and Netlify application now implement player-enabled still screenshots. A server cannot obtain pixels from an ordinary Minecraft client by itself. The player opens a private invitation, explicitly enables sharing, and chooses their Minecraft application window in the browser's permission chooser. Once enabled, staff can request individual screenshots without asking the player again for each image. The sharing page and browser indicator remain visible; this is not covert capture.

Staff and player workflow

  1. Install the updated modern ForgeGuard JAR and deploy the full updated Netlify application with Functions and persistent Blobs. Pair the server normally. Use HTTPS in production; explicit loopback HTTP is for local development only.
  2. Keep web.allow-moderation enabled. In the website's online player panel, open Screen capture and send an invitation. Alternatively use /fg menu, select an online player, then Invite screen sharing. The in-game action requires both forgeguard.staff and forgeguard.recordings.
  3. The player receives a private, disclosed link in Minecraft. It expires after five minutes and can be claimed only once. The player does not need a website staff account. They read the explanation, check consent, click enable, and select their Minecraft window. Entire-monitor and browser-tab selections are rejected. No microphone, game audio or desktop fallback is requested.
  4. While sharing is active, staff can request a screenshot from either the website or in-game player GUI. View the received image in the website's Screen capture tab. A pending or failed request never displays a fabricated image.
  5. The player can stop with the page button or browser sharing control. Staff can also revoke the session. Stopping, closing the sharing page, loss of heartbeat, a changed Minecraft player session, changed server link, or expiry ends access. Start again with a fresh invitation.

The browser must support getDisplayMedia, secure contexts and application-window sharing. Keep the sharing page connected and the game window available. Browser suspension, a minimized game, protected graphics surfaces, or incompatible clients may prevent a usable screenshot. This feature has no client mod requirement, but browser/OS support is separate from Minecraft server-version support. The portable legacy loader does not implement these new capture controls; see Version support.

Bounds and evidence quality

  • Sharing lasts at most 30 minutes from claiming the invitation. A recorder heartbeat older than ten seconds requires a new invitation; server/player status must also be fresh.
  • One screenshot request can be pending per player, with a 30-second deadline and at least five seconds between requests.
  • Images are non-interlaced RGB/RGBA PNG, at most 1280 by 720 pixels and 768 KiB decoded file size. The browser may scale further to meet its conservative upload bound. The backend validates PNG structure, CRCs and bounded decompression, and strips ancillary metadata.
  • Only the latest image is retained. It becomes unavailable after 15 minutes or session expiry, whichever comes first. A new request, replacement invitation, or stop clears it earlier. Reads enforce expiry immediately; a scheduled cleanup removes expired persisted image data. Cleanup runs every five minutes on published Netlify deployments, with bounded batches; local development uses a timer.
  • Web owners, admins and moderators have capture.view and capture.request; viewers do not. Staff operations require workspace membership, the appropriate role and CSRF protection. Requests, received images, views and stops are audited. Client recorder tokens have no staff powers and are held only in page memory; persisted capture authorization uses token hashes. The private invitation necessarily travels in the authenticated plugin relay payload until its short retention ends.
  • Screenshots are client-supplied evidence. A browser cannot prove the selected application is Minecraft, nor prove an image is untampered or includes hidden cheat overlays. Refusing or failing capture is not proof of cheating and does not trigger an automatic ban. A received image time is the service's receipt time, not a trusted client timestamp.

This release does not implement video recording, rolling clips, an installed native companion, or screen images inside Minecraft's inventory GUI. The in-game buttons invite and request; the website displays screenshots. Automated tests use synthetic pixels and browser API doubles, which do not qualify the native permission chooser or actual game-window capture. The separate OBS proof below validates only that local recorder configuration.

API contract

Staff session/CSRF endpoints under /api/capture/servers/{serverId}/players/{playerId}:

Method and suffix Purpose
GET (no suffix) Session state and pending request status
POST /invite with {} Queue a private invitation through the linked plugin; returns an operationId for normal relay polling
POST /request with {reason} Queue a screenshot only while player sharing is active
GET /image Private latest PNG as JSON pngBase64, dimensions, request ID and receipt/expiry times
POST /stop with {} Revoke the session and erase its pending request/image

The player page claims the fragment token with POST /api/capture/claim {token}, then uses the returned scoped bearer for POST /recorder/activate {consent:true,source:"window"}, GET /recorder, POST /recorder/frame {requestId,pngBase64}, POST /recorder/fail {requestId,reason}, and POST /recorder/stop {}. All recorder paths share the /api/capture prefix. The fragment is erased immediately and never sent in a page URL request; do not copy invitation or recorder credentials to analytics or logs.

The plugin authenticates POST /api/capture/device/invite {playerId,playerSessionId,actorId} and /device/request {playerId,playerSessionId,actorId,reason} with its existing device credential. Responses bind siteOrigin and deviceId. The plugin validates the staff permission and current player session before delivering or requesting. The server heartbeat supplies playerSessionId, which rotates each join. The private relay operation players/{uuid}/screen-capture/invite is issued only by the capture function and is deliberately absent from the general browser control-route allowlist.

Tested OBS window capture

On 24 September 2026, OBS 31.0.3 with Windows Graphics Capture successfully recorded the local Lunar Minecraft client. Sampled frames showed the actual world, camera switches, mobs and inventory moves. This validates that local capture setup; it is not a qualification of other clients, versions or PCs.

Reproduce the tested configuration in OBS:

  1. Use the dedicated scene ForgeGuard Minecraft capture with the Window Capture source ForgeGuard - Minecraft only.
  2. Select the exact Lunar game-window title. Set capture method to Windows 10 (1903 and up), which uses Windows Graphics Capture, and set window-match priority to Window title must match. Do not add Display Capture or a desktop fallback.
  3. Enable client-area capture. Leave the source's Capture Audio unchecked and mute both Desktop Audio and Mic/Aux in OBS.
  4. Confirm that the OBS preview follows visible movement and inventory changes in the game, then start and stop recording explicitly. Review the saved clip for the intended actions.

The tested raw file is D:\NEW VIDEOS\2026-09-24 18-13-37.mkv: 116.491 seconds, 1920×1080, 120 fps. The reviewed local export is 65 seconds, 1280×720, 30 fps, H.264/yuv420p, with no audio stream (7,571,266 bytes). FFprobe independently confirmed those export properties; visual checks establish that sampled footage is current gameplay. The file is a local artifact, not a hosted download.

OBS is installed at C:\Program Files\obs-studio\bin\64bit\obs64.exe. The PowerShell helper below does not configure OBS or use this tested capture backend.

Experimental GDI fallback

scripts/record-minecraft-window.ps1 is a bounded experimental GDI fallback, not a qualified Minecraft gameplay recorder. A local GDI test captured stale Lunar menu frames while Minecraft was actively displaying gameplay. A valid MP4 does not mean the pixels are current; use the tested OBS Windows Graphics Capture setup above for this workstation.

For GDI capture diagnostics, run the helper on the Windows PC displaying Minecraft. Open the game and arrange the scene before starting; the helper does not launch, focus, or control Minecraft.

From the ForgeGuard project directory:

.\scripts\record-minecraft-window.ps1 -WindowTitle 'Lunar Client 1.21.11 (v2.22.39-2638)' -DurationSeconds 30

Use the current exact title. To inspect game-process titles:

Get-Process java,javaw,Minecraft.Windows,Minecraft -ErrorAction SilentlyContinue |
    Select-Object Id,MainWindowTitle

Omitting -WindowTitle works only when exactly one supported Minecraft/Lunar game window is open. Browser windows, launchers, duplicate titles, and desktop capture are refused. Keep the selected game window visible throughout the capture. Window resizing, closing or minimizing during capture has not been qualified; review the resulting video.

Install FFmpeg and FFprobe, then provide the paths to your own installation:

.\scripts\record-minecraft-window.ps1 -WindowTitle 'Minecraft 1.21.11' -FfmpegPath 'C:\Tools\ffmpeg\bin\ffmpeg.exe' -DurationSeconds 15

The helper defaults to 30 seconds and accepts 5–120 seconds. It uses the exact window title with FFmpeg's gdigrab, 30 fps, H.264, CRF 16, yuv420p, and fast-start MP4. Odd window dimensions receive an edge pad for H.264 compatibility. There is no audio, desktop fallback, upload, or persistent recording service. A wall-clock timeout stops the helper's recorder if FFmpeg stalls.

Unique timestamped clips go to captures/client-screen/; existing clips are never overwritten. FFprobe checks the format and duration before a clip receives its -unreviewed.mp4 filename. Failed or interrupted captures retain .partial.mp4 when present, with diagnostics in the matching .log. Play the entire clip and compare it with the intended actions to detect stale menus, frozen frames or missing gameplay. These are local diagnostics, not public website assets or verified evidence; review them before sharing.

What this proves

An earlier DungeonForge artifact contains real Lunar 1.21.11 imagery at 1280×720 and 30 fps, but that historical result does not establish that GDI is currently capturing the live OpenGL surface. The newer stale-menu result prevents claiming the GDI backend works reliably. The helper has been syntax checked; it has not itself recorded a new qualification clip. The reviewed export above came from OBS Windows Graphics Capture instead.

A server JAR cannot obtain the actual screen of an ordinary remote Minecraft client. ForgeGuard's server-side gameplay replays reconstruct recorded positions and nearby blocks; they are not screen video. The integrated player-enabled browser flow above now transfers screenshots to the dashboard. Neither this local helper nor the OBS proof implements client-to-dashboard video recording, automatic clip upload, or universal client/server-version support.

Search all plugin wikis.