Samples

Copy and adaptUnity 2022.3 LTS or 6

Three things to start from: a minimal script that marks moments, spans and positions; a set of prompts to ask an AI agent about your sessions; and a CI job that builds a playtest player and pushes it. Each says what it needs and what isn't built.

1. A minimal Unity integration

The package already ships a runnable sample. In Unity, open Package Manager › Mulno Playtest › Samples and import Playtest Basics: a small 2D scene, a script and a PlaytestConfig at their defaults. The script below is the same idea cut to the calls you'll use most. Recording is compiled in only with the MULNO_PLAYTEST define, so in a normal build every call here compiles away.

Assets/Scripts/BossRoom.cs
using Mulno.Playtest;
using UnityEngine;

public class BossRoom : MonoBehaviour
{
    [SerializeField] Transform player;
    PlaytestSpan fight;                            // the default is an inert handle

    void Awake()
    {
        // State is kept until a session starts, then written at its start.
        Playtest.SetMeta("difficulty", "hard");
        Playtest.Track(player, "player");          // positions at 10 Hz
    }

    public void OnBossSpawned()
    {
        Playtest.Mark("castle/boss_spawned", new { hp = 500, phase = 1 });
        // Spans and markers made while nothing records are dropped.
        if (Playtest.IsRecording)
            fight = Playtest.BeginSpan("castle/boss_room", new { attempt = 2 });
    }

    public void OnBossDefeated() => fight.End(success: true, data: new { seconds = 41.5 });
    public void OnPlayerDied()    => fight.End(success: false);
}
  • Keys are plain strings such as castle/boss_room, always the first argument, so the Playtest Catalog's scanner can find them.
  • A session may not exist yet when Awake runs, because the consent screen can wait for the tester. Meta and tracked targets are kept and written when it starts; markers and spans made before it are dropped, not buffered.
  • To try it: Project Settings › Mulno Playtest, create the config, then Tools › Mulno Playtest › Build Playtest Player (Windows x64) and run it. Record your first playtest has the steps.

2. Prompts to ask Claude about your sessions

These assume the plugin is loaded (Connect Claude over MCP) and your sessions are in Studio's library. Say which build or campaign you mean; the tools are scoped by it. The three that write need MULNO_MCP_WRITE=1.

AskTypically uses
“List my most recent sessions, and say which have flags or bug reports.”list_sessions, get_events
“Find moments where players got stuck in the latest session.”the friction-finder skill
“Write a playtest report on the sessions for build 0.4.2, with a link and a timestamp for every finding.”the playtest-report skill
“List every blocking bug report from this campaign, oldest first.”get_events with the bug filters
“Which testers spent longest in castle/boss_room, and how many ran past the Catalog's expected time?”across_sessions
“Search every session for boss_ro and show me the moment.”search, get_moment
“What was the tester saying around 03:12 in this session?”get_transcript (after you've transcribed it)
“Show me the frame at 192.4 seconds.”get_frames
“Pin your three most serious friction findings onto the timeline as notes.” (writes)add_note
“Fix the note at mulno://session/<session-id>?t=192.400 and commit.” (writes)the apply-notes skill
“Reply to that note and set it to in progress.” (writes)reply, set_note_status

The remote MCP knows fewer tools

Everything above is for the local mulno mcp. The remote server at mcp.mulno.com has nine tools and no frames, events or get_moment yet: MCP tools.

3. A CI job that pushes a build

There is no CI token yet

The api's build routes accept a signed-in person's session cookie. MULNO_API_SESSION is that cookie's raw value, copied out of a browser: a stand-in that works for a person, not a credential a build pipeline should hold. A workspace-scoped token for CI is not built. The job also needs a workspace and a project, which you make on app.mulno.com. Until there is a CI token, the safe part of this job is the build step and a --dry-run; pushing for real from a build machine means putting a person's session in its secrets.

This GitHub Actions job runs on a self-hosted Windows machine that already has Unity and Studio (which brings mulno.exe) installed. It builds a playtest player in batch mode, then pushes it to the qa branch. The secret is the cookie value above.

.github/workflows/playtest-build.yml
name: playtest-build
on:
  push:
    branches: [qa]

jobs:
  push:
    runs-on: [self-hosted, windows]
    env:
      UNITY_EXE: C:\Program Files\Unity\Hub\Editor\6000.3.12f1\Editor\Unity.exe
      MULNO_EXE: C:\tools\mulno\mulno.exe        # Studio's install folder has one
    steps:
      - uses: actions/checkout@v4
        with: { fetch-depth: 0 }                 # --since reads git history

      - name: Build the playtest player
        shell: pwsh
        run: |
          & $env:UNITY_EXE -batchmode -quit -projectPath . -logFile build.log `
            -executeMethod Mulno.Playtest.Editor.PlaytestBuilder.BuildFromCommandLine `
            -mulno-build Build/Playtest/Game.exe

      - name: Dry run
        shell: pwsh
        run: |
          & $env:MULNO_EXE build push Build/Playtest --project prj_XXXXXXXX --dry-run --json

      - name: Push to qa
        shell: pwsh
        env:
          MULNO_API_SESSION: ${{ secrets.MULNO_API_SESSION }}   # a copied cookie, not a CI token
        run: |
          & $env:MULNO_EXE build push Build/Playtest --project prj_XXXXXXXX `
            --api https://app.mulno.com --workspace ws_XXXXXXXX --branch qa `
            --version "${{ github.run_number }}" --build-number ${{ github.run_number }} `
            --platform windows-x64 --json
  • The batch build is the package's own (PlaytestBuilder.BuildFromCommandLine). Add -mulno-use-profile on Unity 6 to build with the Playtest build profile.
  • The dry run needs nothing else, and is safe to keep in a pipeline. The last step needs an admin's cookie for --branch, and fails without an account.
  • To push straight into your own R2 builds bucket instead, replace --api and --workspace with --endpoint, --bucket and --region auto, and put MULNO_S3_ACCESS_KEY_ID and MULNO_S3_SECRET_ACCESS_KEY in secrets. The build is then uploaded, but not registered, so it can't be put on a branch.
  • Never print the cookie or the bucket key in a log. Rotate them if a fork's pull request could read the secret.