-
hanyul released this
2026-10-23 20:15:08 +09:00 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,rgss23ReleaseProtocol1)이 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()가 staticmkxp_retro::fs소멸자의PHYSFS_deinit을 audio 정리보다 먼저 실행했다. 그래서PHYSFS_mountHandlearchive(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 patchmkxp-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_iseqhook,--parser=prism,RUBYOPT)은 모두NotImplementedError로 막았다. 그래서 legacy 문법 변환(VXsyntaxTransform: 2)은 그대로다. - 바뀌지 않는 4.0 차이: 예외 backtrace의
'Class#method'표기,Hash#inspect형식,Encodinginspect, 알 수 없는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), wrapper0b0a9527, 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 imagenode:26.12.1-trixie-slim(corepack 0.36.0을 hash로 고정),nostalgist0.23.0,@types/node26.6.5. - 제공 VX browser fixture 글꼴은 NeoDunggeunmo v1.601이고, RPGVX RTP 추출 image는 다시 게시된
debian:13.7-slimdigest다. runtime ZIP에는 들어가지 않는다.
재배포 정책 재승인
runtimes/mkxp-z/redistribution-policy.json을 2026-10-23에 runtime lockdc792e75…로 재승인했다(status: approved,redistribution: restricted유지).- 고지 전체를 runtime ZIP
LICENSES/로 내보낸다: CRuby 4.0.9COPYING·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, JS97f21a30…, WASM18848c93…, provenance stamp가 lockdc792e75…·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.jsgame·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 VXresize-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, 이식 전과 같음). RubyThread·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 절을 따른다. 요약:
@rgss23/arca전체를 0.1.25 exact pin으로 올린다(runtime·SDK·Builder·contracts 함께). 0.1.23 이하에서 올리면 0.1.23·0.1.24 절도 함께 적용한다.- runtime bytes가 바뀌었으므로 0.1.25 Builder로 generation을 다시 만든다. Builder digest·config digest를 새 pin과 대조한다.
- 실제 게임의 title·save/load·플레이와 mouse click 위치를 다시 확인한다. Ruby 오류 문자열을 분류에 쓰면 CRuby 4.0 backtrace 표기로 다시 대조한다.
- fresh 재시작과
stop()뒤 재launch를 반복해 frame 메모리가 늘지 않는지 확인한 뒤 0.1.24 절의 instance 보존 경고(횟수 제한)를 해제한다. - 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,restartVX Ace 변형,presentation-qualityFirefox·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-core25.16.0 갱신(pnpmminimumReleaseAge때문에 2026-10-23T11:54Z까지 막힘), Linux 재현.
배포 검증
- tag:
0.1.25(annotated, tag object7366087fff652c4d47aa6dd39eb18df84657bc42) - release source:
8c70f90351(Release: store npm package paths over 100 bytes in the ustar prefix, 버전 커밋Release: prepare ARCA 0.1.255e3fbfe바로 다음) - 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.tgzSHA-256 24ae784104f11ad9138590308ad127f69b0d6481e23e0f59fd0d7a86a24878ad, integritysha512-6EptvRsVnBs4u1qzTjudAdqAI7rebi7K0t3N9Ur336Wl7uAc+0qytfkw8tzMTrThU62DxcliKyiYIkoMV4ei3w==(로컬 계산, registry 게시NOT RUN) - runtime ZIP의
rgss23-core.js(97f21a30…272,594 B)·rgss23-core.wasm(18848c93…48,400,171 B)은 maina5e3af7canonical runtime export와 byte 동일하고, export provenance가 runtime lockdc792e75…과 일치한다.redistribution-policy.jsonruntimeLockSha256은dependencies.lock.json과 일치한다. named volumergss23-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 --checkPASS(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, source8c70f90, manifestsourceCommit= 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.json2,155 363342e99543a4b54055864ea6581377185f28700f8ce47324830c0431609214release-manifest.sha25688 68f95c0e836efc8d106ec7410628fe5abc7c56efff0e372dacb7bfd5ee12aa14release-pin.json537 38ae03c8e8818ef3d7722bab98d6c27efd30883770094a03d25e4503f7cb8b34rgss23-arca-0.1.25.tgz103,622,084 24ae784104f11ad9138590308ad127f69b0d6481e23e0f59fd0d7a86a24878adrgss23-builder-0.1.25.oci.tar63,196,672 90dd41fcbb4787a61ea0074df11d690295833d0542adf2963ddf9b8ee6843529rgss23-contracts-0.1.25.tgz38,268 b7fcebc2d9b5958ac5fede905b0c0d0d54b1f7199847efe5ffdfa6214cec1c14rgss23-runtime-0.1.25.zip50,112,038 4d2657226772c973b8a73f6e67299c844aaa1d250c30f36d7fca3271e3c272d3로컬 경로:
dist/release/0.1.25/,dist/npm/0.1.25/rgss23-arca-0.1.25.tgz.artifacts.json·npm-package.json은 업로드하지 않는다.Downloads 9
-
release-manifest.json
2
2.1 KiB
2026-10-23 20:15:34 +09:00 -
release-manifest.sha256
2
88 B
2026-10-23 20:15:36 +09:00 -
release-pin.json
2
537 B
2026-10-23 20:15:37 +09:00 -
rgss23-arca-0.1.25.tgz
2
99 MiB
2026-10-23 20:15:39 +09:00 -
rgss23-builder-0.1.25.oci.tar
2
60 MiB
2026-10-23 20:15:40 +09:00 -
rgss23-contracts-0.1.25.tgz
2
37 KiB
2026-10-23 20:15:41 +09:00 -
rgss23-runtime-0.1.25.zip
2
48 MiB
2026-10-23 20:15:42 +09:00 -
Source code (zip)
0
2026-10-23 20:15:08 +09:00 -
Source code (tar.gz)
0
2026-10-23 20:15:08 +09:00
- 0.1.24 이하에서는