Replace twelfth battle map with hand-painted asset

This commit is contained in:
2026-07-09 15:11:46 +09:00
parent 0035ba5dc4
commit ef06801d0e
7 changed files with 15 additions and 92 deletions

View File

@@ -2,7 +2,7 @@
## Scope
The first eleven campaign battles now use the same hand-painted tactical map pipeline. The renderer still reads the original scenario tile coordinates and battle logic; only the map texture asset changes from flat/vector map art to low-contrast raster terrain.
The first twelve campaign battles now use the same hand-painted tactical map pipeline. The renderer still reads the original scenario tile coordinates and battle logic; only the map texture asset changes from flat/vector map art to low-contrast raster terrain.
## Art Direction
@@ -28,6 +28,7 @@ python scripts/generate-handpaint-map-sample.py --map eighth --webp-quality 90
python scripts/generate-handpaint-map-sample.py --map ninth --webp-quality 90
python scripts/generate-handpaint-map-sample.py --map tenth --webp-quality 90
python scripts/generate-handpaint-map-sample.py --map eleventh --webp-quality 90
python scripts/generate-handpaint-map-sample.py --map twelfth --webp-quality 90
```
## Current Assets
@@ -43,6 +44,7 @@ python scripts/generate-handpaint-map-sample.py --map eleventh --webp-quality 90
- `src/assets/images/battle/ninth-battle-map.webp`
- `src/assets/images/battle/tenth-battle-map.webp`
- `src/assets/images/battle/eleventh-battle-map.webp`
- `src/assets/images/battle/twelfth-battle-map.webp`
## QA Outputs
@@ -66,5 +68,7 @@ python scripts/generate-handpaint-map-sample.py --map eleventh --webp-quality 90
- `docs/tenth-battle-map-handpaint-preview.png`
- `docs/eleventh-battle-map-handpaint-before-after.png`
- `docs/eleventh-battle-map-handpaint-preview.png`
- `docs/twelfth-battle-map-handpaint-before-after.png`
- `docs/twelfth-battle-map-handpaint-preview.png`
Browser screenshots are saved per verification run after build/deploy.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

View File

@@ -118,6 +118,15 @@ MAP_CONFIGS = {
"before": BATTLE_IMAGE_DIR / "eleventh-battle-map.svg",
"seed": 240804,
},
"twelfth": {
"slug": "twelfth-battle-map",
"terrain_export": "twelfthBattleMap",
"units_export": "twelfthBattleUnits",
"ally_positions_export": "twelfthBattleAllyPositions",
"out": BATTLE_IMAGE_DIR / "twelfth-battle-map.webp",
"before": BATTLE_IMAGE_DIR / "twelfth-battle-map.svg",
"seed": 240814,
},
}

View File

@@ -1,90 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 3000 2400" width="3000" height="2400">
<defs>
<filter id="xiapiGrain">
<feTurbulence type="fractalNoise" baseFrequency="0.017" numOctaves="4" seed="1212" />
<feColorMatrix type="saturate" values="0.68" />
<feBlend mode="multiply" in2="SourceGraphic" />
</filter>
<pattern id="field" width="120" height="120" patternUnits="userSpaceOnUse">
<rect width="120" height="120" fill="#5f704d" />
<path d="M12 34h34M52 80h42M78 20l24 16M22 104l30-20" stroke="#adc077" stroke-width="4" opacity="0.18" />
<path d="M20 68l18-30M62 42l22-20M90 98l14-30" stroke="#283b21" stroke-width="3" opacity="0.34" />
</pattern>
<pattern id="road" width="126" height="126" patternUnits="userSpaceOnUse">
<rect width="126" height="126" fill="#8d7047" />
<path d="M0 36c46-20 88 14 126-10M0 90c52-24 86 12 126-4" stroke="#c7a771" stroke-width="9" opacity="0.24" />
<path d="M24 100l24-32M70 52l30-22M98 98l14-12" stroke="#3a2c20" stroke-width="4" opacity="0.32" />
</pattern>
<pattern id="forest" width="140" height="120" patternUnits="userSpaceOnUse">
<rect width="140" height="120" fill="#1f3825" />
<circle cx="28" cy="52" r="34" fill="#122717" />
<circle cx="68" cy="34" r="40" fill="#456842" />
<circle cx="112" cy="58" r="34" fill="#213a24" />
<circle cx="56" cy="90" r="30" fill="#59774b" />
<path d="M12 72c38 18 84 16 118-12M38 26c26 22 62 20 80-8" stroke="#09180d" stroke-width="5" opacity="0.34" />
</pattern>
<pattern id="hill" width="140" height="110" patternUnits="userSpaceOnUse">
<rect width="140" height="110" fill="#766d4b" />
<path d="M-16 98c52-70 100-88 146-68c38 18 62 50 82 92" fill="#4b4933" opacity="0.72" />
<path d="M20 88c42-46 80-58 118-34" fill="none" stroke="#a39a64" stroke-width="11" opacity="0.26" />
</pattern>
<linearGradient id="river" x1="0" y1="0" x2="1" y2="1">
<stop offset="0" stop-color="#6e9bad" />
<stop offset="0.55" stop-color="#2d637c" />
<stop offset="1" stop-color="#153448" />
</linearGradient>
<linearGradient id="fortWall" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#8b7661" />
<stop offset="1" stop-color="#3c3026" />
</linearGradient>
<radialGradient id="fire" cx="0.5" cy="0.44" r="0.58">
<stop offset="0" stop-color="#ffe6a0" />
<stop offset="0.48" stop-color="#d6752f" />
<stop offset="1" stop-color="#4b1e14" stop-opacity="0" />
</radialGradient>
</defs>
<rect width="3000" height="2400" fill="#111a1f" />
<rect width="3000" height="2400" fill="url(#field)" opacity="0.96" />
<g filter="url(#xiapiGrain)">
<path d="M1500-110c-70 344-42 620 84 828c122 202 96 468-76 796c-118 226-140 544-66 954" fill="none" stroke="#13354c" stroke-width="310" stroke-linecap="round" opacity="0.94" />
<path d="M1500-110c-70 344-42 620 84 828c122 202 96 468-76 796c-118 226-140 544-66 954" fill="none" stroke="url(#river)" stroke-width="194" stroke-linecap="round" opacity="0.98" />
<path d="M2110 250c-88 350-92 710-16 1080c72 350 70 676-32 1030" fill="none" stroke="#13354c" stroke-width="260" stroke-linecap="round" opacity="0.92" />
<path d="M2110 250c-88 350-92 710-16 1080c72 350 70 676-32 1030" fill="none" stroke="url(#river)" stroke-width="158" stroke-linecap="round" opacity="0.95" />
<path d="M-80 1840C384 1780 802 1782 1240 1816c334 26 636 16 948-60c260-64 528-72 906-16" fill="none" stroke="#94754a" stroke-width="250" stroke-linecap="round" opacity="0.82" />
<path d="M-80 1840C384 1780 802 1782 1240 1816c334 26 636 16 948-60c260-64 528-72 906-16" fill="none" stroke="url(#road)" stroke-width="138" stroke-linecap="round" opacity="0.9" />
<path d="M430 2320C668 1946 956 1640 1294 1402c392-276 790-440 1200-522" fill="none" stroke="#94754a" stroke-width="190" stroke-linecap="round" opacity="0.76" />
<path d="M430 2320C668 1946 956 1640 1294 1402c392-276 790-440 1200-522" fill="none" stroke="url(#road)" stroke-width="100" stroke-linecap="round" opacity="0.84" />
<path d="M650 1010c360 14 722 12 1086-8c344-18 718-4 1110 40" fill="none" stroke="#94754a" stroke-width="210" stroke-linecap="round" opacity="0.78" />
<path d="M650 1010c360 14 722 12 1086-8c344-18 718-4 1110 40" fill="none" stroke="url(#road)" stroke-width="108" stroke-linecap="round" opacity="0.84" />
<path d="M20 10c308-76 588-22 842 164c-24 222-170 364-438 426C190 536 36 406 20 10Z" fill="url(#forest)" opacity="0.82" />
<path d="M360 850c298-122 574-72 828 150c-106 216-382 324-826 324c-116-160-116-318-2-474Z" fill="url(#forest)" opacity="0.82" />
<path d="M2230 1650c214-70 418-38 612 96c-44 246-214 414-510 504c-154-108-188-308-102-600Z" fill="url(#forest)" opacity="0.76" />
<path d="M620 198c240-76 452-36 636 120c-42 144-168 238-378 282c-168-74-254-208-258-402Z" fill="url(#hill)" opacity="0.82" />
<path d="M2420 350c206-66 386-34 540 96c-18 210-126 342-324 396c-154-86-226-250-216-492Z" fill="url(#hill)" opacity="0.82" />
<path d="M900 2060c210-62 400-26 570 108c-28 126-144 202-348 228c-142-68-216-180-222-336Z" fill="url(#hill)" opacity="0.76" />
<g transform="translate(2180 760)">
<rect x="-82" y="-66" width="690" height="650" rx="20" fill="#0f0a07" opacity="0.45" />
<rect x="0" y="0" width="540" height="520" rx="14" fill="url(#fortWall)" stroke="#211711" stroke-width="20" />
<path d="M0 112h540M0 226h540M0 340h540M0 450h540" stroke="#2f251c" stroke-width="14" opacity="0.76" />
<path d="M112 0v520M270 0v520M428 0v520" stroke="#67523e" stroke-width="10" opacity="0.48" />
<rect x="164" y="218" width="210" height="134" fill="#1f1713" stroke="#0e0907" stroke-width="12" />
<path d="M164 218l104-72l106 72" fill="#744923" stroke="#21160e" stroke-width="12" />
<path d="M232 352v-82h74v82" fill="#0d0907" />
<circle cx="84" cy="144" r="76" fill="url(#fire)" opacity="0.68" />
<circle cx="462" cy="374" r="76" fill="url(#fire)" opacity="0.64" />
</g>
<g transform="translate(70 1780)">
<rect x="0" y="0" width="245" height="178" rx="10" fill="#594836" stroke="#201914" stroke-width="12" />
<path d="M-26 22L122-70l170 92Z" fill="#986230" stroke="#2a1c12" stroke-width="12" />
<path d="M76 178v-74h74v74" fill="#201713" />
<circle cx="210" cy="30" r="58" fill="url(#fire)" opacity="0.55" />
</g>
</g>
<rect width="3000" height="2400" fill="#000" opacity="0.1" />
</svg>

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

View File

@@ -63,7 +63,7 @@ import twentySecondBattleMapUrl from '../../assets/images/battle/twenty-second-b
import twentySeventhBattleMapUrl from '../../assets/images/battle/twenty-seventh-battle-map.svg';
import twentySixthBattleMapUrl from '../../assets/images/battle/twenty-sixth-battle-map.svg';
import twentyThirdBattleMapUrl from '../../assets/images/battle/twenty-third-battle-map.svg';
import twelfthBattleMapUrl from '../../assets/images/battle/twelfth-battle-map.svg';
import twelfthBattleMapUrl from '../../assets/images/battle/twelfth-battle-map.webp';
export const battleMapAssets: Record<string, string> = {
'battle-map-first': firstBattleMapUrl,