PK battles
Run two-host battles with a score bar, and post gift points from your backend.
A PK battle puts two hosts on a split screen, with a score bar, until a clock runs out. Voxera owns the clock, the winner and the score. Your backend owns the points.
Turn it on
Pass pkConfig. Leaving it null keeps PK off.
VoxeraLiveRoomConfig(
pkConfig: VoxeraPkConfig(
loadOpponents: () => api.liveRooms(), // raw roomName + hostName
sideAColor: const Color(0xFFFF4D6D),
sideBColor: const Color(0xFF4D7CFF),
scoreBarBuilder: (slot) => MyScoreBar(battle: slot.battle),
),
foregroundWidget: const MyGiftTray(),
);The room owner gets a PK button in the controls bar, with Challenge a room (from loadOpponents) and Random match. Each opponent's roomName is the name you pass when you connect.
If you replace controlsBarWidget, open VoxeraPkStartSheet.show yourself.
Posting points
The kit has no score API, because a client that could post points could rig the battle. Your backend charges for the gift, then posts the points:
curl -X POST https://stream.zavryn.online/api/v1/pk/BATTLE_ID/score \
-H "Content-Type: application/json" \
-H "X-App-Id: YOUR_APP_ID" \
-H "X-App-Secret: YOUR_SERVER_SECRET" \
-d '{"side": "a", "points": 100}'Send side as a or b, or send host_identity instead. A gift in a room scores that room's side.
Post each gift once. The engine doesn't de-duplicate these requests, so a retried request counts again. Record the gift id before you post.
Animate the score
Bind your fly-in animation to controller.pkController.scoreTick, which gives deltaA and deltaB. The score bar still reads battle.scoreA and battle.scoreB. The first snapshot after joining doesn't emit a tick.
Customize it
To replace one piece, pass a slot builder: scoreBarBuilder, countdownBuilder, resultBuilder, hostPaneBuilder, battleActionsBuilder or inviteDialogBuilder.
To replace the whole layout, set showBattleOverlay: false, and render each host with cameraTrackFor.