データで書くアプリ

プログラムを書かずに、JSON の定義だけで作るアプリです。天気アプリの見本を教材にして、書き方を順に説明します。

Chapter 4

考え方

  1. 計算はサーバーで済ませる。月齢、日の出、METAR の読み解きなどは、feed を作るサーバー側で計算して値として入れておきます。端末の上では計算しません(式もスクリプトも書けません)
  2. 画面は「型」を選んで「部品」をはめる。自由な配置はできません。そのかわり、見た目とリモコンの操作が Ulexite のほかの画面とそろい、フォーカスの順番も OS が決めます
  3. 画面はエディタで作られる。ワールドでは、テレビを作るときに Ulexite が定義を読んで画面を組み立て、焼き込みます。実行中に起きるのは「データを読んで、変わった値をはめる」ことだけです。だから重くなりにくいのです
  4. URL はすべて焼き込み。Udon は実行中に URL を作れないので、読むファイル・画像の URL は定義の assets に全部書いておきます。地点ごとにファイルが違う場合も、地点の数だけ URL を書き出します(each)

ファイルの並び

Packages/vrc.ulexite.app.weather/
  package.json            VPM のパッケージ情報(バージョンと作者はここが正)
  ulexite-app.json        マニフェスト。kind: declarative、runtimes.world.screens に定義のファイル
  app.screens.json        画面の定義(この章の本題)
  lang.json               翻訳表
  feed.sample.json        feed の見本(エディタの検査とプレビューに使う)
  Textures/               アイコンなど
  NOTICE.txt              データや素材の出典

マニフェストでは、kind を declarative にして、runtimes.world.screens に定義のファイルの名前を書きます。

"kind": "declarative",
"runtimes": { "world": { "os": 1, "appServices": 2, "screens": "app.screens.json" } }

定義のファイルの骨組み

{
  "format": 1,
  "lang": "lang.json",
  "settings": [ ... ],   // アプリの設定項目
  "assets":   { ... },   // 読むファイル・画像の URL(すべて焼き込み)
  "data":     [ ... ],   // いつ、どのファイルを読むか
  "maps":     { ... },   // 値 → 文字・色・アイコンの対応表
  "tile":     { ... },   // ホームのタイルに出すもの
  "screen":   { ... }    // 画面
}

画面の型

型使いどころ例
tabs上にタブ、下にそれぞれの画面。中に別の型を入れる天気(天気/月/地震/地図)
list-detail左に一覧、右に選んだものの詳細METAR、地震
dashboardカードの並び(数値・短い文・小さな表)月の満ち欠け
map地図の下地に、画像・点・印を重ねる雨雲、震源
gridタイルの格子ライブカメラ(まだ使えません)

型は入れ子にできます。天気アプリの「天気」タブは、tabs の中に list-detail があり、その詳細が dashboard です。

"screen": {
  "type": "tabs",
  "title": "t:weather.name",
  "tabs": [
    { "id": "forecast", "label": "t:weather.tab.forecast",
      "screen": {
        "type": "list-detail",
        "list":   { ... },
        "detail": { "type": "dashboard", "cards": [ ... ] }
      } }
  ]
}

部品

部品内容状態
text文字。style で caption(補足)・title・strong など使える
value大きな数値と単位(と、横のアイコン)使える
icon同梱のアイコンを名前で使える
badge・badges色つきの札(警報の種類など)使える
strip横並びの小さなカード(週間予報など)使える
list一覧使える
note出典・注意書き使える
imageassets の画像まだ
chart折れ線・棒(点は12まで)まだ
button動作を呼ぶボタンまだ
customU# で書いた部品をはめるまだ

dashboard のカードの例(今の天気):

{ "size": "wide", "parts": [
  { "text": "{{ selected.area | choice:jma-areas }}・{{ t:weather.now }}", "style": "caption" },
  { "value": "{{ area.current.temp | num:0 }}", "unit": "℃", "icon": "{{ area.current.wx | map:wxIcon }}" },
  { "text": "{{ area.current.wxText }}" }
] }

値のはめ込み

{{ }} の中に、値の道筋を書きます。

書き方指すもの
{{ area.current.temp }}data の id が area の feed の、current.temp
{{ area.days[0].max }}配列の0番目
{{ settings.areas[0] }}設定の値
{{ item.name }}一覧・strip の中で、その1件
{{ selected.area }}一覧で選んでいるもの(一覧に "select": "area" と書いたとき)
{{ common.warnings[selected.area] }}道筋の中に、別の値を差し込む(式は書けません。差し込みだけ)
{{ common.quakes }}共通の feed(地震・津波・警報など)
t:weather.now翻訳表のキー

整形

| でつなぎます。使えるのは OS が用意した関数だけです。

関数例結果
num:桁{{ 18.44 | num:1 }}18.4
unit:単位{{ 18 | unit:℃ }}18℃
time{{ "2026-10-18T21:20:00+09:00" | time }}21:20
time:dayAware昨日の時刻昨日 23:51
date・date:weekday・date:short10月19日・月・10/19
ago3分前
map:表の名前{{ "100" | map:wxIcon }}sun
choice:選択肢の表{{ "130000" | choice:jma-areas }}東京都
scale:名前{{ 31 | scale:temp }}温度の色の段階

値がないときは「—」、データがまだ1つも読めていないときは「読み込み中…」、読めなかったときは「読み込めませんでした」を OS が出します。アプリで気にする必要はありません(古いときの「〇時〇分の情報」の表示は準備中)。

対応表 maps

値を、文字・色・アイコンに対応させます。"*" は「それ以外」です。

"maps": {
  "wxIcon":   { "100": "sun", "200": "cloud", "300": "rain", "400": "snow", "*": "cloud" },
  "warnColor": { "special": "level5", "danger": "level4", "warning": "level3", "advisory": "level2" }
}

色は意味の名前で書きます:danger・warning・caution・info・muted。実際の色はテーマとユーザー補助(色の見分けやすさ)に合わせて OS が決めます。凡例など、色そのものに意味があるところだけ #rrggbb を使えます。

警報・注意報には、気象庁のレベルの色に合わせた level5(特別警報・黒)・level4(危険警報・紫)・level3(警報・赤)・level2(注意報・黄)を使います。この4つはテーマで変わりません。色だけに頼らず、気象庁の名前(「レベル4大雨危険警報」など)を必ず一緒に出してください。

震度には int1〜int7 を使います(int5l・int5u、int6l・int6u は「5弱」「5強」「6弱」「6強」)。

札の文字の色は OS が決めます。アプリから文字の色は指定できません。level5・level4・level3 と int1・int2・int3・int5u・int6l・int6u・int7 は白、level2・int4・int5l は暗い色になり、level5 は明るい線で囲まれます(暗い画面に沈むため)。danger・warning・caution・info・muted は今までどおりです。文字が入りきらないとき(震度の「5弱」など2文字)は OS が自動で小さくする(約 0.75 倍)ので、大きさは指定しません。

表示の条件 when

道筋を書くと、その値があって、空でも false でもないときだけ表示します。比較(「震度4以上なら」など)は書けません。絞り込みが必要なら、サーバーで別の欄を作ってください。

{ "size": "wide", "when": "common.warnings[selected.area]", "style": "alert", "parts": [ ... ] }

設定

"settings": [
  { "id": "areas", "type": "order", "scope": "global", "max": 3,
    "choices": "jma-areas", "default": ["130000"], "label": "t:weather.setting.areas" }
]

読むファイルとタイミング

"assets": {
  "files": {
    "area": { "each": "jma-areas", "url": "https://thesilver0913.github.io/ulexite-catalog/v1/feed/weather/{{key}}.json" },
    "map":  { "url": "https://thesilver0913.github.io/ulexite-catalog/v1/feed/weather-map.json" }
  }
},
"data": [
  { "id": "area", "file": "area[{{selected.area}}]", "every": "10m" },
  { "id": "map",  "file": "map", "every": "10m", "when": "screen:map" },
  { "id": "now",  "file": "area[{{settings.areas[0]}}]", "every": "10m", "background": true }
]

feed の形

feed はサーバーが作る JSON です。ほかの作者のアプリの feed は、アプリの開発者が信頼済みドメイン(自分の GitHub Pages など)に置き、URL を定義に書きます。共通の feed は Ulexite 公式が用意するものだけです。決まりは3つです。

  1. version を入れる。項目は足すだけにして、意味を変えない
  2. 計算済みの値を入れる(端末は計算しない)
  3. 小さく保つ(目安 1ファイル 50KB 以内)
{
  "version": 1,
  "updatedAt": "2026-10-18T21:20:00+09:00",
  "current": { "temp": 18.4, "wx": "200", "wxText": "くもり" },
  "days": [ { "date": "2026-10-18", "wx": "200", "max": 21, "min": 14, "pop": 30 } ],
  "sun":  { "rise": "05:49", "set": "17:08" }
}

ホームのタイル

"tile": {
  "icon": "{{ now.current.wx | map:wxIcon }}",
  "text": "{{ now.current.temp | num:0 | unit:℃ }}"
}

確かめ方

  1. 定義と同じフォルダに feed の見本を置きます:feed.sample.json(全部の data)、feed.<data の id>.sample.json(その data だけ)、common.sample.json(共通の feed)
  2. Tools → Ulexite → データで書くアプリのプレビュー で、Play せずに見本の値をはめた画面が見られます。タブや選んでいる行も切り替えられます
  3. 同じ窓に検査の結果が出ます:道筋が見本に実在するか、URL のドメイン、文字のはみ出し
  4. Tools → Ulexite → テレビを作り直す(再設置と再紐づけ) でテレビに組み込み、ClientSim や Build & Test で確かめます

地図(map 型)

画面の状態の同期

開いているタブ、一覧で選んでいるもの、地図に重ねているものは、シェルが全員に同期します(全員が同じテレビを見ているため)。アプリで同期を書く必要はありません。

よくある質問

Q. 「震度4以上だけ」のように絞り込みたい
A. 書式では絞り込めません。サーバーで quakes4plus のような欄を作ってください。

Q. 画像を feed から出したい
A. URL は焼き込みなので、feed からは assets の画像の ID を指します。feed の中に URL を書いても読めません。

Q. ボタンを押して何かしたい
A. 動作は OS が用意したものだけです:open(同じアプリの別の画面)、openApp(ほかのアプリを開く)、play(再生)、set(設定を変える)、pick(選択肢を選ぶ画面)。今使えるのは、一覧の下のボタン(footer)の pick だけです。button 部品と、ほかの動作は準備中です。