Roblox UI 제작기
라이선스를 먼저 확인하세요. 아이콘은 개발자가 소유한 하나의 라이선스 벡터 아이콘 팩에서만 가져옵니다. 이 스킬은 아이콘이나 텍스처를 자체적으로 제공하지 않습니다. 사용하는 아이콘 팩의 라이선스를 읽으세요. 대부분의 유료 팩은 자체 게임에서 사용하는 것을 허용하지만, 재판매, 재배포, 에셋 팩 및 AI 학습(해당 조건이 있는 경우, 팩의 PNG를 어떤 이미지 모델에도 절대 보내지 마세요)을 금지합니다. 게임 리포지토리에서는 라이선스가 허용하지 않는 한, 팩 자체가 아닌 icons.json과 복사 스크립트만 커밋하세요. 텍스처는 https://ui-resources.com 에서 직접 다운로드하며(UI_RESOURCES.md 참조), 제작자의 크레딧을 표시해야 합니다.
Figma 가져오기 도구는 이미 Figma에 존재하는 디자인을 위한 것입니다. 이 스킬은 HTML을 먼저 통해 새로운 UI를 디자인하거나(또는 스크린샷을 다시 제작)하기 위한 것입니다.
루프: 참고 자료 -> 토큰 -> HTML(모든 상태) -> 개발자 확인 -> 학습 -> 가져오기 -> 검증.
LESSONS.md를 먼저 읽고 모든 작업을 시작하세요(지금까지 배운 모든 규칙과 그 이면의 버그가 기록되어 있습니다). 아래 내용과 충돌하는 경우 LESSONS.md가 우선합니다.
이 스킬의 파일
| 파일 | 설명 |
|---|---|
LESSONS.md | 모든 규칙과 이유. 먼저 읽고, 개발자의 피드백을 여기에 기록하세요(REVIEW_LOOP.md) |
STYLE.md | 참고 자료를 토큰으로 읽는 방법, 프리셋, CSS 토큰을 Roblox 테이블로 변환 |
UI_RESOURCES.md | ui-resources.com 소개, 다운로드 방법, stud 텍스처와 저장 위치 |
PATTERNS.md | HUD, 상점, 크레이트 릴 + 확률, 토스트, 확인, 로딩, 튜토리얼, 버블, 목표 알약, 리스트 |
PIPELINE.md | HTML -> JSON -> Roblox 상세: rbx.json, 내보내기 마커, 매핑 테이블, 원장, 템플릿, 복사본 |
REVIEW_LOOP.md | 화면 표시, 피드백 수집, 승인 방법 |
VERIFY.md | 모의 렌더링, 속성 검사, 편집 모드 하네스, 플레이테스트 클릭, 체크리스트 |
ROBLOX_FACTS.md | 측정된 엔진 및 MCP 도구 사실(inset, TextSize, 업로드, 캡처) |
styles/ | stud.css(기본 프리셋), glass.css(어두운 시뮬레이터 프리셋) |
templates/examples/ | 작동하는 UI 프로젝트: build.py, kit.css, icons.json, rbx.json |
templates/luau/ | Builder, UIKit, NumberFormat, Theme, client/UI + Controller, Toasts, UpdateInPlace, PixelRows, ProgressiveReveal, NextGoal, CrateRoll, LoadingScreen, PropertySweep, WorldHitTest |
scripts/ | read_reference, copy_icons, cdp/export/dump, gen, ledger, assets, bundle, mock/mockshot/mockdiff, check_copies, luau_to_rbxmx; remake/ = 1:1 측정 도구 |
SK=<이 스킬의 폴더 경로> (이 SKILL.md 파일이 있는 폴더). 필요한 도구: python3(PIL + numpy), node 22+, Google Chrome(헤드리스 렌더링, CHROME 환경변수로 macOS 기본 경로 재정의 가능), luau-analyze, 페이지 보기용 브라우저 창 또는 브라우저 자동화 도구(Claude Code 데스크탑: mcp__Claude_Browser__*, ToolSearch로 로드), Luau 실행 및 .rbxmx 파일 가져오기가 가능한 Studio MCP 서버(이 스킬은 커뮤니티 robloxstudio MCP 기준으로 작성됨), upload_image 전용 내장 Roblox_Studio MCP(ROBLOX_FACTS.md 참조).
1. 브리프, 참고 자료, 스타일 (필수: 스타일 참고 자료)
- 브리프를 확인하세요: 어떤 화면인지, 기능, 표시할 데이터, PC 및 휴대폰. 각 화면에 필요한 모든 상태를 나열하세요.
- 스타일 참고 이미지는 필수입니다. 개발자가 제공한 것을 사용하세요. 제공되지 않은 경우 한 번만 요청하세요("원하는 스타일의 스크린샷을 보내주세요. 또는 stud 스타일을 사용하겠습니다"). 개발자가 그냥 진행하라고 하면 stud 프리셋을 사용하세요. 대부분의 게임이 stud 스타일입니다.
- 4단계에서 프로젝트 설정을 먼저 수행하세요(
ui/폴더 생성). 그런 다음 참고 이미지를ui/ref.png로 저장하세요. 레이아웃 참고 자료(다른 게임의 상점 등)는 STYLE 참고 자료와 별개입니다. ui/폴더 안에서 참고 자료를 읽으세요(STYLE.md 섹션 2):python3 $SK/scripts/read_reference.py ref.png-> 팔레트, 외곽선 픽셀, 텍스처 힌트, 텍스트 스타일, 밀도 +ref_palette.png,ref_zoom.png(stud/광택을 시각적으로 확인하기 위해 생성) 및 초안style.css. 각 값을 눈으로 확인하고, 선택한 프리셋의 재정의(override)만 유지하세요.- "게임 X처럼" = 영감을 받은 것이지, 복사가 아닙니다. 개발자가 "이것을 1:1로 다시 만들어 주세요"라고 명시적으로 말한 경우에만 복사입니다(LESSONS.md 섹션 7 및
scripts/remake/참조).
2. ui-resources.com의 텍스처
Stud 스타일에는 반드시 stud 텍스처가 포함되어야 합니다. 이 스킬은 텍스처를 제공하지 않습니다. https://ui-resources.com 에서 직접 "Stud texture"(태그 Stud)를 다운로드하고, 필요한 경우 실제 PNG로 변환한 후 프로젝트의 ui/stud.png로 저장하세요(타일당 4x4 stud, 112px 간격으로 타일링, 오버레이 블렌드 모드). 다른 용도(종이, 선버스트, 하프톤, 배경 등)는 먼저 사이트에서 검색하고 다운로드를 ui/tex/ 폴더에 저장하세요(UI_RESOURCES.md: 필터, ?tag=Stud, 지연 로딩 URL 읽기, WebP-이름-png를 위한 file + sips 명령어). build.py 헤더에 제작자 크레딧을 명시하세요.
3. 아이콘: 소유한 아이콘 팩만 사용
아이콘은 개발자가 소유한 하나의 라이선스 벡터 아이콘 팩에서만 가져옵니다(프로젝트당 하나의 벡터 팩, 절대 여러 팩을 혼합하지 않음). 이모지는 사용하지 마세요. 아이콘은 팩 자체의 폴더나 카탈로그를 검색하여 찾으세요(예: find <팩_폴더> -iname '*coin*'). 4단계 설정 후 ui/icons.json을 편집하고({"slug": "Icon file name or path inside the pack"}, 예제 리스트는 시작점입니다), ui/ 폴더에서 python3 $SK/scripts/copy_icons.py icons.json --pack <아이콘 팩>을 실행하세요(아이콘 팩에 해당하는 경우 --prefer " Outline" 옵션을 추가하여 outlined variant를 우선 선택). 이모지는 절대 사용하지 말고, 닫기 버튼은 텍스트 "X"를 사용하세요. 누락된 아이콘이 있다고 판단하기 전에 동의어를 검색하세요.
4. 모든 화면을 HTML/CSS로 제작
게임 리포지토리에서 한 번만 설정하세요(1-3단계가 ui/에 데이터를 쓰기 전에 실행; cp -n은 기존 파일을 덮어쓰지 않음):
mkdir -p ui && cp -rn $SK/templates/examples/. ui/ && cd ui
cp <다운로드한 stud 텍스처> stud.png && cp -r $SK/styles . # stud 텍스처는 ui-resources.com에서
cp <참고 이미지> ref.png && python3 $SK/scripts/read_reference.py ref.png # -> style.css (초안)
python3 $SK/scripts/copy_icons.py icons.json --pack <아이콘 팩> && python3 build.py # -> *.html + index.html
python3 -m http.server 8870 --bind 127.0.0.1 # 백그라운드 실행; 또는 아래 launch.json 항목 + preview_start
게임 리포지토리의 .claude/launch.json 파일(이후 mcp__Claude_Browser__preview_start {name: "ui"} 실행):
{ "version": "0.0.1", "configurations": [
{ "name": "ui", "runtimeExecutable": "python3",
"runtimeArgs": ["-m", "http.server", "8870", "--bind", "127.0.0.1", "--directory", "ui"], "port": 8870 } ] }
build.py를 편집하세요(이 파일이 진실의 원천(source of truth)입니다. 생성된 .html 파일은 절대 수동으로 편집하지 마세요). 가장 중요한 규칙:
- 1920x1080 스테이지, 절대 px 사용; 공유 컴포넌트(
plate,panel,card,T,I) 사용으로 형제 요소들이 동일한 처리를 받도록 하고, 색상만 다르게 합니다. 스타일링은 토큰에서 비롯됩니다:kit.css(구조) ->styles/<프리셋>.css(UI_STYLE=glass python3 build.py로 전환) ->style.css(이 게임).?style=glass로 실시간 미리보기. - 내보내기 마커:
grp(name, html, anchor)= 화면 가장자리에 고정된 최상위 Roblox 프레임;name=은 모든 라이브 레이블/아이콘/버튼에 사용;sub(..., btn=True, opens='Shop');hid=True는 내보내졌지만 숨겨진 상태를 의미합니다. PIPELINE.md 섹션 2에 전체 테이블이 있습니다. - 모든 상태는
states.html에; 휴대폰 레이아웃은hud_phone.html에; 모든 런타임 요소(토스트, 확인, 보상, 튜토리얼, 빌보드)는templates.html에; 실제 게임 캡처가 있으면 컨텍스트 안에서 조각들을 보여주세요. - 인라인
style="..."안에 큰따옴표 사용 금지; Active/Visible/Position...이라는 이름의 요소 금지; 게임에서 토글하는 요소에는display:none대신hid(opacity 0) 사용. - 자체 점검: 브라우저 창에서 각 페이지를
?check와 함께 열어서(checkOverflow()가 overflow와 깨진 이미지 없음을 반환해야 함) 확인; 2개의 헤드리스 스크린샷을 렌더링하고(REVIEW_LOOP.md) 시각적으로 검토하세요.
5. 중단: 개발자가 확인
첫 번째 라운드에서는 style.html과 첫 번째 화면을 보여주고, 그 다음 나머지 화면을 보여주세요(REVIEW_LOOP.md). 명시적인 승인을 기다리세요. 모든 수정 사항에 대해: 일반적인 규칙을 찾아 LESSONS.md에 기록하고(규칙, 이유), 모든 곳에 적용한 후, 개발자에게 한 줄로 저장한 내용을 알리세요. 승인 전까지 Roblox 작업을 수행하지 마세요.
6. Roblox로 가져오기 (승인 후)
자세한 내용: PIPELINE.md. 서버가 실행 중인 ui/ 폴더에서:
# 첫 번째 가져오기만: Luau 런타임 + 빌더 (그런 다음 ../roblox/ui/client/UI.luau의 "<Gui>"를 rbx.json의 "gui"로 교체)
mkdir -p ../roblox/ui/client && cp -n $SK/templates/luau/*.luau ../roblox/ui/ && cp -n $SK/templates/luau/client/*.luau ../roblox/ui/client/
rm -f ../roblox/ui/LoadingScreen.client.luau ../roblox/ui/CrateRoll.luau # 이것들은 ReplicatedFirst / ReplicatedStorage에 있음
node $SK/scripts/export.mjs # 레이아웃 JSON + 래스터 조각당 2개의 투명 PNG -> rbx/out/
python3 $SK/scripts/gen.py # Data_<Screen>.luau, Data_Templates, Data_Manifest -> luau_out; 아트 -> rbx/out/upload
python3 $SK/scripts/mock.py && node $SK/scripts/mockshot.mjs # 오프라인 Roblox 시맨틱 렌더링: 화면당 평균 차이 1-3
python3 $SK/scripts/ledger.py 20 # 업로드할 다음 URL; mcp__Roblox_Studio__upload_image(+studio_id)로 업로드,
# 그런 다음: echo '<result json>' | python3 $SK/scripts/ledger.py 20 ; 0개가 남을 때까지 반복
python3 $SK/scripts/assets.py # AssetIds.luau
python3 $SK/scripts/bundle.py # rbx/out/<Gui>Build.rbxmx
업로드 규칙: 배치당 최대 20개, 게임이 그룹 소유인 경우 GROUP의 플레이스를 열고, 원장(ledger)에 이미 있는 것은 다시 업로드하지 말며, 외부 ID를 검사하세요. 그런 다음 Studio에서 robloxstudio 통해: 이전 ServerStorage.<Gui>Build 삭제 -> import_rbxm으로 .rbxmx 파일을 ServerStorage에 가져오기 -> require(game.ServerStorage.<Gui>Build.Builder).build() 실행 -> gui 활성화, Builder.fit() 두 번 실행, 비활성화. 절대 set_script_source를 사용하지 마세요(\n을 망가뜨림); 항상 .rbxmx + import_rbxm 사용.
게임 코드 연결(Controller가 UI + UIKit을 부트함; 데모 숫자는 gui 속성 PreviewMode로만 표시):
client/UI.luau (열기/닫기/뒤로가기, Button/Opens 속성을 사용한 촉각 버튼, Escape 키, 스크림, 팝업 큐, 카운트업) + UIKit.luau (템플릿 계약: 복제, Shadow 쌍과 함께 set, 아이콘, 막대, 복수형/관사, worldLabel) + NumberFormat.luau. 게임 코드는 템플릿을 복제하여 사용합니다. Instance.new로 룩을 생성하지 마세요. 가져온 화면에 대한 모든 런타임 변경 사항을 기록하세요(PIPELINE.md 섹션 8).
7. Studio에서 검증
VERIFY.md 순서대로: 빈 이미지 없음; fit 비율 확인; PropertySweep.atSizes를 1920x1080 / 1366x768 / 844x390 해상도에서 실행; 편집 모드 하네스(gui 복제, 복제본의 UI require, 구동, UI.destroy(), Archivable=false); 플레이테스트는 필요한 경우에만 실행(다른 사람의 플레이테스트가 실행 중인지 확인): 자홍색 캡처는 UI가 깨진 것을 의미하지 않음; 절대 위치 + 크기/2 +58 px에서 실제 클릭; 휴대폰 기기 프로필; 빠른 클릭 테스트; 리스트가 제자리에서 업데이트되는지 확인. 모든 클라이언트 파일에 대해 luau-analyze --mode=nonstrict 실행; check_copies.py로 Studio의 복사본이 디스크와 일치하는지 확인.
8. 반복
새로운 피드백 -> LESSONS.md -> HTML -> 승인 -> 변경된 페이지만 내보내기 -> gen -> 새 아트만 업로드하도록 ledger -> bundle -> Builder.buildScreen("<Screen>") (패널 하나 제자리에) 또는 build() -> fit -> 검증.
절대 하지 말 것
이모지 또는 두 번째 아이콘 팩 사용; AI 생성 아이콘 사용; 라이선스가 AI 사용을 금지하는 경우 아이콘 팩 파일을 어떤 모델에든 전송; 이미지에 텍스트를 굽기(bake); 승인 전에 가져오기; Data_*.luau를 수동으로 편집; set_script_source 사용; 실제 게임 클라이언트가 실행 중일 때 데모 값 작성; 자동으로 클레임된 보상; 상품 위에 선이나 마커 그리기; 이 스킬 폴더 내에 게임 특정 ID 또는 이름 저장.