Skip to content
| Marketplace
Sign in
Visual Studio Code>Programming Languages>Pika StudioNew to Visual Studio Code? Get it now.
Pika Studio

Pika Studio

Phạm Văn Toán

|
114 installs
| (0) | Free
Run and debug Pika Lua game packs in the native simulator directly from VS Code.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Pika Studio

Run and debug Pika Lua game packs in the native simulator directly from VS Code.

Features

  • Explorer — browse all packs under SD/games in the Pika Activity Bar view
  • Configuration — set what the host passes into game_start(params): server params (level, difficulty, …), language, and is_a2a
  • Run / Stop — launch the native simulator with one click or from the command palette
  • Debug — set breakpoints in Lua files and step through code with the built-in Pika Lua debugger
  • Manifest form editor — visual editor for manifest.json (open via the gear icon in the editor title bar)
  • Output console — simulator stdout/stderr streamed to the "Pika Engine" Output channel
  • Robot view — a 3D Pika driven by the game's servo / LED commands with back's timing rules, showing the live LCD; its buttons (or the keyboard) drive the game
  • Robot ↔ backend log — a chat column beside the robot view: every request the robot sends (device API, game voice WebSocket, telemetry, media downloads) and every reply, with status and body; rows that never went on the wire (dry-run, mock, journey file) are dashed
  • SDK — docs, examples and Lua libraries from the Pika SDK repo (pika.sdk.source), with an asset library and New Game from Example
  • To-do journey — launch a pack as back's to-do journey would (pika.todo.*): map or reward phase, journey from the server or a file, POSTs dry-run or real

Requirements

  • Windows x64 (the bundled simulator pika_studio.exe is a Windows native binary)
  • A workspace containing a SD/games folder, or open SD/games directly

Quick Start

  1. Install the extension (.vsix) via Extensions → ... → Install from VSIX
  2. Open the Pika firmware repo (or the SD/games folder) in VS Code
  3. Click the Pika icon in the Activity Bar
  4. Right-click a game pack → Run, or press the ▶ button

Commands

Every command is in the Command Palette under the Pika: prefix (run, stop, debug, export to SD, robot view, SDK browsing, A2A toggle, …); the common ones also sit on the Explorer's title bar and context menu.

Extension Settings

Setting Default Description
pika.startParams {} Server start params for game_start(params) — free-form, server-defined (128 B / 32 nodes, shared with game_id)
pika.language "vi" params.language, the robot's UI language — one of the 10 language_t codes
pika.simulateTalkFlow false params.is_a2a — launch as an A2A talk flow
pika.rankMode "real" Where Ranking.get_result() data comes from — real (full robot behaviour, writes a live score row), fetch (real board, no upload), mock (no HTTP, always nil)
pika.sdk.source https://github.com/toanpv-tech/pika-sdk.git Pika SDK source (local folder or git URL): assets, docs, libraries, examples
pika.voiceMode "off" Voice source: off (voice disabled), asr (text inject from the ASR server), real (live /ws/v3/game_command)
pika.voiceServer "" External voice ASR server (host:port, used in asr mode)
pika.gameVoice.* "" Device credentials (robot id, session or master key, backend host) for real voice, ranking and journey calls
pika.robotView "window" Robot view on Run: window (floating window), tab (editor tab), off
pika.robotGlassReflection false Room reflection on the robot's glass face
pika.todo.* enabled: false, phase: "auto", journey: "fetch", journeyFile: "", postMode: "dryrun" To-do journey launch: on/off, map or reward phase, journey source, and whether reward/result POSTs are sent

game_start(params) — where each field comes from

The Configuration section mirrors how the robot assembles that table, and keeps the two sources apart because confusing them is the common mistake:

Field Source on the robot Control
language Host-side (game_get_language), the robot's current UI language. Dropdown — the robot's full language_t enum (kLangIso[]), 10 codes. Out of range → vi.
is_a2a Host-side, true when launched inside an A2A talk flow. Dropdown — true / false.
level, difficulty, … The backend's GAME_START data object, forwarded verbatim. Add-a-row, name is a combobox with presets.

Those two host fields are the only ones the firmware defines by name, which is why only they get a closed list. They are attached after the server object is decoded, so a server field of the same name cannot override them.

Everything else is server-defined: back stashes the whole data object without inspecting it, precisely so a new server field needs no firmware change. The presets (difficulty → easy/medium/hard, level, game_type, hero_label) are conventions drawn from packs and docs, not a contract — so the name field stays typeable and any new server field remains testable here.

Only an A2A launch carries server params. A menu launch sends GameStartMsg_st, which holds nothing but game_id. Setting params with is_a2a off therefore describes a launch the robot cannot perform, and the section warns when you do.

The 128-byte budget includes game_id

conversation.cpp serializes the whole data object into the char[128] params_json field, and game_id is part of that object — so the pack name eats into the same budget (and costs one of the 32 nodes). The meter accounts for it: the Configuration section sizes against the longest installed pack name, and the runner sizes against the pack actually being launched.

This matters because the overflow is silent on the device: back logs a warning but strncpys anyway, the clipped JSON no longer parses, and the game receives an empty table — indistinguishable in-game from "the server sent nothing". Studio therefore refuses to save an over-budget payload and drops it rather than truncating at launch.

Ranking on PC (pika.rankMode)

On the robot, back closes the ranking loop by itself: Ranking.report() arrives as IPC_CMD_GAME_RESULT, back POSTs /games/result, then GETs /games/rank, unwraps data, and sends it down as IPC_CMD_GAME_RANK_RESULT. Head latches that reply and Ranking.get_result() consumes it once.

The simulator runs no back, so nothing closes that loop on its own and Ranking.get_result() would return nil forever — which looks exactly like a broken pack. pika.rankMode decides how it gets closed:

Mode Ranking.report() Ranking.get_result()
real (default) POSTs a real score row real GET /games/rank
fetch logged only, not uploaded real GET /games/rank
mock logged only always nil

The default is real so the PC behaves like the robot without being configured into it — a leaderboard branch that works here works there.

It writes to the live board. Every Ranking.report() in real mode appends a score row children will see. When you are iterating on a pack and don't want that trail, switch to fetch: same real board data, no upload. mock needs no credentials at all and is the offline fallback.

fetch and real need pika.gameVoice.* credentials; without them the sim falls back to mock and says so in the log.

Both real modes reuse the pika.gameVoice.* credentials (robot id + session or master key) and send the same robot-id / challenge / request-token headers back sends. They are independent of pika.voiceMode: fetching a leaderboard does not turn on the microphone.

The POST body is built field-for-field against Application::PostGameResult (robot_id, game_id, version, entry, ended_reason, score, duration), and both calls carry firmware_version in the query like every other device API call back makes. Both modes were verified end-to-end against the live backend: fetch returns the real board, and real gets {"recorded":true} back with the board updating in the same run.

Two behaviours worth knowing before reading a real-mode result: the backend keeps only your best score, so posting below your current best changes nothing visible even though the row was written; and duration is 0 unless the pack actually ran that long, since the engine computes it from VM start.

Debug

Add a launch.json configuration:

{
  "type": "pika-lua",
  "request": "launch",
  "name": "Pika: Debug Game",
  "gameId": "${command:pika.pickGame}"
}

Or press F5 — Pika Studio will prompt you to pick a game pack.

Icons

File Role
media/icon-source.svg Vector master: the pika18 simulator logomark on a light rounded tile. Edit this one.
media/icon.png Marketplace icon, 512×512, rendered from the master.
media/icon.svg Activity-bar icon: the same logomark filled with currentColor. VS Code renders it as a monochrome mask, so colour and gradients there are discarded.

The Extensions view shows the icon of the installed .vsix, but the extension details page takes it from the Marketplace listing once the extension is published there: a new icon shows on that page only after vsce publish.

icon.png is a build product: after changing icon-source.svg, re-render it or the shipped icon silently keeps the old art.

npx sharp-cli -i media/icon-source.svg -o media/icon.png resize 512 512

License

MIT

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft