MomijiUI éšååïŒãã«ãæå±éïŒèšèš â E2
Generated by Claude Opus 4.8 â 2026幎6æ2æ¥
05-uikit-cross-media-next-steps ã® E2ïŒé »åºæ§æã®éšååïŒ ããAæ¡ïŒãã«ãæå±éã§å®è£ ããããã®èšèšãã¡ã¡ã³ãã¢ãªé¢šã¢ãã¯ã®äœã蟌ã¿ã§é¡åšåãããããããŒ/ã¿ãããŒ/ã¹ããŒã¿ã¹è¡/ã«ãŒããç»é¢éã§ã³ããè€è£œãããã¬ã³ãã©ïŒnative C++ / web JSïŒãäžåå€ããã«è§£æ¶ããã
1. ç®çã»éç®ç
ç®ç
- é »åºæ§æãåå©çšéšåïŒcomponentïŒãšããŠ1ç®æã§å®çŸ©ããç»é¢JSONããåç §ã§å±éããã
- nativeïŒ
Momiji.cpp:nodeFromJsonïŒãš webïŒweb-momijiïŒã®äž¡ããŒãµãç¡æ¹ä¿®ã«ä¿ã€ã momiji-validateãå±éåŸããªãŒã«æããŠåŸæ¥ã©ããæ€èšŒã§ããã
éç®ç
- ã©ã³ã¿ã€ã åçUIïŒå®è¡äžã«éšåãå·®ãæ¿ããçïŒã¯å¯Ÿè±¡å€ã
{var}è£éïŒgamehost.jsïŒã¯æ¢åã®ãŸãŸã - ã¹ããŒãïŒ
momiji-schema.jsonïŒã® widget enum æ¡åŒµã¯ããªããéšåïŒæ¢å12 widget ã®æ§æç©ã
2. èšèšååïŒå±éã¯ãã«ãæãã¬ã³ãã©ã¯çŽ ã®JSONã ãé£ã
ç»é¢JSONãèªãçµè·¯ã2ã€ããïŒMomiji.cpp:47 ã® C++ ååž°ããŒãµ / web-momiji/src/momiji.js ã® JSïŒãããã«åç
§è§£æ±ºãå
¥ãããšäºéå®è£
ïŒdriftïŒ05 ã®ãªã¹ã¯æ¬ã»F2 ã®æžå¿µïŒã«ãªãã
â åç
§è§£æ±ºãååŠçã¹ãããã«å¯ããçŽ ã® UiNode ããªãŒãžå¹³åŠåããŠããé
ãã äž¡ã¬ã³ãã©ã¯å¹³åŠåæžã¿JSONãä»ãŸã§ã©ããèªãã ããscaffold-game.mjsïŒNodeã»äŸåãŒãïŒã®å
åŒããŒã«ãšããŠå®è£
ã§ããCI/AI ãããåŒã¹ãã
components/*.json ââ
ââ[expand-components.mjs]â å¹³åŠãª screens/*.json ââ¬â native nodeFromJsonïŒç¡æ¹ä¿®ïŒ
ç»é¢JSON(useåç
§) ââ â ââ web momiji.jsïŒç¡æ¹ä¿®ïŒ
ââ momiji-validateïŒç¡æ¹ä¿®ã»å±éåŸã«æ€èšŒïŒ
3. ããŒã¿åœ¢åŒ
3.1 éšåå®çŸ© components/<name>.json
éšåã¯ãã©ã¡ãŒã¿ïŒpropsïŒãšã¹ãããïŒåããªãŒå·®ã蟌ã¿å£ïŒãæã€1ã€ã® UiNode ãµãããªãŒã
{
"name": "stat-row",
"props": { "label": "HP", "value": 0.9, "color": "#b1894e" },
"node": {
"type": "HorizontalLayout", "gap": 8,
"children": [
{ "type": "Label", "text": "{{label}}", "w": 60 },
{ "type": "Slider", "value": "{{value}}", "color": "{{color}}", "flex": 1 }
]
}
}
props: æ¢å®å€ã€ããã©ã¡ãŒã¿ãå㯠string / number / color(string)ãnode: éšåæ¬äœãæååå€ã®äžã®{{propName}}ã props ã§çœ®æã- ã¹ãããïŒåå·®ã蟌ã¿ïŒã¯æ¬äœã«
{ "slot": "body" }ãã¬ãŒã¹ãã«ãã眮ãã
3.2 ç»é¢JSONããã®åç §
åç
§ããŒã㯠type ãæãã use ãæã€ïŒåŸè¿°ã®ãšããå±éåJSON㯠momiji-schema éé©åã§æ§ããªã â æ€èšŒã¯å±éåŸïŒã
{ "type": "VerticalLayout", "children": [
{ "use": "header", "props": { "title": "ãã£ã©ã¯ã¿ãŒ" } },
{ "use": "stat-row", "props": { "label": "ATK", "value": 0.78, "color": "#5aa05a" } },
{ "use": "card", "props": { "name": "ãªãšã©" }, "slots": {
"body": [ { "type": "Label", "text": "Lv60" } ] } }
] }
props: éšåã®æ¢å®å€ãäžæžãïŒæå®ããŒã®ã¿ïŒãslots: ã¹ãããå â å·®ã蟌ãåããŒãé åã
3.3 ããªãã¿èŠçŽïŒæéèŠïŒ
| èšæ³ | 解決ã¿ã€ãã³ã° | 解決è | äŸ |
|---|---|---|---|
{{prop}} | ãã«ãæïŒå±éåšïŒ | expand-components.mjs | {{title}} |
{var} | ã©ã³ã¿ã€ã | gamehost.js / native | {coins} |
äºéãã¬ãŒã¹ãšåäžãã¬ãŒã¹ã§å±€ãåé¢ãéšåã®äžã«ã©ã³ã¿ã€ã {var} ãæ®ãããå ŽåïŒäŸïŒé貚ãã«éšåãç»é¢ããšã«éã倿°ãèŠãïŒã¯ãprops ã§å€æ°åãæž¡ã {{ }} â {coins} ã®ãããªåäžãã¬ãŒã¹æååãçæã§ãããå±éåšã¯ {{ }} ã®ã¿åŠçãã{ } ã¯çŽ éãããã
3.4 å埩ãšéžæïŒrepeat / selectionïŒâ èšç®ãäŒŽãæ§æ
äžéšããïŒå šç»é¢ã«åå8ã»ã«ïŒãã«ãŒãã°ãªããïŒååã«ãŒãÃNïŒã¯ãåãæ§é ã®å埩ïŒéžæã»ã«ã®åŒ·èª¿ãã§ãæåå眮æã ãã§ã¯ç³ããªãããããç®è¡ãªãã§è¡šçŸãããããåé åã«å埩ãã£ã¬ã¯ãã£ãã眮ããã
{ "repeat": "tabs", "as": "t", "indexAs": "i", "selected": "active",
"node": { "type": "VerticalLayout", "action": "{{t.action}}", "children": [
{ "$whenSelected": { "type": "Image", "h": 4, "color": "{{navOn}}" } },
{ "type": "Label", "text": "{{t.name}}",
"textColor": { "$selected": "{{navOn}}", "$else": "{{navOff}}" } }
] } }
repeat: é å prop åïŒ"tabs"/"{{tabs}}"ïŒãèŠçŽ ããšã«nodeã1ã€çæã芪ã®åãšããŠäžŠã¹ããas/indexAs: åèŠçŽ ã»æ·»åã®ãã€ã³ãåããã³ãã¬å ã§{{t.field}}ïŒãããåç §ïŒã»{{i}}ãselected: éžææ·»åãæã€ prop åãå埩äžããã®æ·»åã®èŠçŽ ã ããéžæãæèã«ãªãã{"$selected":A,"$else":B}: å€ã®éžæåæ¿ïŒéžæã»ã«ã¯ Aãä»ã¯ BïŒã{"$whenSelected": node}: éžæã»ã«ã«ã®ã¿æ¿å ¥ãããããŒãïŒã€ã³ãžã±ãŒã¿çïŒã
ã€ã³ãžã±ãŒã¿ã¯ active*160 ã®çµ¶å¯Ÿåº§æšã§ãªãéžæã»ã«å
é ã®ã¢ã¯ã»ã³ãããŒã§ç䟡衚çŸãããããç®è¡ããžãã¯ã¯äžèŠãã¬ã³ãã©ã¯ç¡æ¹ä¿®ã®ãŸãŸã
3.5 ç®è¡åŒ {{ expr }} â éãªãåã«ãŒãã®éšåå
ãœã·ã£ã²/æŸçœ®ã²ãŒã ã®äžå¿ã¯ãæ ã»ããŒãã¬ãŒãã»ãããžã»æã»ã²ãŒãžãéãåããã絶察座æšã«ãŒããã¬ã³ãã©ã¯ãã¬ãŒã³ã³ã³ãã(Image/Panel)ã®åã芪åç¹ã§ãªãã»ããããªãïŒMomiji.cpp:369/378ã»web åæ§ïŒãããèªå·±å®çµã«ãŒãã®å
éš offset ãçžå¯Ÿåã§ããªãããããç®è¡ãªãã§ã¯ç³ããªãã®ã§ã{{ }} ã®äžèº«ãåŒãšããŠè©äŸ¡ã§ããããã«ããã
{ "type": "Image", "x": "{{cx + 4}}", "y": "{{cy + ch - 56}}", "w": "{{cw - 8}}" }
- äžèº«ãåäžèå¥å(
{{cx}}/{{c.frame}})ãªã props ã®çŽ ã®åïŒæ°å€/è²æåå/é åïŒããã®ãŸãŸè¿ãïŒåŸæ¥ã©ããïŒã - æŒç®å(
+ - * / %)ã»æ¬åŒ§ãå«ãã°æ°å€åŒãšããŠè©äŸ¡ïŒååž°äžéã»evaläžäœ¿çšã®å°åè©äŸ¡åšïŒãèå¥åã¯æ°å€ã«è§£æ±ºãããå¿ èŠããããæªè§£æ±ºã»éæ°å€ã¯ ERRORã - ããŒã¿åŽãã«ãŒãã®
cx/cyãæã¡ãå éš offset ã¯åŒã§è¡šçŸ â éãªãåã«ãŒãã repeat ã§éç£ã§ããèŠãç®ã¯äžå€ãæ¡ä»¶ä»ãèŠçŽ (NEW ãããž)ã¯ãéè©²åœæã¯éæè²+空æåã§åžžæå梱ãã§åå²ãåé¿ã
4. å±éã¢ã«ãŽãªãºã
expandNode(node, registry):
if node.use:
comp = registry[node.use] # ç¡ããã° ERROR ã§åæ¢
props = { ...comp.props, ...node.props } # æ¢å®å€ã«äžæžããããŒãž
body = deepClone(comp.node)
substituteProps(body, props) # æååå
{{key}} ã眮æïŒæ°å€propâæ°å€åïŒ
fillSlots(body, node.slots ?? {}) # {slot:name} ãåé
åã§çœ®æãæªæå®ã¹ãããã¯é€å»
return expandChildren(body, registry) # éšåãéšåã䜿ãå Žåã«ååž°å±é
else:
node.children = node.children.map(expandNode) # éåžžããŒãã¯åã ãå±é
return node
- ãã¹ã: éšåãå¥éšåã
useããŠããïŒexpandChildrenã§ååž°ïŒã - ååž°æ€åº: å±éã¹ã¿ãã¯ã«ååãååºçŸããã埪ç°ãšã㊠ERRORïŒç¡éå±é鲿¢ïŒã
- æ°å€prop:
"value": "{{value}}"ã§å€å šäœãåäžã®{{key}}ã®ãšããprops ã number ãªãæååã§ãªãæ°å€ãšããŠåããïŒSlider.value㯠number å¿ é ïŒã - æªè§£æ±º
{{key}}: props ã«ç¡ãããŒãæ®ã£ãã ERRORïŒã¿ã€ãæ€åºïŒã
5. ããŒã«æ§æ
packages/native-engine/tools/
scaffold-game.mjs # æ¢å
expand-components.mjs # æ°èŠ: <game>/ ãèªã¿ãcomponents åç
§ãå¹³åŠåããŠåºå
- å
¥å:
<game>/screens/*.json+<game>/components/*.json - åºå: æ¢å®ã§
<game>/.expanded/screens/*.jsonïŒå ãç Žå£ããªãïŒã--in-placeã§äžæžããå¯ã - äŸåãŒãïŒæšæº Node ã®ã¿ïŒã
scaffold-game.mjsã®copyTree/parseArgsãèžè¥²ã - CLI:
node tools/expand-components.mjs --game assets/games/mementomori-mock node tools/expand-components.mjs --game <dir> --out /tmp/expanded
ãã€ãã©ã€ã³äžã®äœçœ®
[author/AI ã screens + components ãæžã]
â expand-components.mjs # å¹³åŠå
â momiji-validate <expanded>/screens/* # æ€èšŒïŒæ¢åã»ç¡æ¹ä¿®ïŒ
â kaedevn_game / web-momiji ã <expanded> ãèªã
native ã®ã¢ã»ããé
眮ïŒassets/games/<id>/screens/ïŒã web ã® fetchïŒmain.jsïŒã¯å±éåŸãã£ã¬ã¯ããªãæãããé
ç·ããã ãããã«ãæã« .expanded ãå®äœã® screens/ ã«çœ®ãéçšã§ãå¯ïŒèŠã»é
眮æ¹éã®æ±ºå® â §7ïŒã
6. ãã¹ãæ¹é
| å±€ | å 容 |
|---|---|
| å±éåšãŠããã | props äžæžã / æ°å€prop / slot å·®ã蟌㿠/ ãã¹ã / åŸªç°æ€åº / æªè§£æ±ºã㌠ERROR ã Node test ã§ç¶²çŸ |
| æ€èšŒé£æº | å±éåŸããªãŒã momiji-validate ãéãïŒæ¢å CLI ãåŒã¶ïŒ |
| äžå€æ§ïŒååž°ïŒ | ã¡ã¡ã³ãã¢ãªæ¢åç»é¢ããéšåååã®ææžãJSONããšãéšååâå±éããçµæãã§ãã€ãäžèŽ or ããŒãç䟡ãç §åãèŠãç®ãå€ããã«ãªãã¡ã¯ã¿ããä¿èšŒ |
| åªäœäžèŽ | å±éåŸJSONã§ native collectedHits ãš web 幟äœãç
§åïŒ05 F2 ãšåãä»çµã¿ã»å±éåŸã«æããïŒ |
7. æ¹é決å®ïŒ2026-06-02 確å®ïŒ
åæïŒéçšæ¹éïŒ: 宣èšçUI(MomijiUI) ã¯çæAIãåç
§ç»åãåçŸããŠç»é¢JSONãäœãããããã¯ãšãã£ã¿ã¯ããã«ã²ãŒã å°çšã§åœé¢æ©èœè¿œå ãªãã宣èšçUIããšãã£ã¿ã§éããã¹ã¯ç¡ããäœããªãã確èªã¯ãã¬ã€ç»é¢ã®å®æç»ïŒkaedevn_game --capture çïŒã§è¡ãã
- é
眮æ¹é â æ±ºå®: å±éã¯ãã€ãã©ã€ã³ã®1ã¹ããããAIã
useå ¥ãç»é¢ãçæ â å±éåšã§çŽ ã®ããªãŒãžå¹³åŠå â ã¬ã³ãã©ã¯å±éåŸãèªã¿ããã¬ã€ç»é¢ã§æç»ç¢ºèªããšãã£ã¿çµè·¯ãç¡ããã.expanded/å¥çœ®ãã®åã£ãèŠçŽã¯äžèŠãçŸç¶ã® build-mm-screens 㯠in-process å±éïŒçææã«å¹³åŠåããŠscreens/ã«çŽæ¥æžãïŒã§ãã®æ¹éã«åèŽãAIçæã²ãŒã ïŒgame-produceïŒã§ã¯çæåŸã«expand-componentsã1ã¹ãããæãã - ãšãã£ã¿ schema 飿º â æ±ºå®: äžèŠïŒãããªãïŒã
useããŒãã®ãšãã£ã¿å¯Ÿå¿ã»GET /api/editor-schemaãžã®éšåæ²èŒã¯ããªãã宣èšçUIã®ç·šéã¯AIçæã§å®çµãã人æã®ãšãã£ã¿ç·šé察象ã«ããªãã - éšåã®æåš â æ±ºå®: 暪æå
±æ
_components/ïŒ_templates/ãšåéå±€ïŒãã²ãŒã åå¥<game>/components/ãå±éåšã¯ãã©ãŒã«ããã¯å¯Ÿå¿æžã¿ïŒgame-local åªå ïŒã - æªæå®ã¹ããã â æ±ºå®: é€å»ïŒä»»æã¹ãããæ±ãïŒãå®è£ ã»ãã¹ãæžã¿ã
â 4ç¹ãšã確å®ãæ®ãã¯å¿çšïŒã«ãŒãç³»ã®éšååã»web-momiji 衚瀺確èªã»CI é ç·ïŒã®ã¿ã
8. 段éå°å ¥
expand-components.mjs+ ãŠããããã¹ãïŒéšåãŒãã§ãçŽ éããã no-op ããïŒã- ã¡ã¡ã³ãã¢ãªã® header / tab-bar ãéšåå â å šç»é¢çœ®æ â äžå€æ§ãã¹ãã§èŠãç®äžå€ãä¿èšŒã
- stat-row / card / currency-pill ãé æ¬¡éšååã
momiji-validateããã€ãã©ã€ã³ã®å±éåŸã«åºå®ïŒCI é ç·ïŒã- é 眮æ¹éïŒÂ§7-1ïŒã確å®ã native/web ã®åç §å ãå±éåŸãžã
scaffold-game.mjsã®ãã³ãã¬ãéšååç §ããŒã¹ã«æŽæ°ïŒE3 ãšåæµïŒã
èŠæš¡æã¯ 05 ã® E2ãMãã®ãŸãŸãã¬ã³ãã©ç¡æ¹ä¿®ãªã®ã§ native/web åæ¹ãåæã«æ©æµãåããã
9. æ¢å build-mm-screens.mjs ãšã®é¢ä¿
ã¡ã¡ã³ãã¢ãªç»é¢ã¯ tools/build-mm-screens.mjsïŒJS ãã«ããŒïŒãçæããŠãããããã§ã¯æ¢ã« nav(active)ïŒäžéš8ã¿ãïŒã»topTabs(...)ã»ã«ãŒã factory ãšã㊠JS 颿°ã§éšååãããŠãããã€ãŸããè€è£œãã¯çæãããåºåJSONã«åºãŠããŠããœãŒã¹åŽã¯ JS ã§ factoring æžã¿ããã ããã®æ¹åŒã¯ native ã¢ãã¯å°çšã»äžåéãã§ãweb-momiji / momiji-validate / game-produce(AI) ã®ã©ãã«ãä¹ããªãã
æ¬èšèšã®å®£èšç components/*.json ïŒå±éåšã¯ããã® JS factory ãç§»æ€å¯èœã»æ€èšŒå¯èœã»AI/web å
±æå¯èœã«ããçãtopTabs() 㯠top-tabs.jsonãnav() 㯠bottom-nav.json ã«1察1ã§åãããç§»è¡ã¯ build-mm-screens ã®å factory ã宣èšçéšåãžçœ®ãæããåœ¢ã§æ®µé宿œã§ããã
10. å®è£ ç¶æ³ïŒ2026-06-02ïŒ
- â
tools/expand-components.mjså®è£ ïŒprops{{ }}眮æ / ãããåç § / æ°å€prop / slot / repeat / selectionïŒ$selectedã»$whenSelectedïŒ / ãã¹ã / åŸªç°æ€åº / æªè§£æ±ºERROR /{var}çŽ éã / game-local + å ±æ_componentsãã©ãŒã«ãã㯠/.expandedåºåïŒã - â
tools/expand-components.test.mjsâ ãŠããã20ä»¶ãã¹ãŠééïŒnode --testïŒã - â
å
±æéšå:
_components/top-tabs.jsonïŒtopTabs()çžåœïŒã_components/bottom-nav.jsonïŒnav(active)çžåœã»8ã»ã«ïŒéžæãã€ã©ã€ãïŒã - â
E2E å®èšŒ:
top-tabs: å±éçµæãå®characters.jsonã® ToggleGroup ãšããŒãäžèŽãbottom-nav:{"use":"bottom-nav","props":{"active":N}}ã®1è¡ â 8ã»ã«ïŒéžæã»ã«ã®ã¢ã¯ã»ã³ã/è²åããç®è¡ãªãã§çæãCLI å±é âmomiji-validateééãå š9ç»é¢ã®çŽ11ããŒãè€è£œã1åç §ã«éçŽå¯èœã
- â
build-mm-screens.mjs ãéšååç
§ãžç§»è¡:
nav()â{use:bottom-nav}ãtopTabs()â{use:top-tabs, slots}ãwrite()ãæžãåºãæã«expandScreenã§å¹³åŠåããã®ã§çæ screens ã«useã¯æ®ããªãïŒnative/web ç¡æ¹ä¿®ïŒãå š9ç»é¢ regenerate âmomiji-validateééãuseæ®åãŒãã- èŠèŠæ€èšŒ: æ§ã€ã³ã©ã€ã³ nav ãš éšå bottom-nav ã
kaedevn_game --captureã§å®æç»ããŠç䟡確èªïŒæè²ããŒ/8ã»ã«/éžæã»ã«ã®éã¢ã¯ã»ã³ãã»éæåãäžèŽïŒãcharacters(top-tabs+nav)ã»quest(nav active=3) ã®å®ç»é¢ãæ£ããæç»ã - æ§é ã¯å€åïŒnav ã flat 3å
åŒ â
Image>HorizontalLayoutã®å ¥ãåãã€ã³ãžã±ãŒã¿ã¯éžæã»ã«å é ã¢ã¯ã»ã³ãã«ç§»åïŒã ã衚瀺ã¯äžå€ã
- èŠèŠæ€èšŒ: æ§ã€ã³ã©ã€ã³ nav ãš éšå bottom-nav ã
- â
§7 æ¹é4ç¹ã確å®ïŒãšãã£ã¿é£æº=äžèŠãé
眮=ãã€ãã©ã€ã³1ã¹ãããå±éãéšåæåš=å
±æ
_components/ãæªæå®slot=é€å»ïŒãåæ: 宣èšçUIã¯çæAIãç»åãåçŸããŠäœãã確èªã¯ãã¬ã€ç»é¢ã®å®æç»ã - â
web-momiji ã¯ãã¹ã¡ãã£ã¢ç¢ºèª: éçé
ä¿¡ïŒPlaywright ã§ web-momiji(Canvas2D) ã«åäž screens ãæç»ã
characters(top-tabsïŒnav active=1) ãšquest(nav active=3) ã native(kaedevn_game --capture) ãšåäžè¡šç€ºãéšå(top-tabs/bottom-nav)ã»selection($selected/$whenSelected) ã web ã§ãæ£ããåäœïŒåãç»é¢JSONã native/web ã§äžèŽã - â
ç®è¡åŒ
{{ expr }}ïŒÂ§3.5ïŒãå±éåšã«è¿œå ïŒå°åè©äŸ¡åšã»evaläžäœ¿çšã»ãã¹ãèš30ä»¶ééïŒãä»åŸãœã·ã£ã²/æŸçœ®ã²ãŒã ã®éãªãåã«ãŒããéšååããããã®åå°ãšã㊠A æ¡ïŒå±éåšã«ç®è¡ïŒãæ¡çšã - â
éãªãåã«ãŒãã®éšåå: å
±æéšå
_components/char-card.jsonïŒæ /ããŒãã¬ãŒã/屿§ãããž/æ/LvããŒ/NEW ãç®è¡ offset ã§å éšé 眮ïŒãbuild-mm-screens ã®charCard()ã use åç §ãžç§»è¡ãcharacters å š21æãéšååããã«ãŒãç§»è¡å(HEAD) ãšç§»è¡åŸã§ PNG ãã€ãå®å šäžèŽïŒcmp確èªïŒïŒèŠãç®äžå€ãå³å¯æ€èšŒã - â
ãã€ãã©ã€ã³çµã¿èŸŒã¿:
scaffold-game.mjsã«å±éã¹ãããïŒexpandScreensInPlaceïŒã远å ããã³ãã¬ãuse/repeat/ç®è¡ãå«ãã§ã scaffold æã«å¹³åŠåãããnative/web ã¯ãã®ãŸãŸèªããã - â
ã°ãªããéšå
_components/card-grid.json:repeat+ ç®è¡ïŒåi % cols/ è¡(i - i % cols) / colsã®æŽæ°é€ç®ïŒã§ char-card ãã°ãªããé 眮ãããŒã¿é åãæž¡ãã ãã§ã«ãŒãç€é¢ãçæã - â
æ°ãžã£ã³ã«ãã³ãã¬
_templates/gacha/: bottom-nav + card-grid + char-card ã®ã¿ã§æ§æãscaffold-game --genre gachaã§æ°èŠã¬ãã£ã²ãŒã ãå ±æéšåãã1æ¬ç«ã¡äžããããšãå®èšŒïŒããããŒïŒ7å14æã°ãªããïŒ10é£ãã¿ã³ïŒãããmomiji-validateééã»æç»ç¢ºèªïŒãïŒã¡ã¡ã³ãã¢ãªä»¥å€ã®æ°èŠã²ãŒã ã§ãæ¬æ©æ§ã§éç£å¯èœã - â
game-produceskill ã«éšåã·ã¹ãã ãæèš: ãã€ãã©ã€ã³å³ã«å±éã¹ããããå ±æéšåã«ã¿ãã°ïŒtop-tabs/bottom-nav/char-card/card-gridïŒãuse/repeat/selection/ç®è¡ã®èšæ³ãscaffold èªåå±éã远èšãAI çæçµè·¯ãéšåã䜿ãåæã«ã - â
æŸçœ®ã²ãŒãã³ãã¬
_templates/idle/: bottom-nav + æŸçœ®å ±é ¬ããã« + ã¹ããŒãž + ãã¿ã³ã§æ§æãscaffold --genre idleã§æŸçœ®RPGã¡ã€ã³ç»é¢ãç«ã¡äžããæç»ç¢ºèªïŒ{gold}/{stage}è£éãåäœïŒãgacha ãšåãã ãœã·ã£ã²/æŸçœ®ã®2ãžã£ã³ã«ãéšåããŒã¹ã§éç£å¯èœã - â
CI é
ç·:
tools/validate-screens.mjsïŒå®ã²ãŒã 㯠screens ãçŽæ¥ã_templates ã¯å±éããŠããmomiji-validateïŒãci.ymlã® native-tests ã«æ€èšŒã¹ããã远å ïŒmomiji-validate ã¯ããã§æ¢ã«ãã«ãæžã¿ïŒãpre-pushã«ããã€ããªãããã°èµ°ã圢ã§è¿œå ãäžæ£ç»é¢ã§ exit 1 ã確èªã - â
SSIM ååž°:
tools/screen-regression.mjsâ ç»é¢ãæ®ãçŽãã³ãããæžã¿ããŒã¹ã©ã€ã³ PNG ãš SSIM æ¯èŒïŒImageMagickcompareã»CPUã»GPUäžèŠïŒãéŸå€ 0.99 æªæºã§ exit 1ã--updateã§æŽæ°ãç¡å€æŽâå šç»é¢ 1.0000ãããã«è²å€æŽâ0.9292 ã§æ€ç¥ãèšèš 03 ã®ååž°èªååã®å®è£ ã - ⬠æ®ïŒä»»æã»èšèšå€æãªãïŒ: å®ããŒã¿ïŒå®ç»åïŒã§ã®ã«ãŒã/ç«ã¡çµµå·®ã蟌ã¿ïŒ
sprite/fit:coverã¯å®è£ æžãçŽ æãå ¥ããã ãïŒãæŸçœ®/å¥ãœã·ã£ã²ã®æ¬å®è£ ãgame-produceã®ãžã£ã³ã«ãã³ãã¬æ¡å ã
bottom-nav ã®èšèšå€æïŒæ¡çš: å±éåšã« repeat/selection ã远å ïŒ
nav(active) ã¯ãã¢ã¯ãã£ãè²åãïŒã€ã³ãžã±ãŒã¿äœçœ® active*160ããšããèšç®ãæã¡ãToggleGroup ã¯åã»ã«ã1è¡ããã¹ãã§ããæããªãïŒnative Momiji.cpp:428 / web momiji.js:210 åäžæåïŒãã2段ã»ã«ãç³ããªããéžæè¢ã¯ (1) å±éåšã« repeat/selection 远å ã(2) nav ãçææ®ã眮ãã(3) TabBar ãŠã£ãžã§ããæ°èšïŒã¬ã³ãã©æ¹ä¿®=CãŸãŒã³ïŒã(1) ãæ¡çš â ã¬ã³ãã©ç¡æ¹ä¿®ãä¿ã¡ãnav ãšååå埩ïŒã«ãŒãã°ãªããçïŒã®åæ¹ã«å¹ãããã
ãã®ææžã¯ Claude Opus 4.8 ãçæããŸãããå å®¹ã®æ£ç¢ºæ§ã¯äººéã®ã¬ãã¥ãŒãçµãŠç¢ºèªããŠãã ããã
Claude Opus 4.8 â Anthropic