capture:read()
Compatibility
Supported languages: C, C++, C#, Python, JavaScript, Lua 5.4, Luau, Java, PHP and HTML/inline JavaScript (binding spellings and return shapes differ).
Native devices and microphone input require Windows. Game-output recording and the mixer can run headlessly. Other operating systems do not supply the Windows native device backend.
The signature below is the shared reference notation; language examples show the actual binding syntax. Question marks mark optional arguments and explicit defaults are shown where recorded. Do not copy reference notation as a typed declaration.
See Feature status and compatibility for API 1.0/1.1 and per-method restrictions. Engine release tags and Docs v0.1 are independent versions.
Signature
capture:read()
Setup and usage
Available in every supported gameplay language. Create an Object Component script in scripts/, attach it to an enabled scene object, and press Play. Start capture in Start or another callback. Native SDKs use their own member syntax; Lua uses colons. Microphone input requires Windows and OS microphone access. Recording captures audio, not video.
Parameters
This call has no arguments.
Return and timing
Returns {samples, sampleRate, channels, active, droppedSamples}. Consumes at most 4,096 interleaved float samples while preserving complete channel frames. An empty samples table means no queued data is available. Recordings can be read after stop; a hot mic supplies only live queued input. droppedSamples reports input discarded since the preceding read.
Language examples
Choose one snippet at a time and place it inside your language's Start/on_start callback. These are independent examples; each creates its own handles or builders. Follow Gameplay language bindings for imports and callback registration. Python must import the modules used in its snippet from rustic; C# uses using static Rustic; Java examples belong inside a Rustic subclass; PHP callbacks declare global $rustic. HTML snippets go inside an inline script in a ui/ HTML asset.
Use an anchored Part for transform and effect examples, an unanchored collidable Part for forces, and a perspective camera named Camera for camera examples. Create Target for follow examples. Audio examples require assets/music.ogg in the Play snapshot. Replace scene paths with those listed by Game.scene.List(). Animation playback and sequence-animation examples require the Reveal fixture on the Animation page; marker callbacks also require its Halfway marker. Run clock controls separately; a paused clock cannot advance a timer.
C callback examples use these file-scope functions before on_start:
static void on_done(void) { rustic.log("info", "done"); }
static void on_sample(RusticValue value) { (void)value; rustic.log("info", "sample received"); }
static void on_event(const RusticValue *args, size_t count) {
(void)args; (void)count; rustic.log("info", "event received");
}Run inside Start or another callback. Retain the handle across callbacks to record a longer session. Hot microphone input requires Windows; capture samples are interleaved PCM. Native SDKs show their equivalent method syntax. Lua also retains the rustic.game and handle-specific stop aliases. See APIs in every language for setup and platform limits.
Lua 5.4
local capture = Game.startRecording()
local packet = capture:read()JavaScript
const capture = Game.startRecording();
const packet = capture.read();Python
capture = Game.startRecording()
packet = capture.read()C++
auto capture = Game.startRecording();
auto packet = capture.read();C#
var capture = Game.startRecording();
var packet = capture.read();Luau
local capture = Game.startRecording()
local packet = capture:read()C
RusticCaptureHandle capture = Game.startRecording(NULL, NULL);
RusticCaptureData packet = Capture.read(capture);Java
var capture = Game.startRecording();
var packet = capture.read();PHP
global $Game;
$capture = $Game->startRecording();
$packet = $capture->read();HTML / inline JS
const capture = Game.startRecording();
const packet = capture.read();Complete Lua lifecycle example
local capture
return {
Start = function() capture = rustic.game:startRecording() end,
OnStop = function()
capture:stopRecording()
repeat
local packet = capture:read()
print(packet.sampleRate, packet.channels, #packet.samples)
until #packet.samples == 0
capture:unload()
end
}Capture limits and troubleshooting
- Capture handles belong to their script. Destroying the owner, ending Play or successful reload closes devices, finalizes files and releases handles. Read retained data in OnStop before cleanup.
- Each script may retain at most four capture handles; call
:unload()after use. Recordings retain at most 64 MiB of PCM, including recordings written to files (about 175 seconds of stereo game audio). Exceeding the limit stops capture and read/stop report an error. - Hot mic queues at most two seconds of input. Read regularly, using multiple reads if needed.
droppedSamplesreports lost input. Microphone samples are finite floats in[-1, 1]; channel count and rate come from the device. - Default F32, I16 and U16 microphone formats are supported. Missing devices, denied access, unsupported formats, startup timeouts and disconnection raise errors. Catch expected failures with
pcall. - A recording destination must be a new
.wavfile in an existing writable directory. Game mixer recording also works headlessly.
See the recording and hot mic guide for full setup and examples.