.bk.scene and .bk.component format
MessagePack package envelope, document graph, validation, dependencies and safe import/export.
Encoding and extension
.bk.scene and .bk.component files are binary MessagePack, served as application/x-msgpack; they are not JSON despite their object-shaped logical model. Version 2 packages include the root document plus every reusable component dependency reachable from it.
type OverlayPackageV2 = {
format: 'bk.scene' | 'bk.component';
version: 2;
exportedAt: string; // ISO-8601
rootDocumentGuid: string; // sourceGuid of the root
documents: PackageDocumentRecord[];
};
type PackageDocumentRecord = {
sourceGuid: string;
document: {
kind: 'scene' | 'component';
name: string;
widthPx?: number;
heightPx?: number;
sortOrder?: number;
isDefault: false;
publicProperties: Record<string, unknown>;
};
nodes: OverlayNode[];
};Node model
A node has a unique guid, optional parentNodeGuid, nodeType (leaf or component_instance), optional built-in componentKind, optional sourceDocumentGuid, transform/layout fields, appearance fields, data bindings, media configuration and a free-form props object for component-specific settings.
Common transform fields are posX, posY, widthPx, heightPx, rotationDeg, scaleX, scaleY, originX, originY, opacity, zIndex, isVisible and isLocked. See Overlay editor for built-in kinds and inspector settings.
Dependency rules
rootDocumentGuidmust resolve to one record.- The root kind must match the file extension/format.
- Every non-root document must be a reusable
component. sourceGuidvalues are unique.- A v2
sourceDocumentGuidreference must resolve inside the package. - Component dependency cycles are rejected.
- Node GUIDs are unique within a document.
- Parent references must exist in the same document; self-parenting and hierarchy cycles are rejected.
- Width and height, when supplied, must be finite and greater than zero.
publicPropertiesmust be a plain object.
During import, source document and node GUIDs are remapped to new records so packages can coexist. Names/slugs are de-duplicated. A scene cannot be imported as a reusable dependency.
Legacy v1
The importer accepts a legacy v1/single-document shape with optional format, optional version: 1, document, and nodes. It lacks dependency packaging; unresolved reusable references may therefore be skipped. New tools should emit v2 only.
Decode example
import { decode } from '@msgpack/msgpack';
import { readFile } from 'node:fs/promises';
const bytes = await readFile('gameplay.bk.scene');
const pkg = decode(bytes);
if (pkg.version !== 2 || pkg.format !== 'bk.scene') {
throw new Error('Unsupported BeatKhana scene package');
}
console.log(pkg.documents.length, pkg.rootDocumentGuid);Do not edit binary packages with a text editor. Decode, validate, modify, re-encode, then test in a disposable overlay before importing into production.