Releases

  • rgss123 1.0.0

    1.0.0 주요 변경사항

    이름을 rgss123으로 바꾸고 RPG Maker XP(RGSS1) 게임을 초기 범위로 받으며, 깊은 C 재귀로 runtime이 멈추던 문제를 고치고 player SDK에 opt-in API를 더한 1.0.0입니다.

    이름 변경(호환성 깨짐)

    • 이름이 바뀌어 0.1.x와 호환되지 않습니다. host는 package 이름, import, 오류 code 분류, contract ID와 storage namespace를 한 번에 함께 바꿔야 합니다.
    • npm package는 @rgss23/arca에서 **@arca/rgss123**으로 바뀌었습니다. registry 주소 https://git.2ex.dev/api/packages/hanyul/npm/는 같고, .npmrc의 scope 줄은 @arca:registry=입니다.
    • API·타입은 Rgss23*와 Arca*에서 Rgss123*로 바뀌었습니다(예: launchRgss123Player, getRgss123Release, stageRgss123Release, prepareRgss123Rtp). npm facade의 ArcaBuilderError는 Rgss123BuilderImageError입니다.
    • 오류 code는 ARCA_*에서 RGSS123_*로, CLI는 arca-release에서 rgss123-release로 바뀌었습니다. 오류 message 안의 ARCA도 rgss123입니다.
    • schema·contract·interface ID(rgss123-*, links-rgss123-web-launch-v1), 환경 변수(RGSS123_*), OPFS·Web Lock·storage namespace(rgss123-lazy 등), page global과 native runtime patch symbol·protocol이 함께 바뀌었습니다.
    • player SDK 기본 저장소의 save 경로 prefix는 arca-path-v1/에서 rgss123-path-v1/로, runtime 가상 경로는 /arca/에서 /rgss123/로 바뀌었습니다. migration은 없으며 이전 prefix로 저장한 snapshot은 원래 파일로 복원되지 않습니다.
    • 배포 파일 이름(rgss123-runtime-*.zip, rgss123-builder-*.oci.tar, rgss123-contracts-*.tgz, rgss123-arca-*.tgz), Builder 명령 rgss123-builder, Docker image·volume 이름도 바뀌었습니다. 저장소는 git.2ex.dev/hanyul/rgss123-web입니다.
    • 이전 이름은 어디에서도 받지 않습니다. deprecation 기간 없이 사용자 승인으로 바꿨습니다.

    RPG Maker XP(RGSS1) 초기 범위

    • .rxdata·.rgssad로 XP 게임을 알아보고, Game.ini의 RTP와 RTP1–RTP3을 읽습니다. XP는 VX처럼 mkxp.json에 syntaxTransform: 2가 필요하며 XP용 runtime patch는 없습니다.
    • XP RTP는 prepareRgss123Rtp({ id: "RPGXP" })가 공식 xp_rtp104e.exe에서 Standard.mkxpz(Audio·Graphics)로 만듭니다. npm package에 RTP 데이터는 들어 있지 않습니다.
    • contracts에 engine xp, runtime configuration.json의 engines에 rpg-maker-xp를 더했습니다. 이 값은 runtime이 XP 게임을 받아 실행한다는 선언이며 XP 일반 지원 판정이 아닙니다.
    • XP 근거는 제공 샘플 하나의 자동 title·play smoke이고 사용자 확인은 하지 않았습니다. 대부분 이전 runtime에서 실행했고 이 release의 runtime에서는 Chrome title만 다시 확인했습니다.

    runtime

    • sandbox CRuby의 C 함수 안에서 재귀가 깊어지면 runtime 전체가 중단되던 문제를 고쳤습니다. 이제 게임 script가 잡을 수 있는 SystemStackError가 납니다(한도 640 frame, C 코드가 오류를 삼킨 뒤의 두 번째 한도 672 frame).
    • 한도는 이전 runtime이 비결정적으로 중단되던 깊이보다 경로마다 약 10~20% 낮습니다. Windows Chromium 156·Firefox 153에서 측정했고, 다른 OS·브라우저의 stack 크기와 실제 게임의 깊은 장면은 확인하지 않았습니다.
    • runtime이 MIDI 재생에 쓰는 기본 SoundFont GMGSx.sf2를 public domain으로 기록하고 runtime ZIP의 license 고지에 넣었습니다.

    player SDK

    • Rgss123ArtifactSource.openBlob으로 host가 이미 가진 Blob을 runtime·game·RTP artifact로 넘길 수 있습니다.
    • artifactTransfer(idleTimeoutMs·retries)로 artifact 전송이 멈췄을 때의 timeout과 재시도를 켤 수 있습니다.
    • runtime JS·WASM을 page 사이에 재사용하는 read-through cache(createRgss123CachedArtifactSource, Rgss123ArtifactBlobStore, OPFS 구현 createRgss123OpfsArtifactStore)를 더했습니다. host가 준 namespace에 두며 save와 분리됩니다.
    • 전체화면 helper requestRgss123Fullscreen·exitRgss123Fullscreen·isRgss123Fullscreen을 더했습니다. backing은 그대로 두고 CSS로 확대합니다.
    • prepareRgss123Rtp()가 선택 onProgress로 RTP 준비 진행을 알립니다.
    • 자동 저장은 직전과 byte가 같은 save 파일의 SHA-256을 다시 계산하지 않습니다.
    • 새 API를 쓰지 않으면 이름 변경을 뺀 동작은 0.1.27과 같습니다. Emscripten 6 runtime(0.1.16 이후)만 받습니다.

    Builder와 release

    • Builder build context의 줄바꿈을 모든 host에서 LF로 고정하고, Builder build 전과 Builder gate에서 LICENSE를 release manifest의 licence sha256과 대조합니다.
    • Linux host에서 release를 만들 때 생기던 결함(Builder context 파일 mode, 비root Builder가 쓰는 출력 디렉터리, ZIP 읽기)을 고쳤습니다.
    • Forgejo release 제목은 rgss123 <version>입니다.

    배포 파일

    runtime ZIP, Builder OCI, contracts tgz, npm tgz와 release manifest·pin·checksum 일곱 파일이 모두 바뀌었고, 앞의 네 파일은 이름이 rgss123-*로 바뀌었습니다. version 문자열은 먼저 게시했다가 지운 1.0.0과 같지만 bytes와 hash는 다릅니다.

    호스트 업데이트와 주의사항

    적용 절차는 1.0.0 적용 시 확인할 동작 변경을 따릅니다.

    • package 교체: @rgss23/arca를 지우고 @arca/rgss123을 1.0.0 exact pin으로 설치합니다. import, error.code 분류, CLI 호출, contract ID, storage namespace를 같은 변경에서 함께 바꿉니다. 이름 목록은 1.0.0 이름 변경에 있습니다.
    • 지운 게시본: 이 1.0.0은 먼저 게시했다가 지운 1.0.0(2026-10-29·30)과 1.1.0(2026-10-31)을 대체합니다. 그 게시본을 받아 둔 환경은 lockfile을 새로 만들고, 그 Builder로 만든 generation을 재사용하지 않습니다.
    • 이전 package: @rgss23/arca(0.1.x)는 registry에서 지웠습니다. 0.1.x로 되돌릴 때는 이미 만든 이미지나 Forgejo release에 첨부한 rgss23-arca-<version>.tgz를 씁니다.
    • Builder: 새 Builder digest·config digest를 pin과 대조하고, 기존 generation은 1.0.0 Builder로 다시 만듭니다.
    • save: SDK 기본 저장소의 이전 snapshot은 새 prefix로 복원되지 않습니다. 이어 써야 하면 host가 snapshot 키를 변환합니다.
    • XP: XP 게임을 받으려면 prepareRgss123Rtp({ id: "RPGXP", storeRoot })로 RTP를 준비하고, artifact 이름 Standard.mkxpz를 그대로 둡니다. 판정은 RPG Maker XP (RGSS1)에 있습니다.
    • opt-in API: 새 SDK API는 필요할 때만 켭니다. 도입 버전은 player SDK README에 있습니다. 전체화면으로 전환하는 순간 누르고 있던 키는 다시 눌러야 하고, 전체화면 중 Escape는 브라우저가 종료에 씁니다.
    • 알려진 한계: VX·VX Ace의 사용자 확인 기준 runtime은 0.1.25이고 1.0.0 사용자 확인은 하지 않았습니다. 그 밖의 한계는 알려진 한계와 위험에 있습니다.

    0.1.27 대비 전체 변경

    Downloads 9
  • ARCA 0.1.27

    ARCA 0.1.27 변경 사항

    이전 버전: 0.1.26. ARCA 저장소의 개발 도구와 reference app만 바뀐 release다. host가 쓰는 native runtime(mkxp-z core JS·WASM), player SDK, Builder와 contracts의 동작·공개 API·기본값·오류 code·schema는 0.1.26과 같다. runtime ZIP의 rgss23-core.js·rgss23-core.wasm은 0.1.26과 같은 runtime export에서 만든다. version 문자열(package version, Builder compatibility report producer의 contractsVersion·inspectorVersion)이 바뀌어 runtime ZIP·contracts tgz·Builder archive·npm tgz bytes와 release pin을 새로 고정한다.

    포함 변경 요약

    개발 도구: puppeteer-core 25.16.0

    • root devDependency puppeteer-core를 25.15.0에서 25.16.0으로 올렸다(exact pin 유지). release artifact에는 들어가지 않는다.
    • pnpm-lock.yaml은 그 하위 의존성(@puppeteer/browsers 3.2.6, modern-tar 0.8.6, devtools-protocol)만 바뀌었다.
    • cross-browser title smoke 계약의 automation.puppeteerCore 단언을 25.16.0으로 바꿨다.

    로컬 이전 content generation 정리(pnpm clean:generations)

    • ARCA checkout의 work/web-public·dist/web에 쌓인 이전 generation을 정리하는 수동 명령이다. 기본은 dry-run이고 --apply일 때만 삭제한다.
    • 두 catalog가 참조하는 generation, root별 최신 runtime generation과 artifact 파일명별(게임·엔진별 RTP) 최신 generation을 보존한다. 두 root 밖(games/**, dist/release/**, dist/npm/**, work/runtime/**, work/cache/** 등)은 건드리지 않으며 link·junction과 보호 경로를 realpath로 다시 확인한다.
    • browser prepare(tools/prepare-browser-smoke.mjs)와 work/web-public.lock으로 서로 배제한다. 죽은 소유자의 lock은 이름 변경 방식으로 안전하게 넘겨받고, 삭제는 .deleting-*로 이름을 바꾼 뒤 지워 중단된 삭제를 다음 --apply가 마무리한다.

    reference app: OPFS 이전 generation 정리

    • catalog 게임을 준비하기 직전에 게임별 Web Lock(arca-reference-game:<id>)을 exclusive로 얻은 탭만 현재 catalog가 가리키지 않는 games/<id>/content/<sha256>와 SDK 지연 cache rgss23-lazy/<id>/{game,rtp}/<sha256>를 지운다. save·state·폴더 실행 namespace는 건드리지 않는다.
    • 다른 탭이 같은 게임을 준비·실행 중이면 정리를 건너뛰고, 다른 탭이 정리 중이면 기다린 뒤 준비한다. Web Locks가 없거나 요청이 거절되면 정리 없이 기존처럼 준비·선부팅한다. 정리 실패는 경고만 남기고 실행을 막지 않는다.
    • reference app은 SDK 기본값과 같은 지연 cache directory(rgss23-lazy)를 공개 option으로 명시해 기존 cache를 그대로 쓴다. SDK에 정리 API는 추가하지 않았다.

    문서

    • LINKS 가이드에 0.1.27 절을 더했다. 프로젝트 상태·호환성 매트릭스·검증 체크리스트·아키텍처에 위 변경과 자동 근거를 기록했다.
    • release bytes에 들어가는 packages/contracts/README.md, packages/packager-rgss/README.md, tools/release/npm/README.md는 0.1.26 이후 바뀌지 않았다.

    자동 근거(2026-10-24, 같은 PC)

    • puppeteer-core 25.16.0: test:browser-tools PASS, browser:smoke:chrome:vx-ace:title 자동 PASS(0.1.26 runtime, system Chrome 155.0.8059.86, report automation.puppeteerCore 25.16.0).
    • clean:generations: clean-generations.test.mjs·prepare-browser-smoke-lib.test.mjs(test:browser-tools) PASS, 합성 tree의 dry-run·--apply(보호 경로 보존, 중단된 삭제 정리, 죽은 lock 인계) PASS, main checkout dry-run은 삭제 대상 없음.
    • reference app 정리: apps/web vitest PASS(실제 SDK 지연 실행으로 만든 이전·현재 generation 중 비현재만 삭제, 다른 탭 lock, Web Locks 없음·거절 fallback). Edge VX Ace title smoke(0.1.26 runtime, commit 800b089) 자동 PASS는 lock 경로가 실행을 막지 않는다는 근거이며 새 profile이라 삭제는 일어나지 않았다.
    • runtime은 0.1.26과 같은 bytes라 runtime smoke와 그 밖의 browser smoke는 다시 실행하지 않았다. built release artifact로 한 browser smoke도 실행하지 않았다.

    알려진 문제와 위험

    • 0.1.25 runtime에 기록한 사용자 acceptance PASS는 0.1.26·0.1.27 runtime으로 이어지지 않는다(사용자 acceptance NOT RUN).
    • reference app 정리는 실행 중인 이전 build의 탭(lock을 잡지 않음)을 보호하지 못한다. 갱신 뒤 이전 탭을 닫는다. 오래된 catalog를 가진 탭이 새 generation cache를 지우는 최악의 경우에도 다음 실행이 Range 요청으로 다시 읽는다.
    • clean:generations는 실행 중인 vite dev/preview/smoke server와 열린 탭을 감지하지 못한다. 정리 전에 server를 멈추고 탭을 닫으며 pnpm build와 동시에 실행하지 않는다.
    • 0.1.26의 나머지 한계(전체화면 크기, CRuby 4.0 Ractor·Prism·shape 용량, 이식 코드 고지 version, 소수 DPR pointer 경계)는 그대로다.

    host 적용 순서

    LINKS 적용 가이드 0.1.27 절을 따른다. 요약:

    1. host 측 동작 변경은 없다. 0.1.26을 아직 적용하지 않았다면 0.1.26 절의 확인(Firefox player-dpr RGSS 셀 page error 0 등)을 함께 한다.
    2. @rgss23/arca 전체를 0.1.27 exact pin으로 올린다(runtime·SDK·Builder·contracts 함께).
    3. coordinator가 새 Builder digest·config digest를 pin과 대조하게 한다. pin이 바뀌므로 기존 active generation은 새 준비를 거치며 0.1.27 Builder로 generation을 다시 만든다(native runtime bytes가 같아도 strict release binding에서는 이전 release generation을 재사용하지 않는다).

    NOT RUN

    • 사용자 acceptance(0.1.26·0.1.27 runtime), LINKS 적용.
    • 이전 generation이 있는 실제 브라우저 profile의 reference app 삭제 smoke, 다중 탭 확인, main checkout의 실제 clean:generations --apply.
    • puppeteer-core 25.16.0으로 한 Firefox·Edge smoke.
    • Linux 재현.

    배포 검증

    • tag: 0.1.27(annotated, tag object 2842f72aa3)
    • release source: f105ddb6c1(Release: prepare ARCA 0.1.27)
    • manifest SHA-256: 8a4e4c252fb30a68305655484babffc7f894651279c9c5eb1ed2b20357906052
    • Builder digest(pin): sha256:2c46d1dbb66ac5e09b507ce1dd24f4253e82f05b8681a6dfe0baa4f14d589dbf · Builder config digest(pin builderConfigDigest): sha256:aaae1db26abd10a0f17929cbd5f61ec9a58b8b0a9fdb3e6bb14e19f592d4dbe9
    • artifact SHA-256: builder f232767bff58d4dac90cf1fea0e4307299c913679a60ae01f334e58ce394fb06 · contracts bf98fdd3cc818825c49c9658918529884e123692a9220699995ac38862874149 · runtime b862a3781451daa46c7bf13a1fd274fcc27469664ae5be66d873b16e6afd64f8
    • npm: rgss23-arca-0.1.27.tgz SHA-256 2fd95ab9dd4e77bd6f631096bfeb4eea3106eef5bc0e2e8176e770ea3990aef6, integrity sha512-Ek7JIJtqa/uNt9IUBMWCXW2EQf38A4hxtlgff5QQo0DWWwkB4E7qoaKQQp/X2gdWBlfCfODtikeKhfPz+V4GNw==
    • runtime ZIP의 rgss23-core.js(b34cd34b… 272,967 B)·rgss23-core.wasm(c4ac76c4… 48,400,171 B)은 0.1.26과 같은 canonical runtime export와 byte 동일하고, export provenance가 runtime lock c216a320…·recipe·Dockerfile·patch hash와 일치한다. redistribution-policy.json runtimeLockSha256은 dependencies.lock.json과 일치한다(2026-10-24 승인 유지). runtime은 다시 build하지 않았다.
    • 게이트(source f105ddb, 2026-10-24): install --frozen-lockfile, 단위 테스트 674개, 타입 검사, release 회귀 51개, browser 도구 회귀 159개, verify:locks, native 준비 recipe 검증, git diff --check PASS(work/release-0.1.27/logs/)
    • release:build(Builder gate·source-free consumer gate)·release:verify·release:npm:test·release:reproduce: PASS(2026-10-24, source f105ddb, manifest sourceCommit = HEAD; release:reproduce는 clean detached worktree에서 end-to-end로 pin·세 artifact·Builder digest·npm이 동일, work/release-0.1.27/logs/). Windows·같은 Docker host만, Linux 재현 NOT RUN.

    asset 7개

    파일 크기(B) SHA-256
    release-manifest.json 2,155 8a4e4c252fb30a68305655484babffc7f894651279c9c5eb1ed2b20357906052
    release-manifest.sha256 88 f8d0424f61f1a44fe5f0e7bbb79155fbc28c6d195f1a060d35ea4af5adb4cd6b
    release-pin.json 537 282c6018dfc3f589703b06f37ff5d506d90de177227053804562ef05605e9582
    rgss23-arca-0.1.27.tgz 103,627,133 2fd95ab9dd4e77bd6f631096bfeb4eea3106eef5bc0e2e8176e770ea3990aef6
    rgss23-builder-0.1.27.oci.tar 63,196,672 f232767bff58d4dac90cf1fea0e4307299c913679a60ae01f334e58ce394fb06
    rgss23-contracts-0.1.27.tgz 38,268 bf98fdd3cc818825c49c9658918529884e123692a9220699995ac38862874149
    rgss23-runtime-0.1.27.zip 50,122,220 b862a3781451daa46c7bf13a1fd274fcc27469664ae5be66d873b16e6afd64f8

    로컬 경로: dist/release/0.1.27/, dist/npm/0.1.27/rgss23-arca-0.1.27.tgz. artifacts.json·npm-package.json은 업로드하지 않는다.

    0.1.26 대비 전체 변경

    Downloads 9
  • ARCA 0.1.26

    ARCA 0.1.26 변경 사항

    이전 버전: 0.1.25. audio 출력이 없는 Firefox에서 fresh 재시작·stop() 뒤 남던 AudioContext resume() 처리되지 않은 거절을 runtime에서 고치고, player SDK에 Fast Start opt-in(runtime WASM 스트리밍 컴파일, host 검증 cache hit)을 더한 runtime·SDK release다. native runtime(mkxp-z core JS·WASM)이 0.1.25와 달라진다. 공개 API 변경은 player SDK의 선택 필드·타입 추가뿐이고 기존 기본값·오류 code, Builder 동작과 contracts schema는 바뀌지 않았다. runtime, SDK bundle과 version 문자열이 바뀌어 runtime ZIP·contracts tgz·Builder archive·npm tgz bytes와 release pin을 모두 새로 고정한다.

    포함 변경 요약

    runtime: AudioContext resume() 거절 처리

    • 0.1.25 runtime은 AudioContext가 running이 아닐 때 1초마다 resume()을 부르고 그 promise를 처리하지 않았다(retroarch-audio-continuity). audio 출력이 없는 Firefox(장치 없음·비활성)에서는 context가 suspended에 머물러 대기 중인 resume()이 쌓이고, 0.1.25의 instance 해제(fresh 재시작·stop())가 context를 닫으면 모두 "Closed before resume completed"(InvalidStateError) 처리되지 않은 거절과 page error로 남았다. close()가 대기 중인 resume()을 거절하는 Firefox(확인한 버전 Nightly 161.0a1)에서 보이며 Firefox 153 release는 그 promise를 resolve해 보이지 않는다. LINKS player-dpr Firefox 셀마다 2~4건이 보고됐다.
    • retroarch-audio-continuity: context가 없거나 해제됐거나(rgss23Released) closed면 resume()을 부르지 않는다. 부른 resume()에는 .catch를 붙여 해제·종료된 context와 InvalidStateError는 무시하고 그 밖의 실패는 runtime log(console.error)로 보낸다. 1초 throttle은 그대로다.
    • retroarch-instance-release: audioworklet_free의 비동기 suspend()와 audioworklet_close의 close()도 해제·종료된 context를 건너뛰고 거절을 처리한다.
    • host가 runtime 오류를 걸러내거나 감쌀 필요는 없으며 게임·저장·재시작 결과와 SDK API·오류 code는 같다.

    player SDK: Fast Start(선택 기능)

    • 같은 문서 안 cache hit 재해시 생략: 기본 저장소가 이 문서에서 전체 검증한 바로 그 Blob 객체(File 제외)만 객체 identity·SHA-256·크기로 기억해 같은 문서의 fresh 재시작과 stop() 뒤 재launch에서 다시 해시하지 않는다. 문서·frame 경계 너머의 host Blob은 계속 전체 검증한다.
    • host 검증 cache hit opt-in(Rgss23HostVerifiedBlob): artifactCache.get이 { blob, integrity: "host", sha256, bytes }를 돌려주고 선언이 요청 artifact pin과 같으면 크기 비교와 첫·마지막 byte 읽기만 하고 mount한다. 무결성 책임은 host로 넘어간다. 선언이 다르면 무시하고 전체 검증한다.
    • runtime WASM 스트리밍 컴파일: 선택 Rgss23ArtifactSource.url({ artifact, role })이 runtime WASM의 http(s) URL을 주면 SRI(integrity: "sha256-…") fetch → WebAssembly.compileStreaming으로 SDK의 WASM 해시를 없애고 다운로드·컴파일을 game·RTP staging과 겹친다. factory opt-in supportsRuntimeWasmModule(기본 Nostalgist factory는 켜져 있음). URL·compileStreaming·application/wasm이 없거나 fetch(SRI 포함)·컴파일이 실패하면 기존 open() + SDK SHA-256 경로로 돌아간다. fresh 재시작은 같은 pin의 컴파일된 module을 재사용한다.
    • 두 opt-in을 쓰지 않으면 무결성 검증 경로는 0.1.25와 같고, 같은 문서 안 재해시 생략만 자동으로 적용된다.

    runtime 재배포 정책 재승인

    • runtimes/mkxp-z/redistribution-policy.json을 2026-10-24에 runtime lock c216a320…으로 재승인했다(status: approved, redistribution: restricted 유지).
    • frontend-notice-inventory.json(SHA-256 8ed50a36…)은 retroarch/audio/drivers/audioworklet.c의 파일 hash만 바뀌었다(분류 copyleft 유지, 고지·closure 변경 없음).

    문서

    • LINKS 가이드에 0.1.26 절, 7절(runtime 파일 배포: 불변 URL·brotli·WASM MIME), 8절(host 검증 cache hit 신뢰 조건)을 더했다. player SDK README에 runtime WASM 스트리밍 컴파일과 host 검증 cache hit을 설명했다.
    • release bytes에 들어가는 packages/contracts/README.md, packages/packager-rgss/README.md, tools/release/npm/README.md는 0.1.25 이후 바뀌지 않았다.

    자동 근거(2026-10-24, 같은 PC)

    • runtime(runtime lock c216a320… clean export, JS b34cd34b…, WASM c4ac76c4…, provenance stamp가 lock·recipe·Dockerfile·patch hash와 일치):
      • runtime:smoke:instance-release -- --browser firefox(Firefox Nightly 161.0a1, media.cubeb.force_null_context, heap·지연 콘텐츠 각각 launch → fresh 재시작 → stop() → 재launch → stop()): 0.1.25 runtime은 경로마다 page error 15건·처리되지 않은 거절 15건으로 FAIL, 수정 runtime은 0건으로 PASS.
      • Chrome 155 runtime:smoke:instance-release(memory) PASS.
    • browser smoke canonical runtime을 이 export로 다시 고정하고 reference app 지연 실행 계약을 하나씩 실행했다. 자동 PASS: edge:vx-ace(title), chrome:vx-ace:title, firefox:vx-ace:title, edge:vx(title)(Edge 155·Chrome 155·Firefox 153). 바뀐 gold 화소는 없다.
    • Fast Start(0.1.25 runtime, heap, opaque frame, VX Ace+RTP, Chrome 155·Firefox 153): SDK 단위 테스트, runtime:smoke:host-storage-metrics --storage heap(기본값·--host-verified), runtime:smoke:restart --game vx-ace PASS. --host-verified cache hit의 artifacts 단계는 Chrome 2827 → 536 ms, Firefox 4867 → 846 ms였다. 스트리밍 컴파일은 커밋하지 않은 측정 harness에서 SDK의 WASM 해시(Chrome 약 0.46 s, Firefox 약 0.65~0.85 s)가 사라짐을 확인했다.
    • release 전 built release artifact로 browser smoke를 다시 실행하지 않았다(위 근거와 같은 runtime bytes·SDK 코드).

    알려진 문제와 위험

    • 0.1.25 runtime에 기록한 사용자 acceptance PASS는 0.1.26 runtime으로 이어지지 않는다(0.1.26 사용자 acceptance NOT RUN).
    • audio 출력이 있는 Firefox의 별도 smoke는 실행하지 않았다(변경은 guard와 .catch 추가뿐이다).
    • 스트리밍 컴파일은 host가 runtime WASM을 application/wasm과 (opaque frame이면) CORS로 서빙해야 한다. 조건이 맞지 않으면 조용히 기존 경로로 돌아가며 WASM을 두 번 받는다.
    • host 검증 cache hit opt-in은 무결성 책임을 host로 넘긴다. host가 같은 bytes를 전체 SHA-256으로 검증했고 신뢰하지 않는 code가 cache에 쓸 수 없을 때만 쓴다.
    • 0.1.25의 나머지 한계(전체화면 크기, CRuby 4.0 Ractor·Prism·shape 용량, 이식 코드 고지 version, 소수 DPR pointer 경계, Firefox·지연 경로 반복 메모리 측정)는 그대로다.

    host 적용 순서

    LINKS 적용 가이드 0.1.26 절을 따른다. 요약:

    1. @rgss23/arca 전체를 0.1.26 exact pin으로 올린다(runtime·SDK·Builder·contracts 함께). 0.1.24 이하에서 올리면 0.1.25 절도 함께 적용한다.
    2. runtime bytes가 바뀌었으므로 0.1.26 Builder로 generation을 다시 만든다. Builder digest·config digest를 새 pin과 대조한다.
    3. PulseAudio null sink 없이 Firefox player-dpr RGSS 셀을 한 번 실행해 page error 0을 확인한다.
    4. Fast Start는 선택이다. 쓸 때만 가이드 7절의 배포 header·MIME·CORS와 8절의 신뢰 조건을 갖춘 뒤 켠다.

    NOT RUN

    • 사용자 acceptance(0.1.26 runtime), LINKS opaque frame 적용, Fast Start의 실제 망 측정, audio 출력이 있는 Firefox smoke.
    • 0.1.26 runtime에서 위 4개 외 browser scenario(gamepad·touch-pad·save-load·play 등)와 instance-release 외 runtime smoke.
    • Linux 재현.

    배포 검증

    • tag: 0.1.26(annotated, tag object eadf5ac0e8)
    • release source: 2f788155b3(Release: prepare ARCA 0.1.26)
    • manifest SHA-256: 1fab47825bbf6a925da5c65eb4914e8fcd6a51bfae10bfd9a9c07d70713638bf
    • Builder digest(pin): sha256:7843fc53749e698318fab661951bf98f5207dc6f7326de25ba8abf01b6cff69f · Builder config digest(pin builderConfigDigest): sha256:843f7ab707ad37d96293bac55a96d3b918a8449b1a5f68e2890b01ca22bfb05d
    • artifact SHA-256: builder 6ca8e7937089f788e9771dc8ab4146e939602ef0c2d7c9ec3223adbd33aa81e6 · contracts 3f5b2e357e95c1bd74f56756b3e465eff41b09e99cfcc8631abbcbf1a6544387 · runtime 9c8259208be15ec77f9bdd1c48541fc9a1dc8363987d694b3a5c8ff7b8c13fed
    • npm: rgss23-arca-0.1.26.tgz SHA-256 73275b7c7e1233025b248ddad56f3f259921c80aad41c94c2c4e1ca80fec3902, integrity sha512-hfPoLBcmb7yxMY/0MqSkhHrnBPPoUFXaEu3ybdeLVzVtJ+GbZweRP3RncJ2h+UGamA0wGf2R0FsJ9/kTQOmD4w==
    • runtime ZIP의 rgss23-core.js(b34cd34b… 272,967 B)·rgss23-core.wasm(c4ac76c4… 48,400,171 B)은 canonical runtime export와 byte 동일하고, export provenance가 runtime lock c216a320…·recipe·Dockerfile·patch hash와 일치한다. redistribution-policy.json runtimeLockSha256은 dependencies.lock.json과 일치한다. named volume rgss23-mkxp-build의 provenance stamp·frontend JS·WASM이 export와 같은 hash라 runtime을 다시 build하지 않았다.
    • 게이트(source 2f78815, 2026-10-24): install --frozen-lockfile, 단위 테스트 662개, 타입 검사, release 회귀 51개, browser 도구 회귀 142개, verify:locks, native 준비 recipe 검증, git diff --check PASS(work/release-0.1.26/logs/gates.log)
    • release:build(Builder gate·source-free consumer gate)·release:verify·release:npm:test·release:reproduce: PASS(2026-10-24, source 2f78815, manifest sourceCommit = HEAD; release:reproduce는 clean detached worktree에서 end-to-end로 pin·세 artifact·npm이 동일, work/release-0.1.26/logs/pipeline.log). Windows·같은 Docker host만, Linux 재현 NOT RUN.

    asset 7개

    파일 크기(B) SHA-256
    release-manifest.json 2,155 1fab47825bbf6a925da5c65eb4914e8fcd6a51bfae10bfd9a9c07d70713638bf
    release-manifest.sha256 88 c563b58d3eefbde6f05b6ec6522d7149f717acadeae3b966cca3726b6dc7447b
    release-pin.json 537 4ae479f52d815de7a32e0a2d94f1c3a56bf228ed9dcf0eb0449fc98bd40fa2c5
    rgss23-arca-0.1.26.tgz 103,627,581 73275b7c7e1233025b248ddad56f3f259921c80aad41c94c2c4e1ca80fec3902
    rgss23-builder-0.1.26.oci.tar 63,196,672 6ca8e7937089f788e9771dc8ab4146e939602ef0c2d7c9ec3223adbd33aa81e6
    rgss23-contracts-0.1.26.tgz 38,268 3f5b2e357e95c1bd74f56756b3e465eff41b09e99cfcc8631abbcbf1a6544387
    rgss23-runtime-0.1.26.zip 50,122,220 9c8259208be15ec77f9bdd1c48541fc9a1dc8363987d694b3a5c8ff7b8c13fed

    로컬 경로: dist/release/0.1.26/, dist/npm/0.1.26/rgss23-arca-0.1.26.tgz. artifacts.json·npm-package.json은 업로드하지 않는다.

    0.1.25 대비 전체 변경

    Downloads 9
  • ARCA 0.1.25

    ARCA 0.1.25 변경 사항

    이전 버전: 0.1.24. stop()·fresh 재시작마다 instance가 남던 메모리 누적과 native exit trap을 runtime에서 고치고, runtime toolchain·upstream과 sandbox CRuby를 올린 runtime release다. native runtime(mkxp-z core JS·WASM)이 0.1.21~0.1.24와 달라진다. 공개 API·타입·기본값·오류 code와 contracts schema는 바뀌지 않았다. runtime, Builder base image, SDK 의존성과 version 문자열이 바뀌어 runtime ZIP·contracts tgz·Builder archive·npm tgz bytes와 release pin을 모두 새로 고정한다.

    포함 변경 요약

    runtime·SDK: stop()·fresh 재시작 instance 해제

    • 0.1.24 이하에서는 stop()과 restart({ presentation: "fresh" })를 할 때마다 내린 WASM instance(Module, WebAssembly.Memory, AudioContext, page hook)가 page unload까지 남았다. RTP를 쓰는 VX Ace 게임은 회당 약 450~500 MB씩 늘었다.
    • runtime patch retroarch-instance-release가 재시작 transaction에 UNLOAD(operation 4)를 더한다. 일시정지한 core를 frame 경계에서 CMD_EVENT_CORE_DEINIT으로 내리고, 한 번만 실행되는 release hook(Module.rgss23Release, rgss23ReleaseProtocol 1)이 main loop, browser hook, Emscripten event listener, AudioWorklet port·node, AudioContext를 정리한다. release 뒤에 끝나는 getBattery()·AudioWorklet module load 같은 비동기 continuation도 native code를 부르지 않는다.
    • SDK는 이 protocol을 알리는 runtime에서 PAUSE → UNLOAD → release → exit() 순서로 종료한다. Nostalgist가 남긴 전역 override를 되돌리고 handle이 쥔 내린 runtime 참조를 놓는다. UNLOAD는 restart transport에서 한 번만 쓴다. protocol이 없는 runtime에서는 0.1.24 경로를 그대로 쓴다.
    • 자동 근거(Chrome 155, heap VX Ace + pinned RTP, runtime:smoke:instance-release): fresh 재시작 3회와 stop()+재launch 3회 모두 회차마다 완료된 exit 하나, trap 없음. 열린 AudioContext·살아 있는 Wasm memory는 fresh 중 1개, stop() 뒤 0개. OS private은 fresh 1055→1060 MB, stop() 478→489 MB였다(0.1.24 SDK와 0.1.21 runtime은 같은 page에서 fresh 1560→2581 MB, stop() 2562→4091 MB로 FAIL).

    runtime: native exit trap 수정

    • 0.1.24의 알려진 문제: 강제 exit()가 static mkxp_retro::fs 소멸자의 PHYSFS_deinit을 audio 정리보다 먼저 실행했다. 그래서 PHYSFS_mountHandle archive(RTP, 암호화 Game.rgssad·.rgss2a·.rgss3a)에 열린 항목이 있으면 closeFileHandleList에서 use-after-free trap이 났다(Chrome "table index is out of bounds", Firefox "indirect call to null").
    • 이제 UNLOAD를 거친 종료는 audio가 열린 항목을 닫은 뒤 PhysFS를 정리하므로 이 경로를 밟지 않는다. 방어용 core patch mkxp-z-physfs-deinit-close-list는 각 항목을 list에서 뗀 뒤 destroy한다. 0.1.24 SDK의 abort 격리는 실패 fallback으로만 남는다.
    • runtime:smoke:instance-release -- --scenario exit-archive: BGM 재생 중 stop()이 RTP 없는 암호화 Game.rgss2a와 RTP archive 모두에서 ExitStatus로 끝난다(수정 전에는 둘 다 trap).

    runtime: sandbox CRuby 4.0.9

    • RGSS interpreter를 CRuby 3.3.12에서 4.0.9(3e93b23a)로 올렸다(ARCA patch mkxp-z-cruby-4.0: syntax-transform/4.0, 4.0용 user threads·WASI sockets patch, Ruby 3.3의 32-bit shape 용량 유지).
    • parse.y를 기본 parser로 configure했다. Prism parser·compiler 진입점(compile_prism, compile_file_prism, load_iseq hook, --parser=prism, RUBYOPT)은 모두 NotImplementedError로 막았다. 그래서 legacy 문법 변환(VX syntaxTransform: 2)은 그대로다.
    • 바뀌지 않는 4.0 차이: 예외 backtrace의 'Class#method' 표기, Hash#inspect 형식, Encoding inspect, 알 수 없는 pack 지시자의 오류 등.

    runtime: pointer 회귀 수정

    • RetroArch 갱신으로 RETRO_DEVICE_POINTER가 화면 왼쪽 위만 보고하던 회귀를 게시 전에 고쳤다(0.1.24 게시본에는 없던 회귀). retroarch-browser-input은 unpack한 pointer_x·pointer_y를 canvas CSS 크기 × DPR로 정규화한다. offscreen 여부는 양자화 전에 정수 CSS 좌표를 CSS box와 비교해 정한다.

    library·toolchain 갱신

    • RetroArch master a159f9ce(upstream에 들어간 Firefox patch 2개를 제거하고 나머지 10개를 rebase), wrapper 0b0a9527, zlib·libsndfile·PhysicsFS·stb 등 core dependency는 branch HEAD 기준으로 올렸다.
    • emscripten/emsdk 6.0.13, FreeType VER-2-15-0(CVE-2026-50811·CVE-2026-95512 수정 포함), runtime image Node 26.12.1, 기본 runtime build image tag rgss23-mkxp-build:emscripten-6.0.13-v2.
    • Builder base node:26.12.1-alpine, player SDK image node:26.12.1-trixie-slim(corepack 0.36.0을 hash로 고정), nostalgist 0.23.0, @types/node 26.6.5.
    • 제공 VX browser fixture 글꼴은 NeoDunggeunmo v1.601이고, RPGVX RTP 추출 image는 다시 게시된 debian:13.7-slim digest다. runtime ZIP에는 들어가지 않는다.

    재배포 정책 재승인

    • runtimes/mkxp-z/redistribution-policy.json을 2026-10-23에 runtime lock dc792e75…로 재승인했다(status: approved, redistribution: restricted 유지).
    • 고지 전체를 runtime ZIP LICENSES/로 내보낸다: CRuby 4.0.9 COPYING·COPYING.ja·LEGAL(ext/json vendor 코드 포함), RetroArch libarchive 유래 RAR reader, frontend·core 내장 허용 license 고지(frontendSourceNotices·coreSourceNotices), frontend link closure의 header 고지 311개(frontend-notice-inventory.json, 정규화 기준 23개 고지), 이식 코드 upstream 고지(frontendDerivedNotices: libvpx·libwebp·Code Review Stack Exchange attribution), Emscripten sysroot, nostalgist가 inline하는 ini·path-browserify.

    release 도구

    • npm facade packer가 100 byte를 넘는 경로를 ustar prefix(155 byte)에 나눠 쓴다. 0.1.25 고지 export가 package/runtime/LICENSES/core/mkxp-z/subprojects/freetype/include/freetype/internal/fthash.h.NOTICE.txt(104 byte) 같은 경로를 더해 release:build가 npm 단계에서 멈췄기 때문이다. 100 byte 이하 경로의 header bytes는 그대로다.

    문서

    • 남은 일과 알려진 한계·위험을 로드맵과 프로젝트 상태(알려진 한계와 위험)에 기록했다. LINKS 가이드에 0.1.25 절을 더했다.
    • release bytes에 들어가는 packages/contracts/README.md, packages/packager-rgss/README.md, tools/release/npm/README.md는 0.1.24 이후 바뀌지 않았다.

    자동 근거(2026-10-22~23, 같은 PC, 로컬 runtime clean export = 0.1.25 runtime)

    • 최종 runtime(main a5e3af7, JS 97f21a30…, WASM 18848c93…, provenance stamp가 lock dc792e75…·patch hash와 일치), Chrome 155·Firefox 153·Edge 155, 자동 PASS:
      • runtime:smoke:dpr 기본 행렬(DPR 1·2·3 × 두 viewport), Chrome·Firefox.
      • 지연 resize-restart --hold-reads-during-relaunch.
      • shutdown, restart, instance-release(memory·exit-archive·release-async), audio-controls, context-lifecycle, isolated-player, presentation-quality.
      • syntax-transform(Prism 음성 대조 포함), ruby-untaint, host-storage-metrics(VX Ace Chrome heap, lazy+preboot).
      • rgss23-lazy-smoke.js game·faults·reject-duplicate·rollback.
    • browser smoke 자동 PASS: edge:vx-ace(title), chrome:vx-ace:title, firefox:vx-ace:title, edge:vx-ace:gamepad, edge:vx-ace:touch-pad, edge:vx(title), firefox:vx:title, edge:vx:action-event, Chrome VX resize-input.
    • edge:vx-ace:save-load·movement-cancel·audio-map004·action-event와 edge:vx:save-load는 동작·화소 검사를 모두 통과했고 바뀐 screenshot도 없다. 다만 gold 검토 browser가 Edge 154여서 runner 결과는 NOT REVIEWED다(사람 gold 검토 NOT RUN).
    • release 전 built release artifact로 browser smoke를 다시 실행하지 않았다(위 근거와 같은 runtime bytes·SDK 코드).

    알려진 문제와 위험

    • 전체화면: explicitSwapControl 아래에서 Emscripten 전체화면 helper가 getCanvasElementSize로 초기화되지 않은 OffscreenCanvas record를 읽는다. 그래서 전체화면 크기가 잘못될 수 있다. 전체화면은 후순위 범위이며 검증하지 않았다.
    • CRuby 4.0 sandbox는 Ractor를 명시적으로 막지 않는다(thread model none, 이식 전과 같음). Ruby Thread·Fiber 실행 범위 전체의 검증은 NOT RUN이다.
    • Prism은 모든 진입점에서 꺼져 있어 parse.y가 유일한 parser다.
    • shape 용량은 0x8000개로 제한된다. 다 쓰면 too-complex fallback으로 넘어가며, 이 경로는 native build에서만 확인했고 실제 게임에서는 NOT RUN이다.
    • rvp8.c·rwebp.c가 이식한 libvpx·libwebp의 원래 upstream version은 확정할 수 없어 현재 upstream 원문을 고지로 쓴다. codepen 예제를 참고한 particle 효과는 고지 대상이 아닌 것으로 기록했다.
    • 소수 DPR pointer 경계는 산술·정적 검사로만 확인했다. touch·pointer-lock·실기 기기는 NOT RUN이다.
    • 반복 메모리 측정은 Chrome heap 경로만 했다. Firefox·지연 콘텐츠 경로는 NOT RUN이다.

    host 적용 순서

    LINKS 적용 가이드 0.1.25 절을 따른다. 요약:

    1. @rgss23/arca 전체를 0.1.25 exact pin으로 올린다(runtime·SDK·Builder·contracts 함께). 0.1.23 이하에서 올리면 0.1.23·0.1.24 절도 함께 적용한다.
    2. runtime bytes가 바뀌었으므로 0.1.25 Builder로 generation을 다시 만든다. Builder digest·config digest를 새 pin과 대조한다.
    3. 실제 게임의 title·save/load·플레이와 mouse click 위치를 다시 확인한다. Ruby 오류 문자열을 분류에 쓰면 CRuby 4.0 backtrace 표기로 다시 대조한다.
    4. fresh 재시작과 stop() 뒤 재launch를 반복해 frame 메모리가 늘지 않는지 확인한 뒤 0.1.24 절의 instance 보존 경고(횟수 제한)를 해제한다.
    5. runtime을 재배포·서빙할 때는 runtime ZIP의 LICENSES/ 전체를 함께 둔다.

    NOT RUN

    • 사용자 acceptance(제공 VX/VX Ace의 acceptance 기준은 이전 CRuby 3.3 runtime의 2026-08-05 결과 그대로), LINKS opaque frame 적용, 실기 모바일·DPR.
    • 최종 runtime에서 runtime:smoke:bitmap-profile, restart VX Ace 변형, presentation-quality Firefox·opaque-origin 변형, dpr 기타 변형(opaque-origin·hidden-start·focus·기타 DPR/browser), browser scenario 일부(Edge VX play·cancel-menu·movement-left·audio-title, Edge VX Ace play, Firefox VX Ace play·movement-cancel·action-event, Firefox VX first-dialogue·background-resume·resize-input). font-selection은 운영자 입력이 없어 설계상 BLOCKED다.
    • puppeteer-core 25.16.0 갱신(pnpm minimumReleaseAge 때문에 2026-10-23T11:54Z까지 막힘), Linux 재현.

    배포 검증

    • tag: 0.1.25(annotated, tag object 7366087fff652c4d47aa6dd39eb18df84657bc42)
    • release source: 8c70f90351(Release: store npm package paths over 100 bytes in the ustar prefix, 버전 커밋 Release: prepare ARCA 0.1.25 5e3fbfe 바로 다음)
    • manifest SHA-256: 363342e99543a4b54055864ea6581377185f28700f8ce47324830c0431609214
    • Builder digest(pin): sha256:11d1d483fa333fae3e85aea535b219db433baf0325c1ea53df3304364cc0f85e · Builder config digest(pin builderConfigDigest): sha256:31e0ce5f42938563769f39579ae04c9da7b8c332d36109dd21bb3b3329f0614a
    • artifact SHA-256: builder 90dd41fcbb4787a61ea0074df11d690295833d0542adf2963ddf9b8ee6843529 · contracts b7fcebc2d9b5958ac5fede905b0c0d0d54b1f7199847efe5ffdfa6214cec1c14 · runtime 4d2657226772c973b8a73f6e67299c844aaa1d250c30f36d7fca3271e3c272d3
    • npm: rgss23-arca-0.1.25.tgz SHA-256 24ae784104f11ad9138590308ad127f69b0d6481e23e0f59fd0d7a86a24878ad, integrity sha512-6EptvRsVnBs4u1qzTjudAdqAI7rebi7K0t3N9Ur336Wl7uAc+0qytfkw8tzMTrThU62DxcliKyiYIkoMV4ei3w==(로컬 계산, registry 게시 NOT RUN)
    • runtime ZIP의 rgss23-core.js(97f21a30… 272,594 B)·rgss23-core.wasm(18848c93… 48,400,171 B)은 main a5e3af7 canonical runtime export와 byte 동일하고, export provenance가 runtime lock dc792e75…과 일치한다. redistribution-policy.json runtimeLockSha256은 dependencies.lock.json과 일치한다. named volume rgss23-mkxp-build의 frontend JS·WASM·core archive가 같은 hash라 runtime을 다시 build하지 않았다.
    • 게이트(source 8c70f90, 2026-10-23): install --frozen-lockfile, 단위 테스트 646개, 타입 검사, release 회귀 51개, browser 도구 회귀 137개, verify:locks, native 준비 recipe 검증, git diff --check PASS(work/release-0.1.25/logs/gates.log)
    • release:build(Builder gate·source-free consumer gate)·release:verify·release:npm:test·release:reproduce: PASS(2026-10-23, source 8c70f90, manifest sourceCommit = HEAD; release:reproduce는 clean detached worktree에서 end-to-end로 pin·세 artifact·npm이 동일, work/release-0.1.25/logs/pipeline.log). 첫 release:build(5e3fbfe)는 npm ustar 경로 한도로 실패해 위 수정 뒤 다시 실행했다. Windows·같은 Docker host만, Linux 재현 NOT RUN.

    asset 7개

    파일 크기(B) SHA-256
    release-manifest.json 2,155 363342e99543a4b54055864ea6581377185f28700f8ce47324830c0431609214
    release-manifest.sha256 88 68f95c0e836efc8d106ec7410628fe5abc7c56efff0e372dacb7bfd5ee12aa14
    release-pin.json 537 38ae03c8e8818ef3d7722bab98d6c27efd30883770094a03d25e4503f7cb8b34
    rgss23-arca-0.1.25.tgz 103,622,084 24ae784104f11ad9138590308ad127f69b0d6481e23e0f59fd0d7a86a24878ad
    rgss23-builder-0.1.25.oci.tar 63,196,672 90dd41fcbb4787a61ea0074df11d690295833d0542adf2963ddf9b8ee6843529
    rgss23-contracts-0.1.25.tgz 38,268 b7fcebc2d9b5958ac5fede905b0c0d0d54b1f7199847efe5ffdfa6214cec1c14
    rgss23-runtime-0.1.25.zip 50,112,038 4d2657226772c973b8a73f6e67299c844aaa1d250c30f36d7fca3271e3c272d3

    로컬 경로: dist/release/0.1.25/, dist/npm/0.1.25/rgss23-arca-0.1.25.tgz. artifacts.json·npm-package.json은 업로드하지 않는다.

    0.1.24 대비 전체 변경

    Downloads 9
  • ARCA 0.1.24

    ARCA 0.1.24 변경 사항

    이전 버전: 0.1.23. 0.1.23 게시본의 지연 콘텐츠 fresh 재시작 FAIL(LINKS T81 재현)을 고치는 player SDK release다. native runtime(mkxp-z core JS·WASM)·Builder 동작·contracts schema는 0.1.23과 같다. 공개 API·타입·기본값·오류 code는 바뀌지 않았다. version 문자열, SDK bundle과 release artifact에 들어가는 package README 문구 수정 때문에 runtime ZIP·contracts tgz·Builder archive·npm tgz bytes와 release pin은 새로 고정된다.

    포함 변경 요약

    SDK: 지연 콘텐츠 fresh 재시작의 relaunching 멈춤 수정

    • 0.1.23에서 지연 콘텐츠(content.reader·content.directory) launch의 restart({ presentation: "fresh" })가 relaunching에서 frame과 부모 page를 함께 멈출 수 있었다(LINKS 재현 조건: RTP·BGM을 읽은 instance).
    • 원인: 내린 runtime의 exit() 중 native 소멸자가 trap하면 Nostalgist가 오류를 삼키고 keepalive가 비워진 채 SDK가 pthread Worker를 종료한다. 다음 mailbox callback(checkMailbox → callUserCallback → maybeExit)이 exit를 다시 실행해 남은 소멸자를 돌리고, 지연 mount backend의 ProxyWorker 소멸자가 이미 종료된 proxy thread를 main thread에서 join하며 끝없이 돌았다. heap 경로는 join할 thread가 없어 멈추지 않았다.
    • 수정: SDK가 bind하는 factory 결과의 release()가 exit() 뒤 Worker 종료 전에 ABORT = true를 둔다(stop()과 prepare 실패 정리). 완료된 exit가 남기는 상태와 같으며 내린 instance의 callback은 native 코드 전에 반환한다. stop()·dispose()·fresh 재시작이 같은 정리 경로라 모두 같은 수정을 받는다.
    • 단위 테스트: exit가 trap하는 runtime source로 stop() 뒤 Worker 종료·이후 mailbox 처리에서 exit 재진입이 없음을 고정했다(수정 없이 실패).

    smoke·도구

    • runtime:smoke:dpr -- --scenario resize-restart --content lazy: opaque-origin 격리 선부팅 frame, 부모 page MessagePort reader·chunk cache, 고정 VX Ace RTP를 두 번째 지연 artifact로 쓰고 boot 중 RTP BGM과 재시작 호출 시 진행 중 읽기를 둔 지연 fresh 재시작 cell. 선택 flag --reader-latency-ms, --hold-reads-during-relaunch, --chunk-bytes. flag는 엄격히 parse한다.
    • 지연 chunk 계약·digest helper를 tools/build-runtime/smoke-common.mjs로 모으고 단위 테스트를 더했다.

    문서

    • 0.1.23 게시본의 지연 fresh 재시작 FAIL, 0.1.24 후보 SDK의 자동 PASS, native exit trap 원인 범위, instance 보존 FAIL을 호환성 매트릭스·로드맵·SDK README·LINKS 가이드(0.1.24 절)에 기록했다.
    • release bytes에 들어가는 packages/contracts/README.md(0.1.21 변경 이력의 release set manifest 표기)와 tools/release/npm/README.md(RTP 다운로드 재시도 jitter 설명)의 사실 오류를 고쳤다. packages/packager-rgss/README.md는 바뀌지 않았다.

    자동 근거(2026-10-22, 같은 PC, 로컬 runtime build = 0.1.21 native pin, 0.1.24 후보 SDK)

    • 지연 resize-restart Chrome 155·Firefox 153 × DPR 1·2: 결과 presentation: "fresh"·completion: "native-started", synced, backing = CSS × DPR, 재시작 commit의 save 재읽기, page 응답 유지, 새 instance가 같은 proxy cache로 읽음 PASS.
    • --reader-latency-ms 200(relaunching 시 응답 대기 1건) Chrome·Firefox PASS, --hold-reads-during-relaunch(두 cell 모두 보류 읽기 1건, restart-settled에서 해제) Chrome·Firefox PASS, heap resize-restart Chrome PASS.
    • 수정 전 같은 지연 smoke는 Chrome·Firefox 6/6에서 멈춤을 재현했다(failure: "page-unresponsive", 마지막 phase relaunching).
    • 보고서: main checkout work/browser-smoke/의 dpr-chrome-resize-restart-lazy-1792623952680(기본)·-1792623978331(latency)·-1792624020411(hold), dpr-firefox-resize-restart-lazy-1792624049603(기본)·-1792624074655(latency)·-1792624640749(hold), dpr-chrome-resize-restart-1792624118042(heap).
    • release 전 built SDK로 대표 browser smoke를 다시 실행하지 않았다(위 근거와 같은 SDK 코드, native runtime 불변).

    알려진 문제

    • native exit trap(Chrome "table index is out of bounds"·"null function", Firefox "indirect call to null"): SDK 종료는 core를 unload하지 않고 runtime을 강제 종료하므로 static mkxp_retro::fs 소멸자의 PHYSFS_deinit이 audio 정리보다 먼저 돌고, PhysFS closeFileHandleList가 PHYSFS_mountHandle로 mount한 archive(RTP 파일 archive, 암호화 Game.rgssad·.rgss2a·.rgss3a)의 열린 항목을 닫을 때 해제한 handle을 다시 쓴다(use-after-free). heap·지연 경로 모두 해당한다. 0.1.24 SDK는 내린 runtime을 abort 상태로 두어 이 trap이 page를 멈추지 않게 격리할 뿐 trap 자체는 남는다. 수정 방향(종료 전 frame boundary core unload runtime patch, PhysFS 방어 patch)은 로드맵에 있다.
    • instance 보존: stop()과 restart({ presentation: "fresh" })마다 내린 WASM instance 하나가 page unload까지 남는다(Chrome 155 scratch 측정, heap VX Ace + RTP 게임 measureUserAgentSpecificMemory 1·2·3회 457·913·1368 MB, OS private 회당 약 +500 MB, 열린 AudioContext도 회마다 하나 증가). trap 여부와 무관하며 0.1.23과 0.1.24가 같다. host는 한 page의 fresh 재시작과 stop() 뒤 재launch 횟수를 제한하고 반복되면 page·frame을 다시 읽는다.

    host 적용 순서

    LINKS 적용 가이드 0.1.24 절을 따른다. 요약:

    1. @rgss23/arca 전체를 0.1.24 exact pin으로 올린다(runtime·SDK·Builder·contracts 함께). 0.1.22 이하에서 올리면 0.1.23 절도 함께 적용한다.
    2. frame의 지연 콘텐츠 경로(catalog 선부팅)에서도 설정 재시작에 restart({ presentation: "fresh" })를 허용한다. listener 재연결·canvas 표시 유지·FAILED 뒤 새 canvas 규칙은 0.1.23과 같다.
    3. run-player-lazy의 resize→재시작 cell을 presentation: "fresh", synced, save 유지, page 응답 유지의 assert로 바꾼다.
    4. instance 보존 경고(fresh 재시작 횟수 제한)는 해제 수정이 든 release 전까지 유지한다.

    NOT RUN

    • LINKS opaque frame 적용, 실기 모바일·DPR, 사용자 acceptance(제공 VX/VX Ace acceptance 기준은 2026-08-05 그대로).
    • 지연 stop() 뒤 재launch의 browser smoke(단위 테스트만), 기존 browser smoke 행렬 재실행(native runtime 불변), Linux 재현.

    배포 검증

    • tag: 0.1.24(annotated, tag object c9340df496)
    • release source: fda2d8ea66(버전 커밋 Release: prepare ARCA 0.1.24)
    • manifest SHA-256: e69467eb549c95482b0262ac6279e806f74d07990a66a0ea6dd488b97b159712
    • Builder digest(pin): sha256:e506f39a54ce2b46f4299e83c29a25db0e08dc8abc37b0bbf3cd6de07bd25f97 · Builder config digest(pin builderConfigDigest): sha256:13698bac4fda730918fb4b8be2e81ebc1eaf2b8f8c6290e83000f8ad3e23a0c7
    • artifact SHA-256: builder 4400fac4911cdef1c201d4d15a1947763e9231ed6f9fa003f08e9fca4fd20784 · contracts 5f89b64588341bcee5cf6d51296fbc85738ad42d08b59dbdcf183dff20c014e9 · runtime 4c1040c60000025f69228953d254c0b9747cfa370e66dc6a49b11e5f626f6636
    • npm: rgss23-arca-0.1.24.tgz SHA-256 37c2b058be6de83440b64731e1779f7a6117f6a8c15152ae031cea0b6a27a856, integrity sha512-LEdmfb9RtBCrc5Vve3bP/NT5ZtLsONRYLjPRjfQzBCqwoe/Y9C+Y1M3ccf1X6tGNl3zGQqNQ/fVuh1hUXD/W5A==(로컬 계산, registry 게시 NOT RUN)
    • runtime ZIP의 rgss23-core.js(d4884b14… 256,567 B)·rgss23-core.wasm(39085f4e… 44,432,926 B)은 0.1.23과 byte 동일하다. redistribution-policy.json runtimeLockSha256은 dependencies.lock.json과 일치(불변).
    • 게이트(버전 커밋 fda2d8e, 2026-10-22): install --frozen-lockfile, 단위 테스트 640개, 타입 검사, release 회귀 47개, browser 도구 회귀 127개, verify:locks, native 준비 recipe 검증, git diff --check PASS(work/release-0.1.24/logs/gates.log)
    • release:build(Builder gate·source-free consumer gate)·release:verify·release:npm:test·release:reproduce: PASS(2026-10-22, source fda2d8e, manifest sourceCommit = HEAD; release:reproduce end-to-end pin·세 artifact·npm 동일, work/release-0.1.24/logs/pipeline.log). Windows·같은 Docker host만, Linux 재현 NOT RUN.

    asset 7개

    파일 크기(B) SHA-256
    release-manifest.json 2,155 e69467eb549c95482b0262ac6279e806f74d07990a66a0ea6dd488b97b159712
    release-manifest.sha256 88 800e6a7eabe60f77d334b8530bc0c2b422832b55d130e277220d67f6f66f22f1
    release-pin.json 537 db2984a36e7fd17227bc302ebff2eb654839e43edd4bf6bdd1f05cb42b2911cb
    rgss23-arca-0.1.24.tgz 99,994,874 37c2b058be6de83440b64731e1779f7a6117f6a8c15152ae031cea0b6a27a856
    rgss23-builder-0.1.24.oci.tar 61,884,928 4400fac4911cdef1c201d4d15a1947763e9231ed6f9fa003f08e9fca4fd20784
    rgss23-contracts-0.1.24.tgz 38,268 5f89b64588341bcee5cf6d51296fbc85738ad42d08b59dbdcf183dff20c014e9
    rgss23-runtime-0.1.24.zip 45,714,599 4c1040c60000025f69228953d254c0b9747cfa370e66dc6a49b11e5f626f6636

    로컬 경로: dist/release/0.1.24/, dist/npm/0.1.24/rgss23-arca-0.1.24.tgz. artifacts.json·npm-package.json은 업로드하지 않는다.

    0.1.23 대비 전체 변경

    Downloads 9
  • ARCA 0.1.23

    ARCA 0.1.23 변경 사항

    이전 버전: 0.1.22. LINKS 요청 2건(2026-10-21, start-focus-option·restart-fresh-backing) 대응 release다. native runtime(mkxp-z core JS·WASM)·Builder 동작·contracts schema는 0.1.22와 같다. player SDK만 바뀌었고 공개 API는 추가만 했다(기본값·기존 오류 code 불변). version 문자열과 SDK bundle 때문에 runtime ZIP·contracts tgz·Builder archive·npm tgz bytes와 release pin은 새로 고정된다.

    포함 변경 요약

    SDK: 자동 canvas focus 끄기(focus, T81-A 채택)

    • focus?: boolean을 launchRgss23Player·prepareRgss23Player 옵션과 prepared.start({ focus })에 추가했다(start 값이 그 start와 이후 재시작에 우선, 기본 true = 이전 동작).
    • false면 start 끝, 재시작 뒤 입력 해제, runtime video 초기화(선부팅 중 또는 start 직후)의 gesture 없는 canvas.focus()를 모두 건너뛴다. canvas pointerdown·mousedown에 의한 focus는 유지한다. video 초기화 focus는 runtime 변경 없이 SDK가 첫 geometry 보고까지 canvas own focus shim으로 막는다.
    • 요청문이 인용한 Nostalgist element.focus()(0.1.22 rgss23-player.mjs 6032·6372행)는 respondToGlobalEvents: false일 때만 실행되며 SDK는 기본값 true를 유지하므로 도달하지 않는다(단위 테스트로 고정).

    SDK: 새 backing으로 재시작(restart({ presentation: "fresh" }), T81-B 부분 채택)

    • host가 명시적으로 부르는 restart({ presentation: "fresh", canvas? })가 save commit 뒤 runtime instance를 onExit·stopped 없이 내리고 같은 handle에서 같은 launch 입력(storage·save adapter·지연 콘텐츠 reader·cache·presentation·focus·음량)으로 새 instance를 시작해 현재 CSS 크기 × DPR backing으로 synced가 된다. 기본 restart()는 그대로 fast restart(backing 유지)다.
    • runtime이 canvas를 transferControlToOffscreen으로 넘기고 되돌릴 수 없으므로 새 canvas element가 필요하다. canvas를 생략하면 SDK가 cloneNode(false)로 같은 DOM 위치에서 교체하고 읽기 전용 player.canvas가 running 통지 전에 새 element를 가리킨다. 기존 element의 host listener는 옮겨지지 않는다.
    • 숨김·분리 canvas는 teardown 전에 TypeError로 거부한다. commit 실패·취소는 SAVE_FAILED/CANCELLED(recovery: "running"), teardown 뒤 실패는 FAILED(recovery: "relaunch-required", 자동 재시도 없음)이며 stop()은 진행 중인 fresh 재시작을 중단한다. 교체 중 setVolume·setMuted는 기록만 하고 새 instance에 적용한다.
    • 가산 타입: Rgss23RestartPhase에 relaunching, Rgss23RestartResult에 presentation: "retained" | "fresh", completion에 native-started, Rgss23HostFileSystem.release?(). 리터럴 타입을 고정한 host 코드는 pin 갱신 때 컴파일 오류가 날 수 있다.
    • 실행 중 in-place backing 재할당(display-quality-options 3항)은 stale tile 위험으로 계속 보류다.

    smoke·문서

    • runtime:smoke:dpr -- --scenario focus|resize-restart 추가(fixture dpr-player.js 가산 변경). 기존 matrix·hidden-start는 그대로다.
    • player SDK README(입력과 focus, 빠른 재시작, 화면 표시, API 도입 버전), LINKS 가이드 0.1.23 절, 호환성 매트릭스 0.1.23 행, 로드맵 한 절. release bytes에 들어가는 packages/contracts/README.md·packages/packager-rgss/README.md·tools/release/npm/README.md는 바뀌지 않았다.

    자동 근거(2026-10-21, 게시 전 로컬 SDK, native runtime 0.1.22 pin)

    • runtime:smoke:dpr --scenario focus Chrome 155·Firefox 153: focus: false로 modal dialog 입력란이 focus를 가진 채 선부팅·gesture 없는 start → 입력란 focus 유지, 입력 키가 입력란에 남음, canvas 클릭 뒤 ArrowDown이 게임에 도달 PASS. 기본값 cell은 canvas가 running·첫 presentation에서 active PASS(Firefox는 modal inert 때문에 이후 BODY로 떨어지는 현상을 LINKS 보고와 같게 관측).
    • runtime:smoke:dpr --scenario resize-restart Chrome·Firefox × DPR 1·2: 맞춤 시작 → CSS 544×416으로 변경(scaled) → fresh 재시작 → backing 544×416·1088×832 synced, 사분면 표시, 재시작 전 save 읽기 PASS.
    • 기존 matrix cell(Chrome DPR 2 390×844) PASS로 fixture 변경이 기존 scenario를 바꾸지 않음을 확인.
    • host 제공 canvas 경로·지연 chunk cache 재사용은 단위 테스트만, LINKS 적용·실기·사용자 acceptance는 NOT RUN.

    host 적용 순서

    LINKS 적용 가이드 0.1.23 절을 따른다. 요약:

    1. @rgss23/arca 전체를 0.1.23 exact pin으로 올린다(runtime·SDK·Builder·contracts 함께).
    2. 선부팅의 video 초기화 focus는 prepareRgss23Player() 중에 일어나므로 frame은 prepare에 focus: false를 주고 player-start.focus를 prepared.start({ userActivation: true, focus })로 넘긴다.
    3. 설정 재시작은 restart({ presentation: "fresh" })를 쓰고, frame의 focus·터치 pad listener를 player.canvas로 다시 건다. FAILED 뒤 전체 launch에는 새 canvas element가 필요하다.
    4. run-player-lazy focus probe와 run-player-dpr resize→재시작 cell을 assert로 바꾼다.

    NOT RUN

    • LINKS opaque frame 적용, 실기 모바일·DPR, 사용자 acceptance(제공 VX/VX Ace acceptance 기준은 2026-08-05 그대로).
    • 기존 browser smoke 행렬 재실행(native runtime 불변; SDK 변경은 단위 테스트·DPR smoke로 확인), Linux 재현.

    배포 검증

    • tag: 0.1.23(annotated, tag object f6f980c883)
    • release source: 90274419f6(버전 커밋)
    • manifest SHA-256: 96044236f1a0d6dac8d1d24288846bc8bf7c73d85d9ffb0d0cc3976df05d626d
    • Builder digest(pin): sha256:b634496385869a230b21b7c53870b041056f009f502e54f1efa2a58b97e32d42 · Builder config digest(pin builderConfigDigest): sha256:cd2899b3e1574238e4838ae8beac6a6af8f59f3f4b159432f2fe258d31b076b2
    • artifact SHA-256: builder 251559fe5c0f9f870a09a99aa9894d2c75ff8f266638238ee8d32cd57da0ebbc · contracts ee5528f2eb16de52e1cc11112a80a4cb7697c9d926eaadfd7f0fc63fca66bef1 · runtime 4aa1aadbc24d185857252ea608f7051ad7cbac7c96809c8d0ecfb14fe0555553
    • npm: @rgss23/arca@0.1.23 (Forgejo registry), rgss23-arca-0.1.23.tgz SHA-256 3b8b5b2aa9f59e6aada67532dd5239721c0afcec0b5603a8db795de798155ad0, integrity sha512-C1WzYwFrBThQNElvFaFMmG58u63JAqpBiQanbx+5t0mrsiLJtsN0WJ+WcbrTxhpjj03Q4JTToSWFdz0w1Y44Pw==
    • 게이트(버전 커밋 90274419f6, 2026-10-21): install --frozen-lockfile, 단위 테스트 638개, 타입 검사, release 회귀 47개, browser 도구 회귀 125개, verify:locks, native 준비 recipe 검증, git diff --check PASS
    • release:build(Builder gate·source-free consumer gate)·release:verify·release:npm:test·release:reproduce: PASS(2026-10-21, source 9027441; release:reproduce end-to-end pin·세 artifact·npm byte 동일). Windows·같은 Docker host만, Linux 재현 NOT RUN.

    asset 7개

    파일 크기(B) SHA-256
    release-manifest.json 2,155 96044236f1a0d6dac8d1d24288846bc8bf7c73d85d9ffb0d0cc3976df05d626d
    release-manifest.sha256 88 d0d62e3d93f0804ab9adace609fa7b595f60b3c64194162a293f8fc25414c314
    release-pin.json 537 d6b8fb480793574badb9645bd7f33f6fc6363bb470d71628dc813de292c83651
    rgss23-arca-0.1.23.tgz 99,994,584 3b8b5b2aa9f59e6aada67532dd5239721c0afcec0b5603a8db795de798155ad0
    rgss23-builder-0.1.23.oci.tar 61,884,928 251559fe5c0f9f870a09a99aa9894d2c75ff8f266638238ee8d32cd57da0ebbc
    rgss23-contracts-0.1.23.tgz 38,247 ee5528f2eb16de52e1cc11112a80a4cb7697c9d926eaadfd7f0fc63fca66bef1
    rgss23-runtime-0.1.23.zip 45,714,519 4aa1aadbc24d185857252ea608f7051ad7cbac7c96809c8d0ecfb14fe0555553

    로컬 경로: dist/release/0.1.23/, dist/npm/0.1.23/rgss23-arca-0.1.23.tgz. artifacts.json·npm-package.json은 업로드하지 않는다.

    0.1.22 대비 전체 변경

    Downloads 9
  • ARCA 0.1.22

    ARCA 0.1.22 변경 사항

    이전 버전: 0.1.21. 문서 정리와 version 갱신만 포함한 release다. native runtime(mkxp-z core JS·WASM)은 0.1.21과 byte 동일하며 공개 API·schema·오류 code·Builder 동작에 변경이 없다. version 문자열이 들어가는 package.json·Builder producer version 때문에 contracts tgz·Builder archive·runtime ZIP(SDK bundle·provenance)·npm tgz bytes와 release pin·manifest hash는 새로 고정된다.

    포함 변경 요약

    문서

    • docs/project-status.md: 이전 release 절을 제거하고 Forgejo release·tag·git log로 위임했다.
    • docs/compatibility-matrix.md: 0.1.16 통합 판정 절과 과거 실행 서술을 삭제하고 native 자동 회귀 행을 판정·범위·재현 링크로 압축했다. launch 시간·메모리 측정 표 두 개는 유지한다.
    • docs/links-integration-guide.md: 0.1.13~0.1.20 버전별 절을 삭제하고 0.1.21 절 하나에 0.1.13 이하에서 올리는 host가 지켜야 할 누적 규칙 10개를 묶었다. 버전별 세부는 각 Forgejo release note가 소유한다.
    • docs/development/fast-start-analysis.md·tier3-cruby-direct.md: 측정 서술을 지우고 병목 판정·채택 설계·NO-GO 이유·재개 조건만 남긴 결정 기록으로 압축했다. 파일 경로·anchor는 유지한다.
    • docs/roadmap.md: LINKS 소유 7개 항목을 한 줄로 압축했다. 나머지 항목은 모두 유지한다.
    • README.md, AGENTS.md 3절, docs/verification-checklist.md, docs/integration-design.md, patch 근거 문서: 실행 로그·측정 수치·버전 aside를 제거하고 규칙과 NOT RUN 경계는 유지했다.
    • packages/player-sdk/README.md: 삭제된 상태 문서 anchor 한 곳을 Forgejo 0.1.19 release 링크로 바꿨다. release bytes에 들어가는 packages/contracts/README.md·packages/packager-rgss/README.md·tools/release/npm/README.md는 바뀌지 않았다.

    코드

    • 없음. pnpm release:version 0.1.22의 version 갱신만 있다.

    host 적용

    0.1.21을 적용한 host는 올릴 필요가 없다. 0.1.21 미적용 host는 LINKS 적용 가이드 0.1.21 절의 누적 규칙을 따르며 pin만 0.1.22로 둔다. 같은 release의 SDK·runtime·Builder·contracts를 함께 적용한다.

    NOT RUN

    • 새 사용자 acceptance 없음(제공 VX/VX Ace acceptance 기준은 2026-08-05 그대로).
    • browser smoke 재실행 없음(native runtime·SDK 동작 불변, 문서만 변경).
    • LINKS 적용, Linux 재현.

    배포 검증

    • tag: 0.1.22(annotated, tag object b6f6cbf148)
    • release source: c20bd949be(버전 커밋)
    • manifest SHA-256: 645ed379f84db548d5adba39cfc7d0a9086c2d8727e2a441d91b1e170d3374e5
    • Builder digest(pin): sha256:63dd5a5708fbf04e80f1dd9c900f6787d3091a7fe706bf885cf3d649315433df · Builder config digest(pin builderConfigDigest): sha256:cde2c0996f30146b360982d29273a757ba3c262fc85cb6bba7b857de0daa2acf
    • artifact SHA-256: builder 7c2d80e6eaaf1926997f79ea18c6e10b22f41e5005b09202fdb4f352e74596c7 · contracts 4b35fbfc44a32457dd298bfb75c52b0c3aa9bbc96638c55b2b1602586695632b · runtime b32bf65dd234e906241a58b93323f48cd877bae4817346bff39a4cb1744d712b
    • npm: @rgss23/arca@0.1.22 (Forgejo registry), rgss23-arca-0.1.22.tgz SHA-256 6e1cd4bb7d9f7d6e0fc130262a520f217b943f6c4032506ed67b47e61d55f0e2, integrity sha512-8GC838WYKC6fHQIHx1lIACXW4et8iz16ortXvLc91ZejtUEgUyJiuxdU/5CqcLyMPnaUVYQHQjJHHypweTt7sg==
    • 게이트(버전 커밋 c20bd949be, 2026-10-20): install --frozen-lockfile, 단위 테스트 618개, 타입 검사, release 회귀 47개, browser 도구 회귀 125개, verify:locks, native 준비 recipe 검증, git diff --check PASS
    • release:build(Builder gate·source-free consumer gate)·release:verify·release:npm:test·release:reproduce: PASS(2026-10-20, source c20bd94; release:reproduce end-to-end pin·세 artifact·npm byte 동일). Windows·같은 Docker host만, Linux 재현 NOT RUN.

    asset 7개

    파일 크기(B) SHA-256
    release-manifest.json 2,155 645ed379f84db548d5adba39cfc7d0a9086c2d8727e2a441d91b1e170d3374e5
    release-manifest.sha256 88 a5ee8fc5a1a0888b58e265def71f73cd9dff373b1d3748f7aac8c37469a79b50
    release-pin.json 537 31a7c9e37222c327dc9217146a5817a5fc7d7318bad6e4591c89fbdce69457b7
    rgss23-arca-0.1.22.tgz 99,986,402 6e1cd4bb7d9f7d6e0fc130262a520f217b943f6c4032506ed67b47e61d55f0e2
    rgss23-builder-0.1.22.oci.tar 61,884,928 7c2d80e6eaaf1926997f79ea18c6e10b22f41e5005b09202fdb4f352e74596c7
    rgss23-contracts-0.1.22.tgz 38,247 4b35fbfc44a32457dd298bfb75c52b0c3aa9bbc96638c55b2b1602586695632b
    rgss23-runtime-0.1.22.zip 45,707,430 b32bf65dd234e906241a58b93323f48cd877bae4817346bff39a4cb1744d712b

    로컬 경로: dist/release/0.1.22/, dist/npm/0.1.22/rgss23-arca-0.1.22.tgz. artifacts.json·npm-package.json은 업로드하지 않는다.

    0.1.21 대비 전체 변경

    Downloads 9
  • ARCA 0.1.21

    ARCA 0.1.21 변경 사항

    이전 버전: 0.1.20. LINKS 요청 6건(2026-10-16) 대응 release다. native runtime(mkxp-z core JS·WASM)·SDK bundle·contracts tgz·Builder archive·npm tgz bytes가 바뀐다. 새 오류 code·schema는 없고 삭제된 export도 없다. 새 공개 값은 모두 가산이다(release pin builderConfigDigest, getArcaRelease().builder.configDigest, loadArcaBuilder() 결과 configDigest, SDK presentation 옵션과 onPresentation의 filter·scaling).

    포함 변경 요약

    runtime: 비율 맞춤 여백 잔상 수정

    • canvas 비율과 게임 비율이 다를 때(Graphics.resize_screen, 정수 배율, 17:13이 아닌 canvas) Emscripten WebGL 1 offscreen blit이 gl2의 letterbox viewport를 그대로 써서 frame이 그 안으로 눌리고 여백 바깥 줄에 이전 화면이 남았다. frontend patch retroarch-main-thread-webgl-proxy의 swap이 commit 전에 viewport를 drawing buffer 전체로 둔다(근거).

    runtime: suspended AudioContext의 선부팅 지연 수정

    • user gesture 전 suspended AudioContext에서 RetroArch AudioWorklet writer가 즉시 반환해 threaded core audio가 속도 제한 없이 decode하고 write마다 main thread에 resume()을 쌓았다(선부팅이 20 s 상한까지 대기). frontend patch retroarch-audio-continuity가 blocking writer를 버린 frame의 재생 시간만큼 기다리게 하고 resume() 요청을 1초에 한 번으로 줄인다(근거).
    • runtimes/mkxp-z/dependencies.lock.json·build recipe와 redistribution-policy.json의 lock hash를 갱신했다. 제3자 dependency·license 변경은 없다.
    • native runtime export(named volume clean build): rgss23-core.js d4884b14f717f5b2ac35ec8a53f6d4663d6b1c70e2f477682e93326ef6cd8bd2(256,567 B), rgss23-core.wasm 39085f4e81f83ae1a7588849b4c696ea2fadf6d2a03f0c50954c44403c45c716(44,432,926 B).

    SDK: 표시 품질 launch 옵션

    • presentation: { filter?: "nearest" | "bilinear", scaling?: "fit" | "integer" }(launch·prepare 전용, 시작 뒤 변경 없음). 기본값 nearest·fit은 이전 release의 실제 동작과 같다(RetroArch video_smooth 기본 off). 알 수 없는 값은 launch 전 TypeError. onPresentation 상태에 적용된 filter·scaling을 보고한다.
    • presentation 통지가 정지·dispose 뒤 한 번 더 올 수 있던 RAF 경로를 막았다.
    • browser compositor의 CSS 확대(부모 transform, scaled 상태)는 host CSS 책임이며 SDK는 canvas style을 바꾸지 않는다(SDK 화면 표시).

    release·deploy: Builder config digest

    • release pin builderConfigDigest(Builder archive의 OCI image config descriptor digest = Docker 24 graphdriver store의 load 뒤 image ID). getArcaRelease().builder.configDigest는 integrity로 결속된 archive를 Docker 없이 읽어 pin과 같을 때만 돌려준다(다르면 ARCA_RELEASE_BUILDER_MISMATCH). release manifest schema는 그대로다.

    smoke·문서

    • runtime:smoke:dpr: resize 뒤 640×480·544×480·544×416 여백 전체 검정·frame 무축소 단언, --worker-mode. runtime:smoke:presentation-quality 신설. runtime:smoke:host-storage-metrics: --suspend-audio·--autoplay-policy.
    • LINKS 가이드 0.1.21 절(요청별 판정·검증 대응), 프로젝트 상태·호환성 매트릭스·로드맵(backing 재할당 보류, RTP pruning 미채택, iOS 초안 보류). release bytes에 들어가는 packages/contracts/README.md·tools/release/npm/README.md가 바뀌었다.

    측정 요약

    2026-10-16, 같은 PC, Chrome 155.0.8059.84·Firefox 153.0.1 headless, 자동화 PASS·사람 검토 NOT RUN.

    • resize 여백: runtime:smoke:dpr Chrome·Firefox × DPR 1·2·3 × 390×844·820×1180 × module·opaque-origin Worker 24셀 PASS(수정 전 runtime은 같은 셀 FAIL).
    • 표시 품질: runtime:smoke:presentation-quality Chrome·Firefox × module·opaque-origin 80셀 PASS(DPR 1의 2·3·2.3배, DPR 1.25·1.5; backing = CSS × DPR, nearest 경계 혼합 0, integer 여백 검정).
    • 선부팅(AudioContext 강제 suspended, prepare→paused): 제공 VX Ace Chrome lazy 4.6/3.8 s, opaque frame + opaque-origin Worker 3.4/4.1 s, heap 9.3 s, Firefox 4.1/3.2 s, 클릭 뒤 오디오 재개. WAV BGM 합성 게임 0.1.20 20.8 s → 0.1.21 3.7 s.
    • browser:smoke:chrome:vx-ace:title PASS(title gold 28353853… 일치).

    host 적용 순서

    LINKS 적용 가이드 0.1.21 절을 따른다. 요약:

    1. @rgss23/arca 전체를 0.1.21 exact pin과 registry integrity로 올리고 release pin·runtime generation을 함께 적용한다(절차는 0.1.20과 같다).
    2. Builder 실행 참조: load 뒤 daemon image ID가 getArcaRelease().builder.digest(containerd store) 또는 configDigest(Docker 24 graphdriver store)와 같을 때만 그 ID로 실행한다.
    3. 선명도가 필요하면 launch·prepare에 presentation을 전달한다. 부모 CSS transform 확대는 browser가 bilinear로 리샘플링하므로 표시 크기 배치를 우선한다.
    4. resize 여백 edge 단언과 suspended AudioContext 선부팅(force probe)을 host 경로에서 다시 측정한다.

    NOT RUN

    • LINKS opaque frame 적용·force probe·run-player-dpr 재측정, NAS 실환경, Docker 24.0.2 실제 daemon 재확인.
    • 실행 중 backing 재할당(보류), sharp 배율(미포함).
    • 사람 화면·청취 확인, 새 사용자 acceptance(제공 VX/VX Ace acceptance 기준은 2026-08-05 그대로), 새 runtime의 나머지 browser smoke 행렬.
    • 실기 모바일·Safari, Linux 재현.

    배포 검증

    • tag: 0.1.21(annotated, tag object 07605b80a1)
    • release source: 07ade373fa(버전 커밋)
    • manifest SHA-256: 219cfa29635aeda918ab73c40b093f90bdd5a3bccdf090507e7e40855023a603
    • Builder digest(pin): sha256:83adbc29a760db8f94cbbd331ba36028526067165b17d241a56fc8a13abe4d7b · Builder config digest(pin builderConfigDigest): sha256:43bc702e27c753de3c61fa206624a30a321efd3c1348a556d1aaba3d5a8c8d7c
    • artifact SHA-256: builder e97830b7d7e657d722a970ca59a54309aa9adb440d880148951037f2c8160a07 · contracts 63ceb690cd532aaf955af23d5dfb2bece1c6c988f8b138ed7c454ad95a2d649d · runtime 376de5df60edf710520bdc2927729aa9fd88750263c9acfedbd363df2abd53d5
    • npm: @rgss23/arca@0.1.21 (Forgejo registry), rgss23-arca-0.1.21.tgz SHA-256 70eb2ed4e281c32ca3db4bea5032a5e2c344239b1a55b79ef3738f127dbf2c82, integrity sha512-MA28KwXCDci8cpO6Twss9W3XFCbvudRNQpk+lyZXxB36DDyYRolNbscVMVXXAZ9vNiQb3GwgcU+cQIC4+CmiGg==
    • 단위 테스트 618개, 타입 검사, release 회귀 47개, native 준비 recipe 검증, git diff --check: PASS(2026-10-16, 버전 커밋 07ade37). runtime lock·native 진단 lock 검증과 browser 도구 회귀 125개: PASS(같은 code, 버전 커밋 직전).
    • release:build(Builder gate·source-free consumer gate)·release:verify·release:npm:test·release:reproduce: PASS(2026-10-16, source 07ade37). Windows·같은 Docker host만, Linux 재현 NOT RUN.

    asset 7개

    파일 크기(B) SHA-256
    release-manifest.json 2,155 219cfa29635aeda918ab73c40b093f90bdd5a3bccdf090507e7e40855023a603
    release-manifest.sha256 88 c619c86baa17c55c86eb1cc29a4b6011c489e9fa4880684aa21051d05a7d84c4
    release-pin.json 537 3cb9a5821ddcc2f0a1f79ee220b22637d37d378feeade952a99c04f6fc581efc
    rgss23-arca-0.1.21.tgz 99,986,173 70eb2ed4e281c32ca3db4bea5032a5e2c344239b1a55b79ef3738f127dbf2c82
    rgss23-builder-0.1.21.oci.tar 61,884,928 e97830b7d7e657d722a970ca59a54309aa9adb440d880148951037f2c8160a07
    rgss23-contracts-0.1.21.tgz 38,248 63ceb690cd532aaf955af23d5dfb2bece1c6c988f8b138ed7c454ad95a2d649d
    rgss23-runtime-0.1.21.zip 45,707,430 376de5df60edf710520bdc2927729aa9fd88750263c9acfedbd363df2abd53d5

    로컬 경로: dist/release/0.1.21/, dist/npm/0.1.21/rgss23-arca-0.1.21.tgz. artifacts.json·npm-package.json은 업로드하지 않는다.

    0.1.20 대비 전체 변경

    Downloads 9
  • ARCA 0.1.20

    ARCA 0.1.20 변경 사항

    이전 버전: 0.1.19. SA-06 빠른 시작·heap 축소 release다. native runtime(mkxp-z core JS·WASM)·SDK bundle·contracts tgz·Builder archive·npm tgz bytes가 바뀐다. 기존 heap 경로(content 생략)와 공개 API는 그대로이고 삭제된 export는 없다. schema 변경은 game·RTP manifest의 선택 필드 payload.archive.chunks 하나이며 0.1.19 이하 contracts parser는 이 필드를 거부하므로 host는 contracts(= @rgss23/arca 전체)를 먼저 올린다. 지연 콘텐츠·선부팅·폴더 실행은 opt-in이고 keyboard.minimumPressMs는 기본값이 켜진 가산 option이다.

    포함 변경 요약

    contracts·packager: manifest chunk digest

    • rgss23-game-package-v1·rgss23-rtp-package-v1의 payload.archive에 선택 필드 chunks({ algorithm: "sha256", chunkBytes, digests })를 추가했다. chunkBytes는 65,536–16,777,216 사이의 2의 거듭제곱이고 packager 기본은 1 MiB다. archive bytes·sha256(content ID)은 그대로이고 manifest bytes만 바뀐다.
    • 0.1.19 이하 parser는 chunks를 unknown field로 거부한다. chunk가 있는 manifest를 만들거나 받기 전에 consumer가 먼저 0.1.20으로 올라가야 한다(contracts 변경 이력).

    SDK

    • 지연 콘텐츠(가산): content: { mode: "lazy", reader, cache }. game·RTP package를 Wasm memory에 복사하지 않고 runtime이 읽은 chunk만 host reader에 요청한다. 첫 읽기 chunk를 manifest chunks로 WebCrypto 검증하고 기본 createRgss23LazyOpfsCache()가 검증된 chunk를 OPFS에 저장한다(OPFS가 없는 opaque-origin frame은 64 MiB 메모리 LRU). content를 생략한 기본 heap 경로도 mount 선할당으로 Wasm memory가 줄었다.
    • 선부팅(가산): prepareRgss23Player({ preboot: true })·onBoot. 메뉴·설명 화면 동안 타이틀까지 무음·입력 차단으로 부팅해 일시정지하고, 클릭 gesture 안의 start()는 재개만 한다.
    • 폴더 실행(files-only, 가산): Builder package 없이 directory handle·webkitdirectory FileList·Range 지원 서버의 HTTP manifest로 게임 폴더를 지연 모드로 실행한다. 경로를 NFC·/로 정규화해 빈·상위 segment와 대소문자·NFC 충돌을 거부하고, identity는 내용을 읽지 않는 sha256-path-size-v1 fingerprint(Builder 원본 fingerprint와 같음), save namespace 기본값은 dir-<fingerprint>다. 브라우저 안 inspect가 Game.ini·mkxp.json만 읽고 VX syntaxTransform: 2·글꼴 치환 mkxp.json·선택적 PNG tRNS 정리를 메모리 overlay로 얹는다. 폴더 bytes는 host 입력이라 chunk 검증·chunk cache가 없고 Builder의 script 감사·package 한도 검사·game-scoped overlay가 적용되지 않는다.
    • native 키 최소 누름: runtime keyup을 keydown 뒤 keyboard.minimumPressMs(기본 50 ms, 0~1000 정수, 0은 지연 없음, 범위 밖은 launch 전 TypeError)까지 늦추고 같은 키 연타는 누름·뗌이 각각 runtime input poll에 보이게 한다. 물리 키·별칭·가상 입력에 같이 적용하며 host page listener와 onInputAlias 호출 시점은 바뀌지 않는다.
    • API 세부: SDK 지연 콘텐츠와 선부팅, SDK 폴더 실행, SDK 입력과 focus.

    runtime patch와 identity

    • frontend patch retroarch-rgss23-lazy-mount: game·RTP package를 Wasm memory에 복사하지 않고 읽힌 chunk만 MessagePort로 embedder에게 요청하는 읽기 전용 WASMFS backend(/arca/lazy)를 추가했다. read 하나는 기본 30초 안에 응답받지 못하면 EIO다(rgss23 lazy mount).
    • core patch mkxp-z-lazy-archive-reads: PhysFS ZIP stat이 local header를 읽지 않게 하고 글꼴 scan을 FreeType stream 읽기로 바꿔, 부팅 중 path cache가 game·RTP의 모든 local header를 읽고 RTP 글꼴 2개를 통째로 읽던 접근을 없앴다(부팅 read 줄이기).
    • runtimes/mkxp-z/dependencies.lock.json·build recipe·verifier와 redistribution-policy.json의 lock hash를 갱신했다. 제3자 dependency·license 변경은 없다.
    • native runtime export(named volume clean build, canonical pin과 일치): rgss23-core.js 8cc0c878c70332c76fdb09d350d0b9fe6ac5caa90d15821369ff78c8789d16f7(256,567 B), rgss23-core.wasm d3f17b3569e99d42e7c9e182f3b9500b5551156a636cb92d224668d2d0fbfb4c(44,432,679 B).

    reference app·smoke·문서

    • reference app은 catalog 게임을 지연 콘텐츠(HTTP Range reader, OPFS chunk cache)와 선부팅으로 준비하고, “게임 폴더 열기”(directory picker·webkitdirectory·끌어 놓기)로 폴더 실행을 제공한다.
    • browser smoke 계약: staged artifact는 runtime JS·WASM만이고 game·RTP는 catalog 항목 pin·206 Range 읽기·[Rgss23Lazy] mounted log·RTP mount·Wasm memory 상한·선부팅 timeline으로 검사한다(gold·입력·save/load 단언 유지, 지연 실행 계약).
    • 문서: fast-start 분석(Tier 1~3 설계 근거, Tier 3 CRuby 직접 링크 spike NO-GO/보류 판정), LINKS 가이드 0.1.20 절, 프로젝트 상태·호환성 매트릭스 갱신. release bytes에 들어가는 packages/contracts/README.md·packages/packager-rgss/README.md가 바뀌었다.

    측정 요약

    2026-10-16, 같은 PC, runtime:smoke:host-storage-metrics(opaque-origin Worker), Chrome 155·Firefox 153 headless, 자동화 PASS·사람 검토 NOT RUN. artifact는 page가 미리 Blob으로 받아 둔 뒤 재므로 네트워크 전송 시간은 포함하지 않는다. 수치는 측정이며 판정이 아니다.

    게임·브라우저 heap 클릭→타이틀 cold / cache hit 지연 cold / cache hit 선부팅 클릭→start() Wasm memory(타이틀 뒤) heap → 지연
    VX Ace Chrome 8.5 s / 8.5 s 3.5 s / 2.6 s 32 ms 432 → 184 MiB
    VX Chrome 12.5 s / 12.5 s 3.4 s / 2.8 s 34 ms 627 → 184 MiB
    VX Ace Firefox 9.4 s / 8.9 s 4.0 s / 2.7 s 33 ms 432 → 184 MiB
    VX Firefox 13.6 s / 14.4 s 3.7 s / 2.9 s 32 ms 627 → 184 MiB

    mkxp-z-lazy-archive-reads 전/후 지연 cold source 요청(Chrome 155, 1 MiB chunk): VX Ace RTP 156회 163.0 MB → 8회 7.8 MB·game 19회 → 14회, 클릭→타이틀 3.6 → 2.5 s; VX RTP 39회 → 5회·game 84회 87.8 MB → 10회 10.2 MB, 3.7 → 2.7 s. 측정 조건·각주·회귀 smoke는 프로젝트 상태 0.1.19 대비 변경과 LINKS host 판정이 소유한다.

    host 적용 순서

    LINKS 적용 가이드 0.1.20 절을 따른다. 요약:

    1. contracts 먼저: @rgss23/arca 전체(contracts·SDK·runtime·Builder)를 0.1.20 exact pin과 registry integrity로 올린다. 이전 pin의 coordinator·API가 chunk가 있는 manifest를 읽는 혼합 배포를 하지 않는다.
    2. release pin·runtime generation 적용: 새 runtime identity와 release pin을 함께 적용한다(절차는 0.1.19와 같다).
    3. 지연 모드를 켤 때만: 새 Builder로 generation을 다시 만들어 chunks를 얻고, descriptor의 game·RTP artifact에 chunks를 넣고(RTP fileName은 RTP/<Game.ini RTP 이름>.mkxpz와 일치), PlaySession이 허용한 content-addressed URL의 HTTP Range나 Blob slice()로 reader를 구현하고, opaque frame에서 chunk 재사용이 필요하면 Rgss23LazyCacheAdapter를 parent 저장소로 구현한다.
    4. 선부팅은 곧 시작할 게임 하나에만 쓰고 양수 크기로 보이는 canvas에서 준비하며 떠나면 dispose()한다.
    5. 폴더 실행은 host가 bytes를 보증하는 입력에만 쓰고 승인된 Installation 배포는 Builder package·chunks 검증 경로를 유지한다. cache/save namespace는 기존처럼 host가 주입한다.
    6. keyboard.minimumPressMs 기본 50 ms가 켜진다. 이전 keyup 시점이 필요하면 0을 준다.
    7. lazy 경로(/arca/lazy)는 읽기 전용이며 host가 main thread에서 그 경로를 동기로 읽지 않는다. custom workerFactory는 SDK port 메시지를 Emscripten load보다 먼저 전달한다.

    NOT RUN

    • 실제 망(HTTP Range) 측정, opaque frame chunk cache, LINKS 적용·실제 플레이 재검증, NAS 실환경.
    • 사람 화면·청취 확인, 새 사용자 acceptance(제공 VX/VX Ace acceptance 기준은 2026-08-05 그대로).
    • Edge 155 save-load gold 검토(browser:smoke:edge:vx-ace:save-load는 모든 동작·화소 검사를 통과했지만 Edge version pin drift로 NOT REVIEWED), 새 runtime의 나머지 browser smoke 행렬.
    • 폴더 실행의 VX·Firefox·Edge·자동 smoke와 사용자 acceptance(자동 근거는 Chrome VX Ace만), 짧은 키 tap 사용자 acceptance.
    • 실기 모바일·Safari, Linux 재현.

    게시 identity와 registry 검증은 현재 상태, 상세 값은 해당 release manifest/pin을 따른다.

    배포 검증

    • tag: 0.1.20(annotated, tag object a685cde46f)
    • release source: e859dc27b3(버전 커밋 b31ba50 뒤 npm facade 중첩 선언 복사 수정 커밋)
    • manifest SHA-256: a6dac661743a62b332ee395cd65bb39b9578a640a151bb736c4a35a173055891
    • Builder digest(pin): sha256:6b0f47faa2197d31417bc9fdfaf372e9660167c944e2c21d973d99d4b85a364c · Builder config digest(Docker 24 image ID): sha256:a2c4940dd4322af01e14ec1495dc40aa2a458f4c36a4a67af3ce71d601eed2a1
    • artifact SHA-256: builder 38d560fc6e1ab42137708a9f35baa7e328287bcabfd80b1e2f05fccce6bd451b · contracts c915415c93d56e9a3dcdcbd446f676949c3e5afddc4176295e8df709040fd766 · runtime 74994b84c427fc020d1f7a480467607f38f69f219838b63c9ce4b0e9cdff5b98
    • npm: @rgss23/arca@0.1.20 (Forgejo registry), rgss23-arca-0.1.20.tgz SHA-256 056acb021cf93daf650c9cc037e5a395fd87a3b3ae37be3f1915ff8b7b4c78d2, integrity sha512-b4QlYhHLa1fbVozueuqQqnVsGhtVZZuO+p7j+wJ0LOPIJ0X7PdhuGVR2rWyHLS8EZkkwE6e8MgLzOeuJGPRSCA==
    • 단위 테스트 609개, 타입 검사, release 회귀 45개(수정 커밋 뒤 46개), browser 도구 회귀 125개, runtime lock·native 진단 lock·native 준비 recipe 검증, git diff --check: PASS(2026-10-16, 버전 커밋 b31ba50).
    • release:build(Builder gate·source-free consumer gate)·release:verify·release:npm:test: PASS(2026-10-16, source e859dc2). release:reproduce(clean detached worktree e859dc2, pin·세 artifact·Builder digest·npm tgz byte 동일): PASS(2026-10-16). Windows·같은 Docker host만, Linux 재현 NOT RUN.

    asset 7개

    파일 크기(B) SHA-256
    release-manifest.json 2,155 a6dac661743a62b332ee395cd65bb39b9578a640a151bb736c4a35a173055891
    release-manifest.sha256 88 6d39f5824ca9ce54565919e89c4aaa2f50d617466232b9ea334c95a9c65d45b8
    release-pin.json 441 b1be6a0c1188d3d185f5d687710e650732e9f1f9341971abcd11f4ece00f83e8
    rgss23-arca-0.1.20.tgz 99,982,340 056acb021cf93daf650c9cc037e5a395fd87a3b3ae37be3f1915ff8b7b4c78d2
    rgss23-builder-0.1.20.oci.tar 61,884,928 38d560fc6e1ab42137708a9f35baa7e328287bcabfd80b1e2f05fccce6bd451b
    rgss23-contracts-0.1.20.tgz 37,871 c915415c93d56e9a3dcdcbd446f676949c3e5afddc4176295e8df709040fd766
    rgss23-runtime-0.1.20.zip 45,705,529 74994b84c427fc020d1f7a480467607f38f69f219838b63c9ce4b0e9cdff5b98

    로컬 경로: dist/release/0.1.20/(manifest·sha256·pin·Builder·contracts·runtime), dist/npm/0.1.20/rgss23-arca-0.1.20.tgz. artifacts.json·npm-package.json은 업로드하지 않는다.

    0.1.19 대비 전체 변경

    Downloads 9
  • ARCA 0.1.19

    ARCA 0.1.19 변경 사항

    이전 버전: 0.1.18. LINKS 요청(T47: devicePixelRatio 2·3 모바일·태블릿에서 RGSS 화면이 왼쪽 아래 1/DPR만 확대 표시, host용 논리 해상도 공개)에 대한 release다. native runtime(mkxp-z core JS·WASM)·SDK bundle·npm tgz bytes가 바뀐다. 삭제된 공개 API는 없고 새 오류 code·contracts schema 변경도 없다. rgss23-runtime-status-v1, inspection v1/fingerprint ABI, contracts schema, Builder subcommand·기본 출력·exit code는 그대로다. 변경은 독립 리뷰 R48(P2 4건 수정)·R48b(병합 가능) 뒤 병합했다.

    고 DPR 표시 결함 수정

    • 현상: devicePixelRatio 2·3(모바일·태블릿·고해상도 데스크톱)에서 게임 화면의 왼쪽 아래 1/DPR 영역만 canvas 전체로 확대돼 보였다. DPR 1에서는 재현되지 않았다.
    • 원인: RetroArch는 main()에서 처음 보이는 canvas CSS 크기 × DPR로 backing(drawing buffer)과 renderer viewport를 한 번 정하는데, Nostalgist postRun이 시작 직후 canvas backing을 CSS px로 다시 줄여 renderer viewport(CSS × DPR)와 drawing buffer(CSS px)가 어긋났다.
    • 수정(SDK): SDK가 Nostalgist size에 runtime이 적용한 backing을 그대로 돌려줘 모든 DPR에서 drawing buffer == renderer 크기이고 시작 직후 onPresentation.status === "synced"다. 이후 CSS resize·회전·주소창·DPR 변화는 설계대로 backing 고정 + scaled이며 그림 전체가 보인다.
    • 영향 브라우저: Chrome 155(모바일 emulation DPR 1·2·3)·Firefox 153(DPR emulation)에서 수정 전 FAIL·수정 후 PASS를 자동 smoke로 확인했다. 실기 모바일·Safari는 NOT RUN이다.

    업그레이드 시 확인할 동작 변경

    • Rgss23PresentationState.logicalWidth·logicalHeight(가산): 게임 논리 해상도(Graphics.width·Graphics.height). 소스는 새 RetroArch frontend patch retroarch-presentation-geometry의 Module.onRgss23Geometry hook(main loop가 core geometry 변경을 frame 경계에서 보고)이며 로그 문자열을 읽지 않는다. 시작 직후 544×416, Graphics.resize_screen 뒤 새 값으로 다시 통지된다. hook이 없는 runtime(0.1.18 이하)과 첫 보고 전에는 null이다. host는 iframe 크기·고정 배율(100% = 논리 해상도 CSS px) 계산에 canvas backing이 아니라 이 값을 쓴다.
    • aspectRatio 계산 변경: backing 비율이 아니라 logicalWidth / logicalHeight다(첫 통지 전에는 RGSS 기본 544×416의 17/13). 필드 이름·타입은 그대로다.
    • hidden·0×N 시작 gate: SDK는 native 시작 전에 canvas의 clientWidth·clientHeight가 모두 양수가 될 때까지 기다린다(display:none, layout 전, 0×N·N×0은 가시 크기가 아님). starting이 canvas가 보일 때까지 유지되고 running은 첫 가시 크기 × DPR로 backing을 잡은 뒤 온다. canvas를 숨긴 채 launch하고 running을 기다려 canvas를 보이게 하는 host 순서는 서로 기다리므로 쓰지 않는다. 시작 중 취소는 launch에 전달한 signal abort(RUNTIME_ABORTED, reason: "aborted")이며 prepared.dispose()는 start 전 자원 해제용이다. 새 export waitForVisibleCanvasSize·isVisibleCanvasSize.
    • host callback 예외 격리: onPresentation이 throw해도 runtime은 멈추지 않는다. SDK가 native geometry hook 경계에서 예외를 잡아 reportError(없으면 console.error)로 window의 일반 uncaught error로 다시 보고하고 geometry 상태·다음 통지는 유지된다. host는 자기 callback 오류를 window error 이벤트로 본다.
    • installResponsiveCanvas 가산 속성: 0.1.x대로 호출 가능한 disposer 함수를 돌려주며 같은 함수에 dispose()·setLogicalSize() 속성이 더해졌다. 반환 계약의 삭제·변경은 없다.
    • status 의미: scaled는 고정 backing의 CSS 확대·축소(회전·resize·주소창·시작 뒤 DPR 변화)이고 표시 결함이 아니다. 시작 뒤 DPR이 바뀐 뒤 선명도가 필요하면 host가 player를 다시 실행한다.
    • artifact identity: native runtime JS·WASM(새 frontend patch, clean rebuild), SDK dist, runtime ZIP, contracts tgz(package.json), Builder archive, npm tgz bytes·integrity가 모두 바뀐다. release pin·runtime generation과 lockfile의 @rgss23/arca integrity를 함께 적용한다.

    새 runtime patch와 identity

    • frontend patch retroarch-presentation-geometry(emscripten/library_platform_emscripten.js·retroarch.c, retroarch-shutdown-cleanup 뒤·retroarch-restart-transaction 앞) 추가. runtimes/mkxp-z/dependencies.lock.json·build recipe·verifier·Dockerfile과 redistribution-policy.json의 lock hash를 갱신했다. 제3자 dependency·license 변경은 없다.
    • native runtime: rgss23-core.js c0b7d84b27956d220303000e809a5f355f7f62184f5f80f5d46e601ae4c65c28(251,121 B), rgss23-core.wasm b7ca2b80bffeca4568eb3e4bd92c3b70866ac10a15fea2e47cadaacb80a2ebd6(44,417,165 B). 2026-10-14 runtime:all clean rebuild 2회(dpr-fix worktree, main) export가 byte 동일하다.

    LINKS 적용 가이드 0.1.19 절을 따른다. 요약: T47 DPR gate(DPR 1·2·3 × 390×844·820×1180 × 회전·주소창)에서 4분면 전체 표시와 synced를 확인하고, reportResolution·iframe 크기·고정 배율 100%를 logicalWidth·logicalHeight로 계산하며(null이면 544×416 기본값 또는 이전 값 유지), scaled를 오류로 처리하지 않고, hidden canvas launch → running 대기 → 표시 순서를 쓰지 않으며, onPresentation 안의 오류를 자체 telemetry로 잡는다. canvas width·height를 host가 덮어쓰지 않는다는 계약은 그대로다.

    검증 범위와 알려진 제한

    • 자동 근거(2026-10-14, 합성 4분면 VX Ace fixture, runtime:smoke:dpr): Chrome 155.0.8059.79(모바일 emulation) 6셀(DPR 1·2·3 × 390×844·820×1180, 각 initial·rotated·address-bar·resize-screen) PASS, Firefox 153.0.1 같은 6셀 PASS. runtime:smoke:dpr:hidden-start(DPR 2 한 셀) Chrome·Firefox PASS. DPR 1 회귀 browser:smoke:firefox:vx:resize-input PASS, pixel gold browser:smoke:chrome:vx-ace:title PASS(기존 gold와 rgbaSha256 일치).
    • NOT RUN: 실기 모바일·Safari, 실제 monitor DPR 이동·zoom·fullscreen, opaque iframe, LINKS 통합·NAS 실환경, Linux 재현, 사람 acceptance. 0.1.18의 Docker 24 docker load 호환·게임패드·터치 자동 근거와 NOT RUN 범위는 유지한다.

    게시 identity와 registry 검증은 현재 상태, 상세 값은 해당 release manifest/pin을 따른다.

    배포 검증

    • release source: a73e2cdc13
    • manifest SHA-256: 1652eb2fec2be89063cc0d7dea624b95b83ddfb470ce6b6da7257f709c547c9c
    • Builder digest(pin): sha256:63e1502baa90a54e8ba9cea675ed07077b3b7dc6f55f07d5d36d412a3c58b95b · Builder config digest(Docker 24 image ID): sha256:bfdd0427236a222093a1edee923eb16acef389387106d2d62faaf20d5d873926
    • artifact SHA-256: builder e058456287d2d253065b2fa9acf4c8544fa8da7daec012e14b073e7de8f6b20d · contracts c7ce5314cae39e6a74e6437ce854eb3d2399cc8f94c45b58c963efbbec123565 · runtime a8e04c4332c9bde900f92db9459b10d4b48c8cc925c0c948136aeda902034ee2
    • npm: @rgss23/arca@0.1.19 (Forgejo registry), rgss23-arca-0.1.19.tgz SHA-256 ec4fa8e58f5c8f9d90a6b068632646b8efe86fdb28eca67af148014fdb96b71b, integrity sha512-+BDlRHGgORrXjYoDMwTGwMI1wZy4pzAJmkJtivesyLDZXDP4UNJ+/BTNyTdyUdUpzdSSgUq4SFYQqXLNBQ89CQ==
    • 단위 테스트 491개, 타입 검사, release 회귀 45개, browser 도구 회귀 117개, runtime lock·native 진단 lock·native 준비 recipe 검증, git diff --check: PASS(2026-10-14, 버전 커밋 a411741).
    • release:build·release:verify·release:npm:test·release:reproduce(clean detached worktree, pin·세 artifact·Builder digest·npm tgz byte 동일): PASS(2026-10-14).

    0.1.18 대비 전체 변경

    Downloads 9