| name | setup-resonite-env |
| description | Use when setting up the resonite-io dev environment on a fresh clone, configuring Gale profile, setting Steam Launch Options (WINEDLLOVERRIDES), or troubleshooting mod-load failures. Triggers: 'just init', 'Gale ãããã¡ã€ã«', 'WINEDLLOVERRIDES', 'check-gale', 'mod ãèªãŸããªã', 'ç°å¢æ§ç¯', 'fresh clone'. |
| version | 0.1.0 |
Setup Resonite-IO Dev Environment
resonite-io ããã¹ãã§åããããã«å¿
èŠãªæºåã®äžèЧãšèœãšã穎ã®è§£èª¬ããã¹ãåŽã§å¿
èŠãªãã®ã¯ docker / docker compose v2 / just ã«å ã㊠devcontainer ãéãææ®µ (VS Code ã® Dev Containers æ¡åŒµ / Zed / @devcontainers/cli) ã®ããããã.NET / uv / protoc / pre-commit ã¯ãã¹ãŠã³ã³ããå
ã«éããŠããã
1. Docker éçºç°å¢
éçºããŒã« (.NET 10 SDK / uv / protoc / dotnet local tools / pre-commit) 㯠debian:13-slim (trixie) ããŒã¹ã®åäž image ã«å梱ããhost ã«ã¯ã€ã³ã¹ããŒã«ããªããå image ã«ã¯ devcontainer å
ã§ Resonite ãèµ·åããããã® X11 / GPU ãŠãŒã¶ãŒã¹ããŒã¹ / audio / umu-launcher (Proton) ã忢±ããã
compose.yml 㯠.devcontainer/compose.yml ã«çœ®ã (name: resonite-io)ã.devcontainer/devcontainer.json ããããåç
§ãããbuild context ã .devcontainer/
- GPU åºæèšå® (
runtime: nvidia / devices / Mesa ç°å¢å€æ°ç) 㯠.devcontainer/compose.{nvidia,amd,intel}.yml overlay ã«åé¢ããinitialize.sh ã host GPU ãã³ããæ€åºã㊠.devcontainer/compose.gpu.yml symlink ã貌ã (NVIDIA / AMD / Intel 察å¿ãNVIDIA ã¯ãã©ã€ãã nvidia-container-toolkit ã injectãAMD 㯠Mesa RADV / Intel 㯠Mesa ANV ã build-arg GPU ã§ image ã«å梱)
- äœæ¥ãã£ã¬ã¯ããªã¯ host repo ã
/workspace ã«çŽæ¥ rw bindãhost åŽã®ç·šéãå³åº§ã« container åŽã«åæ ãããcontainer å
ã® build ææç© (bin/, obj/, python/.venv/ ç) ã .gitignore çµç±ã§ host åŽã«åºã
- Resonite ãã©ã«ãã¯
/resonite ã« read-only bind ã®ã¿ (FrooxEngine.dll çã® HintPath åç
§çšãã〠container å
Resonite èµ·åæã® rsync sourceãmod ã® deploy å
ã§ã¯ãªã)
- Resonite çš named volume:
resonite-app (/opt/resonite ã€ã³ã¹ããŒã«ã³ããŒ) / resonite-share (~/.local/shareãSteamRT/Proton + ãŠãŒã¶ãŒããŒã¿) / resonite-cache (~/.cache) / resonite-prefix (~/prefixãWine prefix)
- Gale ãããã¡ã€ã« (
./gale/) 㯠/workspace/gale çµç±ã§åç
§ãã (environment.GalePath: /workspace/gale ã csproj ã® deploy å
ã解決)
- ã³ã³ããå
dev user ã® UID/GID ã host user ã«äžèŽ ãã㊠build (HOST_UID / HOST_GID ã build-arg ã§æž¡ã)ãããã«ãã deploy-mod ã§åºåããã DLL/PDB ã host user ææã«ãªããhost åŽ git ãããã®ãŸãŸèŠãã
- NuGet / uv ã®ãã£ãã·ã¥ã¯ named volume ã«ããŠã³ãããŠåãã«ããé«éå (
/home/dev/.nuget / /home/dev/.cache/uv)
csharpier / tcli çã® .NET CLI ããŒã«ã¯ .config/dotnet-tools.json ã® local tool ãšããŠåºå®ããdotnet tool restore + dotnet <tool> ã§åŒã³åºã
åå setup ãããŒ:
.env.example ã .env ã«ã³ããŒããResonitePath ã Resonite å®è¡ãã¡ã€ã«ãã£ã¬ã¯ããªçµ¶å¯Ÿãã¹ã«èšå® (container å
Resonite èµ·åã§ã¯ /resonite:ro bind ã® source ãšããŠåå©çšããã)
just init ã host åŽã§å®è¡ â docker / docker compose v2 æ€åº â .env æ€èšŒ â ResonitePath æ€èšŒ â Gale ãããã¡ã€ã«ç¢ºèªãåªçã«å®æœ
- devcontainer ãéã â VS Code: ãDev Containers: Reopen in ContainerããZed: dev container ãšããŠéããCLI (ä»»æã»headless / CI çš):
devcontainer up --workspace-folder . â devcontainer exec --workspace-folder . bash (@devcontainers/cliãæ¢å®ã§ã¯æªã€ã³ã¹ããŒã«)
- devcontainer ãèªåå®è¡ãã:
initializeCommand (host åŽã»äœæåã.devcontainer/initialize.sh): host UID/GID ã .env ã«èšé² (build-arg ã§ã³ã³ãã user ã«äžèŽãããdeploy ææç©ã host ææã«ãªã)ãå ã㊠container å
Resonite èµ·åã®ããã« AppArmor ã®éç¹æš© user namespace å¶éã hard fail ãã§ã㯠(§6 åç
§)ãDISPLAY / X auth cookie (FamilyWild æžæãã§ .xauth) / renderã»video GID / GPU ãã³ããæ€åºã㊠.env ã«èšé²ããcompose.gpu.yml symlink ã貌ããæ¬çª gRPC UDS dir 㯠host åŽã«äœããªã â Resonite 㯠container å
ã§èµ·åããmod (GrpcHost) ã container å
~/.resonite-io/ ã bind åã«èªåã§ mkdir ãã
postCreateCommand (container å
ã»äœæåŸ): scripts/container-init.sh ãå®è¡ (deps 解決: dotnet tool restore + uv sync + pre-commit install + Claude settings symlink)
- 以éã¯ã³ã³ããå
ã¿ãŒããã«ã§
just gen-proto / just build / just deploy-mod çãåŸæ¥ã©ããå®è¡ãããdevcontainer å
ã§ Resonite ãèµ·åããå Žå㯠just resonite-launch --vanilla (mod ãªã) / just resonite-launch (mod 蟌ã¿) (§5)
2. Gale ãããã¡ã€ã«æ¹åŒ
ãã¹ã Resonite ã«ã¯ BepisLoader ãçŽæ¥ã€ã³ã¹ããŒã«ããªã (Vanilla ç¶æ)ã代ããã« Gale (v1.5.4+) ã®ã«ã¹ã¿ã ãããã¡ã€ã«æ©èœã§ repo root ã® ./gale/ ã mod sandbox ã«ããã
æåã»ããã¢ããæé :
- Gale ã§ profile ãæ°èŠäœæãããã¹ã
<repo>/gale ã«æå® (æå®å
㯠EMPTY ã§ããå¿
èŠãããã./gale/ ãäºåã«äœããªã)
- profile ã«å¿
é mod ãæå
¥ãã:
- æšå¥š: äœæãã profile ãéžæããç¶æ
ã§ Import > ... profile from file ãéžã³ã
<repo>/GaleProfile.r2z (å¿
é mod ãçæå®èŸŒã¿ã§å«ã repo 忢±ã® profile snapshot) ãéžãã§ profile ã overwrite ãããããã§å¿
é mod äžåŒãäžæ¬ã§æå
¥ããã
- ãã©ãŒã«ãã㯠(æå): snapshot ã mod æŽæ°ã«è¿œåŸããŠå€ããªã£ãå Žåçã¯ãä»¥äž 6 åãåå¥ã« install ãã:
ResoniteModding-BepisLoader (>=1.5.1)
ResoniteModding-BepInExResoniteShim (>=0.9.3)
ResoniteModding-BepisResoniteWrapper (>=1.0.2)
ResoniteModding-BepInExRenderer (>=5.4) â Camera v2 ã§è¿œå (Renderer åŽ BepInEx 5 frameworkãRenderer/BepInEx/core/ ã« framework deploy)
ResoniteModding-RenderiteHook (>=1.1.1) â Camera v2 ã§è¿œå (engine â Renderer doorstop inject)
Nytra-InterprocessLib (>=3.0.0) â Camera v2 ã§è¿œå (engine â Renderer shared-mem queue)
GaleProfile.r2z ã¯ãããŸã§å©äŸ¿ã®ããã® snapshot ã§ãããå¿
é éšåã®æ£æ¬ã¯ just check-gale (äžèš step 4)
- Gale ã§ Resonite ãèµ·åãããš
LinuxBootstrap.sh ããããã¡ã€ã«çã«å·®ãæ¿ãããBepInEx ãæå¹åããã
just check-gale (ãŸã㯠just init) ã§å¿
é DLL ã®åšäžãæ€èšŒ
just deploy-mod ã§ Thunderstore zip ã pack ã gale/BepInEx/plugins/ResoniteIO/ é
äžãžå®ã€ã³ã¹ããŒã«ãšåãã¬ã€ã¢ãŠãã§å±éãã (engine DLL ã¯äžæ®µãã¹ãã㊠âŠ/ResoniteIO/ResoniteIO/ ã«å
¥ããbuild æã®èªå deploy ã¯å»æ¢ã deploy-mod ã® 1 çµè·¯ã«éçŽæžã¿)
just check-gale 㯠BepInExRenderer æ€åºæã« Renderer/BepInEx/core/BepInEx.Preloader.dll ã®ååšã§å€å®ãã (plugin dir ã§ã¯ãªã framework dir ã« deploy ãããããfeedback_bepinex_renderer_as_framework.md åç
§)ã
Camera v2 Renderer plugin (committed prebuilt)
Camera v2 ã® Renderer åŽ plugin (ResoniteIO.Rendererãnet472 Unity MonoãBepInEx 5) ã¯ãjust deploy-mod ã pack æžã¿ zip å
ã® committed prebuilt ã gale/Renderer/BepInEx/plugins/ResoniteIO/ResoniteIO.Renderer/ ãžå±éãã (engine åŽ gale/BepInEx/plugins/ResoniteIO/ ãšã¯å¥ç³»çµ±)ã
UnityEngine.CoreModule ãéåé
åžã§ CI build äžå¯ã®ãããé
åžç© (Thunderstore zip) ã«ã¯ committed prebuilt mod/prebuilt/renderer/ ã忢±ãã (release-resonite skill §7 åç
§)ãRenderer ã®ãœãŒã¹ (mod/src/ResoniteIO.Renderer/ ⥠mod/src/ResoniteIO.RendererShared/) ã倿ŽããããResonite ã®ããããŒã«ã«ã§ just renderer-prebuild ãå®è¡ã mod/prebuilt/ ã®å·®åã commit ãããå¿ãããš just run æ«å°Ÿã® check-renderer-prebuilt (ããã³ CI ã® drift guard) ã fail ããã
ãã¹ã Resonite ã Vanilla ã§èµ·å (Gale ãä»ãã Steam ããçŽæ¥èµ·å) ããå Žå㯠mod ã¯èªã¿èŸŒãŸããªããæ³šæ: Gale çµç±èµ·ååŸã«ãã¹ã Resonite ãã£ã¬ã¯ããªãž hookfxr.ini (enable=true) çãæ®ãå ŽåããããVanilla 埩垰æã¯ç¢ºèªããããšã
3. WINEDLLOVERRIDES (äž¡çµè·¯ã§å¿
é â container ã¯èªå exportãhost Steam ã¯æå)
Camera v2 ã® Renderer åŽ BepInEx ãèµ·åããã doorstop 㯠hook ç winhttp.dll ãããã·ã§ãWine ã« system 忢±ã§ãªã hook ç winhttp.dll ãèªãŸããã«ã¯ ã©ã¡ãã®èµ·åçµè·¯ã§ã WINEDLLOVERRIDES="winhttp=n,b" ãå¿
èŠ (2026-06-19 宿©æ€èšŒ)ã--doorstop-* ã® CLI åŒæ°ã¯ doorstop ã® æå ãèšå®ããã ãã§ãwinhttp.dll ã® èªã¿èŸŒã¿èªäœ ã¯ãã® override ãåæãçµè·¯ã§éãã®ã¯ã誰ã override ãèšå®ããããã ã:
- container å
just resonite-launch çµè·¯: resoio launch (python/src/resoio/launcher.py) ã mod èµ·åæã« WINEDLLOVERRIDES="winhttp=n,b" ãèªåã§ export ãããã å©çšè
ã®æåèšå®ã¯äžèŠãumu-run 㯠Steam ãšéã env ãçŽ éãããã®ã§ env çµç±ã§æž¡ãã
- host Steam çµç±èµ·åã®å Žå: Steam ã§ Resonite ãéžæ â Properties â Launch Options ã«ä»¥äžãèšå®ãã:
WINEDLLOVERRIDES="winhttp=n,b" %command%
- ãªãå¿
é : Wine 㯠system 忢±
winhttp.dll ãåªå
ãããããRenderiteHook ã deploy ãã hook ç winhttp.dll (= doorstop) ãèªãŸããã«ã¯ override ãå¿
èŠããããç¡ããš Renderer åŽ BepInEx ã¯æ°žé ã«èµ·åãããCamera v2 ã® renderer-side plugin ã load ãããªã
- debug ãå°é£: çã®åå ã override æŒãã§ããããšã¯
/proc/<pid>/environ ã§ç¢ºèªã§ããªããšèŠæããªã (Wine ããã»ã¹ã® env ã host ããèŠãã®ãé¢å)
- host Steam ã§ã¯ Launch Options ãå¯äžã®çµè·¯: env ã§
WINEDLLOVERRIDES ãæž¡ããŠã Steam ã sanitize ããããéããªããumu-run ã¯çŽ éããªã®ã§ container ã§ã¯ resoio launch ã env ã§æž¡ããããšããéã
4. UDS ãã¹ãš pressure-vessel sandbox
- æ¬çª gRPC IPC ã¯
$HOME/.resonite-io/ãResonite ã container å
ã§èµ·åãããã host ãšã¯å
±æãããcontainer å
/home/dev/.resonite-io/ ã« mod (GrpcHost) ã socket ãäœããå container å
ã® Python client ããããž connect ãã
$XDG_RUNTIME_DIR/ (= /run/user/<UID>/) 㯠pressure-vessel sandbox ãéããªãããäžæ¡çš
/tmp/ ãéããªãã$HOME/ é
äžã®ã¿ãå®å
š
- 詳现ã¯
reference_pressure_vessel_paths.md
5. devcontainer å
ã§ Resonite ãèµ·å (just resonite-launch)
devcontainer å
ã§ Resonite ãçŽæ¥èµ·åã§ãããro bind ã® /resonite ããæžèŸŒå¯èœãª /opt/resonite ãžã® rsync 㯠.devcontainer/entrypoint.sh ã container èµ·åæã«è¡ã (åå㯠install ã³ããŒã2 åç®ä»¥éã¯å·®åã®ã¿)ãresoio launch (python/src/resoio/launcher.py) ã umu-run (umu-launcher/Proton) ã§ RESONITE_EXE (= /opt/resonite/Resonite.exe) ãèµ·åãããGE-Proton ã¯ããŒãžã§ã³åºå®ã§ image ã« prefetch æžã¿ (PROTONPATH=/opt/proton/GE-Proton10-34) ãªã®ã§èµ·åæã® Proton DL ã¯çºçããªããåå㯠install ã³ã㌠(~2GB) ã§æéããããã
èµ·åã»åæ¢ã¯ä»¥äž:
just resonite-launch (= resoio launch): MOD_PATH ã® Gale ãããã¡ã€ã« (./gale = /workspace/gale) ãã mod 蟌ã¿ã§èµ·åãããengine åŽã¯ hookfxrãRenderer åŽã¯ doorstop (hook ç winhttp.dll)ãresoio launch ã WINEDLLOVERRIDES="winhttp=n,b" ãèªå export ãããã Steam Launch Options ã®æåèšå®ã¯äžèŠ (§3)ã./gale/BepInEx ãç¡ããã° fail-fast (å
ã« just deploy-mod)ãengine (native ã® dotnet ããã»ã¹) ãš renderer (Renderite.Renderer.exe) ã®äž¡ããã»ã¹ãçŸãããŸã§åŸ
ã£ãŠããäž¡ host PID ãè¿ããæ¢ã«èµ·åäžãªã error (single-instance)
just resonite-launch --vanilla: mod ãèªãŸãªãçŽ ã® Resonite ãèµ·å (èµ·å確èªã»åãåãçš)
just resonite-stop (= resoio terminate): engine + renderer ã psutil çµç±ã§ SIGTERM â 3s â SIGKILL ã®æ®µé killãengine ã®å®äœã¯ dotnet ããã»ã¹ã§ãResonite.exe åã®ããã»ã¹ã¯ wine ããŒãã¹ãã©ããã«ãããªã
- èµ·åç¶æ
ã®ç¢ºèªã¯
pgrep -af Renderite.Renderer.exe (renderer ããã»ã¹ã®æç¡ã§å€å®)
just resonite-launch ã§èµ·åãã mod ã®ãã°ã¯ gale/BepInEx/LogOutput.log (just log ã§ tail)ãumu/Proton ã®èµ·åãã€ãºã¯ gale/BepInEx/umu-launch.log ã«åé¢ãããã
åæ (host åŽ)
- graphical session (X11 / Xwayland): Resonite ã®æç»ã«å¿
èŠã
initialize.sh ã DISPLAY ãæ€åºããX auth cookie ã FamilyWild (ffff) æžæãã§ .xauth ã«çšæãã (container hostname ãã©ã³ãã ã§ MIT-MAGIC-COOKIE ã® hostname ãããã«å€±æãããã)
- PipeWire/PulseAudio: é³å£°ã«å¿
èŠ (ç¡ããšååãªã³ããŒãã£ã³ã°ã§åºãŸãããšããã)
- AppArmor ç·©å:
kernel.apparmor_restrict_unprivileged_userns=0 ãå¿
é (§6 åç
§)
- GPU: NVIDIA / AMD / Intel ãããã察å¿ã
initialize.sh ããã³ããæ€åºã㊠compose overlay ãåæ¿ãã
.env 倿° (éåžžã¯æåèšå®äžèŠ)
initialize.sh ãèªåæ€åºã㊠.env ã« upsert ããããéåžžã¯è§Šããªã: DISPLAY / XAUTHORITY_HOST / RENDER_GID / VIDEO_GID / NVIDIA_GPU_UUID / AMD_RENDER_NODE / AMD_VK_DEVICE_SELECT / AMD_DRI_PRIMEãæ¢åã® ResonitePath ã¯ãã®ãŸãŸ (/resonite:ro bind ã® source ãšããŠåå©çšããã)ã
6. AppArmor: éç¹æš© user namespace
pressure-vessel (Steam Linux Runtime) ã¯éç¹æš© user namespace ãå¿
èŠãšãããUbuntu 24.04+ ã¯æ¢å®ã§ããã AppArmor ã§å¶éãããããkernel.apparmor_restrict_unprivileged_userns=0 ãç¡ããš container èµ·åã 倱æãã (host åŽ initialize.sh ãš container åŽ entrypoint.sh ã®äºæ®µã§ hard fail)ã
sudo sysctl kernel.apparmor_restrict_unprivileged_userns=0
echo 'kernel.apparmor_restrict_unprivileged_userns=0' | sudo tee /etc/sysctl.d/99-resonite-userns.conf
sudo sysctl --system
7. é¢é£ memory
8. 宿© mod load æ€èšŒæé
just deploy-mod â just resonite-launch (container å
ã§ mod 蟌㿠Resonite ãèµ·å) â just log ã§ gale/BepInEx/LogOutput.log ã tail ããLoading Plugin ResoniteIO è¡ãåºãã®ãç¢ºèª â just resonite-stop ã®æµããClaude ã container å
ã§å®çµã§ããã詳现㪠debug çµè·¯ã¯ /debug-resonite-mod skill ãåç
§ã