playbit / docs

Playbit apps

Playbit programs are wasm modules with an optional extra pbapp section describing the app and its embedded resources.

pbapp.toml

pbapp.toml describes your app and may list resources to be included in the app.

Example of myapp/pbapp.toml & myapp/myapp.c:

# myapp/pbapp.toml
app_name = "My App"
app_id = "my-identifier.my-app"

[resources]
app_icon = "icon.png"
names_db = "family_names.txt"
// myapp/myapp.c
void main(void) {
    print("app name: \"%.*s\"", PBStr_FMT_ARG(PBAppName()));
    print("app ID:   \"%.*s\"", PBStr_FMT_ARG(PBAppId()));

    PBAppResource db = PBAppResourceWithName(PBStrLit("named_db"));
    print("names db: %p (%zu bytes)", db.data.v, db.data.len);
}

Create dummy resources:

$ printf '\211PNG\r\n\032\n' > icon.png
$ truncate -s 123 family_names.txt

Build & run it via the Playbit.app GUI or pb run myapp:

Each "resource" listed in the [resources] section will be embedded as read-only data into the program's memory and becomes available at runtime via PBAppResource in the C library.

Binary format

typedef struct PBBundleResource {
    u32 flags;
    u32 nameLen;
    u64 size;
    u64 addr;
    // u8 name[nameLen]
} PBBundleResource;

typedef struct PBBundleManifest {
    u32 version;
    u32 flags;
    u32 appNameLen;
    u32 appIdLen;
    u32 resourceCount;
    // u8 appName[appNameLen]
    // u8 appId[appIdLen]
    // u8 padding[...] // align each PBBundleResource to 8 bytes
    // PBBundleResource resource[resourceCount]
} PBBundleManifest;

extern const uint8_t  __pbbundle_manifest[]; // 8-byte aligned
extern const uint32_t __pbbundle_manifest_size;

Each PBBundleResource entry starts at the next 8-byte boundary after the app id. This means there may be zero padding bytes after the app id and after each resource name. The normalized manifest size is padded to a 16-byte boundary.

Each PBBundleResource.addr points into the resource payload bytes stored after the manifest within the same exported wasm data blob. Each resource payload starts at a 16-byte boundary, so there may be zero padding bytes before each payload.