EZRAFFLE
Player raffle system for VRChat worlds

Copyright (c) 2026 NiAka

============================================================
日本語
============================================================

概要
----

「EzRaffle」は、【かんたん設置・かんたん設定・かんたんカスタマイズ】を
合言葉にした「NiAka Ez シリーズ」の、ワールド向けプレイヤー抽選システムです。
参加者が自分でボタンを押して名簿に入り、その名簿から当選者を抽選します。

当選は朱印スタンプの演出で発表します。名前ルーレットが回り、
「当」の判子が押されて当選者が表示されます。

イベントのプレゼント抽選、景品配布、出し物の指名などに使えます。


主な特徴
--------

・参加者が自分で「参加する」を押して登録します。運営の手入力は不要です。
・当選人数を指定して、まとめて抽選できます。
・当選者は名簿から自動で外れ、そのまま次の抽選に移れます。
・名簿と抽選ログは参加者間で同期されます。後から入った人にも表示されます。
・退室した参加者は名簿に残り、「退室中」と表示されます。再入室で戻ります。
・操作できる人を「誰でも / マスターのみ / 指定リスト」から選べます。
・抽選の対象を「在室者のみ / 全登録者」から選べます。
・ログの時刻はJST / UTC / 任意の時差(分単位)に対応しています。
・最大参加人数を1〜100の範囲で設定できます (初期値80)。
・演出の「標準 / 短縮」と効果音の音量・ミュートを、各自が自分だけ変更できます。
・VRではボタン操作した本人のコントローラが短く振動します。発表と同時に、
  その場にいた当選者本人にだけ3連の振動で当選を知らせます (どちらも
  Inspectorで無効化・強さ調整ができます)。
・ワールド内の表示は日本語 / English / 한국어 / 中文の4言語に対応しています。
  表示する言語はInspectorで選びます (ワールド全体で1つの言語です)。
・参加、参加者一覧、音量設定、抽選操作、ログ、当選者一覧の6種のパネルを
  分けて配置できます。参加者一覧と当選者一覧は、閲覧用と管理用を選べます。
  各種類はInspectorから何台でも追加できます。
・標準Prefabは、参加者が使うPlayerUIと運営が使うOperatorUIに分かれています。
  EzRaffleのルートがCoreを持つため、グループを動かしても同期に影響しません。
・抽選人数は全員で共有されます。どの抽選操作パネルで変更しても全台へ反映され、
  後から入った人にも現在値が表示されます。
・当選者一覧には名前と累計当選回数が表示されます。再参加後にもう一度当選した
  場合も回数を加算し、その人を一覧の先頭へ移動します。
・発表のタイミングで外部のUdonギミック(花火など)を起動できる
  コールバックを備えています (開発者向け)。
・Inspectorは日本語 / English / 한국어 / 中文に対応しています。
・初期設定済みPrefabと確認用のSample Sceneを同梱しています。


配布・導入
----------

EzRaffleはBOOTHで無料配布しているパッケージです。

VCC / ALCOMをお使いの場合は、VPMリポジトリからの導入をおすすめします。
https://vpm.2aka.io/

パッケージページ
https://vpm.2aka.io/packages/com.niaka.ezraffle

BOOTHダウンロード版には.unitypackageと、VPMリポジトリ追加用の
ショートカットを同梱しています。VCC / ALCOMにリポジトリを追加してから、
EzRaffleをプロジェクトへ追加してください。.unitypackageをプロジェクトへ
直接インポートすることもできます。

BOOTHショップ「NiAka堂」
https://niaka.booth.pm/

更新方法
--------

VCC / ALCOMに https://vpm.2aka.io/ を登録していれば、新しいバージョンは
一覧に表示されます。更新はその画面から行えます。

.unitypackageを直接インポートした場合は自動で更新されません。新しい
バージョンが出るたびに手作業で入れ替えることになります。更新管理をしたい
場合は、VPMリポジトリ経由での導入をおすすめします。

.unitypackageとVPMリポジトリは、どちらか一方だけを導入し、
同じプロジェクトへ重複して追加しないでください。


必要環境
--------

・Unity 2022.3
・VRChat Worlds SDK 3.10.4以上
・TextMeshPro (SDKに同梱されています)

当選演出にVRCTweenを使っているため、SDK 3.10.4以上が必要です。


セットアップ
------------

1. Packages/com.niaka.ezraffle/Runtime/Prefabs/EzRaffle.prefabを
   Hierarchyへドラッグします。
2. EzRaffle (ルート)を選択します。Inspectorに設定画面が開きます。
3. Step 1で「プレイヤー用」と「運営用」のパネル数を確認します。
   参加者一覧と当選者一覧は、プレイヤー用に追加すると閲覧だけできるパネルに、
   運営用に追加すると削除操作つきのパネルになります。各追加ボタン、または
   「＋ 当選発表を生成」を押すと同じ種類を何台でも追加できます。
4. Step 2で操作できる人、抽選の対象、ログの時刻、最大参加人数、
   効果音を設定します。
5. Step 3の「すべて検証」を押します。[要対応] が出た項目は
   「まとめて修復」で直せます。
6. ワールドをアップロードします。

Runtime/Sample/EzRaffleSample.unityで配置例を確認できます。

標準PrefabではPlayerUIとOperatorUIをEzRaffle直下に分けています。
PlayerUIには参加、音量、閲覧用の参加者一覧と当選者一覧、当選発表があります。
OperatorUIには抽選操作、ログ、管理用の参加者一覧と当選者一覧があります。
各グループやパネルは好きな場所へ動かせます。同じ種類を複数置いても、
EzRaffleルートのCoreが持つ同じ状態を表示します。


使い方
------

参加する
  参加者が参加パネルの「参加する」を押します。名簿に名前が追加されます。
  参加中は「参加中」と表示され、隣の「参加をやめる」で取り消せます。

抽選する
  操作できる人が、抽選操作パネルで当選人数を「−」「＋」で決めてから
  「抽選する」を押します。名前ルーレットが1.4秒回り、朱印スタンプで
  当選者が発表されます。当選人数はすべての抽選操作パネルで共通です。

当選者を確認する
  発表のあとも、当選発表には「直近の当選」として結果が残ります。
  ログパネルには時刻つきで記録され、当選者一覧パネルには名前と
  累計当選回数が残ります。

名簿から外す
  管理用の参加者一覧パネルでは、各行の「×」で個別に削除できます。
  「全消去…」で名簿全体を消せます。どちらも確認画面が出ます。
  閲覧用の参加者一覧パネルには、削除ボタンがありません。

当選履歴を消す
  管理用の当選者一覧パネルでは、「履歴を消去…」から履歴だけを消せます。
  確認画面で確定するまで消去されません。名簿とログは残ります。
  閲覧用の当選者一覧パネルには、消去ボタンがありません。

演出と音を自分だけ変える
  音量設定パネルで「演出（自分のみ）」の「短縮」を押すと、
  名前ルーレットを回さずに
  「まもなく発表」の待機表示になり、発表時刻に結果だけを表示します。
  発表のタイミングは全員で同じです。スピーカーのアイコンでミュート、
  その隣のスライダーで音量を変えられます。
  これらの設定は自分にだけ適用され、他の参加者には影響しません。

表示言語
  パネルと当選発表の言語は、InspectorのStep 2で選びます。
  ログも選んだ言語で表示されます。ワールド内での切替はありません。


同期とネットワーク
------------------

名簿、抽選ログ、直近の当選者、抽選人数、累積当選履歴はワールド内で
同期されます。後から入った人にも、現在の内容がそのまま表示されます。
同期する状態はEzRaffleルートのCoreだけが持ち、登録された各パネルは
同じCoreの状態を表示します。

抽選の結果は「いつ発表するか」の時刻も含めて同期します。
そのため、通信の遅い人にも同じタイミングで結果が表示されます。
同期された発表時刻までは、名簿、ログ、当選履歴の更新を止めて結果が先に
見えないようにしています。

参加、取り消し、抽選、削除の要求は名簿のownerがまとめて処理します。
連続した操作や大人数の同時操作は、owner側で間隔を空けて受け付けます。

演出の「標準 / 短縮」、音量、ミュートはローカル設定です。
他の参加者には送信されず、ワールドに入り直すと初期値へ戻ります。

累積当選履歴は100名まで保持します。再当選した人の回数は上限到達後も
加算できます。履歴にない人が当選して100名を超える場合、その抽選は
実行されません。古い履歴も自動では消えません。続ける場合は当選者一覧パネルで
履歴を明示的に消去してください。

ログは言語に依存しない形式で同期され、設置時に選んだ言語で表示されます。
そのため、あとからInspectorで言語を変えると、過去のログも新しい言語で
表示されます。


Inspectorの設定
----------------

操作できる人
  誰でも      … 参加者全員が抽選・削除できます。(初期設定)
  マスターのみ … そのインスタンスのマスターだけが操作できます。
                 マスターは最初に入った人で、退室すると別の人へ移ります。
                 ワールド作者のことではありません。
  指定リスト   … 入力した名前(displayName)と完全一致する人だけが操作できます。
                 主催者が確実に操作したい場合はこちらを使ってください。

抽選の対象
  在室者のみ … 名簿にいて、かつワールドにいる人だけが当選します (初期設定)。
  全登録者   … 退室中の人も当選します。あとで結果を伝える運用向けです。

ワールド内の言語
  パネルと当選発表の表示言語を、日本語 / English / 한국어 / 中文から
  選びます。ログも選んだ言語で表示されます。

ログの時刻
  JST / UTCのほか、「カスタム」で任意の時差を時間単位(小数可)で入力できます。
  たとえば5.75と入力するとUTC+5:45になります。

最大参加人数
  1〜100の範囲で設定します。初期値は、VRChatインスタンスの上限に合わせた80です。

効果音
  ルーレット音とスタンプ音を差し替えられます。ルーレット音は、
  鳴り終わりが発表のタイミングと重なるように1回だけ再生されます。
  初期音量(初期値0.3)もここで設定できます。参加者は各自の音量を
  音量設定パネルのスライダーで変更できます。
  音の届く距離は当選発表のAudioSourceで調整します。

コントローラ振動 (VR)
  操作フィードバック … ボタンを押した本人のコントローラを短く振動させます。
  当選者への通知     … 発表と同時に、その場にいた当選者本人のコントローラを
                       3連で振動させます。
  それぞれ有効 / 無効と強さ(0〜1)を設定できます。振動はVRプレイヤー
  本人にだけ伝わり、デスクトップでは振動しません。


テスト参加者 (動作確認)
-----------------------

Inspectorの下部に「テスト参加者」があります。
Playモード中に人数を選んで「テスト参加者を投入」を押すと、
ダミーの参加者が名簿に入ります。そのまま抽選操作パネルの
「抽選する」を押せば、
参加者一覧・名前ルーレット・朱印スタンプ・ログまで、本番とまったく
同じ流れをその場で確認できます。

ダミーは退室中の扱いになるため、抽選の対象はPlay中のみ自動で
「全登録者」に切り替わります。Playモードを終了するとすべて元に戻り、
ワールドのアップロード内容には影響しません。


外部のUdonギミックとの連携 (開発者向け)
-----------------------------------------

Inspectorの「開発者オプション」で、発表と同時に任意のUdonBehaviourへ
SendCustomEventを送るコールバックを設定できます。花火や紙吹雪などの
演出ギミックの起動に使えます。呼び出しは各クライアントのローカルで
抽選ごとに1回、全クライアント共通のタイミングで行われます。

受信側のメソッド名は「_」で始めてください (初期値は _OnEzRaffleReveal)。
「_」の付かない引数なしpublicメソッドは、VRChatの仕様上、
他のプレイヤーからネットワークイベントで遠隔起動できてしまいます。

受信側のUdonBehaviourは、EzRaffleのCoreと別のGameObjectに
置いてください。Coreと同じGameObject上への送信は、内部操作への
誤配線を防ぐためすべて無効になります。

外部のUdonSharpからは、EzRaffleCoreの参照を通じて
_GetLastWinnerNames() (直近の当選者)、_GetRosterNames() (名簿)、
_GetAnnounceId() (抽選ID) などの読み取りAPIを利用できます。
詳しくは開発者オプション内のコピー可能なサンプルを参照してください。


困ったとき
----------

「参加する」を押しても名簿に入らない
  満員のときはボタンが「満員です」に変わります。最大参加人数を確認してください。
  抽選の発表中は参加操作を受け付けません。発表が終わってから押してください。

「抽選する」が押せない
  操作できる人の設定を確認してください。権限がない場合は理由が表示されます。
  対象者が0人のときも押せません。抽選の対象の設定と、
  参加者がワールドにいるかを確認してください。
  当選履歴が100名に達し、履歴にない名前が当選した場合、その抽選は
  実行されません。当選者一覧パネルで履歴を消去してから再度抽選してください。

当選発表に何も出ない
  Step 3の「すべて検証」を押してください。
  当選発表がCoreに配線されていない場合は、まとめて修復で直せます。

効果音が聞こえない
  自分のミュートと音量を確認してください。
  遠い場所から聞こえない場合は、当選発表のAudioSourceの
  Max Distanceを大きくしてください。Step 3でも警告が出ます。

VRでパネルを押せない
  Step 3の検証でVRCUiShapeとBoxColliderの有無を確認できます。
  不足していれば、まとめて修復で追加されます。


制限事項
--------

・名簿とログはそれぞれ最大100件です。古いログから消えます。
・累積当選履歴は最大100名です。古い履歴は自動で消えません。
  上限で新しい当選者を記録できない抽選は実行されません。
・名簿はdisplayNameで記録します。名前を変更すると別人として扱われます。
・ワールド内の表示言語はInspectorで選んだ1言語に固定されます
  (参加者ごとの切替はありません)。
・当選発表の朱印スタンプの「当」の字は、言語によらず共通のデザインです。
・演出、音量、ミュートの設定はワールドに入り直すと初期値に戻ります。


更新履歴
--------

■ 1.1.0（2026/11/09）

・パネルと当選発表を木の額に収め、額の分だけパネルの間隔を広げました。
・名前に「<」「>」「&」を含むプレイヤーが、「&lt;」のように文字化けして
　表示される問題を修正しました。
・名簿のownerの画面で、退室した参加者に「退室中」がすぐに表示されない
　問題を修正しました。
・同梱ファイルの配置を整理しました。サンプルシーンを
　Runtime/Sample/EzRaffleSample.unityへ移動しました。
・利用条件（LICENSE.txt）に、本パッケージを含むご自身の制作物を
　ファイルとしても配布、販売できることを明記しました。
・VPMリポジトリ（https://vpm.2aka.io/）での配布を始めました。
・README.txtに更新方法の説明を追加しました。
・VRChat Worlds SDKの依存バージョンを「3.10.4以上」に変更しました。

■ 1.0.0

・最初のリリースです。


同梱テキスト
------------

README.txt   この説明書です。
LICENSE.txt  利用条件です。

Runtime/Fonts/OFL.txtに、同梱フォントのライセンスを収録しています。


クレジット
----------

同梱フォント (いずれもSIL Open Font License 1.1)
  EzRaffleCjkRoot     … Noto Sans JP由来 (Copyright 2012 Google Inc.)
  EzRaffleCjkFallback … Noto Sans CJK KR由来 (Copyright 2014-2021 Adobe)

朱印スタンプの「当」の字はNoto Serif JPからラスタライズしています。
こちらもSIL Open Font License 1.1です。

同梱のTextMeshProシェーダー(Runtime/Shaders)は
TextMesh Pro 3.0.6由来で、Unity Companion Licenseが適用されます。

============================================================
English
============================================================

Overview
--------

EzRaffle is a player raffle system for VRChat worlds, part of the NiAka Ez
series: easy to place, easy to configure, easy to customize.

Players join the roster by pressing a button themselves, and winners are drawn
from that roster. Winners are announced with a vermilion stamp effect: a name
roulette spins, then the stamp lands and shows the winners.

Use it for giveaways, prize draws, or picking performers at events.


Features
--------

- Players register themselves. No manual entry by the host.
- Draw several winners at once by setting the winner count.
- Winners are removed from the roster automatically, so you can draw again.
- Roster and log are synchronized, including for late joiners.
- Players who leave stay on the roster and are marked as away.
- Choose who can operate: everyone, master only, or a named list.
- Choose the draw pool: present players only, or all registered players.
- Log time supports JST, UTC, or any custom offset in minutes.
- Max participants is configurable from 1 to 100 (default 80).
- Each player can switch the effect to short mode and adjust or mute the sound
  for themselves only.
- In VR, pressing a button gives a short vibration to the presser's own
  controller, and at the reveal the winner present in the instance feels a
  triple vibration. Both can be disabled or tuned in the Inspector.
- In-world text supports Japanese, English, Korean, and Simplified Chinese.
  The world creator picks the language in the Inspector (one language for
  the whole world).
- Six panel types can be placed separately: Join, Roster, Volume, Draw, Log,
  and Winner History. Roster and Winner History can be created in read-only or
  operator mode. Add as many of each type as needed from the Inspector.
- The standard prefab separates player-facing controls under PlayerUI and
  operator controls under OperatorUI. The EzRaffle root remains the Core.
- The winner count is shared. Changing it on any Draw panel updates every Draw
  panel, and late joiners receive the current value.
- Winner History shows each name and cumulative win count. A repeat win after
  rejoining increments the count and moves that player to the top.
- A developer callback can trigger external Udon gimmicks (fireworks and the
  like) at the reveal moment.
- The Inspector supports Japanese, English, Korean, and Simplified Chinese.
- A preconfigured prefab and a sample scene are included.


Distribution
------------

EzRaffle is a free package distributed on BOOTH.

If you use VCC or ALCOM, installing from the VPM repository is recommended.
https://vpm.2aka.io/

Package page:
https://vpm.2aka.io/packages/com.niaka.ezraffle

The BOOTH download includes a .unitypackage and a shortcut for adding the VPM
repository. Add the repository to VCC or ALCOM, then add EzRaffle to your
project. You can also import the .unitypackage into your project directly.

BOOTH shop NiAka堂:
https://niaka.booth.pm/

Updating
--------

Once https://vpm.2aka.io/ is registered in VCC or ALCOM, new versions
appear in the list. Update from that window.

A .unitypackage you imported directly does not update itself. You have to
swap the files by hand for every release, so the VPM repository is the
easier route when you want update management.

Use either the .unitypackage or the VPM repository, but do not add both to
the same project.


Requirements
------------

- Unity 2022.3
- VRChat Worlds SDK 3.10.4 or newer
- TextMeshPro (included with the SDK)

SDK 3.10.4 or newer is required because the winner effect uses VRCTween.


Setup
-----

1. Drag Packages/com.niaka.ezraffle/Runtime/Prefabs/EzRaffle.prefab into the
   Hierarchy.
2. Select the EzRaffle root object. The setup Inspector opens.
3. In Step 1, check the For Players and For Operators sections. Player Roster
   and Winner History panels are read-only. Operator versions include their
   management controls. Each create button adds another panel or display.
4. In Step 2, set who can operate, the draw pool, the log time, the max
   participants, and the sounds.
5. In Step 3, press Validate All. Any item marked for action can be fixed with
   the repair button.
6. Upload your world.

Runtime/Sample/EzRaffleSample.unity shows an example placement.

The standard prefab places Join, Volume, read-only Roster, read-only Winner
History, and the winner display under PlayerUI. Draw, Log, operator Roster, and
operator Winner History sit under OperatorUI. Move either group or any panel as
needed. Every registered panel reads the Core on the EzRaffle root.


How to Use
----------

Join:
  A player presses Join on the Join panel. Their name is added to the
  roster. While joined, the row shows Joined, and the button next to it cancels.

Draw:
  An operator sets the winner count on a Draw panel, then presses Draw. The
  name roulette spins for 1.4 seconds and the stamp reveals the winners. Every
  Draw panel shows the same winner count.

Review:
  After the announcement, the winner display keeps showing the latest result.
  The Log panel records it with a timestamp. Winner History keeps each name
  and cumulative win count.

Remove from the roster:
  The operator Roster panel can remove a single player with the x button on
  each row, or clear the whole roster. Both ask for confirmation. The read-only
  Roster panel has no removal controls.

Clear winner history:
  The operator Winner History panel can clear the history after confirmation.
  The roster and log remain. The read-only Winner History panel has no clear
  control.

Local effect and sound:
  On the Volume panel, Short mode skips the name roulette: the display waits
  with a "coming up"
  message and shows only the result at the announcement time, which is the same
  for everyone. The speaker icon mutes the sound and the slider changes the
  volume. These apply only to you and are not sent to other players.

Display language:
  The language of the panel and the winner display is chosen in Step 2 of the
  Inspector. The log is also rendered in that language. There is no in-world
  switching.


Synchronization
---------------

The roster, log, latest winners, winner count, and cumulative winner history
are synchronized. Late joiners receive the current values. Only the Core on
the EzRaffle root owns this state; every registered panel displays it.

Draw results are synchronized together with the time at which they should be
revealed, so every client reveals at the same moment even on a slow connection.
Until the synchronized reveal time, the roster, log, and winner history stop
updating so the result is not shown early.

Join, cancel, draw, and remove requests are processed by the roster owner. Rapid
or simultaneous requests are throttled on the owner side.

Effect mode, volume, and mute are local settings. They are not sent to other
players and reset when you rejoin the world.

Winner History holds up to 100 unique names. Repeat wins can still increment
existing entries at the limit. A draw that could add a new name beyond the
limit is rejected, and old history is never removed automatically. Clear the
history explicitly on the Winner History panel before continuing.

The log is synchronized in a language-neutral format and rendered in the
language chosen in the Inspector, so changing the language later also re-renders
past log entries in the new language.


Inspector Settings
------------------

Who can operate:
  Everyone     - Every player can draw and remove. (default)
  Master only  - Only the instance master. The master is the first player who
                 joined and changes when they leave. This is not the world
                 author.
  Named list   - Only players whose displayName matches exactly. Use this to
                 guarantee that the host can operate.

Draw pool:
  Present only - Only players who are on the roster and in the world (default).
  All          - Registered players who left can also win.

In-world language:
  The display language of the panel and the winner display: Japanese, English,
  Korean, or Simplified Chinese. The log is rendered in this language too.

Log time:
  JST, UTC, or a custom offset in hours (decimals allowed). For example, 5.75
  means UTC+5:45.

Max participants:
  From 1 to 100. The default is 80, matching the VRChat instance limit.

Sounds:
  The roulette and stamp sounds can be replaced. The roulette sound plays once,
  timed so that it ends exactly at the reveal. The initial volume (default 0.3)
  is also set here; each player can change their own volume with the slider on
  a Volume panel. Audible distance is set on the AudioSource of the winner
  display.

Controller Vibration (VR):
  Button feedback gives a short vibration to the controller of whoever presses
  a button. Winner notification sends a triple vibration to the winner's own
  controller at the reveal, if they are present. Each can be toggled and its
  strength (0-1) adjusted. Vibration reaches only the VR player themselves;
  nothing happens on desktop.


Test Participants (dry run)
---------------------------

The Inspector has a Test Participants section at the bottom. In Play mode,
choose a count and press the seed button to fill the roster with dummy
participants. Then press Draw on a Draw panel to walk through exactly the real
flow: the participant list, the name roulette, the stamp reveal, and the log.

Dummies count as away, so the draw pool switches to All registered during
Play mode only. Everything resets when Play mode ends and nothing is changed
in the uploaded world.


Integrating with Other Udon Gimmicks (for developers)
-----------------------------------------------------

In the Inspector's Developer Options you can register UdonBehaviours that
receive a SendCustomEvent at the reveal moment. Use it to trigger fireworks,
confetti, or similar effect gimmicks. The call happens once per draw, locally
on each client, at the same timing for everyone.

Name the receiving method with a leading underscore (default:
_OnEzRaffleReveal). A public parameterless method without the underscore can
be invoked remotely by any player through VRChat network events.

Place the receiving UdonBehaviour on a GameObject other than the EzRaffle
Core. Sends to any UdonBehaviour on the Core's own GameObject are disabled to
prevent misrouting into internal operations.

From external UdonSharp code, hold an EzRaffleCore reference and use the read
APIs such as _GetLastWinnerNames() (latest winners), _GetRosterNames() (the
roster), and _GetAnnounceId() (draw ID). See the copyable samples inside
Developer Options for details.


Troubleshooting
---------------

Join does not add me to the roster:
  When the roster is full, the button reads Full. Check max participants. Join
  requests are also rejected while a result is being announced.

Draw is disabled:
  Check who can operate. If you lack permission, the reason is shown. It is also
  disabled when the pool has no eligible players. If Winner History holds 100
  names and a selected winner is not in it, the draw is rejected. Clear the
  history, then draw again.

Nothing appears on the winner display:
  Press Validate All in Step 3. If the display is not wired to the Core, the
  repair button fixes it.

I cannot hear the sounds:
  Check your own mute and volume first. If it is inaudible from a distance,
  increase Max Distance on the AudioSource of the winner display. Step 3 also
  warns about this.

I cannot press a panel in VR:
  Step 3 checks for VRCUiShape and BoxCollider. The repair button adds them.


Limitations
-----------

- The roster and the log hold up to 100 entries each. Oldest log lines are
  dropped.
- Winner History holds up to 100 unique names. Old history is not dropped, and
  a draw that cannot record a new winner is rejected.
- The roster records displayName. Renaming makes a player look like someone new.
- The in-world display language is fixed to the one chosen in the Inspector
  (no per-player switching).
- The vermilion stamp shows the kanji 当 (win) in every language as part of
  the visual design.
- Effect mode, volume, and mute reset when you rejoin the world.


Update History
--------------

■ 1.1.0 (2026/11/09)

・Housed the panels and the winner announcement in wooden frames, and widened
  the panel spacing to make room for the frames.
・Fixed an issue where names containing <, >, or & were displayed as text
  such as &lt;.
・Fixed the roster owner's screen not immediately showing "Left" for players
  who left.
・Reorganized the package files. Moved the sample scene to
  Runtime/Sample/EzRaffleSample.unity.
・LICENSE.txt now states that you may distribute or sell your own works
  that include this package, even as files.
・EzRaffle is now distributed on the VPM repository (https://vpm.2aka.io/).
・Added update instructions to README.txt.
・Changed the VRChat Worlds SDK dependency to 3.10.4 or newer.

■ 1.0.0

・First release.


Included Text
-------------

README.txt   This document.
LICENSE.txt  Terms of use.

Runtime/Fonts/OFL.txt contains the license of the bundled font.


Credits
-------

Bundled fonts (both under the SIL Open Font License 1.1):
  EzRaffleCjkRoot     - derived from Noto Sans JP (Copyright 2012 Google Inc.)
  EzRaffleCjkFallback - derived from Noto Sans CJK KR
                        (Copyright 2014-2021 Adobe)

The stamp glyph is rasterized from Noto Serif JP, also under the SIL Open Font
License 1.1.

The bundled TextMeshPro shaders under Runtime/Shaders are derived from
TextMesh Pro 3.0.6 and are provided under the Unity Companion License.
