polats Claude Opus 4.8 (1M context) commited on
Commit
c7dba29
·
1 Parent(s): 07a1161

Add World Map sandbox tab; fix ported-component styling on the Space

Browse files

Wire the shared Map playground (web/mapSandbox.js, synced from auto-battler) into a
World Map tab: pill switcher + all six sub-pages. build.sh bundles it, copies
worldmap.css, and curates exactly the ~105 map tilesets via the MAP_ASSET_URLS
manifest (no whole-pack copy). curate_assets.py is now manifest-driven and also
walks effects.json (its 204 effect/status icons were missing).

Host fixes so ported component CSS matches auto-battler instead of losing to
Gradio's own styles:
- extract :root design tokens -> web/shell/tokens.css (linked in HEAD)
- strip Gradio's .prose/.gradio-style wrappers off sandbox stages (web/tiny.js)
- scope component CSS under its stage id (build.sh) so it outranks Gradio's
.gradio-container-<ver> button/* base resets
- reroot /assets -> /sprites (incl. *.json) in the URL shim
- gate upgrade-insecure-requests (CSP meta + middleware) to the HTTPS Space so
plain-http LAN testing no longer hits ERR_SSL_PROTOCOL_ERROR

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. app.py +23 -5
  2. build.sh +21 -2
  3. curate_assets.py +53 -16
  4. web/assets/minifantasy/Minifantasy_ForgottenPlains_v3.6_Commercial_Version/Minifantasy_ForgottenPlains_Assets/Minifantasy_ForgottenPlainsMockup.png +0 -0
  5. web/assets/minifantasy/Minifantasy_ForgottenPlains_v3.6_Commercial_Version/Minifantasy_ForgottenPlains_Assets/Tileset/Minifantasy_ForgottenPlainsTiles.png +0 -0
  6. web/assets/minifantasy/Minifantasy_ForgottenPlains_v3.6_Commercial_Version/Minifantasy_ForgottenPlains_Assets/Tileset/Minifantasy_ForgottenPlainsTilesShadows.png +0 -0
  7. web/assets/minifantasy/Minifantasy_ForgottenPlains_v3.6_Commercial_Version/Minifantasy_ForgottenPlains_Assets/props/Minifantasy_ForgottenPlainsProps.png +0 -0
  8. web/assets/minifantasy/Minifantasy_ForgottenPlains_v3.6_Commercial_Version/Minifantasy_ForgottenPlains_Assets/props/Minifantasy_ForgottenPlainsPropsShadows.png +0 -0
  9. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Legendary Weapons/Icerberg Blade/Icerberg_blade_f.png +0 -0
  10. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Legendary Weapons/Thunderbolt Sword/Thunderbolt_sword_f.png +0 -0
  11. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Legendary Weapons/Viper Scimitar/Viper_scimitar_f.png +0 -0
  12. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Legendary Weapons/Volcano Mace/Volcano_mace_f.png +0 -0
  13. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Bow/Front Layer/Bow_bleeding_f.png +0 -0
  14. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Bow/Front Layer/Bow_fear_f.png +0 -0
  15. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Bow/Front Layer/Bow_fire_f.png +0 -0
  16. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Bow/Front Layer/Bow_ice_f.png +0 -0
  17. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Bow/Front Layer/Bow_nature_f.png +0 -0
  18. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Bow/Front Layer/Bow_petrification_f.png +0 -0
  19. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Bow/Front Layer/Bow_poisson_f.png +0 -0
  20. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Bow/Front Layer/Bow_shock_f.png +0 -0
  21. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Bow/Front Layer/Bow_sickness_f.png +0 -0
  22. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Bow/Front Layer/Bow_sleep_f.png +0 -0
  23. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Bow/Front Layer/Bow_stun_f.png +0 -0
  24. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Dagger/Front Layer/Dagger_bleeding_f.png +0 -0
  25. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Dagger/Front Layer/Dagger_fear_f.png +0 -0
  26. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Dagger/Front Layer/Dagger_fire_f.png +0 -0
  27. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Dagger/Front Layer/Dagger_ice_f.png +0 -0
  28. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Dagger/Front Layer/Dagger_nature_f.png +0 -0
  29. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Dagger/Front Layer/Dagger_petrification_f.png +0 -0
  30. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Dagger/Front Layer/Dagger_poisson_f.png +0 -0
  31. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Dagger/Front Layer/Dagger_shock_f.png +0 -0
  32. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Dagger/Front Layer/Dagger_sickness_f.png +0 -0
  33. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Dagger/Front Layer/Dagger_sleep_f.png +0 -0
  34. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Dagger/Front Layer/Dagger_stun_f.png +0 -0
  35. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Flail/Flail_bleeding.png +0 -0
  36. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Flail/Flail_fear.png +0 -0
  37. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Flail/Flail_fire.png +0 -0
  38. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Flail/Flail_ice.png +0 -0
  39. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Flail/Flail_nature.png +0 -0
  40. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Flail/Flail_petrification.png +0 -0
  41. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Flail/Flail_poisson.png +0 -0
  42. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Flail/Flail_shock.png +0 -0
  43. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Flail/Flail_sickness.png +0 -0
  44. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Flail/Flail_sleep.png +0 -0
  45. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Flail/Flail_stun.png +0 -0
  46. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/LongSword/Front layer/LongSword_bleeding_f.png +0 -0
  47. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/LongSword/Front layer/LongSword_fear_f.png +0 -0
  48. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/LongSword/Front layer/LongSword_fire_f.png +0 -0
  49. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/LongSword/Front layer/LongSword_ice_f.png +0 -0
  50. web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/LongSword/Front layer/LongSword_nature_f.png +0 -0
app.py CHANGED
@@ -110,18 +110,27 @@ THEME = ('<style>'
110
  # Gradio still hides it (display:none on the inactive tab's ancestor).
111
  '.gradio-container .tabitem{padding:0 !important;}'
112
  '.gradio-container .tabs{border:0 !important;}'
113
- '#sprite-stage,#persona-stage,#diary-stage,#classes-stage,#enemies-stage{position:fixed !important;top:0;bottom:0;'
114
  'right:0;left:var(--tac-w,240px);height:auto !important;z-index:1;}'
115
  'body.tac-collapsed #sprite-stage,body.tac-collapsed #persona-stage,'
116
- 'body.tac-collapsed #diary-stage,body.tac-collapsed #classes-stage,body.tac-collapsed #enemies-stage{left:0;}'
117
- '@media (max-width:768px){#sprite-stage,#persona-stage,#diary-stage,#classes-stage,#enemies-stage{left:0;}}'
 
118
  '</style>')
119
- HEAD = ('<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">'
 
 
 
 
 
 
120
  + HIDE_TABS + FONTS + THEME +
 
121
  '<link rel="stylesheet" href="/web/shell/sidebar.css">'
122
  '<link rel="stylesheet" href="/web/shell/spriteScene.css">'
123
  '<link rel="stylesheet" href="/web/shell/persona.css">'
124
  '<link rel="stylesheet" href="/web/shell/classes.css">'
 
125
  '<script type="module" src="/web/tiny.js"></script>'
126
  '<script src="/web/shell/sidebar.js"></script>')
127
  STAGE = "height:56vh;border:1px solid #20262e;border-radius:12px;overflow:hidden;background:#0b0e12"
@@ -216,6 +225,11 @@ with gr.Blocks(title="Tiny Army") as ui:
216
  # Sandbox: the shared Enemies playground (web/enemiesSandbox.js) — enemy
217
  # roster + WASD combat + stats/skill customize panel.
218
  gr.HTML('<div id="enemies-stage" style="overflow:hidden"></div>')
 
 
 
 
 
219
  # Pixi canvases start hidden (0×0); re-measure them when a tab is shown.
220
  battle_tab.select(None, None, None, js="()=>window.tinyResize&&window.tinyResize()")
221
  sprite_tab.select(None, None, None, js="()=>window.tinyResize&&window.tinyResize()")
@@ -241,7 +255,11 @@ fastapi_app = gr.Server() if USE_GRADIO_SERVER else FastAPI()
241
  @fastapi_app.middleware("http")
242
  async def upgrade_insecure(request, call_next):
243
  resp = await call_next(request)
244
- resp.headers["Content-Security-Policy"] = "upgrade-insecure-requests"
 
 
 
 
245
  # Our /web modules change on every deploy; without this the browser serves a
246
  # stale cached .js (e.g. old token caps) heuristically. no-cache = always
247
  # revalidate (cheap 304 via etag when unchanged). Model weights are fetched
 
110
  # Gradio still hides it (display:none on the inactive tab's ancestor).
111
  '.gradio-container .tabitem{padding:0 !important;}'
112
  '.gradio-container .tabs{border:0 !important;}'
113
+ '#sprite-stage,#persona-stage,#diary-stage,#classes-stage,#enemies-stage,#worldmap-stage{position:fixed !important;top:0;bottom:0;'
114
  'right:0;left:var(--tac-w,240px);height:auto !important;z-index:1;}'
115
  'body.tac-collapsed #sprite-stage,body.tac-collapsed #persona-stage,'
116
+ 'body.tac-collapsed #diary-stage,body.tac-collapsed #classes-stage,body.tac-collapsed #enemies-stage,'
117
+ 'body.tac-collapsed #worldmap-stage{left:0;}'
118
+ '@media (max-width:768px){#sprite-stage,#persona-stage,#diary-stage,#classes-stage,#enemies-stage,#worldmap-stage{left:0;}}'
119
  '</style>')
120
+ # `upgrade-insecure-requests` is needed on the HTTPS Space (prevents mixed-content behind HF's
121
+ # TLS edge) but BREAKS plain-http LAN testing: it forces every asset/manifest/frame URL to https
122
+ # on a server with no TLS → ERR_SSL_PROTOCOL_ERROR. Only emit it when actually deployed on HF
123
+ # (SPACE_ID/SPACE_HOST are set there); local `python app.py` over http omits it and just works.
124
+ _CSP = ('<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">'
125
+ if (os.environ.get("SPACE_ID") or os.environ.get("SPACE_HOST")) else '')
126
+ HEAD = (_CSP
127
  + HIDE_TABS + FONTS + THEME +
128
+ '<link rel="stylesheet" href="/web/shell/tokens.css">'
129
  '<link rel="stylesheet" href="/web/shell/sidebar.css">'
130
  '<link rel="stylesheet" href="/web/shell/spriteScene.css">'
131
  '<link rel="stylesheet" href="/web/shell/persona.css">'
132
  '<link rel="stylesheet" href="/web/shell/classes.css">'
133
+ '<link rel="stylesheet" href="/web/shell/worldmap.css">'
134
  '<script type="module" src="/web/tiny.js"></script>'
135
  '<script src="/web/shell/sidebar.js"></script>')
136
  STAGE = "height:56vh;border:1px solid #20262e;border-radius:12px;overflow:hidden;background:#0b0e12"
 
225
  # Sandbox: the shared Enemies playground (web/enemiesSandbox.js) — enemy
226
  # roster + WASD combat + stats/skill customize panel.
227
  gr.HTML('<div id="enemies-stage" style="overflow:hidden"></div>')
228
+ with gr.Tab("World Map"):
229
+ # Sandbox: the shared Map playground (web/mapSandbox.js, synced from auto-battler)
230
+ # — pill switcher + all six map sub-pages (World Map / Necropolis / Orc Kingdom /
231
+ # Forgotten Plains / Interiors / Towers), each with Generated/Tilesheet/Reference.
232
+ gr.HTML('<div id="worldmap-stage" style="overflow:hidden"></div>')
233
  # Pixi canvases start hidden (0×0); re-measure them when a tab is shown.
234
  battle_tab.select(None, None, None, js="()=>window.tinyResize&&window.tinyResize()")
235
  sprite_tab.select(None, None, None, js="()=>window.tinyResize&&window.tinyResize()")
 
255
  @fastapi_app.middleware("http")
256
  async def upgrade_insecure(request, call_next):
257
  resp = await call_next(request)
258
+ # ONLY on the HTTPS Space (see the _CSP note above). On a plain-http LAN this header would
259
+ # force every asset/manifest/favicon to https on a TLS-less server → ERR_SSL_PROTOCOL_ERROR,
260
+ # so local `python app.py` over http must NOT send it.
261
+ if os.environ.get("SPACE_ID") or os.environ.get("SPACE_HOST"):
262
+ resp.headers["Content-Security-Policy"] = "upgrade-insecure-requests"
263
  # Our /web modules change on every deploy; without this the browser serves a
264
  # stale cached .js (e.g. old token caps) heuristically. no-cache = always
265
  # revalidate (cheap 304 via etag when unchanged). Model weights are fetched
build.sh CHANGED
@@ -18,13 +18,27 @@ npx --yes esbuild "$AB/src/render/spritePlayground.js" --bundle --format=esm --o
18
  # pulls in the shared combatRenderer + engine. Pixi injected by web/tiny.js.
19
  npx --yes esbuild "$AB/src/render/classesSandbox.js" --bundle --format=esm --outfile=web/classesSandbox.js
20
  npx --yes esbuild "$AB/src/render/enemiesSandbox.js" --bundle --format=esm --outfile=web/enemiesSandbox.js
 
 
 
 
21
 
22
  # 2. App shell (nav IR + sidebar CSS/JS) + the playground chrome CSS → copied
23
  # verbatim, so they can't drift from the React app, which renders the same files.
24
  mkdir -p web/shell
25
  cp "$AB/src/shell/nav.json" "$AB/src/shell/sidebar.css" "$AB/src/shell/sidebar.js" web/shell/
 
 
 
 
26
  cp "$AB/src/render/spriteScene.css" web/shell/spriteScene.css
27
- cp "$AB/src/views/classes.css" web/shell/classes.css
 
 
 
 
 
 
28
 
29
  # 3. Assets → use auto-battler's FULL character manifest (so the Space lists every
30
  # character, like the app) and curate every sheet it references (~1 MB).
@@ -34,7 +48,12 @@ cp "$AB/public/assets/characters.json" web/assets/characters.json
34
  cp "$AB/public/assets/effects.json" web/assets/effects.json
35
  cp "$AB/public/classes.json" web/assets/classes.json
36
  cp "$AB/public/enemies.json" web/assets/enemies.json
37
- AB="$AB" python3 curate_assets.py
 
 
 
 
 
38
 
39
  # 4. /gw icons the Classes sandbox shows — just the ~44 CB skill icons (NOT all
40
  # 1484 GW icons) + the condition pips. Served at /gw (mounted in app.py).
 
18
  # pulls in the shared combatRenderer + engine. Pixi injected by web/tiny.js.
19
  npx --yes esbuild "$AB/src/render/classesSandbox.js" --bundle --format=esm --outfile=web/classesSandbox.js
20
  npx --yes esbuild "$AB/src/render/enemiesSandbox.js" --bundle --format=esm --outfile=web/enemiesSandbox.js
21
+ # Map sandbox — the whole Map page (pill switcher + all six sub-pages: World Map / Necropolis /
22
+ # Orc Kingdom / Forgotten Plains / Interiors / Towers, each with Generated/Tilesheet/Reference).
23
+ # Pulls in every map renderer + the shared chunked-map engine. Pixi injected by web/tiny.js.
24
+ npx --yes esbuild "$AB/src/render/mapSandbox.js" --bundle --format=esm --outfile=web/mapSandbox.js
25
 
26
  # 2. App shell (nav IR + sidebar CSS/JS) + the playground chrome CSS → copied
27
  # verbatim, so they can't drift from the React app, which renders the same files.
28
  mkdir -p web/shell
29
  cp "$AB/src/shell/nav.json" "$AB/src/shell/sidebar.css" "$AB/src/shell/sidebar.js" web/shell/
30
+ # Design tokens — the shared component CSS (classes/worldmap/spriteScene) references the global
31
+ # :root palette/fonts/shadows defined in the React app's styles.css. Extract just that :root block
32
+ # (NOT the app-specific selectors) so the Space's components render with auto-battler's look.
33
+ awk '/:root[[:space:]]*\{/{f=1} f{print} f&&/^\}/{exit}' "$AB/src/styles.css" > web/shell/tokens.css
34
  cp "$AB/src/render/spriteScene.css" web/shell/spriteScene.css
35
+ # Scope the sandbox component CSS under its stage id(s) (native CSS nesting). Gradio's own
36
+ # `.gradio-container-<ver> button` / `… *` base resets (specificity 0,1,1 / 0,1,0) otherwise
37
+ # outrank the components' single-class rules and strip their button/control backgrounds, borders
38
+ # and padding. Adding the stage id gives every rule an id of specificity so it wins. Only the
39
+ # Space's copies are wrapped — auto-battler loads the files unscoped, so the source is untouched.
40
+ { echo '#classes-stage, #enemies-stage {'; cat "$AB/src/views/classes.css"; echo '}'; } > web/shell/classes.css
41
+ { echo '#worldmap-stage {'; cat "$AB/src/views/worldmap.css"; echo '}'; } > web/shell/worldmap.css
42
 
43
  # 3. Assets → use auto-battler's FULL character manifest (so the Space lists every
44
  # character, like the app) and curate every sheet it references (~1 MB).
 
48
  cp "$AB/public/assets/effects.json" web/assets/effects.json
49
  cp "$AB/public/classes.json" web/assets/classes.json
50
  cp "$AB/public/enemies.json" web/assets/enemies.json
51
+ # Map assets: dump the manifest (MAP_ASSET_URLS — assembled from the map renderers + configs in
52
+ # src/render/mapConfigs.js so it can't drift) and curate exactly those PNGs (tilesets / props /
53
+ # premade-scene layers / interior+tower skins, ~105 files). No whole-pack copy.
54
+ AB_ABS="$(cd "$AB" && pwd)"
55
+ node --input-type=module -e "import {MAP_ASSET_URLS} from 'file://$AB_ABS/src/render/mapConfigs.js'; for (const u of MAP_ASSET_URLS) console.log(u)" > /tmp/tac-map-assets.txt
56
+ AB="$AB" python3 curate_assets.py /tmp/tac-map-assets.txt
57
 
58
  # 4. /gw icons the Classes sandbox shows — just the ~44 CB skill icons (NOT all
59
  # 1484 GW icons) + the condition pips. Served at /gw (mounted in app.py).
curate_assets.py CHANGED
@@ -1,19 +1,25 @@
1
  #!/usr/bin/env python3
2
- """Curate the Space's sprite assets from the full auto-battler set.
3
 
4
- The Space ships a SUBSET of auto-battler's 65 MB asset library only the sheets
5
- the curated characters (web/assets/characters.json) actually reference. Previously
6
- only the 5 core body sheets per character were copied, so every shadow, effect,
7
- projectile and diagonal sheet 404'd and silently degraded. This copies EVERY sheet
8
- the manifest references (body + shadows + extras + companions) so the Space renders
9
- identically to the React app for those characters.
10
 
11
- AB=../auto-battler python3 curate_assets.py # copy referenced sheets
12
- Run from the tiny-army dir; idempotent. Add to build.sh so it stays reproducible.
 
 
 
 
 
 
 
13
  """
14
  import json
15
  import os
16
  import shutil
 
17
  from urllib.parse import unquote
18
 
19
  HERE = os.path.dirname(os.path.abspath(__file__))
@@ -23,8 +29,8 @@ DST_ROOT = os.path.join(HERE, "web", "assets")
23
  MANIFEST = os.path.join(DST_ROOT, "characters.json")
24
 
25
 
26
- def referenced_urls(manifest):
27
- """Every /assets/... sheet URL the manifest points at, across all sheet kinds."""
28
  urls = set()
29
  for pack in manifest["packs"]:
30
  for c in pack["characters"]:
@@ -41,13 +47,44 @@ def referenced_urls(manifest):
41
  return urls
42
 
43
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  def main():
45
- manifest = json.load(open(MANIFEST))
 
 
 
 
46
  copied = skipped = absent = 0
47
- for url in sorted(referenced_urls(manifest)):
48
- # Manifest URLs are URL-encoded (e.g. "Carnival%20NPCs"); decode so the path
49
- # matches the real on-disk folder names (with spaces). The static server
50
- # decodes the request the same way, so files land where the browser asks.
51
  rel = unquote(url[len("/assets/"):] if url.startswith("/assets/") else url.lstrip("/"))
52
  src = os.path.join(SRC_ROOT, rel)
53
  dst = os.path.join(DST_ROOT, rel)
 
1
  #!/usr/bin/env python3
2
+ """Curate the Space's assets from the full auto-battler set — manifest-driven.
3
 
4
+ The Space ships a SUBSET of auto-battler's 65 MB asset library: only the files the
5
+ app actually references. Rather than per-feature copy logic, this resolves a UNION of
6
+ asset URLs from one or more manifests and copies exactly those, decoding %-escapes so
7
+ URL-encoded folder names (e.g. "Carnival%20NPCs", "_Premade%20Scene") match on disk.
 
 
8
 
9
+ Manifests:
10
+ web/assets/characters.json — every sprite sheet the curated characters reference
11
+ (built in; body + shadows + extras + companions).
12
+ • extra URL-list files (argv) — newline-delimited /assets/... URLs, e.g. the map's
13
+ MAP_ASSET_URLS dumped from auto-battler. Comment/blank
14
+ lines (#, empty) are skipped.
15
+
16
+ AB=../auto-battler python3 curate_assets.py [urls1.txt urls2.txt ...]
17
+ Run from the tiny-army dir; idempotent. Driven by build.sh so it stays reproducible.
18
  """
19
  import json
20
  import os
21
  import shutil
22
+ import sys
23
  from urllib.parse import unquote
24
 
25
  HERE = os.path.dirname(os.path.abspath(__file__))
 
29
  MANIFEST = os.path.join(DST_ROOT, "characters.json")
30
 
31
 
32
+ def character_urls(manifest):
33
+ """Every /assets/... sheet URL characters.json points at, across all sheet kinds."""
34
  urls = set()
35
  for pack in manifest["packs"]:
36
  for c in pack["characters"]:
 
47
  return urls
48
 
49
 
50
+ def file_urls(path):
51
+ """Newline-delimited /assets/... URLs from an extra manifest (skip blanks/comments)."""
52
+ with open(path) as f:
53
+ return {ln.strip() for ln in f if ln.strip() and not ln.startswith("#")}
54
+
55
+
56
+ def json_asset_urls(path):
57
+ """Every /assets/....png|jpg URL anywhere in a JSON data file (recursive walk). Used for
58
+ effects.json — the classes/enemies skill cards render its effect + status-effect icons."""
59
+ urls = set()
60
+
61
+ def walk(o):
62
+ if isinstance(o, str):
63
+ if o.startswith("/assets/") and o.lower().endswith((".png", ".jpg", ".jpeg", ".webp")):
64
+ urls.add(o)
65
+ elif isinstance(o, dict):
66
+ for v in o.values():
67
+ walk(v)
68
+ elif isinstance(o, list):
69
+ for v in o:
70
+ walk(v)
71
+
72
+ if os.path.exists(path):
73
+ walk(json.load(open(path)))
74
+ return urls
75
+
76
+
77
  def main():
78
+ urls = character_urls(json.load(open(MANIFEST)))
79
+ urls |= json_asset_urls(os.path.join(DST_ROOT, "effects.json")) # effect + status-effect icons
80
+ for path in sys.argv[1:]:
81
+ urls |= file_urls(path)
82
+
83
  copied = skipped = absent = 0
84
+ for url in sorted(urls):
85
+ # URLs are URL-encoded; decode so the path matches real on-disk folder names (with
86
+ # spaces). The static server decodes requests the same way, so files land where the
87
+ # browser asks. Strip the leading /assets/ (or any leading slash) to get the rel path.
88
  rel = unquote(url[len("/assets/"):] if url.startswith("/assets/") else url.lstrip("/"))
89
  src = os.path.join(SRC_ROOT, rel)
90
  dst = os.path.join(DST_ROOT, rel)
web/assets/minifantasy/Minifantasy_ForgottenPlains_v3.6_Commercial_Version/Minifantasy_ForgottenPlains_Assets/Minifantasy_ForgottenPlainsMockup.png ADDED
web/assets/minifantasy/Minifantasy_ForgottenPlains_v3.6_Commercial_Version/Minifantasy_ForgottenPlains_Assets/Tileset/Minifantasy_ForgottenPlainsTiles.png ADDED
web/assets/minifantasy/Minifantasy_ForgottenPlains_v3.6_Commercial_Version/Minifantasy_ForgottenPlains_Assets/Tileset/Minifantasy_ForgottenPlainsTilesShadows.png ADDED
web/assets/minifantasy/Minifantasy_ForgottenPlains_v3.6_Commercial_Version/Minifantasy_ForgottenPlains_Assets/props/Minifantasy_ForgottenPlainsProps.png ADDED
web/assets/minifantasy/Minifantasy_ForgottenPlains_v3.6_Commercial_Version/Minifantasy_ForgottenPlains_Assets/props/Minifantasy_ForgottenPlainsPropsShadows.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Legendary Weapons/Icerberg Blade/Icerberg_blade_f.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Legendary Weapons/Thunderbolt Sword/Thunderbolt_sword_f.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Legendary Weapons/Viper Scimitar/Viper_scimitar_f.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Legendary Weapons/Volcano Mace/Volcano_mace_f.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Bow/Front Layer/Bow_bleeding_f.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Bow/Front Layer/Bow_fear_f.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Bow/Front Layer/Bow_fire_f.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Bow/Front Layer/Bow_ice_f.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Bow/Front Layer/Bow_nature_f.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Bow/Front Layer/Bow_petrification_f.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Bow/Front Layer/Bow_poisson_f.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Bow/Front Layer/Bow_shock_f.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Bow/Front Layer/Bow_sickness_f.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Bow/Front Layer/Bow_sleep_f.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Bow/Front Layer/Bow_stun_f.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Dagger/Front Layer/Dagger_bleeding_f.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Dagger/Front Layer/Dagger_fear_f.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Dagger/Front Layer/Dagger_fire_f.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Dagger/Front Layer/Dagger_ice_f.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Dagger/Front Layer/Dagger_nature_f.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Dagger/Front Layer/Dagger_petrification_f.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Dagger/Front Layer/Dagger_poisson_f.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Dagger/Front Layer/Dagger_shock_f.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Dagger/Front Layer/Dagger_sickness_f.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Dagger/Front Layer/Dagger_sleep_f.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Dagger/Front Layer/Dagger_stun_f.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Flail/Flail_bleeding.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Flail/Flail_fear.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Flail/Flail_fire.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Flail/Flail_ice.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Flail/Flail_nature.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Flail/Flail_petrification.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Flail/Flail_poisson.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Flail/Flail_shock.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Flail/Flail_sickness.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Flail/Flail_sleep.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/Flail/Flail_stun.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/LongSword/Front layer/LongSword_bleeding_f.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/LongSword/Front layer/LongSword_fear_f.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/LongSword/Front layer/LongSword_fire_f.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/LongSword/Front layer/LongSword_ice_f.png ADDED
web/assets/minifantasy/Minifantasy_Magic_Weapons_And_Effects_v1.0/Minifantasy_Magic_Weapons_And_Effects_Assets/Addon Effects (Minifantasy - Weapons)/Magic Weapons/LongSword/Front layer/LongSword_nature_f.png ADDED