吉里吉里Z 上の Elements ベース汎用ダイアログ/画面 UI (cycfi/elements + elements_modal) の作り方リファレンス。TJS で JSON / Dictionary 定義のダイアログを作る・出す・イベントを受ける・複数画面フロー(navigator)や常駐メニューを組む・入力/フォーカス/モーダルを制御する・Agent で動作検証する、といった場面で使う。基本的なダイアログ画面の作り方(最小例・レイアウト JSON スキーマ・ウィジェット一覧)から、モーダル/非モーダル/独立ウィンドウ/常駐フロー、複数インスタンス/z-order、DrawDevice 登録タイミング等のハマりどころまで網羅。Win32 ネイティブの WIN32Dialog(win32dialog プラグイン)とは別物。TJS2 言語仕様は skill `tjs2`、本体クラス API は `krkrz`、REPL/Agent 駆動は `krkrz-repl` を参照。
krkrz-repl
吉里吉里Z (krkrz) の SDL3 / WINVER ビルドを REPL 経由でエージェントから駆動するためのリファレンス。krkrz を起動して TJS スクリプトを評価・検証・デバッグする、startup.tjs を介さず明示的に処理を開始する、入力イベント (キー/マウス) を注入する、画面をキャプチャして目視確認する、Elements ダイアログを観測・操作する、例外やダイアログ表示をコンソールで観測する、コアデモ全シーンを自動巡回してキャプチャで表示確認する (-demotest / -demotestcap)、といった場面で使う。**外部エージェントは console(CONIN$) に打てないので -replfile ファイルチャネルが本命**。起動フラグ (-repl / -replfile / -nostartup / -loglevel / -display / -ignoremouse)、ファイルチャネルのプロトコル、Agent API (入力注入 / captureScreen / dialogs / dialogClick)、ドットコマンド (.cap/.dlg/.click/.mem 等)、REPL 駆動時の挙動変更 (例外で即終了しない / inform と例外ダイアログがコンソールに出る) を網羅。TJS2 言語仕様そのものは skill `tjs2`、本体クラス API は skill `krkrz` を参照。
インストール方法を見る含まれるファイル(1)
- SKILL.md29.0 KB
SKILL.md(原文)
インストールする前に、エージェントに与えられる指示の中身を確認できます。
パスの基点: 本文の相対パスは engine ルート基準 (krkrz_dev では
src/core/を前置。下記参照)。作業ディレクトリが krkrz_dev 以外 (krkrz_android / krkrz_ios などの外枠や案件フォルダ) のときは${KRKRZ_BASE}/krkrz_dev/を前置して読む (echo $KRKRZ_BASEで実パスを確認。マシンごとに値が違うので絶対パスは書き込まない)。
krkrz REPL 駆動リファレンス
krkrz SDL3 ビルドには対話型 TJS シェル (REPL) が組み込まれている
(engine の common/utils/REPL.cpp)。エージェントが krkrz を立ち上げて
スクリプトを評価・検証するための仕組み。
リポジトリ構成による読み替え (最初に確認)
このスキルは engine repo (krkrz.git / krkrz_develop.git) を対象にするが、 チェックアウト形態が 2 通りあり、engine ソースのパス表記だけが異なる。 REPL / Agent のプロトコルや TJS 側の使い方は同一。
| 形態 | engine ルート | 例: REPL 実装 | data 既定 | ビルド |
|---|---|---|---|---|
engine 単独 (krkrz 等) | リポ直下 | common/utils/REPL.cpp | data/ | cmake --preset x64-windows |
umbrella (krkrz_dev) | src/core/ | src/core/common/utils/REPL.cpp | src/core/data/ | make(プリセットは src/core/CMakePresets.json) |
以降の本文は engine ルート相対 (common/..., sdl3/..., doc/...) で書く。
umbrella で作業しているなら src/core/ を前置して読む。
REPL 本体 + -replfile チャネルは全デスクトップ変種で有効 (KRKRZ_REPL
は KRKRZ_DESKTOP 既定。WIN32 = ON なので WINVER (x64-windows-win) でも
TJS eval / 状態確認が -replfile でできる)。REPL/実行キュー/ファイルチャネルは
common/ にあり SDL 非依存。Agent API・captureScreen も WINVER 対応済
(2026-07-31):
- Agent API は
common/environ/AgentControlIntf.cppに共通化済。入力注入だけAgentInputseam (generic/environ/AgentInput.cpp= SendMouseMessage/SendMessage、win32/environ/AgentInput.cpp= OnMouse*/OnKey*) でプラットフォーム分離。SDL3 / WINVER 両方でAgent.click/keyPress/dialogs/dialogClick/textが動く。 - screencapture も
BasicDrawDevice::FulfillScreenCapture[FromBackBuffer]実装済で WINVER でSystem.captureScreen/Agent.captureScreenが overlay 込み PNG を保存できる。
したがって WINVER でも SDL3 と同様に GUI 検証 (入力注入 + captureScreen 目視) が可能。
SDL3 専用として残るのは起動時 UserConfig UI (-userconf、ゲーム窓生成前の独立 OS
ウィンドウが必須) のみ。
重要: 作業に入る前に
- 外部エージェント (Claude) が GUI の krkrz を駆動するなら
-replfile=<dir>ファイルチャネルを使う。-replの console REPL は Windows でCONIN$(実コンソール) を読むため、ツールからは打ち込めない。ファイルチャネルならcmd/respファイルの Write/Read だけで逐次駆動でき、captureScreenの PNG を Read で目視確認できる。→ 下の「ファイルチャネル駆動」。 - REPL 駆動時は 例外で即終了しない / inform・例外ダイアログがネイティブ message box でなくコンソールに出る。この差分を前提にログを読む。
-replfileと-replは独立に起動できる (両方同時も可)。メイン実行は 共有キューReplMainQueueで直列化される。
起動フラグ
| フラグ | 意味 |
|---|---|
-repl | console REPL (CONIN$ 直読み) を起動。人間の対話向け。-repl=no/off/false/0 で抑止。 |
-replfile=<dir> | ファイルチャネルを起動 (外部エージェント向け、本命)。<dir> の cmd/resp ファイルで駆動。-repl と独立。 |
-replweb[=port] | HTTP+SSE サーバ (既定 127.0.0.1:8899)。GET /=ブラウザ REPL ページ / GET /events=ログ SSE / POST /cmd=TJS 評価 / GET /sub/<ch>=汎用 SSE / `GET |
-nostartup | startup.tjs の自動実行を抑止。window 無し起動でも即終了しない。明示的にスクリプトを呼んで初めて処理が始まる。-nostartup=no/off/false/0 で無効。 |
-loglevel=info | ログレベル。コンソールに出る量を制御。MASTER ビルドだと既定 WARNING。 |
-display=<番号|名前> | 起動するディスプレイ (モニタ) の指定。マルチディスプレイ環境でメインディスプレイを占有せずに検証したいときに使う。番号は 1 origin (Windows の \\.\DISPLAYn の n)、名前はモニタ名の部分一致、primary も可。-display=list で一覧をログ出力。WINVER / SDL3 両対応。 |
⚠
-replwebの既定ポート 8899 は PC 全体で 1 つ。 別のセッション (あるいは user 本人) の krkrz が先に握っていると、 後から起動した自分の アプリはポートを取れないのに 自分のログにはlistening on http://127.0.0.1:8899/が出るので気付けず、curlは 相手のアプリを駆動する。 検証で起動するときは-replweb=<固有ポート>を明示すること (ブラウザを開かせたくなければ-replwebopen=noも)。-replfileの チャネルは自分のディレクトリなので必ず自分のアプリに届く — HTTP とファイルチャネルで 結果が食い違ったらこれを疑う。 確定はGet-CimInstance Win32_Process -Filter "Name='krkrz64.exe'"で ExecutablePath / CommandLine を見る。
WebServer クラス (-replweb の拡張登録口)
KRKRZ_REPL_WEB ビルドではスクリプト/プラグインが web サーバへ機能を追加公開できる
(常時登録可、サーバ稼働時のみ配信)。ハンドラは常にメインスレッド実行。
WebServer.register(prefix, handler)— 動的ハンドラ (最長一致)。handler(%[method,path,query,body,bytes])→ 文字列=200 JSON / octet / 整数=status / void=204 /%[status,mime,body]WebServer.serveStatic(prefix, storageDir)— Storages 経由の静的配信 (".." 拒否)WebServer.broadcast(channel, text)—/sub/<channel>購読者へ SSE 配信WebServer.active/WebServer.url(=System.replWebURL)
詳細は engine doc/REPL.md の「ブラウザ REPL / Web サーバ」節。threepp の
ブラウザ編集 UI (threepp/docs/webui.md, /ui/ + /app/ + /api/three/) が実利用例。
検証は curl で足りる: ハンドラ登録は -replfile チャネルか /cmd から eval →
curl http://127.0.0.1:8899/<path> で応答確認。
代表的なエージェント起動 (ファイルチャネル + ゲーム画面あり):
krkrz64.exe <ABS_DATA_DIR> -replfile=<ABS_CHANNEL_DIR>
-nostartup を付けると startup.tjs を実行しない静止起動 (window も無い)。
描画やダイアログ検証には window が要るので、その場合はチャネルから明示的に
Window を作るか、startup.tjs を実行させる。
exe は krkrz_dev のビルド出力を使う (リポジトリルート相対):
- SDL3 版:
build/x64-windows/core/Release/krkrz64.exe - WINVER 版:
build/x64-windows-win/core/Release/krkrz64.exe
プロセスの起動・停止は skill dev-toolkit:appctl の規約に従うこと (PID を記録し、停止は
その PID のみ・exe パス照合付き。taskkill /IM krkrz64.exe のようなイメージ名
一括 kill は並行セッションを巻き添えにするため禁止)。dev-toolkit:appctl は
プラグイン dev-toolkit 収録なので、同梱ヘルパ scripts/appctl.sh の位置は
そちらの SKILL.md を見る ($APPCTL に入れてある想定で以下は書く)。
シェル操作そのものは skill dev-toolkit:msys2 の起動定型に従う
(MSYSTEM=MSYS /c/msys64/usr/bin/bash.exe -lc '...')。素の bash 呼びは
Git Bash を引いてしまう。
export APPCTL_DIR="$SCRATCHPAD/appctl"
S="$APPCTL" # dev-toolkit:appctl の scripts/appctl.sh
CH="$SCRATCHPAD/replchan"
bash "$S" start krkr \
"$REPO/build/x64-windows-win/core/Release/krkrz64.exe" \
"$REPO/src/core/data" -readencoding=UTF-8 -replfile="$CH" -loglevel=info
# ... チャネル経由で評価・検証 ...
bash "$S" stop krkr
パスの落とし穴
プロジェクトディレクトリ引数は exe からの相対で解決される。リポジトリの
data ディレクトリを使うなら 絶対パスで渡す。相対 data/ だと
build/.../Release/data/ を探して "startup.tjs が見つかりません" になる。
リポジトリルート相対では src/core/data/ ( umbrella の場合 )。engine 単独チェックアウト
なら data/。いずれも 絶対パスに展開して渡すこと。
REPL 駆動時の挙動変更 (このビルドで実装済み)
TVPReplActive (REPL 起動中 true、SysInitIntf.h) を見て、Application->MessageDlg
を呼ぶ各ラッパ側で分岐している (override 実装の SDL3Application::MessageDlg
本体は無改造)。
- 例外で即終了しない:
TVPShowScriptExceptionは REPL 中、ネイティブ ダイアログ表示もTVPTerminateSyncも行わず、例外メッセージ + trace をTVPAddImportantLogでコンソールに出すだけ。修正して再 eval できる。 - System.inform → コンソール:
TVPShowSimpleMessageBoxが REPL 中は[dialog] caption: textをログに出すだけで、ブロッキングな message box を 出さない (既定応答で進む。応答取得は将来拡張)。 - 致命エラー (ShowException):
TVPLOG_CRITICALで出力済みなので REPL 中は message box を抑止。 - System.confirm / Storages.selectFile / Storages.selectDirectory → エージェント応答:
REPL 中はネイティブモーダルを出さず、下記「モーダル応答チャネル」でエージェントが
実際に応答を返せる (応答口が無ければ confirm は既定 Yes、選択はネイティブへ)。
System.inputStringも本体実装済みでこのチャネルに乗る (2026-09-25 実測)。
モーダル応答チャネル (confirm / 文字列入力 / 選択肢 / ファイル選択)
-replfile=<dir> 駆動中、本体が System.confirm / System.inputString / System.choice /
Storages.selectFile / Storages.selectDirectory を実行すると、cmd/resp とは別の専用ファイル対で
応答を求めてくる。メイン実行はブロックするが、応答は別プロセス (エージェント) が
直接書くのでデッドロックしない。
プロトコル (<dir> 配下、cmd を投げた後):
-
本体が要求 JSON を
<dir>/modalに書く。例:{"type":"confirm","caption":"確認","text":"続行?"}{"type":"inputString","caption":"題名","prompt":"入力してください","default":"きてい"}{"type":"choice","caption":"確認","text":"保存しますか?","choices":["yes","no","cancel"],"default":2}{"type":"selectFile","name":"","title":"開く","save":false}{"type":"selectDirectory","name":"","title":"フォルダ","save":false}
-
エージェントは
modalの出現を検知し、応答を<dir>/modalrespに書く (プレーン文字列):- confirm :
yesy1trueokが真、それ以外は偽 - inputString :
ok<改行><入力値>/cancel単独でキャンセル (void が返る) - choice : 選んだ要素の文字列 (大小文字は区別しない) か index。空 / 該当しない値 =
default - selectFile/Dir : 返すパス (直接入力でよい) / 空文字列 = キャンセル
⚠ 種別ごとにキャンセルの書き方が違う。汎用の 1 文字列では済まないので
modalの"type"を見て振り分けること (cancelを selectFile に返すと 「cancel という名前のパスを選んだ」ことになる)。 - confirm :
-
本体が
modalrespを読み、modal/modalrespを削除して処理続行 → 通常どおりrespに最終結果が出る。
つまり selectFile/selectDirectory はダイアログを出さず、エージェントが返したい
パスを modalresp に直接書けばそれが選択結果になる (name に正規化されて書き戻る)。
手順のキモ: cmd を投げたら resp を待つ前に modal の出現をポーリングし、
出たら modalresp を書く。その後 resp が出る。PowerShell 例:
# cmd 送信後
while (-not (Test-Path "$chan/modal")) { Start-Sleep -Milliseconds 30 }
[IO.File]::WriteAllText("$chan/modalresp", "yes") # or "ok`n<値>" / "cancel" / パス / "no" / ""
# この後 $chan/resp が出るので通常どおり読む
⚠ 答えないと resp は返らない。本体は既定 30 秒 (-replmodaltimeout=<秒>、0 で無限)
待ってから TJS 例外を投げる。モーダルを出しうる式を投げるハーネスは、resp 待ちループの中で
modal も見て、出たら種別に応じて答えること。
スクリプト側から「いま REPL で駆動されているか」は System.replActive (読み取り専用) で分かる。
⚠ WINVER では REPL が起動スクリプトの後に有効になるので、startup.tjs の実行中はまだ偽
(SDL3 は起動時から真)。起動直後の判定は System.getArgument("-replfile") を併用する。
ファイルチャネル駆動 (エージェント推奨)
-replfile=<dir> で起動すると、<dir> 配下のファイルで REPL を駆動できる。
console を介さないので Claude のツール (Write/Read) でそのまま操作できる。
プロトコル (lockstep):
- コマンド (UTF-8 TJS) を
<dir>/cmd.tmpに書き、<dir>/cmdに rename。 - チャネルが実行し、結果 JSON を
<dir>/respに書く ({"ok":bool,"result":"<pretty>","error":"<msg>"})。 respの出現を待って読み、削除してから次のcmdを出す。 (未読respが残る間は次コマンドを処理しない)
PowerShell ヘルパ例 (Move-Item で atomic rename → resp 待ち):
function Send-Cmd($script, $timeoutMs = 5000) {
$cmdTmp = "$chan/cmd.tmp"; $cmd = "$chan/cmd"; $resp = "$chan/resp"
[IO.File]::WriteAllText($cmdTmp, $script, [Text.UTF8Encoding]::new($false))
Move-Item -Force $cmdTmp $cmd
$sw = [Diagnostics.Stopwatch]::StartNew()
while ($sw.ElapsedMilliseconds -lt $timeoutMs) {
if (Test-Path $resp) { Start-Sleep -Milliseconds 30
$c = [IO.File]::ReadAllText($resp); Remove-Item -Force $resp; return $c }
Start-Sleep -Milliseconds 30
}
"<TIMEOUT>"
}
起動 → 数秒待って window/DrawDevice 初期化 → Send-Cmd でコマンドを送る。
win 等 startup.tjs のグローバルもそのまま参照できる。
- 1 コマンド = 1 式/1 文。複数文を
;で繋ぐと syntax error になることが あるので、分割送信するか(function(){ ...; return x; })()で包む。
Agent API (入力注入 / キャプチャ / ダイアログ制御)
Agent は System 同様インスタンス不要でクラスメソッドを呼ぶ (SDL3 / WINVER +
KRKRZ_USE_ELEMENTS + KRKRZ_USE_REPL で登録。KRKRZ_REPL=OFF で消える)。入力は
実入力と同じ経路を通るのでゲームにも Elements ダイアログにも届く。
| メソッド | 用途 |
|---|---|
Agent.mouseMove/mouseDown/mouseUp(x,y[,btn[,shift]]) | マウス (論理座標、btn: 0=左1=右2=中) |
Agent.click(x,y[,btn[,shift]]) / Agent.wheel(delta,x,y) | クリック (move+down+up) / ホイール(120単位) |
Agent.keyDown/keyUp/keyPress(vk[,shift]) | キー (vk は VK_* 数値、例 VK_RETURN) |
Agent.text(str) | アクティブダイアログへテキスト入力 (input_box 等) |
Agent.ignoreRealMouse | 真にすると実マウス入力を捨てる(Agent の注入だけ通す)。起動オプション -ignoremouse=yes でも設定可。人がポインタを動かしても測定が汚れない。⚠有効中は人の手でマウス操作できない |
Agent.dialogs() | アクティブダイアログ配列 %[index,modal,active,screen,focused,x,y,w,h] |
Agent.closeDialog() / Agent.closeAllDialogs() | 最前面 / 全ダイアログを閉じる |
Agent.dialogClick(i,id) / Agent.dialogFocus(i,id) | id 指定で起動 / フォーカス (座標不要) |
Agent.captureScreen(path[,x,y,w,h]) | overlay 込み実画面を次フレームで PNG 保存 (戻り値=path) |
Agent.lastCapture() | 直近キャプチャ結果 %[path,width,height,ok] |
Agent.a11yTree() | 読み上げツリー (スクリーンリーダーに見えるもの) を JSON 文字列で。{"dialogs":[…],"game":…}。スクリーンリーダー無しでも取れる |
Agent.a11yLog([since]) | 読み上げログ %[lines, next] (「おおよそ何と読むか」の行: [focus] / [value] / [state] / [caret] / [polite] …)。REPL 稼働中だけ溜まる |
Agent.a11yAction(node, action[, arg]) | スクリーンリーダーと同じ経路で操作 (キー合成ではない)。action = click / focus / increment / decrement / set_value |
検証フロー例 (ファイルチャネル)。$CAP_DIR はセッションの scratchpad など
書き込み可能な作業ディレクトリの絶対パス:
Send-Cmd "win.openMenu()"
Send-Cmd "Agent.dialogs()" # 状態確認 (screen/rect)
Send-Cmd "Agent.click(255,80)" # 座標クリックで遷移
Send-Cmd "Agent.dialogClick(0,'sound')" # or id 指定で操作
Send-Cmd "Agent.captureScreen('$CAP_DIR/cap.png')" # 即 return、~1 フレーム後に保存
# (少し待って) Read tool で cap.png を開いて目視確認
captureScreen は内部で RequestUpdate を呼ぶのでアイドルでも保存される。
既定 DrawDevice は SDLOGLDrawDevice (GL) で、glReadPixels 経由で読み戻す。
PrintWindow/BitBlt では GL クライアント領域が黒くなる問題を回避できるのが
利点 (走らせて数百 ms 待って captureScreen→Read で目視、が定番)。
stdin への TJS 送り込み (console REPL / 人間向け)
REPL worker は ic_readline (icline) または fgets shim で 1 行ずつ読む。
worker からのリクエストは main スレッドの TVPDrainREPL() が毎フレーム
1 件 drain して TVPExecuteExpression で実行する。
バッチ実行 (推奨: 検証・スモーク用)
複数行を流して結果を拾う (data パスは絶対パスで、自分の構成に読み替え):
printf '%s\n' \
'var w = new Window(); w.setSize(320,240); w.visible = true;' \
'Debug.message("hello from repl");' \
'1 + 2 * 3' \
'exit' \
| krkrz64.exe <ABS_DATA_DIR> -repl -nostartup -loglevel=info
=> 行が評価結果。exit / quit で REPL を閉じてプロセス終了。
icline と TTY の注意
既定ビルドは icline (行編集・履歴・色) を使い、raw TTY を期待する。
パイプ stdin だと挙動が乱れる場合があるため、エージェント/ヘッドレスで
パイプ駆動するなら KRKRZ_REPL_LINE_EDIT=OFF でビルドすると fgets ベースの
shim (KRKRZ_REPL_NO_ICLINE) になり、パイプ stdin をそのまま素直に処理できる。
- engine 単独:
cmake --preset x64-windows -DKRKRZ_REPL_LINE_EDIT=OFF - umbrella:
PRESET=x64-windows CMAKEOPT='-DKRKRZ_REPL_LINE_EDIT=OFF' make prebuild build
長いスクリプトは Storages 経由
複数行スクリプトは stdin で送るより、ファイルに置いて REPL から呼ぶ方が確実:
Scripts.execStorage("mytest.tjs"); // data/ 配下 (autopath)
-nostartup で立ち上げてから上記でテストを開始する、が基本フロー。
ドットコマンド
.help で一覧。console / -replfile / -replweb の 3 フロントすべてで使える
(ファイルチャネルでは先頭が . の行がドットコマンドとして扱われ、出力行が
応答 JSON の result に改行区切りで入る)。主なもの:
| コマンド | 用途 |
|---|---|
.help | コマンド一覧 |
.clear | multiline 入力を破棄 |
.depth [N] / .compact [on/off] | 結果の pretty-print 設定 |
.mem | メモリ要約 1 行 (File/Bitmap/Sound/Global/Process/SysAlloc) |
.memdump | 全メモリ統計をログへ (TVPHeapDump) |
.memsites [N] [関数名の一部] | 生存確保を呼び出し元別に上位 N 件 (診断ビルド + -memstatsite 起動時のみ) |
.sysalloc | システムアロケータ情報 |
.filecache / .imagecache | ファイル/画像キャッシュ一覧をログへ |
.memoverlay [on/off] / .padoverlay [on/off] | 画面オーバレイ表示トグル |
.mempeakclear | peak_used リセット |
.cap [path] | 画面キャプチャ (Agent.captureScreen、省略時 agent_cap.png) |
.dlg / .dlgclose | ダイアログ一覧 / 全クローズ (Agent.dialogs/closeAllDialogs) |
.click X Y | (X,Y) にクリック注入 (Agent.click) |
.a11y | 読み上げツリーを表示 (Agent.a11yTree) |
.a11ylog [N] | 読み上げログの N 行目以降 (Agent.a11yLog) |
.a11ydo <node> <action> [arg] | 読み上げツリーのノードを AT の経路で操作 (Agent.a11yAction)。node は .a11y の id (画面 JSON の "id" / setGameA11y の id / layer:<Layer.name> / #<hex>) |
.say <text> | ElementsDialog.announce |
.watch | 監視式の一覧を id: 式 = 値 で表示 (表示前に全件評価) |
.watch add EXPR | 監視式を追加して即評価 (式は空白を含んでよい) |
.watch rm ID / .watch rm all | 監視式の削除 / 全消し |
.watch edit ID EXPR | 監視式の差し替え |
.watch auto [ms/on/off] | 自動更新の間隔 (on=500ms / 0=毎フレーム / 下限 100ms) |
.event [on/off/toggle] | System.eventDisabled の表示 / 切替 |
TJS の評価は dot で始まらない行をそのまま入力する (式・文どちらも可、 括弧/クォートが閉じるまで複数行継続)。
監視式 (.watch) — 状態を張り込んで観測する
吉里吉里2 のデバッグ窓「監視式」相当。毎回同じ式を打ち直さずに状態を見張る ための道具で、値の変化を追う検証に向く。
.watch add win.layer.left
.watch add ElementsDialog.modalActive
.watch auto 500 # 自動更新 (0 = 毎フレーム / off で停止)
.watch # 一覧 (表示前に全件評価する)
- 評価コンテキストは global 固定。式が例外を投げても
(error) <メッセージ>を値として並べるだけで、REPL もアプリも死なない。 - 一覧表示は評価を伴うので、「自動更新だけで評価されたか」を確かめたいときは 副作用のある式 (カウンタを増やす等) を仕込んで別コマンドで読む。
- 式リストと間隔はカレントディレクトリの
.krkrz_watchに保存され、次回起動で 読み戻る (-replwatchfile=<path>で変更、=noで無効)。検証で消したいときは このファイルを消すか=noを付ける。 - HTTP からも同じコアを触れる (
-replweb併用時):curl -s -X POST -d 'op=add&expr=…' localhost:8899/watch/curl -s localhost:8899/watch(評価しない。?eval=1で評価) /curl -N localhost:8899/sub/watch(自動更新の push)。 ドットコマンドと同じリストを見るので、片方で足して片方で観測できる。
典型ワークフロー (エージェント)
-repl -nostartupで起動 (window も startup も無い静止状態)。- REPL から最小 Window を作って
visible=true→ SDL イベントループに入る (window が無いと描画ループに入らない種類の検証はこれが要る)。 - 検証スクリプトを
Scripts.execStorageか stdin で評価。 - 例外が出てもプロセスは生きているので、コンソールの例外/trace を読んで スクリプトを直し、再度評価。
.mem等で状態を観測。exitで終了。
コアデモ全シーンの表示確認 (-demotest / -demotestcap)
エンジン変更後の「全部ちゃんと映るか」の回帰確認は、REPL で 1 シーンずつ
送るより ギャラリーの自動巡回 + 自動キャプチャが速い (demolib 機能。
SSOT は data/demolib/readme.txt の「ヘッドレス自動テスト」)。
krkrz <ABS>/src/core/data -demotest -demotestcap=<ABS_CAP_DIR>
# 例 (Linux、エージェントのシェルから): WAYLAND_DISPLAY=wayland-0 を前置
- 全シーンを 40 フレームずつ巡回し、各シーンを
<dir>/sceneNN.pngに保存して@demotest:okで自動終了 (01 = メニュー)。ログの@demotest:cap <path> <シーン名>が番号 → シーン名の対応、@demotest:<シーン名> ...が各シーンの自己検証結果 <dir>は絶対パス、無ければ作られる。-demotestcap単独でも巡回する- 保存は
System.captureScreenなので REPL 有効ビルドのみ (MASTER では@demotest:cap unavailableが出て撮影なし)。実ウィンドウが要る - 完走しない (ハング / abort) こと自体が不具合のシグナル。最後に出た
@demotest:scene N/Mの次のシーン (またはその離脱処理) を疑う - 目視は PNG を 1 枚ずつ Read するより、PIL 等で縮小して数枚ずつ 並べた一覧画像を作って Read すると速い
- 乱数・アニメのあるシーン (画像処理 / パーティクル / FPS 表示等) は毎回 画素が変わるので、前回キャプチャとの差分比較ではノイズとして扱う
撮れるのは各シーンの最初のページだけ。複数ページあるシーン (GL Canvas 等)
の残りは -replfile で起動して送る:
demoShell.switchTo(13) # シーン番号 (0 = メニュー、sceneNN の NN-1)
Agent.keyPress(VK_RIGHT) # シーン内のページ送り
System.captureScreen("<ABS>/p2.png") # 次フレームで保存されるので少し待つ
demoShell は runDemoHub が global に置いている DemoShell インスタンス。
関連 (パスは engine ルート相対 / umbrella では src/core/ 前置)
- 言語仕様: skill
tjs2/ 本体 API: skillkrkrz - ビルド: engine 単独は
cmake --preset x64-windows、umbrella はmake(プリセットsrc/core/CMakePresets.json)。詳細は各CLAUDE.md - REPL 実装:
common/utils/REPL.cpp/ 共有実行キュー:common/utils/ReplMainQueue.cpp/ ファイルチャネル:common/utils/ReplFileChannel.cpp/ 有効化: CMakeKRKRZ_REPL(=KRKRZ_USE_REPL) - Agent API:
common/environ/AgentControlIntf.cpp(共通) + 入力 seamgeneric/environ/AgentInput.cpp(SDL3/LIB) /win32/environ/AgentInput.cpp(WINVER) / キャプチャ:common/visual/ScreenCapture.cpp - 詳細ドキュメント:
doc/REPL.mdの「エージェント駆動」節 - 複数ダイアログ同時表示の仕様:
doc/ElementsDialog.md
レビュー
まだレビューはありません。使ってみた感想をお寄せください。
同じリポジトリのスキル
概要と使いどころ
吉里吉里Z (kirikiri Z) 本体クラス API のリファレンス。TJS2 で吉里吉里Z 上のスクリプトを書く、レビューする、デバッグするときに使う。Layer / Window / Bitmap / System / Storages / Font / Plugins / Timer / Debug / AsyncTrigger / Scripts / BinaryStream / Matrix32 / Matrix44 / Rect / ImageFunction のコア API、サウンド系 (WaveSoundBuffer / SoundBuffer / VideoOverlay)、DrawDevice (BasicDrawDevice / SDLDrawDevice / OGLDrawDevice / NullDrawDevice)、OpenGL 描画系 (Canvas / Texture / ShaderProgram / Offscreen / VertexBinder / VertexBuffer)、および主要プラグイン提供クラス (HttpRequest / GdiPlus.* / WIN32Dialog / CSVParser / LineParser / Process / Pad / MenuItem / Unzip / Zip / PSD / SimpleHTTPServer) を網羅。**呼び出されたら必ず「共通パターン」と「クロスカッティング概念」を確認し、必要な詳細クラスは doc/reference/*.md を Read しに行くこと。** TJS2 言語そのものや組み込みクラス (Array / Dictionary / Math 等) は別 skill (`tjs2`) を参照。エンジン内部構造 (C++ 実装、レンダリングパイプライン詳細) は対象外。
吉里吉里Z (krkrz) の -replweb HTTP+SSE サーバ (WebServer クラス) にブラウザ UI を載せて、本体アプリの操作/編集/観測パネルをブラウザ側に組み込む方法論。ゲーム本体は 3D 表示やゲーム内 UI に専念させ、編集ツール・インスペクター・ダッシュボード・REPL コンソールをブラウザ (別ウィンドウ/別PC) から使う構成を作るときに読む。プラグインや TJS がサーバへエンドポイントを追加公開する手順 (WebServer.register / serveStatic / broadcast)、ハンドラ呼び出し規約 (req %[method,path,query,body,bytes] → 文字列/octet/整数/辞書)、状態同期パターン (fetch POST + SSE /sub push + throttle + 差分/tick 配信)、既存 REPL コンソール (/events + /cmd) の UI 埋め込み、ブラウザのアプリモード起動 (Chromium --app / -webui)、json.dll 連携、TJS2 由来のハマりどころ (ローカル関数クロージャ不在→クラス化 / ブロックコメントのネスト誤爆 / startup 例外の致命性 / ハンドラは必ずメインスレッド実行) を網羅。エンジン側 WebServer クラスそのものの仕様は krkrz core doc/REPL.md、REPL/Agent 駆動は skill krkrz-repl、Elements ネイティブ UI は skill elements、TJS2 言語は skill tjs2、本体 API は skill krkrz を参照。
TJS2 (吉里吉里Z 内蔵スクリプト言語) の言語仕様と組み込みクラスのリファレンス。.tjs ファイル / *.ks (KAG) 内の埋め込みスクリプト / TJS2 コード断片 を扱う、書く、レビューする、デバッグするときに使う。JavaScript / TypeScript に似ているが文法と意味論が違うので、JS の感覚で書くと壊れる場合が多い。組み込みクラス (Array / Dictionary / Date / Math / RegExp / Exception) の API もここに集約。**呼び出されたら必ず「JS との主な違い」セクションを最初に確認し、その上で必要な詳細リファレンスを Read で取りに行くこと。** 吉里吉里Z 本体のクラス API (Window / Layer / System / Storages / Bitmap 等) や engine 内部はこのスキルの対象外。