diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 1cda4b98..fb924762 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -48,6 +48,13 @@ jobs: Expand-Archive "$env:RUNNER_TEMP\SDL2.zip" "$env:RUNNER_TEMP\sdl2" - name: Run portable simulation, mod and Windows save tests run: cargo test --locked --no-default-features + - name: Complete Black Tide with carried pilot saves and paid repairs + shell: pwsh + run: | + $env:RAPTOR_TEST_DATA = "$env:GITHUB_WORKSPACE\data" + $env:RAPTOR_STAGE2_REPORT = "$env:RUNNER_TEMP\stage2-route.json" + cargo test --release --locked --no-default-features --test iron_coast_stage2 starter_ship_completes_all_eight_missions_with_paid_repairs_and_finale_replay -- --ignored --nocapture + if ($LASTEXITCODE -ne 0) { throw "Native Windows campaign continuation failed" } - name: Check the included Windows executable and launcher shell: pwsh run: | @@ -85,10 +92,38 @@ jobs: $env:SDL_AUDIODRIVER = "dummy" & $exe --profile-root "$env:RUNNER_TEMP\raptor-profile" --smoke-frames 32 --preview-mission base:sector_1_wave_1 --screenshot "$env:GITHUB_WORKSPACE\dist\windows-gameplay.png" if ($LASTEXITCODE -ne 0) { throw "Windows SDL gameplay failed" } + $stageProfile = "$env:RUNNER_TEMP\stage2-profile" + New-Item -ItemType Directory -Force "$stageProfile\config" | Out-Null + $selection = (Get-ChildItem "$package\mods" -Directory | Where-Object { Test-Path "$($_.FullName)\mod.toml" } | ForEach-Object { '"' + $_.Name + '"' }) -join "," + @" + enabled_mods = [$selection] + hd_mode = true + scale = 4 + width = 1920 + height = 1080 + "@ | Set-Content "$stageProfile\config\config.toml" -Encoding utf8 + $env:RAPTOR_AUDIO_CAPTURE = "$env:GITHUB_WORKSPACE\dist\windows-stage2-audio.wav" + $env:RAPTOR_AUDIO_CAPTURE_SECONDS = "3" + & $exe --profile-root $stageProfile --smoke-frames 240 --preview-mission iron_coast_stage2_mission_1:mission_01 --screenshot "$env:GITHUB_WORKSPACE\dist\windows-stage2.png" + if ($LASTEXITCODE -ne 0) { throw "Windows Stage2 SDL gameplay failed" } + if (!(Test-Path $env:RAPTOR_AUDIO_CAPTURE)) { throw "Windows Stage2 audio capture missing" } + python -c "import array, wave; w=wave.open(r'$env:RAPTOR_AUDIO_CAPTURE'); p=array.array('h',w.readframes(w.getnframes())); assert w.getframerate()==44100 and w.getnchannels()==2 and w.getnframes()>=44100 and sum(x!=0 for x in p)>1000" + if ($LASTEXITCODE -ne 0) { throw "Windows Stage2 audio was empty or malformed" } + Add-Content "$stageProfile\config\config.toml" "music_volume = 0" + $env:RAPTOR_AUDIO_CAPTURE = "$env:GITHUB_WORKSPACE\dist\windows-stage2-sfx.wav" + & $exe --profile-root $stageProfile --smoke-frames 240 --preview-mission iron_coast_stage2_mission_8:mission_08 + if ($LASTEXITCODE -ne 0) { throw "Windows Stage2 sound-effect gameplay failed" } + python -c "import array, wave; w=wave.open(r'$env:RAPTOR_AUDIO_CAPTURE'); p=array.array('h',w.readframes(w.getnframes())); assert w.getframerate()==44100 and w.getnchannels()==2 and w.getnframes()>=44100 and sum(x!=0 for x in p)>1000" + if ($LASTEXITCODE -ne 0) { throw "Windows Stage2 sound effects were silent" } + Remove-Item Env:RAPTOR_AUDIO_CAPTURE + Remove-Item Env:RAPTOR_AUDIO_CAPTURE_SECONDS - uses: actions/upload-artifact@v4 with: name: RustRaptor-windows-x86_64 path: | dist/RustRaptor-windows-x86_64.zip dist/windows-gameplay.png + dist/windows-stage2.png + dist/windows-stage2-audio.wav + dist/windows-stage2-sfx.wav if-no-files-found: error diff --git a/README.md b/README.md index ce44fb50..71a05c93 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,15 @@ be enabled individually; each mission selects its own dependencies. weapon mods. Enable them in Mods and buy them in the supply room. The cannon is a selected special that chains through nearby targets; the shield fires with your primary guns while Fire is held. Both ship SD/HD icons and sounds. + +**Iron Coast II: Black Tide** adds eight more missions, eight separate bosses, +three shared enemy types and three original FM music tracks. Enable its campaign +in **Mods**, apply at the main menu, then choose **Nightbreak Inlet** in the +Hangar's mission menu to begin the linked campaign. +The campaign selects its dependencies automatically. **Railburst Cannon** +(685,000 credits) and **Depth Charge** (525,000 credits) are optional shop +purchases; completing missions does not grant either weapon. Each mission, +boss and weapon is also an individual mod. See [Stage 2](docs/iron-coast-stage2-design.md). For a user mods folder, pass `--mods DIR` or create `$XDG_DATA_HOME/RaptorReplica/mods/` on Linux or `%APPDATA%\RaptorReplica\mods\` on Windows. Saves and configuration use separate @@ -60,7 +69,7 @@ Existing untouched Rust default bindings migrate to these controls. | Folder | Contents | | --- | --- | | `src/` | Engine, SDL host and validation CLI | -| `mods/` | Aurora example; six Iron Coast missions, campaign assembly, music, five independent weapons, three shared enemies and five stage bosses | +| `mods/` | 45 packages: Aurora example, two Iron Coast campaigns with 14 missions, seven weapons, shared enemies, bosses and original music | | `schemas/` | Version 1 mod API schemas | | `tests/` | Portable fixtures and opt-in original-data checks | | `tools/` | Replay comparator, content-table generator and asset reference tools | @@ -75,7 +84,7 @@ See [repository layout](docs/repository.md). The engine supports original and 2×/3×/4× crisp scaling, plus an optional HD artwork setting. Bundled mods have SD/HD artwork; the reviewed base-game pack covers a complete light-player banking sequence and selected enemies, boss, -equipment, projectiles, effects and terrain: 800 of 5,753 original pictures +equipment, projectiles, effects and terrain: 1,148 of 5,753 original pictures are now included. [The HD backlog](docs/hd-backlog.md) records the remaining artwork and drafts awaiting review. @@ -88,6 +97,7 @@ cases; wider playtesting and complete base-game HD coverage remain work in progr - [Mod API](docs/modding-api.md) - [AI mod authoring checklist](docs/mod-authoring-checklist.md) - [Iron Coast packages](docs/iron-coast.md) +- [Iron Coast II: Black Tide](docs/iron-coast-stage2-design.md) - [Weapon prices and balance](docs/weapon-balance.md) - [Sprite and shadow validation](docs/visual-validation.md) - [Sound playback validation](docs/sound-validation.md) diff --git a/docs/iron-coast-stage2-design.md b/docs/iron-coast-stage2-design.md new file mode 100644 index 00000000..8a3ff730 --- /dev/null +++ b/docs/iron-coast-stage2-design.md @@ -0,0 +1,137 @@ +# Iron Coast II: Black Tide + +Stage 2 is an eight-sortie expansion built from independent local mods. It +preserves the original 70/3 Hz simulation, native classic enemy movement and +the normal shop, firing controls, shield economy and pilot saves. + +Enable **Iron Coast II: Black Tide** in **Mods**, apply at the main menu, then +select **Nightbreak Inlet** in the Hangar's mission menu. Its dependency selection +includes the eight mission packages, their bosses and shared enemies, music +and the two weapon packages. Enabling a single mission selects only its actual +dependencies and leaves the other missions and optional weapons disabled. +Disabling the campaign offers to remove its unused dependencies in the usual +confirmation popup. + +| Sortie | Mission | Encounter | Boss | Music | +| --- | --- | --- | --- | --- | +| 1 | Nightbreak Inlet | Moonlit harbor breach | Gatebreaker shore platform | assault | +| 2 | Undertow Run | Naval convoy pursuit | Undertow missile submarine | pursuit | +| 3 | Stormglass Refinery | Fuelworks under air attack | Stormglass refinery crawler | assault | +| 4 | Floodgate Zero | River crossing and dam defenses | Floodgate defense platform | pursuit | +| 5 | Skybreaker Arsenal | Cliffside airborne weapons facility | Skybreaker flying fortress | assault | +| 6 | Emberwake Shipyards | Volcanic steelworks and repair docks | Emberwake battleship | pursuit | +| 7 | Siege of the Iron Fleet | Layered coastal fleet raid | Dreadnought carrier | finale | +| 8 | Black Tide | Offshore command citadel assault | Leviathan command carrier | finale | + +## Package contract + +- `iron_coast_stage2_campaign:campaign` links the eight mission IDs in order. + Its manifest depends on all eight mission packages and the two optional + weapon packages. This ID sorts before individual mission campaigns so the + full campaign determines progression when installed together. +- `iron_coast_stage2_mission_N:mission_0N` belongs to mission package N. + Individual mission packages remain independently playable. Each declares + only the shared enemies, own boss and soundtrack it actually references. +- `iron_coast_stage2_boss_N:unit` belongs to a separate boss package. + An actual boss death increments `iron_coast_stage2_boss_N:defeated`. +- Shared enemy packages expose `iron_coast_stage2_interceptor:unit`, + `iron_coast_stage2_siege:unit` and `iron_coast_stage2_skimmer:unit`. + Their death counters use their own `:defeated` objective IDs. +- `iron_coast_stage2_music` supplies `:assault`, `:pursuit` and `:finale`. +- `iron_coast_railburst:equipment` and `iron_coast_depth_charge:equipment` + are separate shop additions. Prices follow actual simulated damage and + target/range/cadence constraints. Their weapons and projectiles have + separate IDs from their inventory items. + +Every package uses API 1 and version 1.0.0. Stage 2 introduces no overrides +of original or Stage 1 content. Mission scripts use `auto_complete=false`: +elapsed duration does not grant victory. Required targets stay reachable; +destroying them and the final boss earns the ending. Every sortie resets its +own objective and phase state. Completion and debrief counters are scoped to +the mission and victory credits are awarded once per sortie. + +## Equipment and controls + +The **Railburst Cannon** costs 685,000 credits. This selected special fires a +fast 42-damage round and can penetrate two further targets in a narrow forward +lane for 32 and 22 damage. It hits air and ground targets and rewards alignment. +The **Depth Charge** costs 525,000 credits. This selected special delivers +72 damage to a ground target, with bounded splash to three nearby ground +targets; aircraft are excluded. Both are reusable, allow one owned copy and +sell for half their purchase price. Their package READMEs include measured +damage, limits, art provenance and reproducible sound recipes. + +Buy either in the supply room after enabling its mod. **Alt or Shift** cycles +selected equipment; **Ctrl** fires it alongside the default guns. **Space** +continues to drop bombs. The campaign grants no equipment loans or automatic +full-shield refill. Later sorties include bounded support repairs; additional +repairs use the normal Energy purchase. + +## Content and review requirements + +New terrain and boss silhouettes should distinguish each mission while +keeping the top-down industrial military appearance of Raptor. Classic +enemy IDs keep their native paths, weapons and behavior. Boss phases should +change the attack pattern visibly and leave reasonable escape lanes. + +New artwork includes SD and HD PNGs with identical logical collision +dimensions and correct transparency. Authored art, generated sound effects, +MUS scores, prompts, provenance and reproducible processing/composition +sources are included in Git. Working original-reference images and review +captures stay in ignored directories. + +Acceptance covers dependency selection and disabling, individual activation, +all eight real mission completions, native enemy movement, owned equipment +and full inventories, pilot save/RNG continuation, finale replay and reward +deduplication. SD/HD gameplay and shop images and actual audio output are +reviewed before updating both self-contained Linux and Windows bundles. + +## Validated release content + +All 23 Stage 2 packages are frozen and add no overrides. The complete installed +set contains 45 packages; its sole override is the existing Stage 1 campaign +progression link. Portable campaign checks cover dependency closure, unused +pruning, individual missions, eight-sortie progression and full inventories. + +The original-data route starts with the actual registered pilot baseline of +75 shields and 10,000 credits at Veteran difficulty. Normal default-gun fire +and pointer input complete all eight sorties, saving and loading the pilot, +script state and RNG between each, then replay the finale. Three normal Energy +purchases are paid from carried credits. The route finishes the first eight +with 334,910 credits, and the saved replay with 396,520; equipment stays owned +and rewards are not duplicated. Authors also check every mission at all four +difficulties, starter gear, full inventories and delayed objective completion. +Control policies vary, so these are achievable fixture outcomes rather than +predictions of player earnings or difficulty. + +Independent review clears 40 boss lifecycle/phase cases, 32 emitted-attack +contracts, eight concurrent-boss cases, four 1,100-lifetime state/migration +probes and exact 14-tick phase-transition warnings. Actual weapon collision, +splash/penetration limits and a 24-enemy command-budget fixture pass. The +review inspected 232 decoded SD/HD outputs at scales 1–4 and checked 75 native +sound effects with nonzero output and exact FX mute. The music package records +separate complete-score FM and loop-boundary validation. + +The ordinary suites pass 310 headless and 374 desktop tests. Final focused +checks pass four portable campaign checks plus the real saved route, nine +weapon tests, nine shared-enemy tests, six animation/effect API tests and the +ignored Host preview check. All 34 Host captures were visually inspected: +SD/HD boss artwork on each mission's terrain, both shop modes, weapon details, +Nightbreak/finale mission cards, dependencies and the disable confirmation. +Bosses in these pictures are deliberate art previews; actual combat phase +and campaign completion evidence is separate. Drawing preserves gameplay +state, Escape cancels diagnostics/disable, and mod rows retain their order. + +Reproduce the original-data route from this folder with: + +```sh +cargo test --release --locked --no-default-features --test iron_coast_stage2 \ + starter_ship_completes_all_eight_missions_with_paid_repairs_and_finale_replay \ + -- --ignored --nocapture +``` + +Set `RAPTOR_TEST_DATA` for a deliberate catalog override, and +`RAPTOR_STAGE2_DIFFICULTY` to 0–3 to choose difficulty. The final Linux and +Windows archive checks use extracted copies, 1080p SDL rendering and separate +music/effect PCM captures. These entry smoke checks are distinct from full +headless combat acceptance; automated SDL uses dummy drivers. diff --git a/docs/music-validation.md b/docs/music-validation.md index eadd5586..52f663b3 100644 --- a/docs/music-validation.md +++ b/docs/music-validation.md @@ -57,3 +57,21 @@ LD_LIBRARY_PATH="$HOME/.local/lib" SDL_AUDIODRIVER=dummy cargo test --locked \ These checks validate the engine path using synthetic scores. Composition, listening review and original-data in-game soundtrack captures are separate release checks for each music package. + +## Black Tide soundtrack + +`mods/iron_coast_stage2_music` contains three original compositions: **Rivetline +Assault** (D minor, 144 BPM, 93.33 seconds), **Undertow Pursuit** (F-sharp minor, +168 BPM, 91.43 seconds), and **Black Tide Rising** (C minor, 126 BPM, 106.67 seconds). +Five FM channels and percussion use the bundled original GENMIDI instruments. +They introduce no original-score copies or replacements. Mission definitions +choose their namespaced IDs and the usual Music setting controls playback. + +The package's real decoder and FM renderer checks cover every second, peak +levels at normal/full volume, exact mute, voice counts, looping boundaries and +one-play release tails. Recomposition and all six full/boundary PCM renders +reproduce byte-for-byte. `validate_music.py` resolves the exact active Cargo +library artifacts instead of guessing from modification time, so separate +desktop and headless builds cannot select incompatible Serde dependencies. +The package README documents the composition and reproduction commands. +These are automated score/PCM checks; physical speaker listening is separate. diff --git a/docs/resume-checkpoint.md b/docs/resume-checkpoint.md index 3a54ef8e..10837758 100644 --- a/docs/resume-checkpoint.md +++ b/docs/resume-checkpoint.md @@ -24,6 +24,32 @@ the relocation. See [repository layout](repository.md). ## Engine and package +### Current runtime and Stage 2 work + +The `b8b8620` runtime checkpoint includes the reviewed **1,148-frame / 421-sequence** +HD snapshot in both executables' shared catalog. It contains **6,848 data files** +with unchanged original `INDEX`. Linux binary SHA-256 is +`fdfcf03f126279246f3b762987e02fa7b385f07b4d31339732037462f9e52413`; +Windows is `a74cc4ea20ddc17a39fe4cbf2da2e7391a561d1975b114ec56dd35fb5ff38f2d`. +The engine now exposes checked script commands for boss animation frames and +native impact-effect kinds. Original effect serialization remains compatible. + +**Iron Coast II: Black Tide** adds eight missions, eight bosses, three shared +enemies, three original FM scores and two optional purchased weapons through +23 individual packages. All eight missions pass starter-gun runs at difficulties +0–3. All 23 package freezes and independent long-run checks are complete. The +actual registered-pilot Veteran route saves between eight wins and a finale +replay; all 34 Host artwork/shop/menu captures are inspected. Final relocated +Linux/Windows archives are the remaining release checks. The ordinary source suites pass **310 +headless / 374 desktop** tests. [Stage 2 design and validation](iron-coast-stage2-design.md) +records the new content and final acceptance scope. + +Original HD work continues under `hd_coordinator`; later approved candidates +remain separate from the immutable packaged 1,148-frame snapshot. The paragraphs +below preserve the earlier recovery and 800-frame package evidence. + +### Earlier package checkpoints + - Windows support is now included: `bin/raptor-rust.exe`, adjacent `SDL2.dll`, `run.cmd`, `runtime-windows-manifest.json` and the Windows export tool/CI. The GNU executable SHA-256 is @@ -89,7 +115,7 @@ are committed, and the executable and zip have been refreshed and launched. Root owns menu fixes. `iron_coast_5` temporarily owns the ground-target diagnosis; its completed boss candidates and pending equipment review remain preserved. -## HD state and owners +## Earlier HD state and recovery owners The original picture inventory is 5,753 IDs. The approved handoff has 800 registered frames across 340 complete sequences; 4,953 IDs remain unregistered. diff --git a/docs/standalone-package.md b/docs/standalone-package.md index 49d4a45c..2775d9bd 100644 --- a/docs/standalone-package.md +++ b/docs/standalone-package.md @@ -45,17 +45,16 @@ Re-run the assembler after engine changes, new approved HD registrations or mod edits to refresh the package. The runtime snapshot contains approved art only; it does not claim the full original HD catalog is complete. -The current package was unpacked into a folder containing spaces and launched -from `/tmp` with only its bundled SDL2 library on the library search path. -Catalog validation checked 6,449 assets, 27 missions, 528 enemies, 16 weapons -and 24 items. The refreshed 11 October bundle validates all 22 bundled mods -and all 800 approved HD frames, with zero rejected supplied frames. Its -runtime manifest verifies all 6,742 data files. The updated desktop executable -also launches from `/tmp` with only the bundled library and an isolated profile. -Menu and gameplay screenshots at 1280×800 and 1920×1080, plus stereo audio -captures, completed successfully. Native `unzip` preserves the executable -permissions stored in the archive. -An original-intro capture at 1080p also confirms a 1440×1080 video area and -black 240-pixel side borders when gameplay stretching is enabled. Removing -the copied catalog produces an error at the copied data path, with no fallback -to the development checkout. +The current runtime contains **6,449 catalog entries, 1,148 approved HD frames +and 6,848 data files**. There are **45 bundled mod packages**, including the +23 packages for [Iron Coast II: Black Tide](iron-coast-stage2-design.md). +All installed mods pass catalog validation; Stage 2 adds no overrides. The +one existing override belongs to the Stage 1 campaign progression package. + +The earlier 800-frame/22-mod archives passed relocated-folder launch, 1080p +SDL rendering, music and isolated sound-effect captures. Their original-intro +capture confirms a 1440×1080 video area with black 240-pixel side borders. +Removing the copied catalog reports its own missing path rather than using a +development checkout. The final Stage 2 archive checks are recorded after +export so their evidence refers to the exact distributed bytes. Native +`unzip` preserves the executable permissions stored in the Linux archive. diff --git a/docs/weapon-balance.md b/docs/weapon-balance.md index 0804666b..1a75d8b7 100644 --- a/docs/weapon-balance.md +++ b/docs/weapon-balance.md @@ -98,6 +98,21 @@ another special never disables it. Its pulses consume no equipment. ## Economy and limits +Stage 2 adds two reusable selected specials, measured separately through the +same real `World::step` and script path for 700 ticks (30 seconds). +**Railburst Cannon**, priced at **685,000**, delivered 44.80 damage/s to an +aligned air or ground target and 102.40 combined across its three-target +forward column. It dealt zero damage to off-axis fixtures. Its narrow alignment +requirement and finite penetration put it below Lightning Cannon's more flexible +chain utility. **Depth Charge**, priced at **525,000**, delivered 36.00 damage/s +to an aligned ground target and 74.00 combined in its bounded ground cluster. +Air and off-axis fixtures took zero damage. With starter guns, the corresponding +single-ground results were 67.93 and 59.13 damage/s. These prices reflect their +specialist roles; campaign missions do not loan or award either item. +The complete observations and fixture constraints are in +[Railburst](../mods/iron_coast_railburst/validation/balance.json) and +[Depth Charge](../mods/iron_coast_depth_charge/validation/balance.json). + Controlled first-mission runs starting with 100 energy and zero credits earned 42,775 credits at difficulty 1 and 59,025 at difficulty 2 with starter guns. The in-game registration flow starts with 10,000 credits and 75 energy, matching diff --git a/docs/windows-build.md b/docs/windows-build.md index 26ccdbc1..37d2a697 100644 --- a/docs/windows-build.md +++ b/docs/windows-build.md @@ -57,34 +57,31 @@ The [Windows workflow](../.github/workflows/windows.yml) runs simulation, modding and save tests on Windows, validates packaged assets and all local mods, captures SDL gameplay and publishes the zip as a workflow artifact. -## Validation checkpoint: 11 October 2026 +## Current runtime and validation -The included GNU executable passed 279 portable tests under Wine 11.19, -including Windows save replacement and preserving a locked existing save. -All 22 installed mod hashes match their previous Linux hashes exactly. -The shared catalog validates 6,449 assets and the current packaged HD snapshot -validates all 800 supplied frames. The exporter verifies all 6,742 shared -data-file hashes and includes only checked Windows DLL dependencies. +The included GNU executable uses the reviewed **1,148-frame HD snapshot**; +the shared manifest binds **6,848 data files** and the package contains +**45 installed mods**. Its SHA-256 is +`a74cc4ea20ddc17a39fe4cbf2da2e7391a561d1975b114ec56dd35fb5ff38f2d`. +The [1,148-frame native Windows run](https://github.com/Quintine/RustRaptor/actions/runs/38126069413) +passed portable tests, exact committed GNU runtime checks, the MSVC desktop +build and exported-folder catalog, HD, mod and SDL gameplay validation. That +run preceded the Stage 2 content commit; it verifies the engine and the +previous 22 mod packages. -The exported zip passed CRC and manifest checks, then launched through -`run.cmd` from another working directory after extraction into a path with -spaces and Unicode. Its HD gameplay capture renders at 1920×1080. The -original intro retains its 4:3 viewport with 240-pixel black side borders. -SDL captured three seconds of 44.1 kHz stereo audio; a separate capture with -music muted verified nonzero original sound effects (251,682 nonzero samples). +The expanded workflow additionally completes all eight Black Tide missions +and a saved finale replay with normal firing/input and paid repairs. It then +checks all 45 mods and captures Stage 2 gameplay, FM music and music-muted +sound effects from the MSVC package. Final archive relocation evidence is +recorded after export and identifies the exact ZIP tested. -Two native Windows CI runs passed all 279 portable tests. The -[first run](https://github.com/Quintine/RustRaptor/actions/runs/38119440288) built the MSVC desktop release and -validated the exported folder's launcher, catalog, HD art, all mods and SDL -gameplay from a path with spaces and Unicode. The -[second run](https://github.com/Quintine/RustRaptor/actions/runs/38119943948) -also checked the exact committed GNU executable, SDL2 DLL and launcher before -building and validating MSVC. Those runs used the previous 340-frame artwork -snapshot. The [800-frame native Windows run](https://github.com/Quintine/RustRaptor/actions/runs/38121272504) -also passed all 279 tests, the committed GNU runtime checks and the rebuilt -MSVC package's complete HD, mod and SDL gameplay validation. The same snapshot -passed the relocated-folder checks under Wine. -The local GNU build additionally -ran Iron Coast mission 1 at 1080p with all 22 mods enabled and captured its -custom music. Both runs used SDL's dummy output drivers for automation; +Earlier Windows checkpoints passed 279 portable tests under Wine 11.19, +including save replacement and preservation of a locked existing save. +The 800-frame/22-mod archive passed CRC, manifest and relocated Unicode/space +folder checks through `run.cmd`, 1920×1080 HD rendering, exact 4:3 intro +borders, stereo music and isolated original effects. Native Windows runs +[38119440288](https://github.com/Quintine/RustRaptor/actions/runs/38119440288), +[38119943948](https://github.com/Quintine/RustRaptor/actions/runs/38119943948) +and [38121272504](https://github.com/Quintine/RustRaptor/actions/runs/38121272504) +record those earlier snapshots. Automated SDL checks use dummy drivers; physical Windows display, audio and controller hardware remain untested. diff --git a/mods/iron_coast_depth_charge/README.md b/mods/iron_coast_depth_charge/README.md new file mode 100644 index 00000000..0da96d1a --- /dev/null +++ b/mods/iron_coast_depth_charge/README.md @@ -0,0 +1,62 @@ +# Depth Charge 1.0.0 + +Enable **Depth Charge** in Mods, apply at the main menu, then buy it in the shop +for **525,000 credits**. It is an independent API 1 mod without dependencies or +overrides. Maximum one; resale returns 262,500 credits. It occupies a normal +inventory slot and preserves other equipment. + +This is a **selectable, reusable ground/naval special weapon**. Choose it in +Inventory or with Alt/Shift, then hold Ctrl to launch. Space remains the owned +mega-bomb control. It does not consume charges or auto-attack merely because it +is equipped. Always-equipped forward guns remain available alongside it. + +The native straight projectile travels six logical pixels per simulation tick. +A real ground-enemy collision deals 72 primary damage and starts one local +ground-blast effect. At most three other living ground enemies can receive +collateral damage: 36 damage within 16 pixels of the primary enemy's center, +or 20 damage between 16 and 36 pixels inclusive. The closest neighbors are +selected first, with stable entity order breaking ties. Aircraft, offscreen +enemies, repeated targets and centers outside that radius are excluded. If the +primary target dies, its contact still triggers the local blast correctly. + +The deliberate 48-tick cooldown is about 2.06 seconds at 70/3 Hz. The charge does +not home or detonate automatically in empty space. Slow travel makes moving +ground targets an aiming challenge; there is no screen-wide damage command. +Destructible terrain receives native primary damage, but cannot trigger scripted +collateral because the public snapshot contains enemies rather than terrain +cells. Enemy contacts emit impact audio; a miss produces only the launch sound +and projectile. The normal native terrain destruction effects remain available. + +SD equipment/projectile canvases are 16×16 and 8×12; detailed HD variants are +64×64 and 32×48. Options selects SD or HD artwork without changing logical +placement or damage. Both are single aligned frames with transparent margins. +[Artwork provenance](art-provenance.json) records unchanged generated masters, +prompts, final PNG hashes and the Rust preparation recipe. All new images, WAVs, +source masters and recipes are included; decoded original style references are +kept outside the mod. + +`python3 generate_audio.py` reproduces the mechanical launch and low naval impact +from deterministic synthesis without external recordings. `prepare_art.rs` +rebuilds SD/HD fitting from the included source masters. The companion Railburst +package's [review helper](../iron_coast_railburst/validation/review.py) is a developer +tool for both packages and is not a gameplay dependency. + +From the RustRaptor directory: + +```sh +cargo test --locked --no-default-features --test iron_coast_stage2_weapons +cargo run --locked --no-default-features -- --data data --mods mods \ + --validate-mods iron_coast_depth_charge +IRON_COAST_STAGE2_BALANCE_REPORT=/tmp/stage2-balance.json \ + cargo test --locked --no-default-features --test iron_coast_stage2_weapons \ + real_catalog_700_tick_balance_and_coexistence_report -- --ignored --nocapture +``` + +[validation/balance.json](validation/balance.json) records the actual controlled +700-tick damage observations supporting this price and role. Portable checks +cover ground filtering, inner/outer falloff, the finite neighbor cap, misses, +kills, cooldown, independent activation, coexistence, half-price resale, full +inventory preservation, deterministic state/RNG continuation and whole-tick +rollback. [validation/review.json](validation/review.json) distinguishes public +decoder/blitter/mixer captures from live desktop review. Read the [API](../../docs/modding-api.md) +for save pins and script execution limits. diff --git a/mods/iron_coast_depth_charge/art-provenance.json b/mods/iron_coast_depth_charge/art-provenance.json new file mode 100644 index 00000000..ac67e04e --- /dev/null +++ b/mods/iron_coast_depth_charge/art-provenance.json @@ -0,0 +1,68 @@ +{ + "tool": "built-in image_gen through imagegen skill", + "skill": "/home/quintine/.codex/skills/.system/imagegen/SKILL.md", + "style_reference_catalog_ids": [ + "102b6", + "101cb" + ], + "style_reference_delivery": "Original catalog inspected separately; decoded originals are not included in this mod. The generated artwork is newly authored.", + "source_records": [ + "art/generation-equipment-v1.json", + "art/generation-projectile-v1.json" + ], + "prompt_records": "prompts.json", + "conversion_recipe": "prepare_art.rs", + "conversion": "Fit alpha>=128 source bounds preserving aspect into one logical pixel margin; SD Triangle reduction and HD4x Lanczos3; binary final alpha128. Raw masters remain byte-identical to builtin outputs. Faint master glow outside the fitting bounds is not a separate in-game effect.", + "canvases": { + "equipment_sd": [ + 16, + 16 + ], + "equipment_hd": [ + 64, + 64 + ], + "projectile_sd": [ + 8, + 12 + ], + "projectile_hd": [ + 32, + 48 + ] + }, + "animation_frames": 1, + "palette": "Engine maps ordinary PNG artwork to original palette0..239; no reserved palette effects requested.", + "audio_recipe": "generate_audio.py", + "audio_provenance": "audio/provenance.json", + "outputs": [ + { + "path": "art/equipment-generated-source-v1.png", + "sha256": "669202bb78951419c9a1f61070be5dba7a55d8bfe096a071ae9cde86a8e26d3a" + }, + { + "path": "art/equipment-hd.png", + "sha256": "b906ee08176c1fe429d61fcb22fe0ea06a513d11efb063def6639809466274ea" + }, + { + "path": "art/equipment-sd.png", + "sha256": "61a9a9edc3fdb257e7f82e70c61d1fd3688728cd9c65cadf2b2e50e82fb789fd" + }, + { + "path": "art/projectile-generated-source-v1.png", + "sha256": "0bc76b678c0d2db073ccf76ba2162465b3beb7fd78d505d875c95c594daeb29d" + }, + { + "path": "art/projectile-hd.png", + "sha256": "1fb0ef6030151d68a477546711f8af120eb2563541d117147c6c2ee4f42f730d" + }, + { + "path": "art/projectile-sd.png", + "sha256": "80a98973fa5e887bec6d90e603b50cef693f7ea69d00b3b8608569a1e59e0776" + } + ], + "recipe_hashes": { + "prepare_art.rs": "bd1d0514317e5063989f2371b9ca9fd71756cb502b0066d9932f6f39031de3f6", + "generate_audio.py": "a554a3a0e2b8f5432705fe32006c87998984b6e27430ac5a77b163c313760fce" + } +} diff --git a/mods/iron_coast_depth_charge/art/equipment-generated-source-v1.png b/mods/iron_coast_depth_charge/art/equipment-generated-source-v1.png new file mode 100644 index 00000000..9a093294 Binary files /dev/null and b/mods/iron_coast_depth_charge/art/equipment-generated-source-v1.png differ diff --git a/mods/iron_coast_depth_charge/art/equipment-hd.png b/mods/iron_coast_depth_charge/art/equipment-hd.png new file mode 100644 index 00000000..7a533a2a Binary files /dev/null and b/mods/iron_coast_depth_charge/art/equipment-hd.png differ diff --git a/mods/iron_coast_depth_charge/art/equipment-sd.png b/mods/iron_coast_depth_charge/art/equipment-sd.png new file mode 100644 index 00000000..925c2a4b Binary files /dev/null and b/mods/iron_coast_depth_charge/art/equipment-sd.png differ diff --git a/mods/iron_coast_depth_charge/art/generation-equipment-v1.json b/mods/iron_coast_depth_charge/art/generation-equipment-v1.json new file mode 100644 index 00000000..f67e1a40 --- /dev/null +++ b/mods/iron_coast_depth_charge/art/generation-equipment-v1.json @@ -0,0 +1,13 @@ +{ + "tool": "built-in image_gen", + "builtin_original_output_path": "/home/quintine/.codex/generated_images/01a129a5-0efd-7c61-8556-922e09c8ea6c/exec-584bb594-5382-4b01-95ac-a78ce6f08c45.png", + "local_raw_copy": "equipment-generated-source-v1.png", + "raw_sha256": "669202bb78951419c9a1f61070be5dba7a55d8bfe096a071ae9cde86a8e26d3a", + "copy_sha256": "669202bb78951419c9a1f61070be5dba7a55d8bfe096a071ae9cde86a8e26d3a", + "exact_byte_equality": true, + "prompt_file": "prompt-equipment-v1.txt", + "prompt_sha256": "3ec33270866c302c452984e3dae48110f2b5438703b90a81dcf27bb3e06f31cb", + "gate_lease_id": "c2377ab5-8490-4d0c-8470-8bb44a22ff8f", + "gate_outcome": "success", + "created_utc": "2026-10-11T08:19:49.376523+00:00" +} diff --git a/mods/iron_coast_depth_charge/art/generation-projectile-v1.json b/mods/iron_coast_depth_charge/art/generation-projectile-v1.json new file mode 100644 index 00000000..2654fc5d --- /dev/null +++ b/mods/iron_coast_depth_charge/art/generation-projectile-v1.json @@ -0,0 +1,13 @@ +{ + "tool": "built-in image_gen", + "builtin_original_output_path": "/home/quintine/.codex/generated_images/01a129a5-0efd-7c61-8556-922e09c8ea6c/exec-4c2fdbca-d17c-4334-893e-963638433a60.png", + "local_raw_copy": "projectile-generated-source-v1.png", + "raw_sha256": "0bc76b678c0d2db073ccf76ba2162465b3beb7fd78d505d875c95c594daeb29d", + "copy_sha256": "0bc76b678c0d2db073ccf76ba2162465b3beb7fd78d505d875c95c594daeb29d", + "exact_byte_equality": true, + "prompt_file": "prompt-projectile-v1.txt", + "prompt_sha256": "1d314f5a738e58139d69fb67aa372022f32fa40ca32399953a67daf36b58cc46", + "gate_lease_id": "aeddcd06-2ad8-4327-b176-13d542e243ec", + "gate_outcome": "success", + "created_utc": "2026-10-11T08:20:28.206524+00:00" +} diff --git a/mods/iron_coast_depth_charge/art/projectile-generated-source-v1.png b/mods/iron_coast_depth_charge/art/projectile-generated-source-v1.png new file mode 100644 index 00000000..f0fd5e17 Binary files /dev/null and b/mods/iron_coast_depth_charge/art/projectile-generated-source-v1.png differ diff --git a/mods/iron_coast_depth_charge/art/projectile-hd.png b/mods/iron_coast_depth_charge/art/projectile-hd.png new file mode 100644 index 00000000..cefb62a9 Binary files /dev/null and b/mods/iron_coast_depth_charge/art/projectile-hd.png differ diff --git a/mods/iron_coast_depth_charge/art/projectile-sd.png b/mods/iron_coast_depth_charge/art/projectile-sd.png new file mode 100644 index 00000000..690b3d5a Binary files /dev/null and b/mods/iron_coast_depth_charge/art/projectile-sd.png differ diff --git a/mods/iron_coast_depth_charge/art/prompt-equipment-v1.txt b/mods/iron_coast_depth_charge/art/prompt-equipment-v1.txt new file mode 100644 index 00000000..62f11697 --- /dev/null +++ b/mods/iron_coast_depth_charge/art/prompt-equipment-v1.txt @@ -0,0 +1 @@ +Use case: stylized-concept. Asset type: a single new HD equipment sprite for the shop/inventory of a Raptor-style military science-fiction vertical shooter. Generate a Depth Charge launcher module: compact dark gunmetal armored double cradle holding two stout gray-blue naval charges side by side, their rounded copper-gray noses pointing exactly UP, two small burnt-orange safety bands and dark aft fins. Squat robust naval ordnance silhouette, readable top-down orthographic overhead view. Muted steel, deep navy-blue enamel, tiny orange safety accents, warm upper-left metal highlights, precise dark recesses. Match chunky industrial1990s military shooter readability with refined HD metal panels and bolts. Logical16x16 and64x64HD. Exactly one complete centered equipment assembly on genuinely transparent square canvas, minimum15percent transparent margin all sides, central65percent occupancy. No ship, water, ground, scenery, text, border, frame, floor, cast shadow, outside glow, separate loose charges or extra objects. Newly authored naval equipment. diff --git a/mods/iron_coast_depth_charge/art/prompt-projectile-v1.txt b/mods/iron_coast_depth_charge/art/prompt-projectile-v1.txt new file mode 100644 index 00000000..c3a6d898 --- /dev/null +++ b/mods/iron_coast_depth_charge/art/prompt-projectile-v1.txt @@ -0,0 +1 @@ +Use case: stylized-concept. Asset type: one new transparent naval depth-charge projectile sprite for a Raptor-style military science-fiction vertical shooter. Exactly one stout gray-blue metallic cylindrical charge traveling exactly UP, rounded copper-steel nose at top, a small burnt-orange safety band around the middle, dark navy barrel and three short robust aft stabilizer fins at bottom. Top-down orthographic overhead view; compact straight symmetrical body, width:height about2:3, no perspective or rotation. Logical8x12pixels and32x48HD. Crisp chunky silhouette readable in SD with refined small metal seams forHD, subdued1990s military shooter palette and upper-left lighting. One full object centered on a genuinely transparent square canvas with at least15percent clear margin all sides. No weapon launcher, aircraft, water, floor, smoke, flame, glow, shadow, text, border, frame, debris, additional objects or an explosion. Keep fins short and legible. diff --git a/mods/iron_coast_depth_charge/audio/fire.wav b/mods/iron_coast_depth_charge/audio/fire.wav new file mode 100644 index 00000000..c1e12436 Binary files /dev/null and b/mods/iron_coast_depth_charge/audio/fire.wav differ diff --git a/mods/iron_coast_depth_charge/audio/impact.wav b/mods/iron_coast_depth_charge/audio/impact.wav new file mode 100644 index 00000000..47dc506a Binary files /dev/null and b/mods/iron_coast_depth_charge/audio/impact.wav differ diff --git a/mods/iron_coast_depth_charge/audio/provenance.json b/mods/iron_coast_depth_charge/audio/provenance.json new file mode 100644 index 00000000..226c2105 --- /dev/null +++ b/mods/iron_coast_depth_charge/audio/provenance.json @@ -0,0 +1,34 @@ +{ + "tool": "original procedural Python synthesis", + "recipe": "generate_audio.py", + "source_recordings": [], + "deterministic_seed": "0xdc042681", + "outputs": [ + { + "file": "audio/fire.wav", + "sha256": "810ac71ce38d2012b6145baa8cb54f39d8eb4807e6c8b05528ad83d8123ff510", + "rate": 22050, + "channels": 1, + "bits": 16, + "frames": 4630, + "duration_seconds": 0.20997732426303856, + "peak": 15254, + "rms": 2870.510735780875, + "dc_mean": -13.693304535637148, + "clipped_samples": 0 + }, + { + "file": "audio/impact.wav", + "sha256": "aef495acd4c70c4d7dfe0868471a769624e23636659c2580fa867355cffc894a", + "rate": 22050, + "channels": 1, + "bits": 16, + "frames": 10143, + "duration_seconds": 0.46, + "peak": 17180, + "rms": 3110.238630183446, + "dc_mean": 2.850142955733018, + "clipped_samples": 0 + } + ] +} diff --git a/mods/iron_coast_depth_charge/content.json b/mods/iron_coast_depth_charge/content.json new file mode 100644 index 00000000..1bff0dbe --- /dev/null +++ b/mods/iron_coast_depth_charge/content.json @@ -0,0 +1,67 @@ +{ + "weapons": [ + { + "id": "iron_coast_depth_charge:projectile", + "name": "Depth Charge Projectile", + "damage": 72, + "speed": 6, + "cooldown": 48, + "behavior": "straight", + "target": "ground", + "offsets": [ + [ + 0, + -4 + ] + ], + "art": { + "png": "art/projectile-sd.png", + "hd_png": "art/projectile-hd.png", + "logical_width": 8, + "logical_height": 12, + "nearest": true + }, + "script": "scripts/weapon.rhai" + } + ], + "items": [ + { + "id": "iron_coast_depth_charge:equipment", + "name": "Depth Charge", + "price": 525000, + "max_count": 1, + "initial_count": 1, + "weapon": "iron_coast_depth_charge:projectile", + "special": true, + "consumable": false, + "art": { + "png": "art/equipment-sd.png", + "hd_png": "art/equipment-hd.png", + "logical_width": 16, + "logical_height": 16, + "nearest": true + }, + "description": "Ground/naval blast, 36px radius. Selectable reusable ground/naval special. Ctrl launches a slow charge; a real ground hit deals 72 damage and splashes at most three other ground enemies within 36 pixels (36 inner / 20 outer). Deliberate 2.06-second cadence; no air damage or ammunition consumed. Alt/Shift selects weapons; Space drops mega bombs." + } + ], + "sounds": [ + { + "id": "iron_coast_depth_charge:fire", + "name": "Depth Charge Fire", + "file": "audio/fire.wav", + "volume": 88, + "pan": 127, + "pitch": 128, + "priority": 1 + }, + { + "id": "iron_coast_depth_charge:impact", + "name": "Depth Charge Impact", + "file": "audio/impact.wav", + "volume": 82, + "pan": 127, + "pitch": 128, + "priority": 2 + } + ] +} diff --git a/mods/iron_coast_depth_charge/generate_audio.py b/mods/iron_coast_depth_charge/generate_audio.py new file mode 100644 index 00000000..9b52712e --- /dev/null +++ b/mods/iron_coast_depth_charge/generate_audio.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 +"""Reproduce original deterministic PCM sound effects; no external recordings.""" +import math, struct, wave, json, hashlib +from pathlib import Path +PACKAGE = 'iron_coast_depth_charge' +RATE = 22050 + +def render(kind): + rail = PACKAGE.endswith("railburst") + duration = (0.16 if kind == "fire" else 0.23) if rail else (0.21 if kind == "fire" else 0.46) + count = int(RATE * duration) + seed = 0x71AC092D if rail else 0xDC042681 + phase = 0.0 + samples = [] + for n in range(count): + t = n / RATE + progress = n / count + seed ^= (seed << 13) & 0xffffffff + seed ^= seed >> 17 + seed ^= (seed << 5) & 0xffffffff + seed &= 0xffffffff + noise = seed / 2147483648.0 - 1.0 + if rail: + frequency = (2100 * math.exp(-22*t) + 280) if kind == "fire" else (780 * math.exp(-14*t) + 95) + tone = 0.30*math.sin(phase) + 0.18*math.sin(phase*1.993) + noise*(0.44 if kind=="fire" else 0.34) + envelope = math.exp(-(32 if kind=="fire" else 19)*t) + else: + frequency = (175 * math.exp(-10*t) + 65) if kind=="fire" else (98*math.exp(-7*t)+42) + tone = math.sin(phase)*0.53 + math.sin(phase*1.47)*0.10 + noise*(0.26 if kind=="fire" else 0.35)*math.exp(-6*t) + envelope = math.exp(-(20 if kind=="fire" else 9)*t) + phase += 2*math.pi*frequency/RATE + attack = min(1.0, n/(RATE*0.002)) + tail = min(1.0, (count-n)/(RATE*0.015)) + samples.append(round(max(-1.0,min(1.0,tone*envelope*attack*tail))*22000)) + return samples + +if __name__ == "__main__": + root=Path(__file__).resolve().parent + rows=[] + for kind in ["fire","impact"]: + samples=render(kind) + path=root/"audio"/(kind+".wav") + with wave.open(str(path),"wb") as output: + output.setparams((1,2,RATE,0,"NONE","not compressed")) + output.writeframes(struct.pack("<"+"h"*len(samples),*samples)) + rows.append({"file":str(path.relative_to(root)),"sha256":hashlib.sha256(path.read_bytes()).hexdigest(),"rate":RATE,"channels":1,"bits":16,"frames":len(samples),"duration_seconds":len(samples)/RATE,"peak":max(abs(x) for x in samples),"rms":math.sqrt(sum(x*x for x in samples)/len(samples)),"dc_mean":sum(samples)/len(samples),"clipped_samples":sum(abs(x)>=32767 for x in samples)}) + (root/"audio"/"provenance.json").write_text(json.dumps({"tool":"original procedural Python synthesis","recipe":"generate_audio.py","source_recordings":[],"deterministic_seed":hex(0x71AC092D if PACKAGE.endswith("railburst") else 0xDC042681),"outputs":rows},indent=2)+"\n") diff --git a/mods/iron_coast_depth_charge/mod.toml b/mods/iron_coast_depth_charge/mod.toml new file mode 100644 index 00000000..a8dcab0e --- /dev/null +++ b/mods/iron_coast_depth_charge/mod.toml @@ -0,0 +1,7 @@ +id = "iron_coast_depth_charge" +name = "Depth Charge" +version = "1.0.0" +api_version = 1 +description = "Independent Iron Coast II selectable upgrade with SD/HD artwork and procedural fire/impact audio." +content = "content.json" +scripts = ["scripts/weapon.rhai"] diff --git a/mods/iron_coast_depth_charge/prepare_art.rs b/mods/iron_coast_depth_charge/prepare_art.rs new file mode 100644 index 00000000..61553298 --- /dev/null +++ b/mods/iron_coast_depth_charge/prepare_art.rs @@ -0,0 +1,76 @@ +const SHOT_W: u32 = 8; +const SHOT_H: u32 = 12; +// Fit untouched generated masters to shared logical canvases and four-times HD. +// Compile with this project's pinned image crate; see README for reproduction. +use image::{Rgba, RgbaImage, imageops}; +use std::{env, fs, path::Path}; +fn fit(source: &RgbaImage, w: u32, h: u32, scale: u32) -> RgbaImage { + let mut bounds = (source.width(), source.height(), 0, 0); + for (x, y, p) in source.enumerate_pixels() { + if p[3] >= 128 { + bounds.0 = bounds.0.min(x); + bounds.1 = bounds.1.min(y); + bounds.2 = bounds.2.max(x + 1); + bounds.3 = bounds.3.max(y + 1); + } + } + assert!( + bounds.2 > bounds.0 && bounds.3 > bounds.1, + "no meaningful source alpha" + ); + let crop = imageops::crop_imm( + source, + bounds.0, + bounds.1, + bounds.2 - bounds.0, + bounds.3 - bounds.1, + ) + .to_image(); + // Exactly one logical pixel of clear margin, shared across SD and HD. + let factor = ((w - 2) as f64 / crop.width() as f64).min((h - 2) as f64 / crop.height() as f64); + let nw = (crop.width() as f64 * factor).round().max(1.) as u32; + let nh = (crop.height() as f64 * factor).round().max(1.) as u32; + let filter = if scale == 1 { + imageops::FilterType::Triangle + } else { + imageops::FilterType::Lanczos3 + }; + let mut scaled = imageops::resize(&crop, nw * scale, nh * scale, filter); + for p in scaled.pixels_mut() { + if p[3] < 128 { + *p = Rgba([0, 0, 0, 0]); + } else { + p[3] = 255; + } + } + let mut out = RgbaImage::new(w * scale, h * scale); + imageops::overlay( + &mut out, + &scaled, + ((w * scale - nw * scale) / 2) as i64, + ((h * scale - nh * scale) / 2) as i64, + ); + out +} +fn main() { + let args: Vec<_> = env::args().collect(); + assert_eq!(args.len(), 2, "usage: prepare_art PACKAGE_DIRECTORY"); + let root = Path::new(&args[1]); + for (kind, w, h) in [("equipment", 16, 16), ("projectile", SHOT_W, SHOT_H)] { + let source = image::open(root.join(format!("art/{kind}-generated-source-v1.png"))) + .unwrap() + .into_rgba8(); + for (mode, scale) in [("sd", 1), ("hd", 4)] { + let image = fit(&source, w, h, scale); + let path = root.join(format!("art/{kind}-{mode}.png")); + image.save(&path).unwrap(); + println!("{} {}x{}", path.display(), image.width(), image.height()); + } + } + assert!( + fs::metadata(root.join("art/equipment-hd.png")) + .unwrap() + .len() + > 0 + ); +} diff --git a/mods/iron_coast_depth_charge/prompts.json b/mods/iron_coast_depth_charge/prompts.json new file mode 100644 index 00000000..d275ba51 --- /dev/null +++ b/mods/iron_coast_depth_charge/prompts.json @@ -0,0 +1,14 @@ +{ + "use_case": "stylized-concept", + "tool": "built-in image_gen", + "skill": "/home/quintine/.codex/skills/.system/imagegen/SKILL.md", + "style_reference_ids": [ + "102b6", + "101cb" + ], + "reference_role": "Original catalog was inspected for classic palette, silhouette and scale; no decoded reference is included in this mod. New generation uses the prepared textual art direction.", + "prompts": { + "equipment": "Use case: stylized-concept. Asset type: a single new HD equipment sprite for the shop/inventory of a Raptor-style military science-fiction vertical shooter. Generate a Depth Charge launcher module: compact dark gunmetal armored double cradle holding two stout gray-blue naval charges side by side, their rounded copper-gray noses pointing exactly UP, two small burnt-orange safety bands and dark aft fins. Squat robust naval ordnance silhouette, readable top-down orthographic overhead view. Muted steel, deep navy-blue enamel, tiny orange safety accents, warm upper-left metal highlights, precise dark recesses. Match chunky industrial1990s military shooter readability with refined HD metal panels and bolts. Logical16x16 and64x64HD. Exactly one complete centered equipment assembly on genuinely transparent square canvas, minimum15percent transparent margin all sides, central65percent occupancy. No ship, water, ground, scenery, text, border, frame, floor, cast shadow, outside glow, separate loose charges or extra objects. Newly authored naval equipment.", + "projectile": "Use case: stylized-concept. Asset type: one new transparent naval depth-charge projectile sprite for a Raptor-style military science-fiction vertical shooter. Exactly one stout gray-blue metallic cylindrical charge traveling exactly UP, rounded copper-steel nose at top, a small burnt-orange safety band around the middle, dark navy barrel and three short robust aft stabilizer fins at bottom. Top-down orthographic overhead view; compact straight symmetrical body, width:height about2:3, no perspective or rotation. Logical8x12pixels and32x48HD. Crisp chunky silhouette readable in SD with refined small metal seams forHD, subdued1990s military shooter palette and upper-left lighting. One full object centered on a genuinely transparent square canvas with at least15percent clear margin all sides. No weapon launcher, aircraft, water, floor, smoke, flame, glow, shadow, text, border, frame, debris, additional objects or an explosion. Keep fins short and legible." + } +} diff --git a/mods/iron_coast_depth_charge/scripts/weapon.rhai b/mods/iron_coast_depth_charge/scripts/weapon.rhai new file mode 100644 index 00000000..6aec29d6 --- /dev/null +++ b/mods/iron_coast_depth_charge/scripts/weapon.rhai @@ -0,0 +1,48 @@ +// Damage is collision-triggered. Empty space, aircraft and inactive equipment +// never start a blast. Native targeting handles the primary ground collision. +fn on_fire(event, state, random) { + if event.hostile { return #{commands: [], state: state}; } + let shots = if state.contains("shots") { state.shots % 100000 + 1 } else { 1 }; + let hits = if state.contains("hits") { state.hits } else { 0 }; + #{commands: [#{op: "play_sound", sound: "iron_coast_depth_charge:fire"}], + state: #{shots: shots, hits: hits}} +} + +fn on_hit(event, state, random) { + let shots = if state.contains("shots") { state.shots } else { 0 }; + let hits = if state.contains("hits") { state.hits % 100000 + 1 } else { 1 }; + let center_x = event.x; + let center_y = event.y; + for enemy in event.entities { + if enemy.entity == event.entity { + center_x = enemy.x + enemy.width / 2; + center_y = enemy.y + enemy.height / 2; + } + } + let commands = [#{op: "play_sound", sound: "iron_coast_depth_charge:impact"}, + #{op: "effect", kind: "ground_blast", x: center_x, y: center_y}]; + let struck = [event.entity]; + for neighbor in 0..3 { + let chosen = #{}; + let nearest = 1000000; + for enemy in event.entities { + let cx = enemy.x + enemy.width / 2; + let cy = enemy.y + enemy.height / 2; + if !enemy.ground || enemy.health <= 0 || struck.contains(enemy.entity) + || cx < 0 || cx >= 320 || cy < 0 || cy >= 200 { continue; } + let dx = cx - center_x; + let dy = cy - center_y; + let distance = dx * dx + dy * dy; + if distance <= 36 * 36 && distance < nearest { + chosen = #{entity: enemy.entity}; + nearest = distance; + } + } + if !chosen.contains("entity") { break; } + let damage = if nearest <= 16 * 16 { 36 } else { 20 }; + commands.push(#{op: "damage", entity: chosen.entity, amount: damage}); + struck.push(chosen.entity); + hits = hits % 100000 + 1; + } + #{commands: commands, state: #{shots: shots, hits: hits}} +} diff --git a/mods/iron_coast_depth_charge/validation/balance.json b/mods/iron_coast_depth_charge/validation/balance.json new file mode 100644 index 00000000..83246f88 --- /dev/null +++ b/mods/iron_coast_depth_charge/validation/balance.json @@ -0,0 +1,901 @@ +{ + "difficulty": 2, + "fixture_health": 100000, + "rate": "70/3 Hz", + "rows": [ + { + "damage": [ + 1344 + ], + "group_dps": 44.8, + "item": "iron_coast_railburst:equipment", + "price": 685000, + "scene": "aligned_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 1344 + ], + "group_dps": 44.8, + "item": "iron_coast_railburst:equipment", + "price": 685000, + "scene": "aligned_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "iron_coast_railburst:equipment", + "price": 685000, + "scene": "off_axis_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "iron_coast_railburst:equipment", + "price": 685000, + "scene": "off_axis_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 1344, + 1024, + 704, + 0 + ], + "group_dps": 102.4, + "item": "iron_coast_railburst:equipment", + "price": 685000, + "scene": "aligned_column", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 1344, + 0, + 0, + 0, + 0, + 0 + ], + "group_dps": 44.8, + "item": "iron_coast_railburst:equipment", + "price": 685000, + "scene": "ground_cluster", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 2038 + ], + "group_dps": 67.93333333333334, + "item": "iron_coast_railburst:equipment", + "price": 685000, + "scene": "aligned_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 2038 + ], + "group_dps": 67.93333333333334, + "item": "iron_coast_railburst:equipment", + "price": 685000, + "scene": "aligned_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "iron_coast_railburst:equipment", + "price": 685000, + "scene": "off_axis_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "iron_coast_railburst:equipment", + "price": 685000, + "scene": "off_axis_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 2040, + 1024, + 704, + 0 + ], + "group_dps": 125.6, + "item": "iron_coast_railburst:equipment", + "price": 685000, + "scene": "aligned_column", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 2038, + 0, + 0, + 0, + 0, + 0 + ], + "group_dps": 67.93333333333334, + "item": "iron_coast_railburst:equipment", + "price": 685000, + "scene": "ground_cluster", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "iron_coast_depth_charge:equipment", + "price": 525000, + "scene": "aligned_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 1080 + ], + "group_dps": 36.0, + "item": "iron_coast_depth_charge:equipment", + "price": 525000, + "scene": "aligned_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "iron_coast_depth_charge:equipment", + "price": 525000, + "scene": "off_axis_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "iron_coast_depth_charge:equipment", + "price": 525000, + "scene": "off_axis_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 1080, + 0, + 0, + 0 + ], + "group_dps": 36.0, + "item": "iron_coast_depth_charge:equipment", + "price": 525000, + "scene": "aligned_column", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 1080, + 540, + 300, + 300, + 0, + 0 + ], + "group_dps": 74.0, + "item": "iron_coast_depth_charge:equipment", + "price": 525000, + "scene": "ground_cluster", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 694 + ], + "group_dps": 23.133333333333333, + "item": "iron_coast_depth_charge:equipment", + "price": 525000, + "scene": "aligned_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 1774 + ], + "group_dps": 59.13333333333333, + "item": "iron_coast_depth_charge:equipment", + "price": 525000, + "scene": "aligned_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "iron_coast_depth_charge:equipment", + "price": 525000, + "scene": "off_axis_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "iron_coast_depth_charge:equipment", + "price": 525000, + "scene": "off_axis_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 1776, + 0, + 0, + 0 + ], + "group_dps": 59.2, + "item": "iron_coast_depth_charge:equipment", + "price": 525000, + "scene": "aligned_column", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 1774, + 540, + 300, + 300, + 0, + 0 + ], + "group_dps": 97.13333333333334, + "item": "iron_coast_depth_charge:equipment", + "price": 525000, + "scene": "ground_cluster", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 800 + ], + "group_dps": 26.666666666666668, + "item": "ion_lance:equipment", + "price": 425000, + "scene": "aligned_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 800 + ], + "group_dps": 26.666666666666668, + "item": "ion_lance:equipment", + "price": 425000, + "scene": "aligned_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "ion_lance:equipment", + "price": 425000, + "scene": "off_axis_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "ion_lance:equipment", + "price": 425000, + "scene": "off_axis_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 800, + 800, + 800, + 800 + ], + "group_dps": 106.66666666666667, + "item": "ion_lance:equipment", + "price": 425000, + "scene": "aligned_column", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 800, + 800, + 0, + 0, + 0, + 800 + ], + "group_dps": 80.0, + "item": "ion_lance:equipment", + "price": 425000, + "scene": "ground_cluster", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 1494 + ], + "group_dps": 49.8, + "item": "ion_lance:equipment", + "price": 425000, + "scene": "aligned_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 1494 + ], + "group_dps": 49.8, + "item": "ion_lance:equipment", + "price": 425000, + "scene": "aligned_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "ion_lance:equipment", + "price": 425000, + "scene": "off_axis_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "ion_lance:equipment", + "price": 425000, + "scene": "off_axis_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 1496, + 800, + 800, + 800 + ], + "group_dps": 129.86666666666667, + "item": "ion_lance:equipment", + "price": 425000, + "scene": "aligned_column", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 1494, + 800, + 0, + 0, + 0, + 800 + ], + "group_dps": 103.13333333333334, + "item": "ion_lance:equipment", + "price": 425000, + "scene": "ground_cluster", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 1248 + ], + "group_dps": 41.6, + "item": "lightning_cannon:equipment", + "price": 825000, + "scene": "aligned_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 1248 + ], + "group_dps": 41.6, + "item": "lightning_cannon:equipment", + "price": 825000, + "scene": "aligned_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "lightning_cannon:equipment", + "price": 825000, + "scene": "off_axis_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "lightning_cannon:equipment", + "price": 825000, + "scene": "off_axis_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 1248, + 780, + 468, + 312 + ], + "group_dps": 93.6, + "item": "lightning_cannon:equipment", + "price": 825000, + "scene": "aligned_column", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 1248, + 468, + 312, + 0, + 0, + 780 + ], + "group_dps": 93.6, + "item": "lightning_cannon:equipment", + "price": 825000, + "scene": "ground_cluster", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 1942 + ], + "group_dps": 64.73333333333333, + "item": "lightning_cannon:equipment", + "price": 825000, + "scene": "aligned_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 1942 + ], + "group_dps": 64.73333333333333, + "item": "lightning_cannon:equipment", + "price": 825000, + "scene": "aligned_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "lightning_cannon:equipment", + "price": 825000, + "scene": "off_axis_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "lightning_cannon:equipment", + "price": 825000, + "scene": "off_axis_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 1944, + 780, + 468, + 312 + ], + "group_dps": 116.8, + "item": "lightning_cannon:equipment", + "price": 825000, + "scene": "aligned_column", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 1942, + 468, + 312, + 0, + 0, + 780 + ], + "group_dps": 116.73333333333333, + "item": "lightning_cannon:equipment", + "price": 825000, + "scene": "ground_cluster", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 694 + ], + "group_dps": 23.133333333333333, + "item": "base:forward_guns", + "price": 12000, + "scene": "aligned_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 694 + ], + "group_dps": 23.133333333333333, + "item": "base:forward_guns", + "price": 12000, + "scene": "aligned_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "base:forward_guns", + "price": 12000, + "scene": "off_axis_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "base:forward_guns", + "price": 12000, + "scene": "off_axis_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 696, + 0, + 0, + 0 + ], + "group_dps": 23.2, + "item": "base:forward_guns", + "price": 12000, + "scene": "aligned_column", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 694, + 0, + 0, + 0, + 0, + 0 + ], + "group_dps": 23.133333333333333, + "item": "base:forward_guns", + "price": 12000, + "scene": "ground_cluster", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 2400 + ], + "group_dps": 80.0, + "item": "base:death_ray", + "price": 950000, + "scene": "aligned_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 2400 + ], + "group_dps": 80.0, + "item": "base:death_ray", + "price": 950000, + "scene": "aligned_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "base:death_ray", + "price": 950000, + "scene": "off_axis_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "base:death_ray", + "price": 950000, + "scene": "off_axis_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 2400, + 0, + 0, + 0 + ], + "group_dps": 80.0, + "item": "base:death_ray", + "price": 950000, + "scene": "aligned_column", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 2400, + 0, + 0, + 0, + 0, + 0 + ], + "group_dps": 80.0, + "item": "base:death_ray", + "price": 950000, + "scene": "ground_cluster", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 8000 + ], + "group_dps": 266.6666666666667, + "item": "base:forward_laser", + "price": 1750000, + "scene": "aligned_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 8000 + ], + "group_dps": 266.6666666666667, + "item": "base:forward_laser", + "price": 1750000, + "scene": "aligned_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "base:forward_laser", + "price": 1750000, + "scene": "off_axis_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "base:forward_laser", + "price": 1750000, + "scene": "off_axis_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 8000, + 0, + 0, + 0 + ], + "group_dps": 266.6666666666667, + "item": "base:forward_laser", + "price": 1750000, + "scene": "aligned_column", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 8000, + 0, + 0, + 0, + 0, + 0 + ], + "group_dps": 266.6666666666667, + "item": "base:forward_laser", + "price": 1750000, + "scene": "ground_cluster", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + } + ], + "target_size": [ + 32, + 32 + ], + "package": "iron_coast_depth_charge", + "final_price": 525000, + "resale_price": 262500, + "pricing_reason": "36 ground single-target DPS and74 finite mixed-cluster ground DPS, zero air/off-axis damage, 48-tick slow cadence. Above425,000 Ion Lance26.67 single and285,000 Seeker Swarm23.4 single for local ground utility, but slower and ground-only. Below825,000 Lightning Cannon41.6 air/ground single and93.6 chain,950,000 Death Ray80 single,1,750,000 Forward Laser266.67. Forward guns add normal primary damage, not unbounded splash.", + "observation": "Actual World::step700ticks; deterministic stationary32x32 health100000 fixtures, ground scroll canceled after normal collision pass. Native original and new weapons unmodified. Forward-gun combination separately observed. Does not measure campaign difficulty or moving-target accuracy.", + "source_input_hashes": { + "mod.toml": "b0acc9149813522720ca6fc1e246a5a383e8641c89f7623558a6a5baa0e2d892", + "content.json": "1806d8451b6734096609c2188e42e002de9c82d7ac19361f51a329fe066ca07e", + "scripts/weapon.rhai": "23eb0d61ce768e6d8392b394c9274deee7ac5624915c4d3bae40e2050fef4d66" + } +} diff --git a/mods/iron_coast_depth_charge/validation/review.json b/mods/iron_coast_depth_charge/validation/review.json new file mode 100644 index 00000000..fec174b0 --- /dev/null +++ b/mods/iron_coast_depth_charge/validation/review.json @@ -0,0 +1,283 @@ +{ + "package": "iron_coast_depth_charge", + "portable_tests": { + "file": "tests/iron_coast_stage2_weapons.rs", + "passed": 9, + "balance_integration_passed": 1, + "cases": [ + "independent activation and coexistence", + "shop half-price resale and duplicate rejection", + "rail aligned contact finite penetration", + "depth contact-only ground radius/falloff/cap", + "unselected/idle/misses without explosions", + "serialized state/RNG continuation and invalid-command rollback", + "explicit cooldown/reusable inventory", + "lethal primary contact continuation", + "full-slot inventory preservation", + "disable/re-enable saved equipment, exact mod pins and script state preserved without altering save" + ] + }, + "native_decoder_blitter_audio": { + "assets": [ + { + "all_scales": [ + { + "height": 16, + "painted": 147, + "scale": 1, + "width": 16 + }, + { + "height": 32, + "painted": 588, + "scale": 2, + "width": 32 + }, + { + "height": 48, + "painted": 1323, + "scale": 3, + "width": 48 + }, + { + "height": 64, + "painted": 2352, + "scale": 4, + "width": 64 + } + ], + "clear_corner_alpha": true, + "frame": 0, + "frames": 1, + "hd": false, + "kind": "equipment", + "logical_canvas": [ + 16, + 16 + ], + "ordinary_palette_only": true, + "owner": "iron_coast_depth_charge", + "physical_canvas": [ + 16, + 16 + ] + }, + { + "all_scales": [ + { + "height": 16, + "painted": 141, + "scale": 1, + "width": 16 + }, + { + "height": 32, + "painted": 561, + "scale": 2, + "width": 32 + }, + { + "height": 48, + "painted": 1252, + "scale": 3, + "width": 48 + }, + { + "height": 64, + "painted": 2236, + "scale": 4, + "width": 64 + } + ], + "clear_corner_alpha": true, + "frame": 0, + "frames": 1, + "hd": true, + "kind": "equipment", + "logical_canvas": [ + 16, + 16 + ], + "ordinary_palette_only": true, + "owner": "iron_coast_depth_charge", + "physical_canvas": [ + 64, + 64 + ] + }, + { + "all_scales": [ + { + "height": 12, + "painted": 34, + "scale": 1, + "width": 8 + }, + { + "height": 24, + "painted": 136, + "scale": 2, + "width": 16 + }, + { + "height": 36, + "painted": 306, + "scale": 3, + "width": 24 + }, + { + "height": 48, + "painted": 544, + "scale": 4, + "width": 32 + } + ], + "clear_corner_alpha": true, + "frame": 0, + "frames": 1, + "hd": false, + "kind": "projectile", + "logical_canvas": [ + 8, + 12 + ], + "ordinary_palette_only": true, + "owner": "iron_coast_depth_charge", + "physical_canvas": [ + 8, + 12 + ] + }, + { + "all_scales": [ + { + "height": 12, + "painted": 28, + "scale": 1, + "width": 8 + }, + { + "height": 24, + "painted": 110, + "scale": 2, + "width": 16 + }, + { + "height": 36, + "painted": 248, + "scale": 3, + "width": 24 + }, + { + "height": 48, + "painted": 444, + "scale": 4, + "width": 32 + } + ], + "clear_corner_alpha": true, + "frame": 0, + "frames": 1, + "hd": true, + "kind": "projectile", + "logical_canvas": [ + 8, + 12 + ], + "ordinary_palette_only": true, + "owner": "iron_coast_depth_charge", + "physical_canvas": [ + 32, + 48 + ] + } + ], + "audio": [ + { + "capture": "iron_coast_depth_charge-fire-mixed.wav", + "decoded_samples": 4630, + "decoder": "SoundBank::mod_sample", + "id": "iron_coast_depth_charge:fire", + "mixed_channels": 2, + "mixed_rate": 44100, + "mixer": "Mixer::sample through SoundBank::queue_mod", + "nonzero_output_samples": 11448, + "peak": 2688, + "source_rate": 22050 + }, + { + "capture": "iron_coast_depth_charge-impact-mixed.wav", + "decoded_samples": 10143, + "decoder": "SoundBank::mod_sample", + "id": "iron_coast_depth_charge:impact", + "mixed_channels": 2, + "mixed_rate": 44100, + "mixer": "Mixer::sample through SoundBank::queue_mod", + "nonzero_output_samples": 27200, + "peak": 3200, + "source_rate": 22050 + } + ], + "scope": "Public PNG decoder, same Host art normalization, indexed Canvas blitter and actual SoundBank/Mixer. Synthetic backgrounds; no live desktop/gameplay claim." + }, + "visual_inspection": "Inspected original style references separately, all four raw masters and actual indexed SD/HD gallery at logical and4x canvases. Readable compact silhouettes, neutral metal with cyan rail/orange charge roles, transparent borders. SD colors intentionally simplified by reduction; no reserved palette effects. Captures use synthetic palette backgrounds, not a live mission or actual shop pane.", + "limitations": [ + "Private desktop Host/shop screenshots are delegated to root integration review.", + "Native point collision may skip exceptionally tiny targets for the speed16 rail shot.", + "Terrain cells receive native primary damage but are not available as scripted penetration/splash snapshots." + ], + "evidence_gallery_sha256": "c1b5d6ad1d286eb17fab1067143222a6071dff5e70a35d904757275767ec5a26", + "reproduction_byte_equality": { + "art/equipment-sd.png": true, + "art/equipment-hd.png": true, + "art/projectile-sd.png": true, + "art/projectile-hd.png": true, + "audio/fire.wav": true, + "audio/impact.wav": true + }, + "native_build_bindings": { + "libraries": { + "raptor_replica": { + "path": "/home/quintine/Projects/RaptorReplica/RustRaptor/target/debug/libraptor_replica.rlib", + "sha256": "4fd737d3c6c808fd5de1ecfc1f9a41b0ef37e82dc1a186f005b8dc9c2360ccd5" + }, + "image": { + "path": "/home/quintine/Projects/RaptorReplica/RustRaptor/target/debug/deps/libimage-25e356663b4aa6b0.rlib", + "sha256": "ea709066ea4c8c625efe3bf7f3741d7a68abfb7ef4b304837f1f0da20e5e2d58" + }, + "serde_json": { + "path": "/home/quintine/Projects/RaptorReplica/RustRaptor/target/debug/deps/libserde_json-1d17875658175ae0.rlib", + "sha256": "e463d4b704418cc5a168d73818662f7a801a77d96e8ef3d6a121e90375e4532f" + } + }, + "review_source_sha256": "32c4e836b7a01d159251427b2203dcf0d40f43bebef1def2f13a571e845d8ca3", + "validation_cases": [ + { + "enabled": [ + "iron_coast_railburst" + ], + "stdout": "Validated 1 mods; 0 override(s)", + "stderr": "", + "exit_code": 0 + }, + { + "enabled": [ + "iron_coast_depth_charge" + ], + "stdout": "Validated 1 mods; 0 override(s)", + "stderr": "", + "exit_code": 0 + }, + { + "enabled": [ + "iron_coast_railburst", + "iron_coast_depth_charge" + ], + "stdout": "Validated 2 mods; 0 override(s)", + "stderr": "", + "exit_code": 0 + } + ], + "scope": "Frozen package copies; public asset, indexed Canvas and audio APIs; no live desktop or pilot mutations." + } +} diff --git a/mods/iron_coast_railburst/README.md b/mods/iron_coast_railburst/README.md new file mode 100644 index 00000000..a00c6f01 --- /dev/null +++ b/mods/iron_coast_railburst/README.md @@ -0,0 +1,63 @@ +# Railburst Cannon 1.0.0 + +Enable **Railburst Cannon** in Mods, apply at the main menu, then buy it in the +shop for **685,000 credits**. It is an independent API 1 mod without dependencies +or overrides. Maximum one; resale returns 342,500 credits. It occupies a normal +inventory slot and never replaces or deletes another upgrade. + +This is a **selectable, reusable special weapon**. Select it in Inventory or with +Alt/Shift during a mission, then hold Ctrl to fire. Space still drops an owned +mega bomb. Merely owning or selecting the cannon does not auto-fire it. No +ammunition is consumed; always-equipped forward guns can fire alongside it. + +A native straight rail slug travels 16 logical pixels per simulation tick, +dealing 42 damage on its first real air or ground collision. That contact +penetrates at most two further living enemies ahead for 32 and 22 damage. Their +centers must stay within 12 pixels of the original firing x coordinate and within +160 pixels ahead of the first target's center. The nearest forward target wins; +stable entity order breaks ties. The primary projectile retires normally, while +the two additional contacts resolve through bounded `on_hit` damage commands. +This is finite contact-triggered penetration rather than a persistent beam. + +The cooldown is 22 ticks, about 0.94 seconds at the original 70/3 Hz simulation +rate. Aim carefully: it does not home, acquire offscreen enemies, turn sideways +or clear the screen. Native point collision can miss exceptionally tiny targets +between its 16-pixel steps. Destructible terrain receives native primary damage; +the API exposes enemy snapshots, so terrain does not trigger scripted penetration. +Small air/ground impacts and impact audio occur only after an enemy contact; +empty-space shots produce fire audio and the projectile, without muzzle blasts. + +The SD equipment/projectile canvases are 16×16 and 4×20, with detailed 4× HD +variants at 64×64 and 16×80. Toggle HD artwork in Options. Both modes share logical +placement and gameplay dimensions; the single-frame master has no animation +misalignment. [Artwork provenance](art-provenance.json) binds untouched built-in +generated masters, prompts, output hashes and the preparation recipe. Generated +masters, final sprites, original procedural WAVs and reproduction inputs belong +to this package; decoded original reference art is kept outside it. + +`python3 generate_audio.py` reproduces the firing crack and short metal impact. +`prepare_art.rs` reproduces SD/HD fitting from the included source PNGs. The +shared read-only [native review helper](validation/review.py) builds this project, +validates both independent packages and writes indexed art/audio captures to an +explicit evidence directory. It requires the included original catalog for the +engine palette and instruments and never changes pilots or selected mods. + +From the RustRaptor directory: + +```sh +cargo test --locked --no-default-features --test iron_coast_stage2_weapons +cargo run --locked --no-default-features -- --data data --mods mods \ + --validate-mods iron_coast_railburst +IRON_COAST_STAGE2_BALANCE_REPORT=/tmp/stage2-balance.json \ + cargo test --locked --no-default-features --test iron_coast_stage2_weapons \ + real_catalog_700_tick_balance_and_coexistence_report -- --ignored --nocapture +python3 mods/iron_coast_railburst/validation/review.py --output /tmp/stage2-native +``` + +See [validation/balance.json](validation/balance.json) for controlled 700-tick +single-target, off-axis, aligned-column, mixed-cluster and forward-gun combination +observations, and [validation/review.json](validation/review.json) for the tested +scope. These stationary fixtures establish the price/role comparison, not a claim +about every campaign encounter. Script counters and RNG checkpoints serialize +normally with pilot state; rejected callback commands roll back the whole tick. +Read the [API](../../docs/modding-api.md) for save compatibility and sandbox limits. diff --git a/mods/iron_coast_railburst/art-provenance.json b/mods/iron_coast_railburst/art-provenance.json new file mode 100644 index 00000000..7dee812f --- /dev/null +++ b/mods/iron_coast_railburst/art-provenance.json @@ -0,0 +1,68 @@ +{ + "tool": "built-in image_gen through imagegen skill", + "skill": "/home/quintine/.codex/skills/.system/imagegen/SKILL.md", + "style_reference_catalog_ids": [ + "102b6", + "101cb" + ], + "style_reference_delivery": "Original catalog inspected separately; decoded originals are not included in this mod. The generated artwork is newly authored.", + "source_records": [ + "art/generation-equipment-v1.json", + "art/generation-projectile-v1.json" + ], + "prompt_records": "prompts.json", + "conversion_recipe": "prepare_art.rs", + "conversion": "Fit alpha>=128 source bounds preserving aspect into one logical pixel margin; SD Triangle reduction and HD4x Lanczos3; binary final alpha128. Raw masters remain byte-identical to builtin outputs. Faint master glow outside the fitting bounds is not a separate in-game effect.", + "canvases": { + "equipment_sd": [ + 16, + 16 + ], + "equipment_hd": [ + 64, + 64 + ], + "projectile_sd": [ + 4, + 20 + ], + "projectile_hd": [ + 16, + 80 + ] + }, + "animation_frames": 1, + "palette": "Engine maps ordinary PNG artwork to original palette0..239; no reserved palette effects requested.", + "audio_recipe": "generate_audio.py", + "audio_provenance": "audio/provenance.json", + "outputs": [ + { + "path": "art/equipment-generated-source-v1.png", + "sha256": "2576062b00f8bc29078b84ff69db9cb578dfcdc08911ba4bdf90038b2c94c834" + }, + { + "path": "art/equipment-hd.png", + "sha256": "afe40548427f4bc1c29a4261f4cdc1ed559d8b11e72a849cde561e9ca7429f6a" + }, + { + "path": "art/equipment-sd.png", + "sha256": "c1dc5c80e9034ae742370d852c42fad5d333fc1e1e461e2a7ad23e9fe04045cf" + }, + { + "path": "art/projectile-generated-source-v1.png", + "sha256": "46d958d55814c9c9fe81cd6d22847f82e1e81f8ed6ca2ff855d155c7e3281d87" + }, + { + "path": "art/projectile-hd.png", + "sha256": "367f8720f69439c68552ada49f52e279ecae69a989747f16dde363c6eebb112e" + }, + { + "path": "art/projectile-sd.png", + "sha256": "91958044ce398a11ed56dfe8073d09d1dd718552a481f69d349fd0490d5211cf" + } + ], + "recipe_hashes": { + "prepare_art.rs": "f1ac3c61649ed9327f4169b3c0aaee3faad4cc0ee7d2c798818a2555bd9e112e", + "generate_audio.py": "1813efe19cd4c0a0914b7e41d41a5966cfcf246fabd0d318b60a65e184d3da96" + } +} diff --git a/mods/iron_coast_railburst/art/equipment-generated-source-v1.png b/mods/iron_coast_railburst/art/equipment-generated-source-v1.png new file mode 100644 index 00000000..1c7f6813 Binary files /dev/null and b/mods/iron_coast_railburst/art/equipment-generated-source-v1.png differ diff --git a/mods/iron_coast_railburst/art/equipment-hd.png b/mods/iron_coast_railburst/art/equipment-hd.png new file mode 100644 index 00000000..a6999e76 Binary files /dev/null and b/mods/iron_coast_railburst/art/equipment-hd.png differ diff --git a/mods/iron_coast_railburst/art/equipment-sd.png b/mods/iron_coast_railburst/art/equipment-sd.png new file mode 100644 index 00000000..32d56765 Binary files /dev/null and b/mods/iron_coast_railburst/art/equipment-sd.png differ diff --git a/mods/iron_coast_railburst/art/generation-equipment-v1.json b/mods/iron_coast_railburst/art/generation-equipment-v1.json new file mode 100644 index 00000000..a7029504 --- /dev/null +++ b/mods/iron_coast_railburst/art/generation-equipment-v1.json @@ -0,0 +1,13 @@ +{ + "tool": "built-in image_gen", + "builtin_original_output_path": "/home/quintine/.codex/generated_images/01a129a5-0efd-7c61-8556-922e09c8ea6c/exec-cdcc2180-8730-4d67-b4f3-7772fc9d997e.png", + "local_raw_copy": "equipment-generated-source-v1.png", + "raw_sha256": "2576062b00f8bc29078b84ff69db9cb578dfcdc08911ba4bdf90038b2c94c834", + "copy_sha256": "2576062b00f8bc29078b84ff69db9cb578dfcdc08911ba4bdf90038b2c94c834", + "exact_byte_equality": true, + "prompt_file": "prompt-equipment-v1.txt", + "prompt_sha256": "b4841b8ab5ea187f3158356a03d7b533f806acd4da8256cc6664e70ddeb292ad", + "gate_lease_id": "d99da2b6-219d-44e0-babb-5ffcc0bc75d1", + "gate_outcome": "success", + "created_utc": "2026-10-11T08:17:17.156727+00:00" +} diff --git a/mods/iron_coast_railburst/art/generation-projectile-v1.json b/mods/iron_coast_railburst/art/generation-projectile-v1.json new file mode 100644 index 00000000..f8e81ecc --- /dev/null +++ b/mods/iron_coast_railburst/art/generation-projectile-v1.json @@ -0,0 +1,13 @@ +{ + "tool": "built-in image_gen", + "builtin_original_output_path": "/home/quintine/.codex/generated_images/01a129a5-0efd-7c61-8556-922e09c8ea6c/exec-a4ce4dec-d02f-43b9-9fd0-e95b61fc25de.png", + "local_raw_copy": "projectile-generated-source-v1.png", + "raw_sha256": "46d958d55814c9c9fe81cd6d22847f82e1e81f8ed6ca2ff855d155c7e3281d87", + "copy_sha256": "46d958d55814c9c9fe81cd6d22847f82e1e81f8ed6ca2ff855d155c7e3281d87", + "exact_byte_equality": true, + "prompt_file": "prompt-projectile-v1.txt", + "prompt_sha256": "55c7d44e0de631fb7ea5f98d07ec3c1581d14e9c87e5d4622ac041a72f582dbf", + "gate_lease_id": "213076b0-b1e0-4b92-a8d4-43f8ef8b1887", + "gate_outcome": "success", + "created_utc": "2026-10-11T08:18:46.812447+00:00" +} diff --git a/mods/iron_coast_railburst/art/projectile-generated-source-v1.png b/mods/iron_coast_railburst/art/projectile-generated-source-v1.png new file mode 100644 index 00000000..32cf8619 Binary files /dev/null and b/mods/iron_coast_railburst/art/projectile-generated-source-v1.png differ diff --git a/mods/iron_coast_railburst/art/projectile-hd.png b/mods/iron_coast_railburst/art/projectile-hd.png new file mode 100644 index 00000000..83e79231 Binary files /dev/null and b/mods/iron_coast_railburst/art/projectile-hd.png differ diff --git a/mods/iron_coast_railburst/art/projectile-sd.png b/mods/iron_coast_railburst/art/projectile-sd.png new file mode 100644 index 00000000..0532ec54 Binary files /dev/null and b/mods/iron_coast_railburst/art/projectile-sd.png differ diff --git a/mods/iron_coast_railburst/art/prompt-equipment-v1.txt b/mods/iron_coast_railburst/art/prompt-equipment-v1.txt new file mode 100644 index 00000000..53551799 --- /dev/null +++ b/mods/iron_coast_railburst/art/prompt-equipment-v1.txt @@ -0,0 +1 @@ +Use case: stylized-concept. Asset type: a single new HD equipment sprite for the shop/inventory of a Raptor-style military science-fiction vertical shooter. Generate a Railburst Cannon: compact armored gunmetal rectangular breech with a single short central accelerator muzzle pointing exactly UP, two restrained cyan induction rails along its sides, a small red service plate and bolted dark gray mounting base. Top-down orthographic overhead view, symmetrical readable silhouette with chunky industrial 1990s shooter forms, warm upper-left metal highlights and deep painted recesses. Fine machined detail for HD, clean hard silhouette readable at 16x16 logical pixels and64x64HD. Exactly one complete centered object on a genuinely transparent square canvas, with at least15percent transparent margin around the entire object. The silhouette should fill the central65percent of the canvas. No floor, black background, scene, ship, words, border, frame, cast shadow, large glow or extra objects. Muted gunmetal/steel, narrow cyan accents, tiny red service plate; no candy colors. Newly authored equipment, not a duplicate of any existing weapon. diff --git a/mods/iron_coast_railburst/art/prompt-projectile-v1.txt b/mods/iron_coast_railburst/art/prompt-projectile-v1.txt new file mode 100644 index 00000000..875ba939 --- /dev/null +++ b/mods/iron_coast_railburst/art/prompt-projectile-v1.txt @@ -0,0 +1 @@ +Use case: stylized-concept. Asset type: one new transparent railgun projectile sprite for a Raptor-style military science-fiction vertical shooter. A single extremely narrow vertical ballistic rail slug traveling exactly UP: sharp pale steel pointed nose, short bright ivory core, a restrained slim cyan sheath, and a tapered blue-gray wake downward. It is a solid compact dart with a visible bright tip and a modest bounded trail, not a screen-length beam, not lightning, not an explosion. Top-down orthographic overhead view, perfectly straight and centered. Subject width:height about1:5; logical canvas4x20 pixels and16x80HD. Chunky crisp small-game silhouette with refined original metal/light detail forHD. One complete object on a genuinely transparent square canvas, generous blank side areas, at least15percent top/bottom transparent margin. No gun, spacecraft, text, border, background, shadow, smoke cloud, detached sparkles, branching, multiple objects or outside glow. Match restrained pale steel/ivory/cyan highlights of a classic1990s military shooter. diff --git a/mods/iron_coast_railburst/audio/fire.wav b/mods/iron_coast_railburst/audio/fire.wav new file mode 100644 index 00000000..c99a1baf Binary files /dev/null and b/mods/iron_coast_railburst/audio/fire.wav differ diff --git a/mods/iron_coast_railburst/audio/impact.wav b/mods/iron_coast_railburst/audio/impact.wav new file mode 100644 index 00000000..a3f9318b Binary files /dev/null and b/mods/iron_coast_railburst/audio/impact.wav differ diff --git a/mods/iron_coast_railburst/audio/provenance.json b/mods/iron_coast_railburst/audio/provenance.json new file mode 100644 index 00000000..69c918c2 --- /dev/null +++ b/mods/iron_coast_railburst/audio/provenance.json @@ -0,0 +1,34 @@ +{ + "tool": "original procedural Python synthesis", + "recipe": "generate_audio.py", + "source_recordings": [], + "deterministic_seed": "0x71ac092d", + "outputs": [ + { + "file": "audio/fire.wav", + "sha256": "fbc829573e92ec4a824bb4ba00a3dff53c866685c0ff1270335d896a6cabdf7c", + "rate": 22050, + "channels": 1, + "bits": 16, + "frames": 3528, + "duration_seconds": 0.16, + "peak": 16253, + "rms": 2346.20609017488, + "dc_mean": 19.44331065759637, + "clipped_samples": 0 + }, + { + "file": "audio/impact.wav", + "sha256": "4a44c8f561c230f519ed926d849e7e0bff1db2f11cf705c67c70d2eccb1c8221", + "rate": 22050, + "channels": 1, + "bits": 16, + "frames": 5071, + "duration_seconds": 0.22997732426303855, + "peak": 15667, + "rms": 2250.0482951936838, + "dc_mean": 14.399132321041215, + "clipped_samples": 0 + } + ] +} diff --git a/mods/iron_coast_railburst/content.json b/mods/iron_coast_railburst/content.json new file mode 100644 index 00000000..063d3a7c --- /dev/null +++ b/mods/iron_coast_railburst/content.json @@ -0,0 +1,67 @@ +{ + "weapons": [ + { + "id": "iron_coast_railburst:projectile", + "name": "Railburst Cannon Projectile", + "damage": 42, + "speed": 16, + "cooldown": 22, + "behavior": "straight", + "target": "all", + "offsets": [ + [ + 0, + -4 + ] + ], + "art": { + "png": "art/projectile-sd.png", + "hd_png": "art/projectile-hd.png", + "logical_width": 4, + "logical_height": 20, + "nearest": true + }, + "script": "scripts/weapon.rhai" + } + ], + "items": [ + { + "id": "iron_coast_railburst:equipment", + "name": "Railburst Cannon", + "price": 685000, + "max_count": 1, + "initial_count": 1, + "weapon": "iron_coast_railburst:projectile", + "special": true, + "consumable": false, + "art": { + "png": "art/equipment-sd.png", + "hd_png": "art/equipment-hd.png", + "logical_width": 16, + "logical_height": 16, + "nearest": true + }, + "description": "Pierces up to 3 aligned targets. Selectable reusable special. Ctrl fires a fast rail slug at air or ground targets. A real hit penetrates up to two more enemies ahead within a narrow 24-pixel lane, with falling damage (42/32/22). Best against aligned armor; no ammunition consumed. Alt/Shift selects weapons; Space drops mega bombs." + } + ], + "sounds": [ + { + "id": "iron_coast_railburst:fire", + "name": "Railburst Cannon Fire", + "file": "audio/fire.wav", + "volume": 88, + "pan": 127, + "pitch": 128, + "priority": 1 + }, + { + "id": "iron_coast_railburst:impact", + "name": "Railburst Cannon Impact", + "file": "audio/impact.wav", + "volume": 82, + "pan": 127, + "pitch": 128, + "priority": 2 + } + ] +} diff --git a/mods/iron_coast_railburst/generate_audio.py b/mods/iron_coast_railburst/generate_audio.py new file mode 100644 index 00000000..4cb5efe8 --- /dev/null +++ b/mods/iron_coast_railburst/generate_audio.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 +"""Reproduce original deterministic PCM sound effects; no external recordings.""" +import math, struct, wave, json, hashlib +from pathlib import Path +PACKAGE = 'iron_coast_railburst' +RATE = 22050 + +def render(kind): + rail = PACKAGE.endswith("railburst") + duration = (0.16 if kind == "fire" else 0.23) if rail else (0.21 if kind == "fire" else 0.46) + count = int(RATE * duration) + seed = 0x71AC092D if rail else 0xDC042681 + phase = 0.0 + samples = [] + for n in range(count): + t = n / RATE + progress = n / count + seed ^= (seed << 13) & 0xffffffff + seed ^= seed >> 17 + seed ^= (seed << 5) & 0xffffffff + seed &= 0xffffffff + noise = seed / 2147483648.0 - 1.0 + if rail: + frequency = (2100 * math.exp(-22*t) + 280) if kind == "fire" else (780 * math.exp(-14*t) + 95) + tone = 0.30*math.sin(phase) + 0.18*math.sin(phase*1.993) + noise*(0.44 if kind=="fire" else 0.34) + envelope = math.exp(-(32 if kind=="fire" else 19)*t) + else: + frequency = (175 * math.exp(-10*t) + 65) if kind=="fire" else (98*math.exp(-7*t)+42) + tone = math.sin(phase)*0.53 + math.sin(phase*1.47)*0.10 + noise*(0.26 if kind=="fire" else 0.35)*math.exp(-6*t) + envelope = math.exp(-(20 if kind=="fire" else 9)*t) + phase += 2*math.pi*frequency/RATE + attack = min(1.0, n/(RATE*0.002)) + tail = min(1.0, (count-n)/(RATE*0.015)) + samples.append(round(max(-1.0,min(1.0,tone*envelope*attack*tail))*22000)) + return samples + +if __name__ == "__main__": + root=Path(__file__).resolve().parent + rows=[] + for kind in ["fire","impact"]: + samples=render(kind) + path=root/"audio"/(kind+".wav") + with wave.open(str(path),"wb") as output: + output.setparams((1,2,RATE,0,"NONE","not compressed")) + output.writeframes(struct.pack("<"+"h"*len(samples),*samples)) + rows.append({"file":str(path.relative_to(root)),"sha256":hashlib.sha256(path.read_bytes()).hexdigest(),"rate":RATE,"channels":1,"bits":16,"frames":len(samples),"duration_seconds":len(samples)/RATE,"peak":max(abs(x) for x in samples),"rms":math.sqrt(sum(x*x for x in samples)/len(samples)),"dc_mean":sum(samples)/len(samples),"clipped_samples":sum(abs(x)>=32767 for x in samples)}) + (root/"audio"/"provenance.json").write_text(json.dumps({"tool":"original procedural Python synthesis","recipe":"generate_audio.py","source_recordings":[],"deterministic_seed":hex(0x71AC092D if PACKAGE.endswith("railburst") else 0xDC042681),"outputs":rows},indent=2)+"\n") diff --git a/mods/iron_coast_railburst/mod.toml b/mods/iron_coast_railburst/mod.toml new file mode 100644 index 00000000..842bd9dc --- /dev/null +++ b/mods/iron_coast_railburst/mod.toml @@ -0,0 +1,7 @@ +id = "iron_coast_railburst" +name = "Railburst Cannon" +version = "1.0.0" +api_version = 1 +description = "Independent Iron Coast II selectable upgrade with SD/HD artwork and procedural fire/impact audio." +content = "content.json" +scripts = ["scripts/weapon.rhai"] diff --git a/mods/iron_coast_railburst/prepare_art.rs b/mods/iron_coast_railburst/prepare_art.rs new file mode 100644 index 00000000..c5eb318f --- /dev/null +++ b/mods/iron_coast_railburst/prepare_art.rs @@ -0,0 +1,76 @@ +const SHOT_W: u32 = 4; +const SHOT_H: u32 = 20; +// Fit untouched generated masters to shared logical canvases and four-times HD. +// Compile with this project's pinned image crate; see README for reproduction. +use image::{Rgba, RgbaImage, imageops}; +use std::{env, fs, path::Path}; +fn fit(source: &RgbaImage, w: u32, h: u32, scale: u32) -> RgbaImage { + let mut bounds = (source.width(), source.height(), 0, 0); + for (x, y, p) in source.enumerate_pixels() { + if p[3] >= 128 { + bounds.0 = bounds.0.min(x); + bounds.1 = bounds.1.min(y); + bounds.2 = bounds.2.max(x + 1); + bounds.3 = bounds.3.max(y + 1); + } + } + assert!( + bounds.2 > bounds.0 && bounds.3 > bounds.1, + "no meaningful source alpha" + ); + let crop = imageops::crop_imm( + source, + bounds.0, + bounds.1, + bounds.2 - bounds.0, + bounds.3 - bounds.1, + ) + .to_image(); + // Exactly one logical pixel of clear margin, shared across SD and HD. + let factor = ((w - 2) as f64 / crop.width() as f64).min((h - 2) as f64 / crop.height() as f64); + let nw = (crop.width() as f64 * factor).round().max(1.) as u32; + let nh = (crop.height() as f64 * factor).round().max(1.) as u32; + let filter = if scale == 1 { + imageops::FilterType::Triangle + } else { + imageops::FilterType::Lanczos3 + }; + let mut scaled = imageops::resize(&crop, nw * scale, nh * scale, filter); + for p in scaled.pixels_mut() { + if p[3] < 128 { + *p = Rgba([0, 0, 0, 0]); + } else { + p[3] = 255; + } + } + let mut out = RgbaImage::new(w * scale, h * scale); + imageops::overlay( + &mut out, + &scaled, + ((w * scale - nw * scale) / 2) as i64, + ((h * scale - nh * scale) / 2) as i64, + ); + out +} +fn main() { + let args: Vec<_> = env::args().collect(); + assert_eq!(args.len(), 2, "usage: prepare_art PACKAGE_DIRECTORY"); + let root = Path::new(&args[1]); + for (kind, w, h) in [("equipment", 16, 16), ("projectile", SHOT_W, SHOT_H)] { + let source = image::open(root.join(format!("art/{kind}-generated-source-v1.png"))) + .unwrap() + .into_rgba8(); + for (mode, scale) in [("sd", 1), ("hd", 4)] { + let image = fit(&source, w, h, scale); + let path = root.join(format!("art/{kind}-{mode}.png")); + image.save(&path).unwrap(); + println!("{} {}x{}", path.display(), image.width(), image.height()); + } + } + assert!( + fs::metadata(root.join("art/equipment-hd.png")) + .unwrap() + .len() + > 0 + ); +} diff --git a/mods/iron_coast_railburst/prompts.json b/mods/iron_coast_railburst/prompts.json new file mode 100644 index 00000000..1939f625 --- /dev/null +++ b/mods/iron_coast_railburst/prompts.json @@ -0,0 +1,14 @@ +{ + "use_case": "stylized-concept", + "tool": "built-in image_gen", + "skill": "/home/quintine/.codex/skills/.system/imagegen/SKILL.md", + "style_reference_ids": [ + "102b6", + "101cb" + ], + "reference_role": "Original catalog was inspected for classic palette, silhouette and scale; no decoded reference is included in this mod. New generation uses the prepared textual art direction.", + "prompts": { + "equipment": "Use case: stylized-concept. Asset type: a single new HD equipment sprite for the shop/inventory of a Raptor-style military science-fiction vertical shooter. Generate a Railburst Cannon: compact armored gunmetal rectangular breech with a single short central accelerator muzzle pointing exactly UP, two restrained cyan induction rails along its sides, a small red service plate and bolted dark gray mounting base. Top-down orthographic overhead view, symmetrical readable silhouette with chunky industrial 1990s shooter forms, warm upper-left metal highlights and deep painted recesses. Fine machined detail for HD, clean hard silhouette readable at 16x16 logical pixels and64x64HD. Exactly one complete centered object on a genuinely transparent square canvas, with at least15percent transparent margin around the entire object. The silhouette should fill the central65percent of the canvas. No floor, black background, scene, ship, words, border, frame, cast shadow, large glow or extra objects. Muted gunmetal/steel, narrow cyan accents, tiny red service plate; no candy colors. Newly authored equipment, not a duplicate of any existing weapon.", + "projectile": "Use case: stylized-concept. Asset type: one new transparent railgun projectile sprite for a Raptor-style military science-fiction vertical shooter. A single extremely narrow vertical ballistic rail slug traveling exactly UP: sharp pale steel pointed nose, short bright ivory core, a restrained slim cyan sheath, and a tapered blue-gray wake downward. It is a solid compact dart with a visible bright tip and a modest bounded trail, not a screen-length beam, not lightning, not an explosion. Top-down orthographic overhead view, perfectly straight and centered. Subject width:height about1:5; logical canvas4x20 pixels and16x80HD. Chunky crisp small-game silhouette with refined original metal/light detail forHD. One complete object on a genuinely transparent square canvas, generous blank side areas, at least15percent top/bottom transparent margin. No gun, spacecraft, text, border, background, shadow, smoke cloud, detached sparkles, branching, multiple objects or outside glow. Match restrained pale steel/ivory/cyan highlights of a classic1990s military shooter." + } +} diff --git a/mods/iron_coast_railburst/scripts/weapon.rhai b/mods/iron_coast_railburst/scripts/weapon.rhai new file mode 100644 index 00000000..34a19ee4 --- /dev/null +++ b/mods/iron_coast_railburst/scripts/weapon.rhai @@ -0,0 +1,52 @@ +// Native straight projectile supplies the first collision and its 42 damage. +// Penetration is contact-triggered, finite and locked to that projectile's x lane. +fn on_fire(event, state, random) { + if event.hostile { return #{commands: [], state: state}; } + let shots = if state.contains("shots") { state.shots % 100000 + 1 } else { 1 }; + let hits = if state.contains("hits") { state.hits } else { 0 }; + #{commands: [#{op: "play_sound", sound: "iron_coast_railburst:fire"}], + state: #{shots: shots, hits: hits}} +} + +fn on_hit(event, state, random) { + let shots = if state.contains("shots") { state.shots } else { 0 }; + let hits = if state.contains("hits") { state.hits % 100000 + 1 } else { 1 }; + let origin_y = event.y; + let ground = false; + for enemy in event.entities { + if enemy.entity == event.entity { + origin_y = enemy.y + enemy.height / 2; + ground = enemy.ground; + } + } + let kind = if ground { "small_ground" } else { "small_air" }; + let commands = [#{op: "play_sound", sound: "iron_coast_railburst:impact"}, + #{op: "effect", kind: kind, x: event.x, y: event.y}]; + let struck = [event.entity]; + let previous_y = origin_y; + let damages = [32, 22]; + for hop in 0..2 { + let chosen = #{}; + let nearest = 1000000; + for enemy in event.entities { + let cx = enemy.x + enemy.width / 2; + let cy = enemy.y + enemy.height / 2; + if enemy.health <= 0 || struck.contains(enemy.entity) + || cx < 0 || cx >= 320 || cy < 0 || cy >= 200 { continue; } + let distance = previous_y - cy; + if abs(cx - event.x) <= 12 && distance > 0 + && origin_y - cy <= 160 && distance < nearest { + chosen = #{entity: enemy.entity, x: cx, y: cy, ground: enemy.ground}; + nearest = distance; + } + } + if !chosen.contains("entity") { break; } + commands.push(#{op: "damage", entity: chosen.entity, amount: damages[hop]}); + let impact = if chosen.ground { "small_ground" } else { "small_air" }; + commands.push(#{op: "effect", kind: impact, x: chosen.x, y: chosen.y}); + struck.push(chosen.entity); + previous_y = chosen.y; + hits = hits % 100000 + 1; + } + #{commands: commands, state: #{shots: shots, hits: hits}} +} diff --git a/mods/iron_coast_railburst/validation/balance.json b/mods/iron_coast_railburst/validation/balance.json new file mode 100644 index 00000000..b6ce07e9 --- /dev/null +++ b/mods/iron_coast_railburst/validation/balance.json @@ -0,0 +1,901 @@ +{ + "difficulty": 2, + "fixture_health": 100000, + "rate": "70/3 Hz", + "rows": [ + { + "damage": [ + 1344 + ], + "group_dps": 44.8, + "item": "iron_coast_railburst:equipment", + "price": 685000, + "scene": "aligned_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 1344 + ], + "group_dps": 44.8, + "item": "iron_coast_railburst:equipment", + "price": 685000, + "scene": "aligned_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "iron_coast_railburst:equipment", + "price": 685000, + "scene": "off_axis_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "iron_coast_railburst:equipment", + "price": 685000, + "scene": "off_axis_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 1344, + 1024, + 704, + 0 + ], + "group_dps": 102.4, + "item": "iron_coast_railburst:equipment", + "price": 685000, + "scene": "aligned_column", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 1344, + 0, + 0, + 0, + 0, + 0 + ], + "group_dps": 44.8, + "item": "iron_coast_railburst:equipment", + "price": 685000, + "scene": "ground_cluster", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 2038 + ], + "group_dps": 67.93333333333334, + "item": "iron_coast_railburst:equipment", + "price": 685000, + "scene": "aligned_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 2038 + ], + "group_dps": 67.93333333333334, + "item": "iron_coast_railburst:equipment", + "price": 685000, + "scene": "aligned_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "iron_coast_railburst:equipment", + "price": 685000, + "scene": "off_axis_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "iron_coast_railburst:equipment", + "price": 685000, + "scene": "off_axis_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 2040, + 1024, + 704, + 0 + ], + "group_dps": 125.6, + "item": "iron_coast_railburst:equipment", + "price": 685000, + "scene": "aligned_column", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 2038, + 0, + 0, + 0, + 0, + 0 + ], + "group_dps": 67.93333333333334, + "item": "iron_coast_railburst:equipment", + "price": 685000, + "scene": "ground_cluster", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "iron_coast_depth_charge:equipment", + "price": 525000, + "scene": "aligned_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 1080 + ], + "group_dps": 36.0, + "item": "iron_coast_depth_charge:equipment", + "price": 525000, + "scene": "aligned_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "iron_coast_depth_charge:equipment", + "price": 525000, + "scene": "off_axis_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "iron_coast_depth_charge:equipment", + "price": 525000, + "scene": "off_axis_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 1080, + 0, + 0, + 0 + ], + "group_dps": 36.0, + "item": "iron_coast_depth_charge:equipment", + "price": 525000, + "scene": "aligned_column", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 1080, + 540, + 300, + 300, + 0, + 0 + ], + "group_dps": 74.0, + "item": "iron_coast_depth_charge:equipment", + "price": 525000, + "scene": "ground_cluster", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 694 + ], + "group_dps": 23.133333333333333, + "item": "iron_coast_depth_charge:equipment", + "price": 525000, + "scene": "aligned_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 1774 + ], + "group_dps": 59.13333333333333, + "item": "iron_coast_depth_charge:equipment", + "price": 525000, + "scene": "aligned_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "iron_coast_depth_charge:equipment", + "price": 525000, + "scene": "off_axis_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "iron_coast_depth_charge:equipment", + "price": 525000, + "scene": "off_axis_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 1776, + 0, + 0, + 0 + ], + "group_dps": 59.2, + "item": "iron_coast_depth_charge:equipment", + "price": 525000, + "scene": "aligned_column", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 1774, + 540, + 300, + 300, + 0, + 0 + ], + "group_dps": 97.13333333333334, + "item": "iron_coast_depth_charge:equipment", + "price": 525000, + "scene": "ground_cluster", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 800 + ], + "group_dps": 26.666666666666668, + "item": "ion_lance:equipment", + "price": 425000, + "scene": "aligned_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 800 + ], + "group_dps": 26.666666666666668, + "item": "ion_lance:equipment", + "price": 425000, + "scene": "aligned_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "ion_lance:equipment", + "price": 425000, + "scene": "off_axis_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "ion_lance:equipment", + "price": 425000, + "scene": "off_axis_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 800, + 800, + 800, + 800 + ], + "group_dps": 106.66666666666667, + "item": "ion_lance:equipment", + "price": 425000, + "scene": "aligned_column", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 800, + 800, + 0, + 0, + 0, + 800 + ], + "group_dps": 80.0, + "item": "ion_lance:equipment", + "price": 425000, + "scene": "ground_cluster", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 1494 + ], + "group_dps": 49.8, + "item": "ion_lance:equipment", + "price": 425000, + "scene": "aligned_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 1494 + ], + "group_dps": 49.8, + "item": "ion_lance:equipment", + "price": 425000, + "scene": "aligned_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "ion_lance:equipment", + "price": 425000, + "scene": "off_axis_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "ion_lance:equipment", + "price": 425000, + "scene": "off_axis_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 1496, + 800, + 800, + 800 + ], + "group_dps": 129.86666666666667, + "item": "ion_lance:equipment", + "price": 425000, + "scene": "aligned_column", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 1494, + 800, + 0, + 0, + 0, + 800 + ], + "group_dps": 103.13333333333334, + "item": "ion_lance:equipment", + "price": 425000, + "scene": "ground_cluster", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 1248 + ], + "group_dps": 41.6, + "item": "lightning_cannon:equipment", + "price": 825000, + "scene": "aligned_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 1248 + ], + "group_dps": 41.6, + "item": "lightning_cannon:equipment", + "price": 825000, + "scene": "aligned_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "lightning_cannon:equipment", + "price": 825000, + "scene": "off_axis_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "lightning_cannon:equipment", + "price": 825000, + "scene": "off_axis_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 1248, + 780, + 468, + 312 + ], + "group_dps": 93.6, + "item": "lightning_cannon:equipment", + "price": 825000, + "scene": "aligned_column", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 1248, + 468, + 312, + 0, + 0, + 780 + ], + "group_dps": 93.6, + "item": "lightning_cannon:equipment", + "price": 825000, + "scene": "ground_cluster", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 1942 + ], + "group_dps": 64.73333333333333, + "item": "lightning_cannon:equipment", + "price": 825000, + "scene": "aligned_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 1942 + ], + "group_dps": 64.73333333333333, + "item": "lightning_cannon:equipment", + "price": 825000, + "scene": "aligned_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "lightning_cannon:equipment", + "price": 825000, + "scene": "off_axis_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "lightning_cannon:equipment", + "price": 825000, + "scene": "off_axis_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 1944, + 780, + 468, + 312 + ], + "group_dps": 116.8, + "item": "lightning_cannon:equipment", + "price": 825000, + "scene": "aligned_column", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 1942, + 468, + 312, + 0, + 0, + 780 + ], + "group_dps": 116.73333333333333, + "item": "lightning_cannon:equipment", + "price": 825000, + "scene": "ground_cluster", + "seconds": 30, + "ticks": 700, + "with_forward_guns": true + }, + { + "damage": [ + 694 + ], + "group_dps": 23.133333333333333, + "item": "base:forward_guns", + "price": 12000, + "scene": "aligned_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 694 + ], + "group_dps": 23.133333333333333, + "item": "base:forward_guns", + "price": 12000, + "scene": "aligned_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "base:forward_guns", + "price": 12000, + "scene": "off_axis_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "base:forward_guns", + "price": 12000, + "scene": "off_axis_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 696, + 0, + 0, + 0 + ], + "group_dps": 23.2, + "item": "base:forward_guns", + "price": 12000, + "scene": "aligned_column", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 694, + 0, + 0, + 0, + 0, + 0 + ], + "group_dps": 23.133333333333333, + "item": "base:forward_guns", + "price": 12000, + "scene": "ground_cluster", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 2400 + ], + "group_dps": 80.0, + "item": "base:death_ray", + "price": 950000, + "scene": "aligned_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 2400 + ], + "group_dps": 80.0, + "item": "base:death_ray", + "price": 950000, + "scene": "aligned_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "base:death_ray", + "price": 950000, + "scene": "off_axis_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "base:death_ray", + "price": 950000, + "scene": "off_axis_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 2400, + 0, + 0, + 0 + ], + "group_dps": 80.0, + "item": "base:death_ray", + "price": 950000, + "scene": "aligned_column", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 2400, + 0, + 0, + 0, + 0, + 0 + ], + "group_dps": 80.0, + "item": "base:death_ray", + "price": 950000, + "scene": "ground_cluster", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 8000 + ], + "group_dps": 266.6666666666667, + "item": "base:forward_laser", + "price": 1750000, + "scene": "aligned_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 8000 + ], + "group_dps": 266.6666666666667, + "item": "base:forward_laser", + "price": 1750000, + "scene": "aligned_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "base:forward_laser", + "price": 1750000, + "scene": "off_axis_air", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 0 + ], + "group_dps": 0.0, + "item": "base:forward_laser", + "price": 1750000, + "scene": "off_axis_ground", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 8000, + 0, + 0, + 0 + ], + "group_dps": 266.6666666666667, + "item": "base:forward_laser", + "price": 1750000, + "scene": "aligned_column", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + }, + { + "damage": [ + 8000, + 0, + 0, + 0, + 0, + 0 + ], + "group_dps": 266.6666666666667, + "item": "base:forward_laser", + "price": 1750000, + "scene": "ground_cluster", + "seconds": 30, + "ticks": 700, + "with_forward_guns": false + } + ], + "target_size": [ + 32, + 32 + ], + "package": "iron_coast_railburst", + "final_price": 685000, + "resale_price": 342500, + "pricing_reason": "44.8 single air/ground DPS and102.4 finite three-target aligned-column DPS, zero off-axis damage. Higher single-target throughput than425,000 Ion Lance26.67, but tighter initial acquisition and finite penetration compared with825,000 Lightning Cannon41.6 single/93.6 chain and wider acquisition. Below950,000 Death Ray80 single and1,750,000 Forward Laser266.67. Ion Lance can exceed this finite penetration against four or more perfectly stacked targets; this is a different aiming/cadence choice, not an upgrade over every role.", + "observation": "Actual World::step700ticks; deterministic stationary32x32 health100000 fixtures, ground scroll canceled after normal collision pass. Native original and new weapons unmodified. Forward-gun combination separately observed. Does not measure campaign difficulty or moving-target accuracy.", + "source_input_hashes": { + "mod.toml": "e22f6dd8e8aaeb7fe1549cdddc2be28fcda71a16f9285c975701e77a009faf84", + "content.json": "de70d59f723cce78ca4b59a3ecce704ce877517d91d83a06526daed7f42d4484", + "scripts/weapon.rhai": "209ae40d88b03bda4802c1970852d791f84b48986990d70c0e3dbcf502ba5b9b" + } +} diff --git a/mods/iron_coast_railburst/validation/native_review.rs b/mods/iron_coast_railburst/validation/native_review.rs new file mode 100644 index 00000000..8a63bd49 --- /dev/null +++ b/mods/iron_coast_railburst/validation/native_review.rs @@ -0,0 +1,145 @@ +//! Read-only public engine asset/audio review for both independent Stage 2 mods. +//! Writes captures only to the caller's evidence directory, never to game data. +use image::{RgbaImage, imageops}; +use raptor_replica::{ + assets::{Catalog, Sprite, TRANSPARENT}, + audio::Mixer, + content::{ContentId, Registry, art_sprite_variant}, + modding::{self, ActiveMods}, + render::{Canvas, nearest}, + sound::{SoundBank, encode_capture}, +}; +use serde_json::json; +use std::{env, fs, path::Path}; +fn normalized(sprite: &Sprite, w: usize, h: usize) -> Sprite { + let mut out = Sprite::blank(w, h); + for y in 0..h { + for x in 0..w { + out.pixels[y * w + x] = + sprite.pixels[(y * sprite.height / h) * sprite.width + x * sprite.width / w]; + } + } + out +} +fn main() { + let args: Vec<_> = env::args().collect(); + assert_eq!(args.len(), 4, "usage: native_review DATA MODS EVIDENCE"); + let catalog = Catalog::open(&args[1]).unwrap(); + let base = Registry::base(&catalog).unwrap(); + let ids = ["iron_coast_railburst", "iron_coast_depth_charge"].map(String::from); + let discovery = modding::discover(Path::new(&args[2])); + let active = ActiveMods::build(&base, &discovery, &ids, Some(&catalog)).unwrap(); + let out = Path::new(&args[3]); + fs::create_dir_all(out).unwrap(); + let palette = catalog.palette().unwrap(); + let mut rows = Vec::new(); + let mut gallery = RgbaImage::new(1024, 1024); + let mut row = 0; + for owner in &ids { + for kind in ["equipment", "projectile"] { + let id: ContentId = format!( + "{owner}:{}", + if kind == "equipment" { + "equipment" + } else { + "projectile" + } + ) + .as_str() + .into(); + let art = active.registry.art(&id).unwrap(); + for hd in [false, true] { + let source = + art_sprite_variant(&catalog, &active.registry, owner, art, 0, hd).unwrap(); + assert!( + source + .pixels + .iter() + .filter(|c| **c != TRANSPARENT) + .all(|c| *c < 240) + ); + assert!( + source.pixels[0] == TRANSPARENT + && source.pixels[source.width - 1] == TRANSPARENT + ); + let mut counts = Vec::new(); + for scale in 1..=4 { + // The same canvas sizing and nearest resampling used by Host::art. + let display = if source.width == art.logical_width as usize + && source.height == art.logical_height as usize + { + nearest(&source, scale) + } else { + normalized( + &source, + art.logical_width as usize * scale, + art.logical_height as usize * scale, + ) + }; + counts.push(json!({"scale":scale,"width":display.width,"height":display.height,"painted":display.pixels.iter().filter(|c|**c!=TRANSPARENT).count()})); + let mut canvas = Canvas::new(scale); + canvas.clear(12); + canvas.rect(160, 0, 160, 200, 93); + for (x, y) in [(70, 90), (230, 90)] { + canvas.blit(&display, x * scale as i32, y * scale as i32); + } + let rgba = RgbaImage::from_raw( + canvas.image.width as u32, + canvas.image.height as u32, + canvas.rgba(&palette, false), + ) + .unwrap(); + rgba.save(out.join(format!( + "{owner}-{kind}-{}-{scale}x.png", + if hd { "hd" } else { "sd" } + ))) + .unwrap(); + } + let display = normalized( + &source, + art.logical_width as usize * 8, + art.logical_height as usize * 8, + ); + let mut cell = Canvas::new(1); + cell.clear(12); + cell.rect(160, 0, 160, 200, 93); + cell.blit(&display, 20, 20); + cell.blit(&display, 180, 20); + let rgba = RgbaImage::from_raw(320, 200, cell.rgba(&palette, false)).unwrap(); + imageops::overlay( + &mut gallery, + &rgba, + if hd { 512 } else { 0 }, + (row * 256) as i64, + ); + rows.push(json!({"owner":owner,"kind":kind,"hd":hd,"physical_canvas":[source.width,source.height],"logical_canvas":[art.logical_width,art.logical_height],"frame":0,"frames":art.frames,"ordinary_palette_only":true,"clear_corner_alpha":true,"all_scales":counts})); + } + row += 1; + } + } + gallery.save(out.join("indexed-sd-hd-gallery.png")).unwrap(); + let instruments = catalog.named("GENMIDI_OP2").unwrap(); + let mut audio = Vec::new(); + for owner in &ids { + for kind in ["fire", "impact"] { + let id: ContentId = format!("{owner}:{kind}").as_str().into(); + let mut bank = SoundBank::default(); + let sample = bank.mod_sample(&active.registry, &id).unwrap(); + assert!(!sample.data.is_empty()); + let mut mixer = Mixer::new(44100, &instruments).unwrap(); + mixer.start_capture(1).unwrap(); + bank.queue_mod(&active.registry, &mut mixer, &id).unwrap(); + let mut samples = vec![0; 44100 * 2]; + mixer.mix(&mut samples); + assert!(samples.iter().any(|x| *x != 0)); + let file = format!("{owner}-{kind}-mixed.wav"); + fs::write( + out.join(&file), + encode_capture(&mixer.take_capture().unwrap()).unwrap(), + ) + .unwrap(); + audio.push(json!({"id":id,"decoder":"SoundBank::mod_sample","mixer":"Mixer::sample through SoundBank::queue_mod","source_rate":sample.rate,"decoded_samples":sample.data.len(),"mixed_rate":44100,"mixed_channels":2,"nonzero_output_samples":samples.iter().filter(|x|**x!=0).count(),"peak":samples.iter().map(|x|(*x as i32).abs()).max().unwrap(),"capture":file})); + } + } + fs::write(out.join("native-review.json"),serde_json::to_vec_pretty(&json!({"scope":"Public PNG decoder, same Host art normalization, indexed Canvas blitter and actual SoundBank/Mixer. Synthetic backgrounds; no live desktop/gameplay claim.","assets":rows,"audio":audio})).unwrap()).unwrap(); +} diff --git a/mods/iron_coast_railburst/validation/review.json b/mods/iron_coast_railburst/validation/review.json new file mode 100644 index 00000000..f375c9af --- /dev/null +++ b/mods/iron_coast_railburst/validation/review.json @@ -0,0 +1,283 @@ +{ + "package": "iron_coast_railburst", + "portable_tests": { + "file": "tests/iron_coast_stage2_weapons.rs", + "passed": 9, + "balance_integration_passed": 1, + "cases": [ + "independent activation and coexistence", + "shop half-price resale and duplicate rejection", + "rail aligned contact finite penetration", + "depth contact-only ground radius/falloff/cap", + "unselected/idle/misses without explosions", + "serialized state/RNG continuation and invalid-command rollback", + "explicit cooldown/reusable inventory", + "lethal primary contact continuation", + "full-slot inventory preservation", + "disable/re-enable saved equipment, exact mod pins and script state preserved without altering save" + ] + }, + "native_decoder_blitter_audio": { + "assets": [ + { + "all_scales": [ + { + "height": 16, + "painted": 94, + "scale": 1, + "width": 16 + }, + { + "height": 32, + "painted": 376, + "scale": 2, + "width": 32 + }, + { + "height": 48, + "painted": 846, + "scale": 3, + "width": 48 + }, + { + "height": 64, + "painted": 1504, + "scale": 4, + "width": 64 + } + ], + "clear_corner_alpha": true, + "frame": 0, + "frames": 1, + "hd": false, + "kind": "equipment", + "logical_canvas": [ + 16, + 16 + ], + "ordinary_palette_only": true, + "owner": "iron_coast_railburst", + "physical_canvas": [ + 16, + 16 + ] + }, + { + "all_scales": [ + { + "height": 16, + "painted": 92, + "scale": 1, + "width": 16 + }, + { + "height": 32, + "painted": 361, + "scale": 2, + "width": 32 + }, + { + "height": 48, + "painted": 809, + "scale": 3, + "width": 48 + }, + { + "height": 64, + "painted": 1434, + "scale": 4, + "width": 64 + } + ], + "clear_corner_alpha": true, + "frame": 0, + "frames": 1, + "hd": true, + "kind": "equipment", + "logical_canvas": [ + 16, + 16 + ], + "ordinary_palette_only": true, + "owner": "iron_coast_railburst", + "physical_canvas": [ + 64, + 64 + ] + }, + { + "all_scales": [ + { + "height": 20, + "painted": 26, + "scale": 1, + "width": 4 + }, + { + "height": 40, + "painted": 104, + "scale": 2, + "width": 8 + }, + { + "height": 60, + "painted": 234, + "scale": 3, + "width": 12 + }, + { + "height": 80, + "painted": 416, + "scale": 4, + "width": 16 + } + ], + "clear_corner_alpha": true, + "frame": 0, + "frames": 1, + "hd": false, + "kind": "projectile", + "logical_canvas": [ + 4, + 20 + ], + "ordinary_palette_only": true, + "owner": "iron_coast_railburst", + "physical_canvas": [ + 4, + 20 + ] + }, + { + "all_scales": [ + { + "height": 20, + "painted": 21, + "scale": 1, + "width": 4 + }, + { + "height": 40, + "painted": 87, + "scale": 2, + "width": 8 + }, + { + "height": 60, + "painted": 200, + "scale": 3, + "width": 12 + }, + { + "height": 80, + "painted": 352, + "scale": 4, + "width": 16 + } + ], + "clear_corner_alpha": true, + "frame": 0, + "frames": 1, + "hd": true, + "kind": "projectile", + "logical_canvas": [ + 4, + 20 + ], + "ordinary_palette_only": true, + "owner": "iron_coast_railburst", + "physical_canvas": [ + 16, + 80 + ] + } + ], + "audio": [ + { + "capture": "iron_coast_railburst-fire-mixed.wav", + "decoded_samples": 3528, + "decoder": "SoundBank::mod_sample", + "id": "iron_coast_railburst:fire", + "mixed_channels": 2, + "mixed_rate": 44100, + "mixer": "Mixer::sample through SoundBank::queue_mod", + "nonzero_output_samples": 6320, + "peak": 3200, + "source_rate": 22050 + }, + { + "capture": "iron_coast_railburst-impact-mixed.wav", + "decoded_samples": 5071, + "decoder": "SoundBank::mod_sample", + "id": "iron_coast_railburst:impact", + "mixed_channels": 2, + "mixed_rate": 44100, + "mixer": "Mixer::sample through SoundBank::queue_mod", + "nonzero_output_samples": 11168, + "peak": 2432, + "source_rate": 22050 + } + ], + "scope": "Public PNG decoder, same Host art normalization, indexed Canvas blitter and actual SoundBank/Mixer. Synthetic backgrounds; no live desktop/gameplay claim." + }, + "visual_inspection": "Inspected original style references separately, all four raw masters and actual indexed SD/HD gallery at logical and4x canvases. Readable compact silhouettes, neutral metal with cyan rail/orange charge roles, transparent borders. SD colors intentionally simplified by reduction; no reserved palette effects. Captures use synthetic palette backgrounds, not a live mission or actual shop pane.", + "limitations": [ + "Private desktop Host/shop screenshots are delegated to root integration review.", + "Native point collision may skip exceptionally tiny targets for the speed16 rail shot.", + "Terrain cells receive native primary damage but are not available as scripted penetration/splash snapshots." + ], + "evidence_gallery_sha256": "c1b5d6ad1d286eb17fab1067143222a6071dff5e70a35d904757275767ec5a26", + "reproduction_byte_equality": { + "art/equipment-sd.png": true, + "art/equipment-hd.png": true, + "art/projectile-sd.png": true, + "art/projectile-hd.png": true, + "audio/fire.wav": true, + "audio/impact.wav": true + }, + "native_build_bindings": { + "libraries": { + "raptor_replica": { + "path": "/home/quintine/Projects/RaptorReplica/RustRaptor/target/debug/libraptor_replica.rlib", + "sha256": "4fd737d3c6c808fd5de1ecfc1f9a41b0ef37e82dc1a186f005b8dc9c2360ccd5" + }, + "image": { + "path": "/home/quintine/Projects/RaptorReplica/RustRaptor/target/debug/deps/libimage-25e356663b4aa6b0.rlib", + "sha256": "ea709066ea4c8c625efe3bf7f3741d7a68abfb7ef4b304837f1f0da20e5e2d58" + }, + "serde_json": { + "path": "/home/quintine/Projects/RaptorReplica/RustRaptor/target/debug/deps/libserde_json-1d17875658175ae0.rlib", + "sha256": "e463d4b704418cc5a168d73818662f7a801a77d96e8ef3d6a121e90375e4532f" + } + }, + "review_source_sha256": "32c4e836b7a01d159251427b2203dcf0d40f43bebef1def2f13a571e845d8ca3", + "validation_cases": [ + { + "enabled": [ + "iron_coast_railburst" + ], + "stdout": "Validated 1 mods; 0 override(s)", + "stderr": "", + "exit_code": 0 + }, + { + "enabled": [ + "iron_coast_depth_charge" + ], + "stdout": "Validated 1 mods; 0 override(s)", + "stderr": "", + "exit_code": 0 + }, + { + "enabled": [ + "iron_coast_railburst", + "iron_coast_depth_charge" + ], + "stdout": "Validated 2 mods; 0 override(s)", + "stderr": "", + "exit_code": 0 + } + ], + "scope": "Frozen package copies; public asset, indexed Canvas and audio APIs; no live desktop or pilot mutations." + } +} diff --git a/mods/iron_coast_railburst/validation/review.py b/mods/iron_coast_railburst/validation/review.py new file mode 100644 index 00000000..3e78ea23 --- /dev/null +++ b/mods/iron_coast_railburst/validation/review.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 +"""Reproduce isolated Stage 2 package validation and public indexed/audio review.""" +import argparse +import hashlib +import json +import os +import shutil +import subprocess +import tempfile +from pathlib import Path + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("--data", type=Path) + parser.add_argument("--output", type=Path, required=True) + args = parser.parse_args() + root = Path(__file__).resolve().parents[3] + data = (args.data or root / "data").resolve() + output = args.output.resolve() + output.mkdir(parents=True, exist_ok=True) + packages = ["iron_coast_railburst", "iron_coast_depth_charge"] + subprocess.run(["cargo", "build", "--locked", "--no-default-features", "--lib", "--bin", "raptor-rust"], cwd=root, check=True) + deps = root / "target/debug/deps" + suffix = ".exe" if os.name == "nt" else "" + executable = output / ("native_review" + suffix) + command = ["rustc", "--edition=2024", str(Path(__file__).with_name("native_review.rs")), "-L", f"dependency={deps}", "-o", str(executable)] + libraries = {} + for name in ["raptor_replica", "image", "serde_json"]: + library = root / "target/debug/libraptor_replica.rlib" if name == "raptor_replica" else max(deps.glob(f"lib{name}-*.rlib"), key=lambda path: path.stat().st_mtime_ns) + command += ["--extern", f"{name}={library}"] + libraries[name] = {"path": str(library), "sha256": hashlib.sha256(library.read_bytes()).hexdigest()} + subprocess.run(command, cwd=root, check=True) + cases = [] + with tempfile.TemporaryDirectory(prefix="iron-coast-stage2-review-") as folder: + frozen = Path(folder) + for package in packages: + shutil.copytree(root / "mods" / package, frozen / package) + for selected in [[packages[0]], [packages[1]], packages]: + result = subprocess.run([str(root / ("target/debug/raptor-rust" + suffix)), "--data", str(data), "--mods", str(frozen), "--validate-mods", ",".join(selected)], cwd=root, check=True, capture_output=True, text=True) + print(result.stdout, end="") + cases.append({"enabled": selected, "stdout": result.stdout.strip(), "stderr": result.stderr.strip(), "exit_code": result.returncode}) + subprocess.run([str(executable), str(data), str(frozen), str(output)], cwd=root, check=True) + (output / "build-bindings.json").write_text(json.dumps({"libraries": libraries, "review_source_sha256": hashlib.sha256(Path(__file__).with_name("native_review.rs").read_bytes()).hexdigest(), "validation_cases": cases, "scope": "Frozen package copies; public asset, indexed Canvas and audio APIs; no live desktop or pilot mutations."}, indent=2) + "\n") + + +if __name__ == "__main__": + main() diff --git a/mods/iron_coast_stage2_boss_1/README.md b/mods/iron_coast_stage2_boss_1/README.md new file mode 100644 index 00000000..f6817bf7 --- /dev/null +++ b/mods/iron_coast_stage2_boss_1/README.md @@ -0,0 +1,40 @@ +# Iron Coast II: Gatebreaker + +A standalone boss content package for Black Tide. Enable this package directly +in **Mods**, or enable its mission to select it as a dependency. It adds +`iron_coast_stage2_boss_1:unit` and no campaign, overrides or equipment. + +The surfaced/ground target has 320 health, awards 12,000 credits and retains +a 128×64 logical collision canvas in SD and HD. It remains reachable until killed. +Its two phases change at half of that life’s actual spawn health on every +difficulty, with a new attack timer and twelve ticks of audible warning before +every volley. Difficulty 0/1 uses the engine’s half-health boss rule; 2/3 uses +the nominal health above. Cadence is 84 / 66 simulation ticks +(first/second phase), at the original 70/3 Hz. Every projectile is hostile and +leaves deliberate escape lanes; no phase is invulnerable. + +Actual death increments `iron_coast_stage2_boss_1:defeated` once. It does not finish a mission. +Per-life cursors are removed on death and pruned on spawn/replay; early kills +before the queued spawn callback still register the real death. + +Artwork is a genuine new builtin imagegen master, with full alpha and identical +SD/HD canvas alignment. `build_assets.py` reproduces palette-aware SD art, 4× HD +and deterministic PCM WAV effects from the tracked raw masters. Projectile art +is the same newly authored micro-missile independently included with each boss. +See [generation provenance](generation-provenance.json) and +[asset recipe/report](asset-report.json). Original Raptor style references and +local review captures are external. + +From `RustRaptor/`: + +```sh +cargo run --locked --no-default-features -- --mods mods --validate-mods iron_coast_stage2_boss_1 +CARGO_TARGET_DIR="$PWD/target" cargo run --locked --release --manifest-path mods/iron_coast_stage2_boss_1/validation/Cargo.toml -- --boss-only +python3 mods/iron_coast_stage2_boss_1/build_assets.py +``` + +The real-catalog standalone kill, every-difficulty phase boundaries, early and +duplicate hook checks and native Mixer/mute observations passed. Exact results +and scopes are recorded in `acceptance-report.json`. + +Asset recipes use Python 3 with Pillow. The game uses the shipped PNG and WAV files. diff --git a/mods/iron_coast_stage2_boss_1/acceptance-report.json b/mods/iron_coast_stage2_boss_1/acceptance-report.json new file mode 100644 index 00000000..0980a256 --- /dev/null +++ b/mods/iron_coast_stage2_boss_1/acceptance-report.json @@ -0,0 +1,127 @@ +{ + "utc": "2026-10-11T08:51:02.199238+00:00", + "status": "author_checked_review_ready", + "real_catalog": true, + "engine_source_hashes_at_report": { + "src/assets.rs": "4cdf11a229f6ca4c6183fb545dba43e9a2323f839f7a095292045aa13a773ddc", + "src/content.rs": "7f35df7100c450ba4bb30a0fdc90101c115b5ae42a7aac57829441c5b7761647", + "src/modding.rs": "f37d67004392f5726121e58a995900cd7062016e3f060ea131b0df38995e2912", + "src/simulation.rs": "0ec9f6da11ab82c1461868a7b147e4cdb14689fa7373bd0c24067d9014e9583a", + "src/render.rs": "d4abdccbc3c1ee840ef8548bcff43080521937ef9f9f5ed69e810f417ef1e842", + "src/sound.rs": "aff6779b85f9f4f4bc30a15ad75ec6fdd61d42895639700f4842870636e73c4b", + "src/persistence.rs": "9a4adf1e33d3504db3d4d3e6091316cc7116fb35c89b2de8fbd4640d368aa0e2", + "Cargo.lock": "aac0a22725250ab35828223f8d129e4d2a4e6113cf81463e59600da3a59ffdea" + }, + "catalog_file_hashes": { + "data/INDEX": "4ce78e5e638b6603114dd233ceaa41f386c0963ba4aa02ecf88ce0215b096681", + "data/misc/PALETTE_DAT": "1cf6adb926d1dee1888b3e3d33b51a7049b3e5eb5f90a3067ef71c8970547204", + "data/misc/GENMIDI_OP2": "fdc93c076bf44207299e61ec1bbcfafca421454bfa99dd14fa4e5dcada1547b9" + }, + "compiled_validation_binary_sha256": "98f43eef5943061a18a465e95e8089189be793b9f8cbac275b8ebe982953567b", + "full_external_result_sha256": "63f97c1f8cab57452ee9235124551178fe2593c5e40f4a5ecd6e2aa9bf0cd19e", + "cli": { + "selected_packages": 10, + "overrides": 0, + "log_sha256": "c9401f44dc4fa438f75ccc00223e95f79cfa8bffcd1c8db5c106963f7b474822" + }, + "visual_limits": "Author inspected native indexed SD1/HD4 Canvas/PNG-loader diagnostics, exact new source masters and SD/HD final art. Terrain in owned captures uses a simplified row sampler. Live SDL/Host captures and independent eight-stage progression are root-owned; no live device or whole-map rendering claim.", + "package": "iron_coast_stage2_boss_1", + "content_sha256": "06d945df4b52b2147bc6e084f4d2c0c5a684f9b8ccfdd8f2b14cbf6c111c65bb", + "scripts": { + "scripts/ai.rhai": "8d4319cf6e71ad0aad1888f197ed44ce392570d1d9e2f033df33167c9300d878" + }, + "asset_report_sha256": "47cd7665858657dc316f5a29ddf210f45eb8ed723e31237710ada55381feebdd", + "raw_identity_checks": [ + { + "package": "iron_coast_stage2_boss_1", + "role": "unit_or_terrain", + "raw": "mods/iron_coast_stage2_boss_1/art/unit-generated-v1.png", + "raw_sha256": "62df3558a79431a86b4ada4fe393b003506aaf912ae74415a33411724b688f65", + "builtin_byte_identical": true, + "raw_dimensions": [ + 1774, + 887 + ], + "raw_alpha": "RGBA", + "reported_success": true + }, + { + "package": "iron_coast_stage2_boss_1", + "role": "projectile", + "raw": "mods/iron_coast_stage2_boss_1/art/projectile-generated-v1.png", + "raw_sha256": "9cc6e7e6cac60f045050bdefe1c84f5fc7185bcb585b87b7a7df5b2206a38ebb", + "builtin_byte_identical": true, + "raw_dimensions": [ + 887, + 1774 + ], + "raw_alpha": "RGBA", + "reported_success": true + } + ], + "standalone_world_kill": { + "boss": "iron_coast_stage2_boss_1:unit", + "cues": [ + "iron_coast_stage2_boss_1:death", + "iron_coast_stage2_boss_1:shot", + "iron_coast_stage2_boss_1:warning" + ], + "digest_before_extra_step": "4ef3f340c570094ccc262640df26df187b3954236284b618da2d3245392c95ee", + "minimum_observed_health": 0, + "serialized_script_state_bytes": 98, + "shield": 75, + "tick": 331 + }, + "all_difficulty_phase_checks": [ + { + "actual_spawn_max_health": 160, + "boss": "iron_coast_stage2_boss_1:unit", + "difficulty": 0, + "half_health_phase": 2, + "initial_phase": 1, + "phase_timer_reset": true + }, + { + "actual_spawn_max_health": 160, + "boss": "iron_coast_stage2_boss_1:unit", + "difficulty": 1, + "half_health_phase": 2, + "initial_phase": 1, + "phase_timer_reset": true + }, + { + "actual_spawn_max_health": 320, + "boss": "iron_coast_stage2_boss_1:unit", + "difficulty": 2, + "half_health_phase": 2, + "initial_phase": 1, + "phase_timer_reset": true + }, + { + "actual_spawn_max_health": 320, + "boss": "iron_coast_stage2_boss_1:unit", + "difficulty": 3, + "half_health_phase": 2, + "initial_phase": 1, + "phase_timer_reset": true + } + ], + "early_duplicate_callback_scope": "Direct Rhai hook protocol checks register an already-dead spawn silently and count its death once; independent actual lethal-spawn World review remains separate.", + "sound_mixer_checks": [ + { + "fx_mute_zero": true, + "mixed_peak": 3072, + "sound": "iron_coast_stage2_boss_1:death" + }, + { + "fx_mute_zero": true, + "mixed_peak": 2688, + "sound": "iron_coast_stage2_boss_1:shot" + }, + { + "fx_mute_zero": true, + "mixed_peak": 1920, + "sound": "iron_coast_stage2_boss_1:warning" + } + ] +} diff --git a/mods/iron_coast_stage2_boss_1/art/projectile-generated-v1.png b/mods/iron_coast_stage2_boss_1/art/projectile-generated-v1.png new file mode 100644 index 00000000..1f51fd1b Binary files /dev/null and b/mods/iron_coast_stage2_boss_1/art/projectile-generated-v1.png differ diff --git a/mods/iron_coast_stage2_boss_1/art/projectile-hd.png b/mods/iron_coast_stage2_boss_1/art/projectile-hd.png new file mode 100644 index 00000000..b415e6b1 Binary files /dev/null and b/mods/iron_coast_stage2_boss_1/art/projectile-hd.png differ diff --git a/mods/iron_coast_stage2_boss_1/art/projectile-sd.png b/mods/iron_coast_stage2_boss_1/art/projectile-sd.png new file mode 100644 index 00000000..97f02457 Binary files /dev/null and b/mods/iron_coast_stage2_boss_1/art/projectile-sd.png differ diff --git a/mods/iron_coast_stage2_boss_1/art/unit-generated-v1.png b/mods/iron_coast_stage2_boss_1/art/unit-generated-v1.png new file mode 100644 index 00000000..ceaf4f00 Binary files /dev/null and b/mods/iron_coast_stage2_boss_1/art/unit-generated-v1.png differ diff --git a/mods/iron_coast_stage2_boss_1/art/unit-hd.png b/mods/iron_coast_stage2_boss_1/art/unit-hd.png new file mode 100644 index 00000000..763f629b Binary files /dev/null and b/mods/iron_coast_stage2_boss_1/art/unit-hd.png differ diff --git a/mods/iron_coast_stage2_boss_1/art/unit-sd.png b/mods/iron_coast_stage2_boss_1/art/unit-sd.png new file mode 100644 index 00000000..59297d15 Binary files /dev/null and b/mods/iron_coast_stage2_boss_1/art/unit-sd.png differ diff --git a/mods/iron_coast_stage2_boss_1/artwork-reference.json b/mods/iron_coast_stage2_boss_1/artwork-reference.json new file mode 100644 index 00000000..49e701c3 --- /dev/null +++ b/mods/iron_coast_stage2_boss_1/artwork-reference.json @@ -0,0 +1,12 @@ +{ + "reference_role": "Original Raptor military style only, not target geometry or approved HD reference", + "reference_review_path": "/home/quintine/Projects/RaptorReplica/RustRaptor/.reference/iron-coast-stage2-authoring/original-style-references.png", + "reference_review_sha256": "d92f7d68008a73d626dcc9125920b7b329d029ca87a01d28bc4005f80c4f9174", + "original_ids": [ + "10139", + "10344", + "400d5", + "4011f" + ], + "original_reference_files_not_packaged": true +} diff --git a/mods/iron_coast_stage2_boss_1/asset-report.json b/mods/iron_coast_stage2_boss_1/asset-report.json new file mode 100644 index 00000000..d153f492 --- /dev/null +++ b/mods/iron_coast_stage2_boss_1/asset-report.json @@ -0,0 +1,351 @@ +{ + "utc": "2026-10-11T08:16:03.984933+00:00", + "recipe": "build_assets.py", + "recipe_sha256": "f86680d12fc6e15b585f4bba40170242518c397acdd0c1cb0992d22e0a46f462", + "palette_sha256": "1cf6adb926d1dee1888b3e3d33b51a7049b3e5eb5f90a3067ef71c8970547204", + "ordinary_palette_entries_only": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 216, + 217, + 218, + 219, + 220, + 221, + 222, + 223, + 224, + 225, + 226, + 227, + 228, + 229, + 230, + 231, + 232, + 233, + 234, + 235, + 236, + 237, + 238, + 239 + ], + "assets": [ + { + "source": "art/unit-generated-v1.png", + "sha256": "62df3558a79431a86b4ada4fe393b003506aaf912ae74415a33411724b688f65", + "logical_size": [ + 128, + 64 + ], + "hd_size": [ + 512, + 256 + ], + "alpha_below128_transparent": true, + "original_master_not_modified": true, + "whole_alpha_bounding_crop_for_projectile": null + }, + { + "source": "art/projectile-generated-v1.png", + "sha256": "9cc6e7e6cac60f045050bdefe1c84f5fc7185bcb585b87b7a7df5b2206a38ebb", + "logical_size": [ + 8, + 16 + ], + "hd_size": [ + 32, + 64 + ], + "alpha_below128_transparent": true, + "original_master_not_modified": true, + "whole_alpha_bounding_crop_for_projectile": [ + 363, + 637, + 525, + 1110 + ] + } + ], + "audio": [ + { + "file": "audio/warning.wav", + "sha256": "84497a75c3eafd803c3e87353c3f2e7e568ba6a57b021d910fa67a3e478f023d", + "samples": 11025, + "rate": 22050, + "duration": 0.5, + "peak": 7344, + "rms": 2423.21, + "seed": 8081 + }, + { + "file": "audio/shot.wav", + "sha256": "823b9d2d3d51ccefea88e1511afaeb7a40d5e22ce47001bc3376e6419f1d0b09", + "samples": 3528, + "rate": 22050, + "duration": 0.16, + "peak": 9463, + "rms": 1891.06, + "seed": 7589 + }, + { + "file": "audio/death.wav", + "sha256": "599d493fa8b7e9944a9932135a62d0007e04533bb78f80e83aff862ca2ab4092", + "samples": 23152, + "rate": 22050, + "duration": 1.05, + "peak": 8143, + "rms": 2001.53, + "seed": 7641 + } + ], + "final_art": [ + { + "file": "art/projectile-hd.png", + "sha256": "449bc288ba96deca89aa9318fba47662d8bf8e07d82494f978ccbc4f5dd4a869", + "size": [ + 32, + 64 + ] + }, + { + "file": "art/projectile-sd.png", + "sha256": "5f408b4713a948f75d7ba1e6ee582fe8eb91a235df41e2e6d1bb4dac050fbac3", + "size": [ + 8, + 16 + ] + }, + { + "file": "art/unit-hd.png", + "sha256": "b20cef0904d3fe854af05d44667d35a491e4a58948358d034ea37f4a555830a3", + "size": [ + 512, + 256 + ] + }, + { + "file": "art/unit-sd.png", + "sha256": "a2ab4da8797b6f820b9ed5f43a86637015eea239248283fd59094d96c71873da", + "size": [ + 128, + 64 + ] + } + ] +} diff --git a/mods/iron_coast_stage2_boss_1/audio/death.wav b/mods/iron_coast_stage2_boss_1/audio/death.wav new file mode 100644 index 00000000..fe8834ad Binary files /dev/null and b/mods/iron_coast_stage2_boss_1/audio/death.wav differ diff --git a/mods/iron_coast_stage2_boss_1/audio/shot.wav b/mods/iron_coast_stage2_boss_1/audio/shot.wav new file mode 100644 index 00000000..720239eb Binary files /dev/null and b/mods/iron_coast_stage2_boss_1/audio/shot.wav differ diff --git a/mods/iron_coast_stage2_boss_1/audio/warning.wav b/mods/iron_coast_stage2_boss_1/audio/warning.wav new file mode 100644 index 00000000..5582e32a Binary files /dev/null and b/mods/iron_coast_stage2_boss_1/audio/warning.wav differ diff --git a/mods/iron_coast_stage2_boss_1/build_assets.py b/mods/iron_coast_stage2_boss_1/build_assets.py new file mode 100644 index 00000000..1afd5dd3 --- /dev/null +++ b/mods/iron_coast_stage2_boss_1/build_assets.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python3 +"""Reproduce SD/HD canvases and PCM WAVs from untouched builtin generated PNGs. +No decoded original images are packaged. No painted/masked master edits occur. +""" +from pathlib import Path +import argparse,datetime,hashlib,json,math,random,struct,wave +from PIL import Image,ImageOps +ROOT=Path(__file__).resolve().parent +h=lambda p:hashlib.sha256(Path(p).read_bytes()).hexdigest() +def palette(path): + raw=path.read_bytes();assert len(raw)==768 + values=[(min(v,63)<<2)|(min(v,63)>>4) for v in raw] + values[720:]=[0]*48 + im=Image.new('P',(1,1));im.putpalette(values);return im + +def small(im,size,pal): + im=im.convert('RGBA').resize(size,Image.Resampling.LANCZOS) + alpha=im.getchannel('A').point(lambda a:255 if a>=128 else 0) + out=im.convert('RGB').quantize(palette=pal,dither=Image.Dither.NONE).convert('RGBA');out.putalpha(alpha);return out + +def canvases(source,name,size,pal): + src=Image.open(source).convert('RGBA');target=(size[0]*4,size[1]*4) + bounds=None + if name=='projectile': + bounds=src.getchannel('A').point(lambda a:255 if a>=128 else 0).getbbox();assert bounds;src=src.crop(bounds) + fit_size=(round(target[0]*.8),round(target[1]*.8)) if name=='projectile' else target + hd=Image.new('RGBA',target);fitted=ImageOps.contain(src,fit_size,Image.Resampling.LANCZOS);hd.alpha_composite(fitted,((target[0]-fitted.width)//2,(target[1]-fitted.height)//2)) + hd.save(ROOT/'art'/f'{name}-hd.png');small(hd,size,pal).save(ROOT/'art'/f'{name}-sd.png') + return {'source':str(source.relative_to(ROOT)),'sha256':h(source),'logical_size':size,'hd_size':target,'alpha_below128_transparent':True,'original_master_not_modified':True,'whole_alpha_bounding_crop_for_projectile':bounds} + +def synth(name,duration,base): + rate=22050;n=int(rate*duration);rng=random.Random(7043+sum(map(ord,name))+base);data=bytearray();peak=0;sumsq=0 + for i in range(n): + t=i/rate;u=i/n;env=min(1,u*30)*(1-u)**1.3 + if name=='shot':s=(math.sin(2*math.pi*(95*t-40*t*t))+rng.uniform(-1,1)*0.45)*math.exp(-u*3) + elif name=='death':s=rng.uniform(-1,1)*0.65+math.sin(2*math.pi*(70*t-18*t*t))*0.4 + elif name=='warning' or name=='boss_alarm':s=math.sin(2*math.pi*(base+70*math.sin(2*math.pi*t*5))*t)*0.8+0.12*math.sin(2*math.pi*base*.5*t) + else: + notes=[1,1.25,1.5,2] if name=='victory' else [1,1.5,1.25];freq=base*notes[min(len(notes)-1,int(u*len(notes)))];s=math.sin(2*math.pi*freq*t)+0.15*math.sin(2*math.pi*freq*2*t) + v=max(-32767,min(32767,int(s*env*8500)));peak=max(peak,abs(v));sumsq+=v*v;data+=struct.pack('0 { return true; } } + false +} +fn on_spawn(event,state,random) { + if !state.contains("ages") { state.ages=#{}; state.phases=#{}; state.directions=#{}; } + if !state.contains("maximums") {state.maximums=#{};} + // Remove cursors from a prior replay or an explicitly despawned life. + for key in state.ages.keys() { + let present=false;for unit in event.entities {if unit.entity.to_string()==key && unit.health>0 {present=true;}} + if !present { state.ages.remove(key);state.phases.remove(key);state.directions.remove(key);state.maximums.remove(key); } + } + let key=event.entity.to_string();state.ages[key]=0;state.phases[key]=1;state.directions[key]=1;state.maximums[key]=1; + for unit in event.entities {if unit.entity==event.entity && unit.health>0 {state.maximums[key]=unit.health;}} + if !alive(event,event.entity) { return #{commands:[],state:state}; } + #{commands:[#{op:"velocity",entity:event.entity,vx:0,vy:2}],state:state} +} +fn on_tick(event,state,random) { + if event.health<=0 || !alive(event,event.entity) { return #{commands:[],state:state}; } + let key=event.entity.to_string(); + if !state.contains("ages") || !state.ages.contains(key) { return #{commands:[],state:state}; } + if event.y<20 { return #{commands:[#{op:"velocity",entity:event.entity,vx:0,vy:2}],state:state}; } + // Older saved cursors lack maximums; initialize at their current living health. + if !state.contains("maximums") {state.maximums=#{};} + if !state.maximums.contains(key) {state.maximums[key]=event.health;} + let phase=if event.health*2<=state.maximums[key] {2} else {1}; + if state.phases[key]!=phase {state.phases[key]=phase;state.ages[key]=0;} + let age=state.ages[key]+1;state.ages[key]=age; + let commands=[]; + commands.push(#{op:"move",entity:event.entity,x:96,y:20});commands.push(#{op:"velocity",entity:event.entity,vx:0,vy:0}); + let cycle=if phase==1 {84} else {66}; + if age%cycle==cycle-12 {commands.push(#{op:"play_sound",sound:"iron_coast_stage2_boss_1:warning"});} + if age%cycle==0 { + if phase==1 { + commands.push(#{op:"projectile",weapon:"iron_coast_stage2_boss_1:projectile",x:120,y:72,vx:0,vy:4,hostile:true}); + commands.push(#{op:"projectile",weapon:"iron_coast_stage2_boss_1:projectile",x:200,y:72,vx:0,vy:4,hostile:true}); + } else { + for lane in [-2,-1,1,2] { + commands.push(#{op:"projectile",weapon:"iron_coast_stage2_boss_1:projectile",x:160+lane*18,y:72,vx:lane,vy:4,hostile:true}); + } + } + commands.push(#{op:"play_sound",sound:"iron_coast_stage2_boss_1:shot"}); + } + #{commands:commands,state:state} +} +fn on_death(event,state,random) { + let key=event.entity.to_string(); + if alive(event,event.entity) || !state.contains("ages") || !state.ages.contains(key) {return #{commands:[],state:state};} + state.ages.remove(key);state.phases.remove(key);state.directions.remove(key);state.maximums.remove(key); + let value=if event.objectives.contains("iron_coast_stage2_boss_1:defeated") {event.objectives["iron_coast_stage2_boss_1:defeated"]+1} else {1}; + #{commands:[#{op:"objective",key:"iron_coast_stage2_boss_1:defeated",value:value},#{op:"effect",x:event.x+64,y:event.y+32},#{op:"play_sound",sound:"iron_coast_stage2_boss_1:death"}],state:state} +} diff --git a/mods/iron_coast_stage2_boss_1/validation/Cargo.lock b/mods/iron_coast_stage2_boss_1/validation/Cargo.lock new file mode 100644 index 00000000..cc945342 --- /dev/null +++ b/mods/iron_coast_stage2_boss_1/validation/Cargo.lock @@ -0,0 +1,822 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "const-random", + "getrandom 0.3.4", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "anyhow" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "bitflags" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "bytemuck" +version = "1.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95832e849adfb21180ccb6826a99da14e5d266ae5c2e668e1602cf234f153797" + +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + +[[package]] +name = "cfg-if" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600" + +[[package]] +name = "const-random" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" +dependencies = [ + "const-random-macro", +] + +[[package]] +name = "const-random-macro" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" +dependencies = [ + "getrandom 0.2.17", + "once_cell", + "tiny-keccak", +] + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01a7799fd6b852db0e61728dde9a204c423b44d689dbd432522543614b490e78" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "dyn-clone" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "fdeflate" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "flate2" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e634e2e0ebac1ee034020da1ca582e17ffe4e0f5e985823721e168928136dcb" +dependencies = [ + "crc32fast", + "miniz_oxide 0.9.1", + "zlib-rs", +] + +[[package]] +name = "futures-core" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" + +[[package]] +name = "futures-task" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" + +[[package]] +name = "futures-util" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "image" +version = "0.25.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85ab80394333c02fe689eaf900ab500fbd0c2213da414687ebf995a65d5a6104" +dependencies = [ + "bytemuck", + "byteorder-lite", + "moxcms", + "num-traits", + "png", +] + +[[package]] +name = "indexmap" +version = "2.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "iron-coast-stage2-early-validation" +version = "1.0.0" +dependencies = [ + "anyhow", + "raptor-replica", + "serde_json", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "js-sys" +version = "0.3.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7883d941dae510fb2d978fc3fe018c71c9e2892fd38854de3e8b92c2e5ad9cc5" +dependencies = [ + "cfg-if", + "futures-util", + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.190" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce5d3ddc6d3fa000eb1536d85e147bfe31aacaba692ed6a876f95cb7c855be78" + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "miniz_oxide" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b63fbc4a50860e98e7b2aa7804ded1db5cbc3aff9193adaff57a6931bf7c4b4c" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "moxcms" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb85c154ba489f01b25c0d36ae69a87e4a1c73a72631fc6c0eb6dde34a73e44b" +dependencies = [ + "num-traits", + "pxfm", +] + +[[package]] +name = "no-std-compat" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c" +dependencies = [ + "spin", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "png" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61" +dependencies = [ + "bitflags", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide 0.8.9", +] + +[[package]] +name = "portable-atomic" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "pxfm" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d55d956fa96f5ec02be2e13af0e20391a5aa83d6a074e3ad368959d0fab299ea" + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "raptor-replica" +version = "0.1.0" +dependencies = [ + "anyhow", + "image", + "rhai", + "schemars", + "semver", + "serde", + "serde_json", + "sha2", + "toml", +] + +[[package]] +name = "rhai" +version = "1.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0334639972c0ea5a3fd366aa36116754a11431b619fec3ed559b3f73bcbcebf5" +dependencies = [ + "ahash", + "bitflags", + "no-std-compat", + "num-traits", + "once_cell", + "rhai_codegen", + "serde", + "smallvec", + "smartstring", + "thin-vec", + "web-time", +] + +[[package]] +name = "rhai_codegen" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cd3a7535e50bf36857e7be7bec276d334e8c2dfa469c2201226fd01638ea5ca" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "rustversion" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" + +[[package]] +name = "schemars" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615" +dependencies = [ + "dyn-clone", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e265784ad618884abaea0600a9adf15393368d840e0222d101a072f3f7534d" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 2.0.119", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" +dependencies = [ + "serde", + "serde_core", +] + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.7", +] + +[[package]] +name = "serde_derive_internals" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "serde_json" +version = "1.0.152" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1741ab7a6cc54a03a89b5d563ed60075c277d9e3cfa73ad0c1f23f23974703c6" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_spanned" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +dependencies = [ + "serde", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "simd-adler32" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b3dc8af474f516a851ff4bd12db780f948b9250ad37211e4eec0bccea54e01b" +dependencies = [ + "serde", +] + +[[package]] +name = "smartstring" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29" +dependencies = [ + "autocfg", + "static_assertions", + "version_check", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "syn" +version = "2.0.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "3.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d62a2e0561533f2ca2561d0cf27fd9fedb640a1bf2616ff5d5c80d99017faadc" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thin-vec" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6a4b9ba8738cb4a4f399d37e266becfd475e75eb73425b87a05a2f2039ba63e" + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "toml" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "toml_write", + "winnow", +] + +[[package]] +name = "toml_write" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" + +[[package]] +name = "typenum" +version = "1.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" + +[[package]] +name = "unicode-ident" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasip2" +version = "1.0.4+wasi-0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.129" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb54f33acc68fd454578d9820b0bde1a1a3d17aa17bb7b6595806d02886d409" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.129" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e29d0c35b16e224a7eeb5cd2d25e3e1968fbd65604117b44d3b789d00ee8535" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.129" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f501a8bc3719dba86ef8ae4728879c08001bea749eb1333ac5b91e040e2a6b7" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 3.0.7", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.129" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23f0c9c52aa7cd7d77769a4cfe2a9adb1b331f489a41d912ce14513d5ab995c6" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winnow" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" +dependencies = [ + "memchr", +] + +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + +[[package]] +name = "zerocopy" +version = "0.8.62" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86502bf56ac7c77571a32e2647bb2a15894565e981fb2a48d7bde2d91c965a9d" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.62" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5457206954b06561e2608c7e19cf58b1926586d999c246eebe4502f7e2039d1a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "zlib-rs" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b268e58e7c693d7c271f93ffc4ba3b380412554231c85bf61ca7af91042a4112" + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/mods/iron_coast_stage2_boss_1/validation/Cargo.toml b/mods/iron_coast_stage2_boss_1/validation/Cargo.toml new file mode 100644 index 00000000..3cfd92e4 --- /dev/null +++ b/mods/iron_coast_stage2_boss_1/validation/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "iron-coast-stage2-early-validation" +version = "1.0.0" +edition = "2024" +[dependencies] +raptor-replica = { path = "../../..", default-features = false } +serde_json = "1" +anyhow = "1" +[[bin]] +name = "validate-stage2-early" +path = "validate.rs" diff --git a/mods/iron_coast_stage2_boss_1/validation/validate.rs b/mods/iron_coast_stage2_boss_1/validation/validate.rs new file mode 100644 index 00000000..f93db208 --- /dev/null +++ b/mods/iron_coast_stage2_boss_1/validation/validate.rs @@ -0,0 +1,646 @@ +//! Actual API/World integration; all captured original art stays outside packages. +use anyhow::{Result, ensure}; +use raptor_replica::{ + assets::{Catalog, Sprite}, + content::{ContentId, ContentPack, Registry, art_sprite_variant}, + modding::{self, ActiveMods, Command}, + persistence::Pilot, + render::{self, Canvas}, + simulation::{Input, Outcome, World}, + sound, +}; +use serde_json::{Value, json}; +use std::{ + collections::{BTreeMap, BTreeSet}, + fs, + path::{Path, PathBuf}, +}; +fn id(s: &str) -> ContentId { + s.into() +} +fn build( + base: &Registry, + mods: &Path, + enabled: &[String], + catalog: Option<&Catalog>, +) -> Result { + ActiveMods::build(base, &modding::discover(mods), enabled, catalog) +} +fn input(world: &World, required: &str, boss: &str) -> Input { + let target = world + .enemies + .iter() + .filter(|e| e.health > 0 && e.y >= 0 && e.y < 140) + .find(|e| e.definition.0 == required) + .or_else(|| { + world + .enemies + .iter() + .find(|e| e.definition.0 == boss && e.health > 0) + }) + .or_else(|| { + world + .enemies + .iter() + .filter(|e| e.health > 0 && e.y >= 0 && e.y < 130) + .min_by_key(|e| (e.x - world.player.x).abs()) + }); + let desired = target.map(|e| e.x + e.width / 2 - 16).unwrap_or(144); + Input { + fire: true, + absolute: Some([ + world.player.x + (desired - world.player.x).clamp(-4, 4), + 160, + ]), + ..Input::default() + } +} +fn ppm(path: &Path, im: &Sprite, palette: &[[u8; 3]; 256]) -> Result<()> { + let mut bytes = format!("P6\n{} {}\n255\n", im.width, im.height).into_bytes(); + for c in &im.pixels { + bytes.extend_from_slice(if *c < 256 { + &palette[*c as usize] + } else { + &[18, 22, 28] + }); + } + fs::write(path, bytes)?; + Ok(()) +} +fn capture( + catalog: &Catalog, + active: &ActiveMods, + world: &World, + out: &Path, + label: &str, +) -> Result<()> { + fs::create_dir_all(out)?; + let palette = catalog.palette()?; + let mission = &active.registry.missions[&world.mission]; + let owner = active + .registry + .owners + .get(&world.mission) + .map(String::as_str) + .unwrap_or("base"); + for hd in [false, true] { + let scale = if hd { 4 } else { 1 }; + let mut c = Canvas::new(scale); + c.clear(0); + if !mission.tiles.is_empty() { + let row = (world.tick as usize / 16) + % mission.layout.len().div_ceil(mission.columns as usize); + for gy in 0..7 { + for gx in 0..mission.columns as usize { + let k = ((row + gy) * mission.columns as usize + gx) % mission.layout.len(); + let tile = &mission.tiles[mission.layout[k] as usize]; + let s = art_sprite_variant(catalog, &active.registry, owner, &tile.art, 0, hd)?; + let s = raptor_replica::terrain_hd::logical_sprite(&s, 32 * scale, 32 * scale)?; + c.blit(&s, (gx * 32 * scale) as i32, (gy * 32 * scale) as i32); + } + } + } + for e in &world.enemies { + let def = &active.registry.enemies[&e.definition]; + if let Some(art) = &def.art { + let owner = active + .registry + .owners + .get(&e.definition) + .map(String::as_str) + .unwrap_or("base"); + let s = art_sprite_variant(catalog, &active.registry, owner, art, 0, hd)?; + let s = raptor_replica::terrain_hd::logical_sprite( + &s, + art.logical_width as usize * scale, + art.logical_height as usize * scale, + )?; + c.blit(&s, e.x * scale as i32, e.y * scale as i32); + } + } + for p in &world.projectiles { + if let Some(def) = active.registry.weapons.get(&p.weapon) { + if let Some(art) = &def.art { + let owner = active + .registry + .owners + .get(&p.weapon) + .map(String::as_str) + .unwrap_or("base"); + let s = art_sprite_variant(catalog, &active.registry, owner, art, 0, hd)?; + let s = raptor_replica::terrain_hd::logical_sprite( + &s, + art.logical_width as usize * scale, + art.logical_height as usize * scale, + )?; + c.blit(&s, p.x * scale as i32, p.y * scale as i32); + } + } + } + let player = + catalog.sprite(catalog.id("LPLAYER_PIC")? + world.player.bank.clamp(0, 6) as u32)?; + let player = render::nearest(&player, scale); + c.blit( + &player, + world.player.x * scale as i32, + world.player.y * scale as i32, + ); + ppm( + &out.join(format!("{label}-{}.ppm", if hd { "hd4" } else { "sd1" })), + &c.image, + &palette, + )?; + } + Ok(()) +} +fn bosses(base: &Registry, mods: &Path, catalog: &Catalog) -> Result { + let mut rows = vec![]; + for n in [1, 2] { + let owner = format!("iron_coast_stage2_boss_{n}"); + let unit = format!("{owner}:unit"); + let objective = format!("{owner}:defeated"); + let mut active = build(base, mods, &[owner.clone()], Some(catalog))?; + let def = &active.registry.enemies[&id(&unit)]; + ensure!(def.ground && def.boss && def.legacy.is_none()); + active.registry.apply(serde_json::from_value::(json!({"missions":[{"id":"base:stage2_boss_fixture","name":"Boss integration fixture","duration":6000,"auto_complete":false,"spawns":[{"tick":0,"enemy":unit,"x":96,"y":-80}]}]}))?,"base")?; + let mut p = Pilot::default(); + p.mission = id("base:stage2_boss_fixture"); + p.inventory.insert(id("base:energy"), 75); + let mut w = World::new(&p.mission, &p, &active.registry)?; + let mut cues = BTreeSet::new(); + let mut minimum_health = i32::MAX; + for _ in 0..2200 { + w.step(input(&w, "", &unit), &active.registry, &mut active.scripts)?; + for s in &w.mod_sounds { + cues.insert(s.0.clone()); + } + for e in &w.enemies { + minimum_health = minimum_health.min(e.health); + } + if w.objectives.get(&objective) == Some(&1) { + break; + } + } + ensure!( + w.objectives.get(&objective) == Some(&1), + "boss{n} not killed {:?} tick{} health{}", + w.outcome, + w.tick, + w.player.shield + ); + ensure!(w.player.shield > 0); + ensure!(cues.contains(&format!("{owner}:death"))); + let snapshot = active.scripts.checkpoints(); + let at = w.digest(); + w.step(Input::default(), &active.registry, &mut active.scripts)?; + ensure!(w.objectives[&objective] == 1); + rows.push(json!({"boss":unit,"tick":w.tick,"shield":w.player.shield,"minimum_observed_health":minimum_health,"cues":cues,"digest_before_extra_step":at,"serialized_script_state_bytes":serde_json::to_vec(&snapshot.0)?.len()})); + // Duplicate dead callback cannot pay objective again; prior life cursor removed. + active.scripts.begin_tick(); + let commands = active.scripts.invoke( + &owner, + "scripts/ai.rhai", + "on_death", + &json!({"entity":1,"x":96,"y":20,"entities":[],"objectives":{objective.clone():1}}), + 0, + )?; + ensure!(commands.is_empty()); + // A queued early-killed spawn must register exactly its death, never emit movement/sound. + active.scripts.begin_tick(); + let event = json!({"entity":900,"x":96,"y":20,"entities":[],"objectives":{}}); + ensure!( + active + .scripts + .invoke(&owner, "scripts/ai.rhai", "on_spawn", &event, 0)? + .is_empty() + ); + active.scripts.begin_tick(); + let commands = active + .scripts + .invoke(&owner, "scripts/ai.rhai", "on_death", &event, 0)?; + ensure!( + commands + .iter() + .any(|c| matches!(c,Command::Objective{key,value}if key==&objective&&*value==1)) + ); + } + Ok(json!({"standalone_real_world_bosses":rows,"early_spawn_death_and_duplicate_death":true})) +} +fn missions(base: &Registry, mods: &Path, catalog: &Catalog, output: &Path) -> Result { + let mut report = vec![]; + for n in [1, 2] { + let owner = format!("iron_coast_stage2_mission_{n}"); + let boss = format!("iron_coast_stage2_boss_{n}"); + let required = format!( + "iron_coast_stage2_{}", + if n == 1 { "siege" } else { "skimmer" } + ); + let mission = format!("{owner}:mission_0{n}"); + let enabled = vec![ + "iron_coast_stage2_music".into(), + "iron_coast_stage2_interceptor".into(), + required.clone(), + boss.clone(), + owner.clone(), + ]; + let count = if n == 1 { 3 } else { 4 }; + let mut runs = vec![]; + for case in 0..7 { + let difficulty = match case { + 4 => 0, + 5 => 1, + 6 => 3, + _ => 2, + }; + let full = case == 2; + let purchased = case == 3; + let mut case_enabled = enabled.clone(); + if purchased { + case_enabled.extend([ + "iron_coast_railburst".into(), + "iron_coast_depth_charge".into(), + ]); + } + let mut active = build(base, mods, &case_enabled, Some(catalog))?; + let mut p = Pilot::default(); + p.mission = id(&mission); + p.difficulty = difficulty; + let initial_shield = if case == 1 { 100 } else { 75 }; + p.inventory.insert(id("base:energy"), initial_shield); + p.credits = if case == 1 { 0 } else { 10000 }; + if purchased { + for weapon in [ + "iron_coast_railburst:equipment", + "iron_coast_depth_charge:equipment", + ] { + p.credits += active.registry.items[&id(weapon)].price; + p.buy(&id(weapon), &active.registry)?; + } + p.selected = Some(id(if n == 1 { + "iron_coast_railburst:equipment" + } else { + "iron_coast_depth_charge:equipment" + })); + } + let initial_credits = p.credits; + if full { + for (id, item) in &active.registry.items { + if p.inventory_slots() >= 20 { + break; + } + if item.legacy == Some(16) || item.legacy == Some(17) || item.consumable { + continue; + } + p.inventory.insert(id.clone(), item.initial_count); + } + ensure!(p.inventory_slots() == 20); + } + let inventory = p.inventory.clone(); + eprintln!( + "mission{n}: case{case} difficulty{difficulty} full{full} purchased{purchased} starting" + ); + let mut w = World::new(&p.mission, &p, &active.registry)?; + let mut cues = BTreeSet::new(); + let mut native = BTreeMap::new(); + let mut moving = BTreeSet::new(); + let mut checkpoint = None; + let mut captures = BTreeSet::new(); + for _ in 0..5000 { + w.step( + input(&w, &(required.clone() + ":unit"), &(boss.clone() + ":unit")), + &active.registry, + &mut active.scripts, + )?; + for s in &w.mod_sounds { + cues.insert(s.0.clone()); + } + for e in &w.enemies { + if e.definition.0.starts_with("base:enemy_") { + ensure!(active.registry.enemies[&e.definition].legacy.is_some()); + let old = native.entry(e.entity).or_insert((e.x, e.y)); + if *old != (e.x, e.y) { + moving.insert(e.definition.0.clone()); + } + } + } + if case == 0 && [500, 1600, 2000, 2350, 2500].contains(&w.tick) { + capture( + catalog, + &active, + &w, + output, + &format!("mission{n}-tick{}", w.tick), + )?; + captures.insert(w.tick); + } + if w.tick == 1000 { + checkpoint = Some((w.clone(), active.scripts.checkpoints())); + } + if w.outcome != Outcome::Playing { + break; + } + } + ensure!( + w.outcome == Outcome::Complete, + "mission{n} full{full} {:?} tick{} shield{} objectives{:?}", + w.outcome, + w.tick, + w.player.shield, + w.objectives + ); + ensure!( + w.objectives[&(required.clone() + ":defeated")] == count + && w.objectives[&(boss.clone() + ":defeated")] == 1 + ); + ensure!(w.objectives[&(owner.clone() + ":debrief")] == 1); + ensure!(w.player.shield > 0); + ensure!(moving.len() == 3, "all native classes observed moving"); + if full { + for (item, count) in &inventory { + if item.0 != "base:energy" && item.0 != "base:super_shield" { + ensure!( + w.player.inventory.get(item) == Some(count), + "inventory preservation:{item}" + ); + } + } + } + if purchased { + ensure!( + w.player + .inventory + .get(&id("iron_coast_railburst:equipment")) + == Some(&1) + && w.player + .inventory + .get(&id("iron_coast_depth_charge:equipment")) + == Some(&1), + "owned gear preserved" + ); + } + let final_tick = w.tick; + let final_digest = w.digest(); + let final_scripts = serde_json::to_value(active.scripts.checkpoints())?; + let earned = w.player.credits; + w.step(Input::default(), &active.registry, &mut active.scripts)?; + ensure!(w.player.credits == earned, "reward repeated"); + let (mut resumed, states) = checkpoint.unwrap(); + let mut resumed_active = build(base, mods, &case_enabled, Some(catalog))?; + resumed_active + .scripts + .restore(serde_json::from_slice(&serde_json::to_vec(&states)?)?); + while resumed.tick < final_tick { + resumed.step( + input( + &resumed, + &(required.clone() + ":unit"), + &(boss.clone() + ":unit"), + ), + &resumed_active.registry, + &mut resumed_active.scripts, + )?; + } + ensure!( + resumed.digest() == final_digest + && serde_json::to_value(resumed_active.scripts.checkpoints())? == final_scripts, + "state/RNG continuation deterministic" + ); + // Restart reuses same script state but all mission goals/cursors must reset. + let mut restart = World::new(&p.mission, &p, &active.registry)?; + restart.step(Input::default(), &active.registry, &mut active.scripts)?; + ensure!( + restart.objectives[&(required.clone() + ":defeated")] == 0 + && restart.objectives[&(boss.clone() + ":defeated")] == 0 + && restart.objectives[&(owner.clone() + ":complete")] == 0 + ); + runs.push(json!({"difficulty":difficulty,"full20_inventory":full,"purchased_new_gear":purchased,"initial_shield":initial_shield,"initial_credits":initial_credits,"tick":final_tick,"shield":w.player.shield,"credits":earned,"credit_gain":earned-initial_credits,"objectives":w.objectives,"native_classes_moving":moving,"cues":cues,"captures":captures,"digest":final_digest,"serialized_state_rng_round_trip_identical":true,"replay_reset":true,"reward_once":true})); + fs::write( + output.join(format!("mission{n}-progress.json")), + serde_json::to_vec_pretty(&runs)?, + )?; + eprintln!( + "mission{n}: case{case} difficulty{difficulty} passed tick{final_tick} shield{} credits{earned}", + w.player.shield + ); + } + // Authentic objective callback gating; no elapsed timeout can complete. + let mut active = build(base, mods, &enabled, Some(catalog))?; + let mut p = Pilot::default(); + p.mission = id(&mission); + let mut w = World::new(&p.mission, &p, &active.registry)?; + w.step(Input::default(), &active.registry, &mut active.scripts)?; + w.objectives.insert(boss.clone() + ":defeated", 1); + w.objectives + .insert(required.clone() + ":defeated", count - 1); + w.step(Input::default(), &active.registry, &mut active.scripts)?; + ensure!(w.outcome == Outcome::Playing); + w.objectives.insert(required.clone() + ":defeated", count); + w.step(Input::default(), &active.registry, &mut active.scripts)?; + ensure!( + w.outcome == Outcome::Complete + && w.player.credits == if n == 1 { 24000 } else { 32000 } + ); + // This persistence-only fixture suppresses pilot death. It is separate + // from every ordinary-loadout balance result above, which uses actual + // purchased/registered health and unmodified gameplay damage. + let mut late = World::new(&p.mission, &p, &active.registry)?; + // Use the hardest difficulty for the persistence stress fixture. + late.difficulty = 3; + for _ in 0..5000 { + // Normal original pickups can replace a shield value. Restore + // this explicit fixture buffer each step, rather than treating + // it as a persistent piece of gameplay equipment. + late.player.shield = 10000; + late.step(Input::default(), &active.registry, &mut active.scripts)?; + } + ensure!( + late.outcome == Outcome::Playing, + "late persistence fixture: {:?} tick{} shield{} objectives{:?}", + late.outcome, + late.tick, + late.player.shield, + late.objectives + ); + let required_alive = late + .enemies + .iter() + .filter(|e| { + e.definition.0 == required.clone() + ":unit" + && e.health > 0 + && e.y >= 0 + && e.y < 140 + }) + .count(); + ensure!( + required_alive == count as usize, + "required convoys remain reachable" + ); + ensure!( + late.enemies + .iter() + .any(|e| { e.definition.0 == boss.clone() + ":unit" && e.health > 0 && e.y == 20 }), + "boss must remain until actual death" + ); + let definition = &active.registry.missions[&p.mission]; + let map_height = definition.layout.len() / definition.columns as usize * 32; + ensure!( + late.scroll as usize + 200 < map_height, + "late fight has terrain coverage" + ); + report.push(json!({"mission":mission,"enabled_packages":enabled,"required_deaths":count,"runs":runs,"missing_one_required_death_blocks_victory":true,"late_fight_fixture":{"tick":late.tick,"scroll":late.scroll,"reachable_required_units":required_alive,"boss_remains":true,"playing_beyond_declared_duration":true,"terrain_rows":map_height/32,"terrain_covered":true,"scope":"Persistence-only difficulty3 fixture restoring shield10000 before each step to suppress pilot death; ordinary balance runs above have no health/damage cheats."}})); + } + Ok( + json!({"missions":report,"strategy":"Held Fire; mouseposition moves≤4 logicalpx/tick, y160, aim at required living convoy centers then boss then ordinary visible enemies. No damage/shield/credit cheats or loans.","capture_scope":"Actual PNG loader, native palette, World entity positions, Canvas.blit; simplified terrain row sampler/headless diagnostics, not liveSDL/Host capture."}), + ) +} + +fn difficulty_phases(base: &Registry, mods: &Path, catalog: &Catalog) -> Result { + let mut rows = vec![]; + for n in [1, 2] { + for difficulty in 0..4 { + let owner = format!("iron_coast_stage2_boss_{n}"); + let unit = format!("{owner}:unit"); + let mut active = build(base, mods, &[owner.clone()], Some(catalog))?; + active.registry.apply(serde_json::from_value::(json!({"missions":[{"id":"base:stage2_phase_fixture","name":"Phase fixture","duration":6000,"auto_complete":false,"spawns":[{"tick":0,"enemy":unit,"x":96,"y":-80}]}]}))?,"base")?; + let mut p = Pilot::default(); + p.mission = id("base:stage2_phase_fixture"); + p.difficulty = difficulty; + let mut w = World::new(&p.mission, &p, &active.registry)?; + for _ in 0..70 { + w.step(Input::default(), &active.registry, &mut active.scripts)?; + } + let e = w.enemies.first().unwrap(); + let key = e.entity.to_string(); + let maximum = e.health; + let statekey = format!("{owner}/scripts/ai.rhai"); + ensure!( + active.scripts.states[&statekey]["maximums"][&key] == maximum + && active.scripts.states[&statekey]["phases"][&key] == 1, + "difficulty{difficulty} must start phase1" + ); + w.enemies[0].health = maximum / 2 + 1; + w.step(Input::default(), &active.registry, &mut active.scripts)?; + ensure!(active.scripts.states[&statekey]["phases"][&key] == 1); + w.enemies[0].health = maximum / 2; + w.step(Input::default(), &active.registry, &mut active.scripts)?; + ensure!( + active.scripts.states[&statekey]["phases"][&key] == 2 + && active.scripts.states[&statekey]["ages"][&key] == 1 + ); + rows.push(json!({"boss":unit,"difficulty":difficulty,"actual_spawn_max_health":maximum,"initial_phase":1,"half_health_phase":2,"phase_timer_reset":true})); + } + } + Ok( + json!({"all4_difficulties":rows,"fixture_scope":"Health boundary mutation tests only; ordinary boss/mission outcomes use unmodified damage gameplay."}), + ) +} +fn audio( + base: &Registry, + mods: &Path, + catalog: &Catalog, + enabled: &[String], + output: &Path, +) -> Result { + let active = build(base, mods, enabled, Some(catalog))?; + let mut bank = sound::SoundBank::default(); + let mut rows = vec![]; + fs::create_dir_all(output)?; + for (id, _) in &active.registry.sounds { + if !id.0.starts_with("iron_coast_stage2_") { + continue; + } + let mut mixer = raptor_replica::audio::Mixer::new(22050, &catalog.named("GENMIDI_OP2")?)?; + mixer.fx_volume = 127; + mixer.music_volume = 0; + mixer.start_capture(2)?; + bank.queue_mod(&active.registry, &mut mixer, id)?; + let mut samples = vec![0i16; 22050 * 4]; + mixer.mix(&mut samples); + let peak = samples.iter().map(|v| i32::from(*v).abs()).max().unwrap(); + ensure!(peak > 0, "audible cue:{id}"); + let capture = mixer.take_capture().unwrap(); + fs::write( + output.join(format!("{}.wav", id.0.replace(':', "-"))), + sound::encode_capture(&capture)?, + )?; + let mut muted = raptor_replica::audio::Mixer::new(22050, &catalog.named("GENMIDI_OP2")?)?; + muted.fx_volume = 0; + muted.music_volume = 0; + bank.queue_mod(&active.registry, &mut muted, id)?; + let mut quiet = vec![0i16; 22050 * 4]; + muted.mix(&mut quiet); + ensure!(quiet.iter().all(|v| *v == 0), "mute:{id}"); + rows.push(json!({"sound":id,"mixed_peak":peak,"fx_mute_zero":true})); + } + Ok( + json!({"mixer":"Native SoundBank/Mixer with original GENMIDI,2s PCM capture each cue; no live audio device claim","sounds":rows}), + ) +} + +fn main() -> Result<()> { + let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("../../..") + .canonicalize()?; + let catalog = Catalog::open(root.join("data"))?; + let base = Registry::base(&catalog)?; + let mods = root.join("mods"); + let output = root.join(".reference/iron-coast-stage2-authoring/runtime"); + fs::create_dir_all(&output)?; + let only_boss = std::env::args().any(|s| s == "--boss-only"); + let mut report = json!({"bosses":bosses(&base,&mods,&catalog)?,"difficulty_phase_checks":difficulty_phases(&base,&mods,&catalog)?}); + if !only_boss { + report["mission_acceptance"] = missions(&base, &mods, &catalog, &output)?; + report["combined_audio"] = audio( + &base, + &mods, + &catalog, + &[ + "iron_coast_stage2_boss_1".into(), + "iron_coast_stage2_boss_2".into(), + "iron_coast_stage2_mission_1".into(), + "iron_coast_stage2_mission_2".into(), + "iron_coast_stage2_interceptor".into(), + "iron_coast_stage2_siege".into(), + "iron_coast_stage2_skimmer".into(), + "iron_coast_stage2_music".into(), + ], + &output.join("audio"), + )?; + } + report["boss_audio"] = audio( + &base, + &mods, + &catalog, + &[ + "iron_coast_stage2_boss_1".into(), + "iron_coast_stage2_boss_2".into(), + ], + &output.join("audio"), + )?; + for n in [1, 2] { + let owner = format!("iron_coast_stage2_boss_{n}"); + let active = build(&base, &mods, &[owner], Some(&catalog))?; + for (id, s) in &active.registry.sounds { + if id.0.starts_with("iron_coast_stage2_boss_") { + let p = active + .registry + .asset_roots + .get(id.0.split_once(':').unwrap().0) + .unwrap() + .join(&s.file); + let decoded = sound::decode(&fs::read(p)?)?; + ensure!(!decoded.data.is_empty()); + } + } + } + fs::write( + output.join(if only_boss { + "boss-acceptance.json" + } else { + "acceptance.json" + }), + serde_json::to_vec_pretty(&report)?, + )?; + println!("{}", serde_json::to_string_pretty(&report)?); + Ok(()) +} diff --git a/mods/iron_coast_stage2_boss_2/README.md b/mods/iron_coast_stage2_boss_2/README.md new file mode 100644 index 00000000..b6411fbd --- /dev/null +++ b/mods/iron_coast_stage2_boss_2/README.md @@ -0,0 +1,40 @@ +# Iron Coast II: Undertow + +A standalone boss content package for Black Tide. Enable this package directly +in **Mods**, or enable its mission to select it as a dependency. It adds +`iron_coast_stage2_boss_2:unit` and no campaign, overrides or equipment. + +The surfaced/ground target has 400 health, awards 16,000 credits and retains +a 48×80 logical collision canvas in SD and HD. It remains reachable until killed. +Its two phases change at half of that life’s actual spawn health on every +difficulty, with a new attack timer and twelve ticks of audible warning before +every volley. Difficulty 0/1 uses the engine’s half-health boss rule; 2/3 uses +the nominal health above. Cadence is 76 / 62 simulation ticks +(first/second phase), at the original 70/3 Hz. Every projectile is hostile and +leaves deliberate escape lanes; no phase is invulnerable. + +Actual death increments `iron_coast_stage2_boss_2:defeated` once. It does not finish a mission. +Per-life cursors are removed on death and pruned on spawn/replay; early kills +before the queued spawn callback still register the real death. + +Artwork is a genuine new builtin imagegen master, with full alpha and identical +SD/HD canvas alignment. `build_assets.py` reproduces palette-aware SD art, 4× HD +and deterministic PCM WAV effects from the tracked raw masters. Projectile art +is the same newly authored micro-missile independently included with each boss. +See [generation provenance](generation-provenance.json) and +[asset recipe/report](asset-report.json). Original Raptor style references and +local review captures are external. + +From `RustRaptor/`: + +```sh +cargo run --locked --no-default-features -- --mods mods --validate-mods iron_coast_stage2_boss_2 +CARGO_TARGET_DIR="$PWD/target" cargo run --locked --release --manifest-path mods/iron_coast_stage2_boss_1/validation/Cargo.toml -- --boss-only +python3 mods/iron_coast_stage2_boss_2/build_assets.py +``` + +The real-catalog standalone kill, every-difficulty phase boundaries, early and +duplicate hook checks and native Mixer/mute observations passed. Exact results +and scopes are recorded in `acceptance-report.json`. + +Asset recipes use Python 3 with Pillow. The game uses the shipped PNG and WAV files. diff --git a/mods/iron_coast_stage2_boss_2/acceptance-report.json b/mods/iron_coast_stage2_boss_2/acceptance-report.json new file mode 100644 index 00000000..d9dd97eb --- /dev/null +++ b/mods/iron_coast_stage2_boss_2/acceptance-report.json @@ -0,0 +1,127 @@ +{ + "utc": "2026-10-11T08:51:02.199238+00:00", + "status": "author_checked_review_ready", + "real_catalog": true, + "engine_source_hashes_at_report": { + "src/assets.rs": "4cdf11a229f6ca4c6183fb545dba43e9a2323f839f7a095292045aa13a773ddc", + "src/content.rs": "7f35df7100c450ba4bb30a0fdc90101c115b5ae42a7aac57829441c5b7761647", + "src/modding.rs": "f37d67004392f5726121e58a995900cd7062016e3f060ea131b0df38995e2912", + "src/simulation.rs": "0ec9f6da11ab82c1461868a7b147e4cdb14689fa7373bd0c24067d9014e9583a", + "src/render.rs": "d4abdccbc3c1ee840ef8548bcff43080521937ef9f9f5ed69e810f417ef1e842", + "src/sound.rs": "aff6779b85f9f4f4bc30a15ad75ec6fdd61d42895639700f4842870636e73c4b", + "src/persistence.rs": "9a4adf1e33d3504db3d4d3e6091316cc7116fb35c89b2de8fbd4640d368aa0e2", + "Cargo.lock": "aac0a22725250ab35828223f8d129e4d2a4e6113cf81463e59600da3a59ffdea" + }, + "catalog_file_hashes": { + "data/INDEX": "4ce78e5e638b6603114dd233ceaa41f386c0963ba4aa02ecf88ce0215b096681", + "data/misc/PALETTE_DAT": "1cf6adb926d1dee1888b3e3d33b51a7049b3e5eb5f90a3067ef71c8970547204", + "data/misc/GENMIDI_OP2": "fdc93c076bf44207299e61ec1bbcfafca421454bfa99dd14fa4e5dcada1547b9" + }, + "compiled_validation_binary_sha256": "98f43eef5943061a18a465e95e8089189be793b9f8cbac275b8ebe982953567b", + "full_external_result_sha256": "63f97c1f8cab57452ee9235124551178fe2593c5e40f4a5ecd6e2aa9bf0cd19e", + "cli": { + "selected_packages": 10, + "overrides": 0, + "log_sha256": "c9401f44dc4fa438f75ccc00223e95f79cfa8bffcd1c8db5c106963f7b474822" + }, + "visual_limits": "Author inspected native indexed SD1/HD4 Canvas/PNG-loader diagnostics, exact new source masters and SD/HD final art. Terrain in owned captures uses a simplified row sampler. Live SDL/Host captures and independent eight-stage progression are root-owned; no live device or whole-map rendering claim.", + "package": "iron_coast_stage2_boss_2", + "content_sha256": "e664d46f2cd4a20b7dff8030e6f8932fc5abeb321590e02b53d8a782687d3bda", + "scripts": { + "scripts/ai.rhai": "2e794a01968fc418b86f07c8704276fdfaf35443f07a0f1a1975e52c0f7adc7c" + }, + "asset_report_sha256": "aae01dfc03415a0995e6512fce62af1a740093691f3272a8b3f101eb3f983084", + "raw_identity_checks": [ + { + "package": "iron_coast_stage2_boss_2", + "role": "unit_or_terrain", + "raw": "mods/iron_coast_stage2_boss_2/art/unit-generated-v1.png", + "raw_sha256": "ed272f27c8aa31f3292ff584a3cf0ff1ec2a7fdf8213105e503c64fc133389d0", + "builtin_byte_identical": true, + "raw_dimensions": [ + 972, + 1619 + ], + "raw_alpha": "RGBA", + "reported_success": true + }, + { + "package": "iron_coast_stage2_boss_2", + "role": "projectile", + "raw": "mods/iron_coast_stage2_boss_2/art/projectile-generated-v1.png", + "raw_sha256": "9cc6e7e6cac60f045050bdefe1c84f5fc7185bcb585b87b7a7df5b2206a38ebb", + "builtin_byte_identical": true, + "raw_dimensions": [ + 887, + 1774 + ], + "raw_alpha": "RGBA", + "reported_success": true + } + ], + "standalone_world_kill": { + "boss": "iron_coast_stage2_boss_2:unit", + "cues": [ + "iron_coast_stage2_boss_2:death", + "iron_coast_stage2_boss_2:shot", + "iron_coast_stage2_boss_2:warning" + ], + "digest_before_extra_step": "ffe7a5201733c36b665fbec556de6e17f9e2b7093a854913904a8690a37a129e", + "minimum_observed_health": 0, + "serialized_script_state_bytes": 98, + "shield": 75, + "tick": 412 + }, + "all_difficulty_phase_checks": [ + { + "actual_spawn_max_health": 200, + "boss": "iron_coast_stage2_boss_2:unit", + "difficulty": 0, + "half_health_phase": 2, + "initial_phase": 1, + "phase_timer_reset": true + }, + { + "actual_spawn_max_health": 200, + "boss": "iron_coast_stage2_boss_2:unit", + "difficulty": 1, + "half_health_phase": 2, + "initial_phase": 1, + "phase_timer_reset": true + }, + { + "actual_spawn_max_health": 400, + "boss": "iron_coast_stage2_boss_2:unit", + "difficulty": 2, + "half_health_phase": 2, + "initial_phase": 1, + "phase_timer_reset": true + }, + { + "actual_spawn_max_health": 400, + "boss": "iron_coast_stage2_boss_2:unit", + "difficulty": 3, + "half_health_phase": 2, + "initial_phase": 1, + "phase_timer_reset": true + } + ], + "early_duplicate_callback_scope": "Direct Rhai hook protocol checks register an already-dead spawn silently and count its death once; independent actual lethal-spawn World review remains separate.", + "sound_mixer_checks": [ + { + "fx_mute_zero": true, + "mixed_peak": 3072, + "sound": "iron_coast_stage2_boss_2:death" + }, + { + "fx_mute_zero": true, + "mixed_peak": 2688, + "sound": "iron_coast_stage2_boss_2:shot" + }, + { + "fx_mute_zero": true, + "mixed_peak": 1920, + "sound": "iron_coast_stage2_boss_2:warning" + } + ] +} diff --git a/mods/iron_coast_stage2_boss_2/art/projectile-generated-v1.png b/mods/iron_coast_stage2_boss_2/art/projectile-generated-v1.png new file mode 100644 index 00000000..1f51fd1b Binary files /dev/null and b/mods/iron_coast_stage2_boss_2/art/projectile-generated-v1.png differ diff --git a/mods/iron_coast_stage2_boss_2/art/projectile-hd.png b/mods/iron_coast_stage2_boss_2/art/projectile-hd.png new file mode 100644 index 00000000..b415e6b1 Binary files /dev/null and b/mods/iron_coast_stage2_boss_2/art/projectile-hd.png differ diff --git a/mods/iron_coast_stage2_boss_2/art/projectile-sd.png b/mods/iron_coast_stage2_boss_2/art/projectile-sd.png new file mode 100644 index 00000000..97f02457 Binary files /dev/null and b/mods/iron_coast_stage2_boss_2/art/projectile-sd.png differ diff --git a/mods/iron_coast_stage2_boss_2/art/unit-generated-v1.png b/mods/iron_coast_stage2_boss_2/art/unit-generated-v1.png new file mode 100644 index 00000000..8d530356 Binary files /dev/null and b/mods/iron_coast_stage2_boss_2/art/unit-generated-v1.png differ diff --git a/mods/iron_coast_stage2_boss_2/art/unit-hd.png b/mods/iron_coast_stage2_boss_2/art/unit-hd.png new file mode 100644 index 00000000..45764e83 Binary files /dev/null and b/mods/iron_coast_stage2_boss_2/art/unit-hd.png differ diff --git a/mods/iron_coast_stage2_boss_2/art/unit-sd.png b/mods/iron_coast_stage2_boss_2/art/unit-sd.png new file mode 100644 index 00000000..c20500ae Binary files /dev/null and b/mods/iron_coast_stage2_boss_2/art/unit-sd.png differ diff --git a/mods/iron_coast_stage2_boss_2/artwork-reference.json b/mods/iron_coast_stage2_boss_2/artwork-reference.json new file mode 100644 index 00000000..49e701c3 --- /dev/null +++ b/mods/iron_coast_stage2_boss_2/artwork-reference.json @@ -0,0 +1,12 @@ +{ + "reference_role": "Original Raptor military style only, not target geometry or approved HD reference", + "reference_review_path": "/home/quintine/Projects/RaptorReplica/RustRaptor/.reference/iron-coast-stage2-authoring/original-style-references.png", + "reference_review_sha256": "d92f7d68008a73d626dcc9125920b7b329d029ca87a01d28bc4005f80c4f9174", + "original_ids": [ + "10139", + "10344", + "400d5", + "4011f" + ], + "original_reference_files_not_packaged": true +} diff --git a/mods/iron_coast_stage2_boss_2/asset-report.json b/mods/iron_coast_stage2_boss_2/asset-report.json new file mode 100644 index 00000000..b525bfd8 --- /dev/null +++ b/mods/iron_coast_stage2_boss_2/asset-report.json @@ -0,0 +1,351 @@ +{ + "utc": "2026-10-11T08:16:04.830947+00:00", + "recipe": "build_assets.py", + "recipe_sha256": "f86680d12fc6e15b585f4bba40170242518c397acdd0c1cb0992d22e0a46f462", + "palette_sha256": "1cf6adb926d1dee1888b3e3d33b51a7049b3e5eb5f90a3067ef71c8970547204", + "ordinary_palette_entries_only": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 216, + 217, + 218, + 219, + 220, + 221, + 222, + 223, + 224, + 225, + 226, + 227, + 228, + 229, + 230, + 231, + 232, + 233, + 234, + 235, + 236, + 237, + 238, + 239 + ], + "assets": [ + { + "source": "art/unit-generated-v1.png", + "sha256": "ed272f27c8aa31f3292ff584a3cf0ff1ec2a7fdf8213105e503c64fc133389d0", + "logical_size": [ + 48, + 80 + ], + "hd_size": [ + 192, + 320 + ], + "alpha_below128_transparent": true, + "original_master_not_modified": true, + "whole_alpha_bounding_crop_for_projectile": null + }, + { + "source": "art/projectile-generated-v1.png", + "sha256": "9cc6e7e6cac60f045050bdefe1c84f5fc7185bcb585b87b7a7df5b2206a38ebb", + "logical_size": [ + 8, + 16 + ], + "hd_size": [ + 32, + 64 + ], + "alpha_below128_transparent": true, + "original_master_not_modified": true, + "whole_alpha_bounding_crop_for_projectile": [ + 363, + 637, + 525, + 1110 + ] + } + ], + "audio": [ + { + "file": "audio/warning.wav", + "sha256": "3076a52993dd30e4eb781256c323a865615d85720fe45c47baa4b67541d6ceb9", + "samples": 11025, + "rate": 22050, + "duration": 0.5, + "peak": 7338, + "rms": 2447.2, + "seed": 8111 + }, + { + "file": "audio/shot.wav", + "sha256": "823b9d2d3d51ccefea88e1511afaeb7a40d5e22ce47001bc3376e6419f1d0b09", + "samples": 3528, + "rate": 22050, + "duration": 0.16, + "peak": 9463, + "rms": 1891.06, + "seed": 7589 + }, + { + "file": "audio/death.wav", + "sha256": "599d493fa8b7e9944a9932135a62d0007e04533bb78f80e83aff862ca2ab4092", + "samples": 23152, + "rate": 22050, + "duration": 1.05, + "peak": 8143, + "rms": 2001.53, + "seed": 7641 + } + ], + "final_art": [ + { + "file": "art/projectile-hd.png", + "sha256": "449bc288ba96deca89aa9318fba47662d8bf8e07d82494f978ccbc4f5dd4a869", + "size": [ + 32, + 64 + ] + }, + { + "file": "art/projectile-sd.png", + "sha256": "5f408b4713a948f75d7ba1e6ee582fe8eb91a235df41e2e6d1bb4dac050fbac3", + "size": [ + 8, + 16 + ] + }, + { + "file": "art/unit-hd.png", + "sha256": "e2a136b0b054a94ef7ccc33212602ccdb6b748d7b6eee33ba05c28dbcf7d7f8c", + "size": [ + 192, + 320 + ] + }, + { + "file": "art/unit-sd.png", + "sha256": "7106674b5ab821fcb121a36f5400680c40558ece3e9a14799f5012ebf4d0a11a", + "size": [ + 48, + 80 + ] + } + ] +} diff --git a/mods/iron_coast_stage2_boss_2/audio/death.wav b/mods/iron_coast_stage2_boss_2/audio/death.wav new file mode 100644 index 00000000..fe8834ad Binary files /dev/null and b/mods/iron_coast_stage2_boss_2/audio/death.wav differ diff --git a/mods/iron_coast_stage2_boss_2/audio/shot.wav b/mods/iron_coast_stage2_boss_2/audio/shot.wav new file mode 100644 index 00000000..720239eb Binary files /dev/null and b/mods/iron_coast_stage2_boss_2/audio/shot.wav differ diff --git a/mods/iron_coast_stage2_boss_2/audio/warning.wav b/mods/iron_coast_stage2_boss_2/audio/warning.wav new file mode 100644 index 00000000..cd25aa77 Binary files /dev/null and b/mods/iron_coast_stage2_boss_2/audio/warning.wav differ diff --git a/mods/iron_coast_stage2_boss_2/build_assets.py b/mods/iron_coast_stage2_boss_2/build_assets.py new file mode 100644 index 00000000..1afd5dd3 --- /dev/null +++ b/mods/iron_coast_stage2_boss_2/build_assets.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python3 +"""Reproduce SD/HD canvases and PCM WAVs from untouched builtin generated PNGs. +No decoded original images are packaged. No painted/masked master edits occur. +""" +from pathlib import Path +import argparse,datetime,hashlib,json,math,random,struct,wave +from PIL import Image,ImageOps +ROOT=Path(__file__).resolve().parent +h=lambda p:hashlib.sha256(Path(p).read_bytes()).hexdigest() +def palette(path): + raw=path.read_bytes();assert len(raw)==768 + values=[(min(v,63)<<2)|(min(v,63)>>4) for v in raw] + values[720:]=[0]*48 + im=Image.new('P',(1,1));im.putpalette(values);return im + +def small(im,size,pal): + im=im.convert('RGBA').resize(size,Image.Resampling.LANCZOS) + alpha=im.getchannel('A').point(lambda a:255 if a>=128 else 0) + out=im.convert('RGB').quantize(palette=pal,dither=Image.Dither.NONE).convert('RGBA');out.putalpha(alpha);return out + +def canvases(source,name,size,pal): + src=Image.open(source).convert('RGBA');target=(size[0]*4,size[1]*4) + bounds=None + if name=='projectile': + bounds=src.getchannel('A').point(lambda a:255 if a>=128 else 0).getbbox();assert bounds;src=src.crop(bounds) + fit_size=(round(target[0]*.8),round(target[1]*.8)) if name=='projectile' else target + hd=Image.new('RGBA',target);fitted=ImageOps.contain(src,fit_size,Image.Resampling.LANCZOS);hd.alpha_composite(fitted,((target[0]-fitted.width)//2,(target[1]-fitted.height)//2)) + hd.save(ROOT/'art'/f'{name}-hd.png');small(hd,size,pal).save(ROOT/'art'/f'{name}-sd.png') + return {'source':str(source.relative_to(ROOT)),'sha256':h(source),'logical_size':size,'hd_size':target,'alpha_below128_transparent':True,'original_master_not_modified':True,'whole_alpha_bounding_crop_for_projectile':bounds} + +def synth(name,duration,base): + rate=22050;n=int(rate*duration);rng=random.Random(7043+sum(map(ord,name))+base);data=bytearray();peak=0;sumsq=0 + for i in range(n): + t=i/rate;u=i/n;env=min(1,u*30)*(1-u)**1.3 + if name=='shot':s=(math.sin(2*math.pi*(95*t-40*t*t))+rng.uniform(-1,1)*0.45)*math.exp(-u*3) + elif name=='death':s=rng.uniform(-1,1)*0.65+math.sin(2*math.pi*(70*t-18*t*t))*0.4 + elif name=='warning' or name=='boss_alarm':s=math.sin(2*math.pi*(base+70*math.sin(2*math.pi*t*5))*t)*0.8+0.12*math.sin(2*math.pi*base*.5*t) + else: + notes=[1,1.25,1.5,2] if name=='victory' else [1,1.5,1.25];freq=base*notes[min(len(notes)-1,int(u*len(notes)))];s=math.sin(2*math.pi*freq*t)+0.15*math.sin(2*math.pi*freq*2*t) + v=max(-32767,min(32767,int(s*env*8500)));peak=max(peak,abs(v));sumsq+=v*v;data+=struct.pack('0 { return true; } } + false +} +fn on_spawn(event,state,random) { + if !state.contains("ages") { state.ages=#{}; state.phases=#{}; state.directions=#{}; } + if !state.contains("maximums") {state.maximums=#{};} + // Remove cursors from a prior replay or an explicitly despawned life. + for key in state.ages.keys() { + let present=false;for unit in event.entities {if unit.entity.to_string()==key && unit.health>0 {present=true;}} + if !present { state.ages.remove(key);state.phases.remove(key);state.directions.remove(key);state.maximums.remove(key); } + } + let key=event.entity.to_string();state.ages[key]=0;state.phases[key]=1;state.directions[key]=1;state.maximums[key]=1; + for unit in event.entities {if unit.entity==event.entity && unit.health>0 {state.maximums[key]=unit.health;}} + if !alive(event,event.entity) { return #{commands:[],state:state}; } + #{commands:[#{op:"velocity",entity:event.entity,vx:0,vy:2}],state:state} +} +fn on_tick(event,state,random) { + if event.health<=0 || !alive(event,event.entity) { return #{commands:[],state:state}; } + let key=event.entity.to_string(); + if !state.contains("ages") || !state.ages.contains(key) { return #{commands:[],state:state}; } + if event.y<20 { return #{commands:[#{op:"velocity",entity:event.entity,vx:0,vy:2}],state:state}; } + // Older saved cursors lack maximums; initialize at their current living health. + if !state.contains("maximums") {state.maximums=#{};} + if !state.maximums.contains(key) {state.maximums[key]=event.health;} + let phase=if event.health*2<=state.maximums[key] {2} else {1}; + if state.phases[key]!=phase {state.phases[key]=phase;state.ages[key]=0;} + let age=state.ages[key]+1;state.ages[key]=age; + let commands=[]; + let direction=state.directions[key]; + if event.x>=224 {direction=-1;} if event.x<=48 {direction=1;} + state.directions[key]=direction; + commands.push(#{op:"move",entity:event.entity,x:event.x,y:20});commands.push(#{op:"velocity",entity:event.entity,vx:direction,vy:0}); + let cycle=if phase==1 {76} else {62}; + if age%cycle==cycle-12 {commands.push(#{op:"play_sound",sound:"iron_coast_stage2_boss_2:warning"});} + if age%cycle==0 { + if phase==1 { + commands.push(#{op:"projectile",weapon:"iron_coast_stage2_boss_2:projectile",x:event.x+10,y:90,vx:-1,vy:4,hostile:true}); + commands.push(#{op:"projectile",weapon:"iron_coast_stage2_boss_2:projectile",x:event.x+38,y:90,vx:1,vy:4,hostile:true}); + } else { + for lane in [-2,0,2] { + commands.push(#{op:"projectile",weapon:"iron_coast_stage2_boss_2:projectile",x:event.x+24+lane*6,y:90,vx:lane,vy:4,hostile:true}); + } + } + commands.push(#{op:"play_sound",sound:"iron_coast_stage2_boss_2:shot"}); + } + #{commands:commands,state:state} +} +fn on_death(event,state,random) { + let key=event.entity.to_string(); + if alive(event,event.entity) || !state.contains("ages") || !state.ages.contains(key) {return #{commands:[],state:state};} + state.ages.remove(key);state.phases.remove(key);state.directions.remove(key);state.maximums.remove(key); + let value=if event.objectives.contains("iron_coast_stage2_boss_2:defeated") {event.objectives["iron_coast_stage2_boss_2:defeated"]+1} else {1}; + #{commands:[#{op:"objective",key:"iron_coast_stage2_boss_2:defeated",value:value},#{op:"effect",x:event.x+24,y:event.y+40},#{op:"play_sound",sound:"iron_coast_stage2_boss_2:death"}],state:state} +} diff --git a/mods/iron_coast_stage2_boss_3/README.md b/mods/iron_coast_stage2_boss_3/README.md new file mode 100644 index 00000000..4a8afd26 --- /dev/null +++ b/mods/iron_coast_stage2_boss_3/README.md @@ -0,0 +1,15 @@ +# Iron Coast II — Stormglass + +Independent API1 enemy package: enable this mod alone to make `iron_coast_stage2_boss_3:unit` available to missions. It does not add a playable campaign, shop item, dependency, override or equipment grant. Mission3 uses this boss; other mod missions can reference the unit and its `:defeated` objective. + +Stormglass is a104×72 ground boss with240 normal health and2400 credit reward. It enters at2pixels per tick then holds y24, patrolling x60–156 at1pixel per tick. Each salvo gives a14-tick visual/audio warning and movement pause. Alternating side turrets fire two3-damage shells every72ticks above halfhealth; below halfhealth a central counter-angled shell joins a60-tick cycle. All projectiles have finite standard collision behavior. The actual spawn-health snapshot defines the half-health transition, so easier difficulty begins in the first phase despite the engine halving starting health. + +State is deterministic and per entity. Arrival and fire clocks are independent. Dead or missing snapshots cannot shoot; actual deaths increment `iron_coast_stage2_boss_3:defeated` once, while despawn/escape never count. Spawn clears reused entity-ID flags before checking the live snapshot, allowing saved-state mission replays even when the engine collects a ground projectile death on the following step. The boss never completes a mission or pays a script credit reward; the engine grants its one defined reward. + +The unit and shell have genuine transparent SD/8×HD PNGs and untouched builtin masters, with tracked `prompts/`, per-art provenance, `asset-report.json`, `audio-recipe.json` and `build_assets.py`. Runtime-invisible alpha padding is cropped at16 while runtime alpha128samples remain inside the fitted logical canvas. Generated warning/shot/death WAVs are original seeded mono16-bit22050Hz synthesis. The recipe defaults to the bundled `RustRaptor/data/misc/PALETTE_DAT`; decoded original style references remain outside the package. + +From `RustRaptor/`, run `target/release/raptor-rust --data data --mods mods --validate-mods iron_coast_stage2_boss_3` and `cargo run --manifest-path mods/iron_coast_stage2_boss_3/validation/Cargo.toml --target-dir target/mod-validation --bin validate --release -- mods/iron_coast_stage2_boss_3`. The local probe checks exact warning/volley timing and phase sizes, independent entities, arrival/bounds, deterministic saved state, dead/missing guards, actual difficulty0–3 health transitions and three reused-ID lethal-spawn/reward replays. Mission-level combat balance and SD/HD scene evidence are supplied with Mission3. + +Retired death guards are bounded to the most recent128 entity IDs, including deterministic migration of older checkpoints. Spawn resets a reused ID before any alive check; duplicate deaths for the current lifecycle emit no commands. A new World also discards clocks of absent entities while retaining live peers. The `retained-state` validation binary exercises1,205 actual-catalog/native lethal-collision lives, including1,200 distinct IDs, five reused-ID lives, JSON state/RNG restoration, a960-guard old checkpoint, duplicate callbacks, exact rewards and difficulty0–3. It additionally checks1,205 abandoned-live World resets and two independent live clocks. Run it from `RustRaptor/` with `cargo run --manifest-path mods/iron_coast_stage2_boss_3/validation/Cargo.toml --target-dir target/mod-validation --bin retained-state --release -- mods/iron_coast_stage2_boss_3`. The corresponding `validation/retained-state.json` records actual observations; package pins there identify the activation before generated proof files were finalized. The final external freeze ledger binds the complete resulting package. + +A health-phase change restarts its per-entity warning clock and immediately telegraphs the new phase. It cannot shorten the14-tick charge by changing the modulo period. The actual World regression lowers health immediately after the second high-health warning at all four difficulties and verifies a fresh warning followed by exactly14ticks before release; it also upgrades an old checkpoint lacking the phase latch. diff --git a/mods/iron_coast_stage2_boss_3/art/shell-hd.png b/mods/iron_coast_stage2_boss_3/art/shell-hd.png new file mode 100644 index 00000000..ff14320d Binary files /dev/null and b/mods/iron_coast_stage2_boss_3/art/shell-hd.png differ diff --git a/mods/iron_coast_stage2_boss_3/art/shell-sd.png b/mods/iron_coast_stage2_boss_3/art/shell-sd.png new file mode 100644 index 00000000..3de8c530 Binary files /dev/null and b/mods/iron_coast_stage2_boss_3/art/shell-sd.png differ diff --git a/mods/iron_coast_stage2_boss_3/art/shell-source-v1.png b/mods/iron_coast_stage2_boss_3/art/shell-source-v1.png new file mode 100644 index 00000000..27779a61 Binary files /dev/null and b/mods/iron_coast_stage2_boss_3/art/shell-source-v1.png differ diff --git a/mods/iron_coast_stage2_boss_3/art/shell-v2-source-v1.png b/mods/iron_coast_stage2_boss_3/art/shell-v2-source-v1.png new file mode 100644 index 00000000..3942617a Binary files /dev/null and b/mods/iron_coast_stage2_boss_3/art/shell-v2-source-v1.png differ diff --git a/mods/iron_coast_stage2_boss_3/art/unit-hd.png b/mods/iron_coast_stage2_boss_3/art/unit-hd.png new file mode 100644 index 00000000..d38592f7 Binary files /dev/null and b/mods/iron_coast_stage2_boss_3/art/unit-hd.png differ diff --git a/mods/iron_coast_stage2_boss_3/art/unit-sd.png b/mods/iron_coast_stage2_boss_3/art/unit-sd.png new file mode 100644 index 00000000..a9d6d020 Binary files /dev/null and b/mods/iron_coast_stage2_boss_3/art/unit-sd.png differ diff --git a/mods/iron_coast_stage2_boss_3/art/unit-source-v1.png b/mods/iron_coast_stage2_boss_3/art/unit-source-v1.png new file mode 100644 index 00000000..5f35c6c8 Binary files /dev/null and b/mods/iron_coast_stage2_boss_3/art/unit-source-v1.png differ diff --git a/mods/iron_coast_stage2_boss_3/asset-report.json b/mods/iron_coast_stage2_boss_3/asset-report.json new file mode 100644 index 00000000..aecbc0cd --- /dev/null +++ b/mods/iron_coast_stage2_boss_3/asset-report.json @@ -0,0 +1,126 @@ +{ + "palette_sha256": "1cf6adb926d1dee1888b3e3d33b51a7049b3e5eb5f90a3067ef71c8970547204", + "ordinary_palette_entries_only": true, + "audio": { + "warning": { + "path": "audio/warning.wav", + "sha256": "70865f6e434074019ffb06dcf2e7c9304347286bbdca61ccdbb4c23739aaaa66", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "samples": 7938, + "seconds": 0.36, + "seed": 2199, + "peak": 15728, + "recipe": "deterministic seeded chirp/noise, original synthesis, no recordings" + }, + "shot": { + "path": "audio/shot.wav", + "sha256": "df4dca41b95e92e838ee94e18de4414b4ca990668a635c0005178a516392660a", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "samples": 4410, + "seconds": 0.2, + "seed": 2200, + "peak": 20316, + "recipe": "deterministic seeded chirp/noise, original synthesis, no recordings" + }, + "death": { + "path": "audio/death.wav", + "sha256": "6449a792d04b1208b230f1e75b76a3876692666e52c7d0deed42b528dab212f3", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "samples": 20948, + "seconds": 0.9500226757369614, + "seed": 2201, + "peak": 20316, + "recipe": "deterministic seeded chirp/noise, original synthesis, no recordings" + } + }, + "unit": { + "master": "art/unit-source-v1.png", + "master_sha256": "ab3d53a367890a4a842bd57d86eb14a8f65abf2748ae3d5fc45ed875c9826fad", + "master_size": [ + 1509, + 1042 + ], + "crop_runtime_invisible_padding": [ + 207, + 76, + 1303, + 960 + ], + "crop_threshold": 16, + "runtime_alpha_threshold": 128, + "logical_canvas": [ + 104, + 72 + ], + "hd_canvas": [ + 832, + 576 + ], + "sd_bounds": [ + 11, + 3, + 93, + 69 + ], + "hd_bounds": [ + 88, + 24, + 743, + 552 + ], + "frame_count": 1, + "origin": [ + 0, + 0 + ], + "generated_art_repainted": false + }, + "shell": { + "master": "art/shell-v2-source-v1.png", + "master_sha256": "2f512c5ed0c993da8988dca809a522946d13bbbbe8b288b62361dc5ec4add8e7", + "master_size": [ + 1620, + 971 + ], + "crop_runtime_invisible_padding": [ + 725, + 263, + 896, + 709 + ], + "crop_threshold": 16, + "runtime_alpha_threshold": 128, + "logical_canvas": [ + 8, + 8 + ], + "hd_canvas": [ + 64, + 64 + ], + "sd_bounds": [ + 3, + 1, + 5, + 7 + ], + "hd_bounds": [ + 23, + 8, + 41, + 56 + ], + "frame_count": 1, + "origin": [ + 0, + 0 + ], + "generated_art_repainted": false + } +} diff --git a/mods/iron_coast_stage2_boss_3/audio-recipe.json b/mods/iron_coast_stage2_boss_3/audio-recipe.json new file mode 100644 index 00000000..4990f6ad --- /dev/null +++ b/mods/iron_coast_stage2_boss_3/audio-recipe.json @@ -0,0 +1,38 @@ +{ + "warning": { + "path": "audio/warning.wav", + "sha256": "70865f6e434074019ffb06dcf2e7c9304347286bbdca61ccdbb4c23739aaaa66", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "samples": 7938, + "seconds": 0.36, + "seed": 2199, + "peak": 15728, + "recipe": "deterministic seeded chirp/noise, original synthesis, no recordings" + }, + "shot": { + "path": "audio/shot.wav", + "sha256": "df4dca41b95e92e838ee94e18de4414b4ca990668a635c0005178a516392660a", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "samples": 4410, + "seconds": 0.2, + "seed": 2200, + "peak": 20316, + "recipe": "deterministic seeded chirp/noise, original synthesis, no recordings" + }, + "death": { + "path": "audio/death.wav", + "sha256": "6449a792d04b1208b230f1e75b76a3876692666e52c7d0deed42b528dab212f3", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "samples": 20948, + "seconds": 0.9500226757369614, + "seed": 2201, + "peak": 20316, + "recipe": "deterministic seeded chirp/noise, original synthesis, no recordings" + } +} diff --git a/mods/iron_coast_stage2_boss_3/audio/death.wav b/mods/iron_coast_stage2_boss_3/audio/death.wav new file mode 100644 index 00000000..4fe0a480 Binary files /dev/null and b/mods/iron_coast_stage2_boss_3/audio/death.wav differ diff --git a/mods/iron_coast_stage2_boss_3/audio/shot.wav b/mods/iron_coast_stage2_boss_3/audio/shot.wav new file mode 100644 index 00000000..d19ca713 Binary files /dev/null and b/mods/iron_coast_stage2_boss_3/audio/shot.wav differ diff --git a/mods/iron_coast_stage2_boss_3/audio/warning.wav b/mods/iron_coast_stage2_boss_3/audio/warning.wav new file mode 100644 index 00000000..796f9a8e Binary files /dev/null and b/mods/iron_coast_stage2_boss_3/audio/warning.wav differ diff --git a/mods/iron_coast_stage2_boss_3/build_assets.py b/mods/iron_coast_stage2_boss_3/build_assets.py new file mode 100644 index 00000000..6786d7b8 --- /dev/null +++ b/mods/iron_coast_stage2_boss_3/build_assets.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python3 +"""Reproduce packaged artwork footprints and seeded local PCM audio. + +Builtin imagegen masters are preserved byte-for-byte. This recipe only crops +empty/runtime-subthreshold transparent padding, fits/resamples canvases, splits joined terrain and +quantizes SD to ordinary game palette colors; it never paints generated pixels. +""" +from pathlib import Path +import argparse,hashlib,json,math,random,struct,wave +from PIL import Image,ImageOps +ROOT=Path(__file__).resolve().parent +hashfile=lambda p:hashlib.sha256(p.read_bytes()).hexdigest() +def palette(path): + raw=path.read_bytes();assert len(raw)==768 + colors=[(min(v,63)<<2)|(min(v,63)>>4) for v in raw] + colors[720:]=colors[:48];im=Image.new('P',(1,1));im.putpalette(colors);return im + +def sd(im,size,pal): + im=im.convert('RGBA').resize(size,Image.Resampling.BOX);alpha=im.getchannel('A').point(lambda v:255 if v>=128 else 0) + out=im.convert('RGB').quantize(palette=pal,dither=Image.Dither.NONE).convert('RGBA');out.putalpha(alpha);return out + +def footprint(stem,logical,pal): + p=ROOT/'art'/f'{stem}-source-v1.png' + if stem=='shell' and (ROOT/'art/shell-v2-source-v1.png').exists():p=ROOT/'art/shell-v2-source-v1.png' + raw=Image.open(p).convert('RGBA');assert raw.getchannel('A').getextrema()[0]==0,'genuine transparent master required' + # Keep every visible alpha>=128 sample. Imagegen adds isolated alpha1 noise + # across the canvas; threshold16 bounds remove only runtime-invisible padding, + # while the raw master and its original alpha remain untouched. + box=raw.getchannel('A').point(lambda v:255 if v>=16 else 0).getbbox();assert box;assert raw.getchannel('A').point(lambda v:255 if v>=128 else 0).getbbox();crop=raw.crop(box);size=tuple(v*8 for v in logical);margin=8 if stem=='shell' else 24 + hd=Image.new('RGBA',size);fitted=ImageOps.contain(crop,(size[0]-margin*2,size[1]-margin*2),Image.Resampling.LANCZOS);hd.alpha_composite(fitted,((size[0]-fitted.width)//2,(size[1]-fitted.height)//2));low=sd(hd,logical,pal) + for suffix,im in [('hd',hd),('sd',low)]: + bounds=im.getchannel('A').point(lambda v:255 if v>=128 else 0).getbbox();assert bounds and bounds[0]>0 and bounds[1]>0 and bounds[2]=128 else 0).getbbox()),'frame_count':1,'origin':[0,0],'generated_art_repainted':False} + +def synth(name,duration,seed,mode): + rate=22050;rng=random.Random(seed);count=round(rate*duration);phase=0;slow=0;v=[] + for i in range(count): + u=i/(count-1);t=i/rate;noise=rng.uniform(-1,1);slow=slow*.90+noise*.10 + if mode=='warning':freq=440+220*int(u*2);signal=math.sin(phase)*.60+math.sin(phase*2)*.15;env=math.sin(math.pi*u)**1.4 + elif mode=='shot':freq=440*(1-u)**2+65;signal=math.sin(phase)*.5+noise*.20+math.sin(phase*2.13)*.13;env=math.exp(-5*u) + elif mode=='death':freq=75-50*u;signal=slow*.6+noise*.18+math.sin(phase)*.25;env=math.exp(-4.5*u) + else: + notes=[294,370,440,587] if mode=='victory' else [220,294,440];freq=notes[min(len(notes)-1,int(u*len(notes)))];signal=math.sin(phase)*.65+math.sin(phase*2)*.12;env=min(1,(u*len(notes)%1)*20)*(1-u)**.6 + phase+=2*math.pi*freq/rate;env*=min(1,t/.004)*min(1,(count-1-i)/(rate*.005));v.append(signal*max(0,env)) + peak=max(abs(x) for x in v);target=.48 if mode=='warning' else .62;pcm=[round(x/peak*32767*target) for x in v];p=ROOT/'audio'/f'{name}.wav' + with wave.open(str(p),'wb') as w:w.setnchannels(1);w.setsampwidth(2);w.setframerate(rate);w.writeframes(struct.pack('<'+'h'*count,*pcm)) + return {'path':str(p.relative_to(ROOT)),'sha256':hashfile(p),'sample_rate':rate,'bits':16,'channels':1,'samples':count,'seconds':count/rate,'seed':seed,'peak':max(abs(x) for x in pcm),'recipe':'deterministic seeded chirp/noise, original synthesis, no recordings'} + +def main(): + ap=argparse.ArgumentParser();ap.add_argument('--palette',type=Path,default=ROOT.parents[1]/'data/misc/PALETTE_DAT');ap.add_argument('--audio-only',action='store_true');a=ap.parse_args();is_boss='boss' in ROOT.name;stage=int(ROOT.name[-1]);sounds={} + sound_specs=[('warning',.36,'warning'),('shot',.20,'shot'),('death',.95,'death')] if is_boss else [('approach',.78,'tone'),('target_alarm',.42,'warning'),('boss_alarm',.65,'warning'),('salvage',.32,'tone'),('victory',1.10,'victory')] + for i,(n,d,m) in enumerate(sound_specs):sounds[n]=synth(n,d,stage*733+i,m) + (ROOT/'audio-recipe.json').write_text(json.dumps(sounds,indent=2)+'\n') + if a.audio_only:return + pal=palette(a.palette);report={'palette_sha256':hashfile(a.palette),'ordinary_palette_entries_only':True,'audio':sounds} + if is_boss: + report['unit']=footprint('unit',(104,72 if stage==3 else 64),pal);report['shell']=footprint('shell',(8,8),pal) + else: + report['target']=footprint('target',(32,32),pal);p=ROOT/'art/terrain-source-v1.png';source=Image.open(p).convert('RGBA');assert source.getchannel('A').getextrema()[0]>=128,'terrain must be fully opaque' + hd=ImageOps.fit(source,(1152,2048),Image.Resampling.LANCZOS);low=sd(hd,(288,512),pal);tiles=0 + for reverse in [False,True]: + hi=ImageOps.flip(hd) if reverse else hd;lo=ImageOps.flip(low) if reverse else low + for row in range(16): + for col in range(9): + hi.crop((col*128,row*128,(col+1)*128,(row+1)*128)).save(ROOT/'art'/f'tile-{tiles:03}-hd.png');lo.crop((col*32,row*32,(col+1)*32,(row+1)*32)).save(ROOT/'art'/f'tile-{tiles:03}-sd.png');tiles+=1 + for im in [hd,low]:assert im.crop((0,im.height-1,im.width,im.height)).tobytes()==ImageOps.flip(im).crop((0,0,im.width,1)).tobytes() + # Briefing is a truthful wide crop of the generated terrain, not new artwork. + briefing=ImageOps.fit(source,(1280,800),Image.Resampling.LANCZOS);briefing.save(ROOT/'art/briefing-hd.png');sd(briefing,(320,200),pal).save(ROOT/'art/briefing-sd.png');low.save(ROOT/'art/terrain-preview-sd.png');hd.save(ROOT/'art/terrain-preview-hd.png') + report['terrain']={'master_sha256':hashfile(p),'master_size':list(source.size),'logical_joined_size':[288,512],'hd_joined_size':[1152,2048],'tiles':tiles,'period_rows':32,'repeat':'forward16 rows then reflected16 rows, both periodboundaries identical','joined_before_quantizing_and_splitting':True,'seam_checks':True,'briefing':'320x200 /1280x800 central wide crop from same genuine terrain master'} + (ROOT/'asset-report.json').write_text(json.dumps(report,indent=2)+'\n');print(ROOT.name,'assets/sounds ready') +if __name__=='__main__':main() diff --git a/mods/iron_coast_stage2_boss_3/content.json b/mods/iron_coast_stage2_boss_3/content.json new file mode 100644 index 00000000..6df84a34 --- /dev/null +++ b/mods/iron_coast_stage2_boss_3/content.json @@ -0,0 +1,69 @@ +{ + "weapons": [ + { + "id": "iron_coast_stage2_boss_3:shell", + "name": "Stormglass defense shell", + "damage": 3, + "speed": 4, + "cooldown": 64, + "behavior": "straight", + "target": "all", + "art": { + "png": "art/shell-sd.png", + "hd_png": "art/shell-hd.png", + "logical_width": 8, + "logical_height": 8, + "frames": 1 + } + } + ], + "enemies": [ + { + "id": "iron_coast_stage2_boss_3:unit", + "name": "Stormglass", + "health": 240, + "speed": 0, + "reward": 2400, + "ground": true, + "boss": true, + "cooldown": 64, + "art": { + "png": "art/unit-sd.png", + "hd_png": "art/unit-hd.png", + "logical_width": 104, + "logical_height": 72, + "frames": 1 + }, + "script": "scripts/ai.rhai" + } + ], + "sounds": [ + { + "id": "iron_coast_stage2_boss_3:warning", + "name": "Warning", + "file": "audio/warning.wav", + "volume": 70, + "pan": 127, + "pitch": 128, + "priority": 2 + }, + { + "id": "iron_coast_stage2_boss_3:shot", + "name": "Shot", + "file": "audio/shot.wav", + "volume": 85, + "pan": 127, + "pitch": 128, + "priority": 2 + }, + { + "id": "iron_coast_stage2_boss_3:death", + "name": "Death", + "file": "audio/death.wav", + "volume": 100, + "pan": 127, + "pitch": 128, + "priority": 2 + } + ] +} diff --git a/mods/iron_coast_stage2_boss_3/mod.toml b/mods/iron_coast_stage2_boss_3/mod.toml new file mode 100644 index 00000000..eb7cb46a --- /dev/null +++ b/mods/iron_coast_stage2_boss_3/mod.toml @@ -0,0 +1,7 @@ +id = "iron_coast_stage2_boss_3" +name = "Iron Coast II — Stormglass" +version = "1.0.0" +api_version = 1 +description = "Distinct telegraphed Stormglass boss with two health phases, persistent onscreen patrol, SD/HD artwork and original synthesized sounds." +content = "content.json" +scripts = ["scripts/ai.rhai"] diff --git a/mods/iron_coast_stage2_boss_3/prompts/shell-v1.txt b/mods/iron_coast_stage2_boss_3/prompts/shell-v1.txt new file mode 100644 index 00000000..323024e3 --- /dev/null +++ b/mods/iron_coast_stage2_boss_3/prompts/shell-v1.txt @@ -0,0 +1,4 @@ +Use case: stylized-concept +Asset type: new Iron Coast II game sprite/terrain master +Style reference is the original Raptor contact sheet: exact top-down mechanical vehicle/terrain shapes, muted gray-bronze steel, worn panels, dark outlines, compact DOS-shooter readability. Create original new artwork matching that visual language with cleaner high-resolution detail, not a copy or a photograph. +Primary request: One isolated compact enemy defense projectile for an8x8logical sprite: downward-facing short electric-blue steel sabot shell, pointed tip down, tiny warm pale core, narrow dark gray casing and restrained cyan accent. Orthographic top view, clear simple silhouette, no explosive burst, no expansive bloom, no long trail. Large transparent canvas with generous empty padding around the single shell. SD reduction must stay readable. No text, labels or scenery. diff --git a/mods/iron_coast_stage2_boss_3/prompts/shell-v2.txt b/mods/iron_coast_stage2_boss_3/prompts/shell-v2.txt new file mode 100644 index 00000000..39139194 --- /dev/null +++ b/mods/iron_coast_stage2_boss_3/prompts/shell-v2.txt @@ -0,0 +1 @@ +Create one original Raptor-compatible hostile defense projectile sprite, transparent background, directly top-down, pointing straight DOWN towards the player. Use the attached original Raptor contact sheet only as style guidance. One compact short broad amber-orange tracer shell with a small dark-steel top cap and a prominent pale yellow-white hot core occupying the lower half; broad orange outlines, not a thin cyan spear. It will be rendered in only an 8 by 8 logical canvas, so shape must be very simple, visually high-contrast and clearly readable against dark teal water and gray industrial concrete. Sprite roughly four times taller than wide, actual opaque hot core thickness at least one quarter of shell width. Strong classic 1990s Apogee pixel-art materials, crisp controlled hard edges, no surrounding glow haze, no background, no lettering, no extra sparks, no duplicate sprites. Center the single isolated shell with transparent padding on all sides. The final actual core must remain very bright at a tiny pixel presentation. diff --git a/mods/iron_coast_stage2_boss_3/prompts/unit-v1.txt b/mods/iron_coast_stage2_boss_3/prompts/unit-v1.txt new file mode 100644 index 00000000..1c7d2600 --- /dev/null +++ b/mods/iron_coast_stage2_boss_3/prompts/unit-v1.txt @@ -0,0 +1,4 @@ +Use case: stylized-concept +Asset type: new Iron Coast II game sprite/terrain master +Style reference is the original Raptor contact sheet: exact top-down mechanical vehicle/terrain shapes, muted gray-bronze steel, worn panels, dark outlines, compact DOS-shooter readability. Create original new artwork matching that visual language with cleaner high-resolution detail, not a copy or a photograph. +Primary request: Original Stormglass boss: a broad multi-turret refinery crawler, strict orthographic top view, downscreen-facing, bilateral low tracked industrial chassis, three clearly separate cannon housings, central insulated fuel-reactor drum, four heavy treads with coherent corners, subdued navy-gray/bronze steel, small cyan lightning-season indicators. Entire104x72 logical silhouette framed with generous transparent outer padding. No ground, no cast shadow beyond sprite silhouette. High detail but readable as a small vehicle. Transparent background; no labels, no UI, no text, no glow halo. diff --git a/mods/iron_coast_stage2_boss_3/provenance-shell-v2.json b/mods/iron_coast_stage2_boss_3/provenance-shell-v2.json new file mode 100644 index 00000000..0acccd97 --- /dev/null +++ b/mods/iron_coast_stage2_boss_3/provenance-shell-v2.json @@ -0,0 +1,39 @@ +{ + "generator": "built-in image_gen.imagegen", + "owner": "/root/iron_coast_3", + "job_id": "stage2-shell-readable-v2", + "utc": "2026-10-11T08:28:36.806092+00:00", + "default_output": "/home/quintine/.codex/generated_images/01a1245d-8d97-74e2-9a2c-02e88a570589/exec-225e6e18-97a0-4348-880b-4aaddb90fa21.png", + "raw_master": "art/shell-v2-source-v1.png", + "raw_sha256": "2f512c5ed0c993da8988dca809a522946d13bbbbe8b288b62361dc5ec4add8e7", + "prompt": "prompts/shell-v2.txt", + "prompt_sha256": "763879d9caf0c1fa18c3d053ce2efde45a12c9b2297a7b2fd988b5dc0a81df67", + "style_reference_role": "Original Raptor style only; decoded style reference is intentionally external to authored mod.", + "reference_sha256": "685307409d68baa9413975b59427c74d29f6a09b2b039a3d88ee69abf19e9a9d", + "original_style_source_hashes": [ + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/enemies-200cc-200cd/sources/200cc.png", + "sha256": "c3f92b8a04370029652cfff20dc00ec41228c5adead37affaacd3b9511bb520d", + "role": "Original Raptor style reference; not copied into authored mods." + }, + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/enemies-2008d-2008d/sources/2008d.png", + "sha256": "419514e3b7cbd9fb7283f0550f12991f5570c2de16c367330fa2e8a9b6bb3725", + "role": "Original Raptor style reference; not copied into authored mods." + }, + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/bosses-10310-10310/sources/10310.png", + "sha256": "39404e604c4d535e868ffea924ba206c690e19f7df9c289ce14612cb2451bbef", + "role": "Original Raptor style reference; not copied into authored mods." + }, + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/terrain-10360-1036f/sources/10360.png", + "sha256": "ee5348dbdf57952027349c64cd13c9d2991a33b0378a54f4750622d9bff50dc0", + "role": "Original Raptor style reference; not copied into authored mods." + } + ], + "transparent_background_requested": true, + "gate_lease": "17ea3caa-bd34-4055-8fcb-fe6aee83f390", + "gate_outcome": "success", + "source_pixels_modified": false +} diff --git a/mods/iron_coast_stage2_boss_3/provenance-shell.json b/mods/iron_coast_stage2_boss_3/provenance-shell.json new file mode 100644 index 00000000..9877972b --- /dev/null +++ b/mods/iron_coast_stage2_boss_3/provenance-shell.json @@ -0,0 +1,39 @@ +{ + "generator": "built-in image_gen.imagegen", + "owner": "/root/iron_coast_3", + "job_id": "stage2-shell", + "utc": "2026-10-11T08:13:24.506440+00:00", + "default_output": "/home/quintine/.codex/generated_images/01a1245d-8d97-74e2-9a2c-02e88a570589/exec-76856a96-5638-498c-a52e-4de830611a56.png", + "raw_master": "art/shell-source-v1.png", + "raw_sha256": "097d9ed2ac5be5fd2d749a306391cea1619b53e3eefebd8081e20d05433e8189", + "prompt": "prompts/shell-v1.txt", + "prompt_sha256": "02435865b7a8780486235080ab0cff91199b32eb2cbb7e776c78e8c1ccf9f9f3", + "style_reference_role": "Original Raptor style only; decoded style reference is intentionally external to authored mod.", + "reference_sha256": "685307409d68baa9413975b59427c74d29f6a09b2b039a3d88ee69abf19e9a9d", + "original_style_source_hashes": [ + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/enemies-200cc-200cd/sources/200cc.png", + "sha256": "c3f92b8a04370029652cfff20dc00ec41228c5adead37affaacd3b9511bb520d", + "role": "Original Raptor style reference; not copied into authored mods." + }, + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/enemies-2008d-2008d/sources/2008d.png", + "sha256": "419514e3b7cbd9fb7283f0550f12991f5570c2de16c367330fa2e8a9b6bb3725", + "role": "Original Raptor style reference; not copied into authored mods." + }, + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/bosses-10310-10310/sources/10310.png", + "sha256": "39404e604c4d535e868ffea924ba206c690e19f7df9c289ce14612cb2451bbef", + "role": "Original Raptor style reference; not copied into authored mods." + }, + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/terrain-10360-1036f/sources/10360.png", + "sha256": "ee5348dbdf57952027349c64cd13c9d2991a33b0378a54f4750622d9bff50dc0", + "role": "Original Raptor style reference; not copied into authored mods." + } + ], + "transparent_background_requested": true, + "gate_lease": "1cdecd31-b10e-44d7-aa33-29396970ce2f", + "gate_outcome": "success", + "source_pixels_modified": false +} diff --git a/mods/iron_coast_stage2_boss_3/provenance-unit.json b/mods/iron_coast_stage2_boss_3/provenance-unit.json new file mode 100644 index 00000000..17e7fdd1 --- /dev/null +++ b/mods/iron_coast_stage2_boss_3/provenance-unit.json @@ -0,0 +1,39 @@ +{ + "generator": "built-in image_gen.imagegen", + "owner": "/root/iron_coast_3", + "job_id": "stage2-boss3", + "utc": "2026-10-11T08:10:08.760714+00:00", + "default_output": "/home/quintine/.codex/generated_images/01a1245d-8d97-74e2-9a2c-02e88a570589/exec-cfa9471a-983b-42cd-8ae4-6367ff2f85ef.png", + "raw_master": "art/unit-source-v1.png", + "raw_sha256": "ab3d53a367890a4a842bd57d86eb14a8f65abf2748ae3d5fc45ed875c9826fad", + "prompt": "prompts/unit-v1.txt", + "prompt_sha256": "79ea3067a0367e329912b24e64a26b541294c4cd40d97f7163b5ef3ac8c25766", + "style_reference_role": "Original Raptor style only; decoded style reference is intentionally external to authored mod.", + "reference_sha256": "685307409d68baa9413975b59427c74d29f6a09b2b039a3d88ee69abf19e9a9d", + "original_style_source_hashes": [ + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/enemies-200cc-200cd/sources/200cc.png", + "sha256": "c3f92b8a04370029652cfff20dc00ec41228c5adead37affaacd3b9511bb520d", + "role": "Original Raptor style reference; not copied into authored mods." + }, + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/enemies-2008d-2008d/sources/2008d.png", + "sha256": "419514e3b7cbd9fb7283f0550f12991f5570c2de16c367330fa2e8a9b6bb3725", + "role": "Original Raptor style reference; not copied into authored mods." + }, + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/bosses-10310-10310/sources/10310.png", + "sha256": "39404e604c4d535e868ffea924ba206c690e19f7df9c289ce14612cb2451bbef", + "role": "Original Raptor style reference; not copied into authored mods." + }, + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/terrain-10360-1036f/sources/10360.png", + "sha256": "ee5348dbdf57952027349c64cd13c9d2991a33b0378a54f4750622d9bff50dc0", + "role": "Original Raptor style reference; not copied into authored mods." + } + ], + "transparent_background_requested": true, + "gate_lease": "40308401-7ed8-47b9-91c6-623cde8fbab2", + "gate_outcome": "success", + "source_pixels_modified": false +} diff --git a/mods/iron_coast_stage2_boss_3/scripts/ai.rhai b/mods/iron_coast_stage2_boss_3/scripts/ai.rhai new file mode 100644 index 00000000..8568f5ea --- /dev/null +++ b/mods/iron_coast_stage2_boss_3/scripts/ai.rhai @@ -0,0 +1,77 @@ +// Deterministic per-entity patrol, health phases and visible/audio warning windows. +fn alive(event) { for unit in event.entities { if unit.entity==event.entity && unit.health>0 { return true; } } false } +fn spawn_health(event) { for unit in event.entities { if unit.entity==event.entity {return unit.health.max(1);} } 1 } +// At most128 retired IDs survive checkpoint/replay. Upgrade older checkpoints +// without a FIFO by retaining a deterministic bounded subset of their guards. +fn ready(state) { + if !state.contains("units") {state.units=#{};} + if !state.contains("dead") {state.dead=#{};} + if !state.contains("dead_order") { + let retained=#{};let order=[]; + for key in state.dead.keys() { + if order.len()>=128 {let oldest=order.remove(0);retained.remove(oldest);} + retained[key]=true;order.push(key); + } + state.dead=retained;state.dead_order=order; + } + state +} +fn on_spawn(event,state,random) { + state=ready(state); + // Discard clocks of entities absent from this World after an abandoned run. + // Existing live peers retain their independent clocks. + let live_units=#{}; + for unit in event.entities { + let unit_key=unit.entity.to_string(); + if unit.health>0 && state.units.contains(unit_key) {live_units[unit_key]=state.units[unit_key];} + } + state.units=live_units; + let key=event.entity.to_string();state.dead.remove(key);state.units.remove(key); + let keep=[];for old in state.dead_order {if old!=key {keep.push(old);}}state.dead_order=keep; + // A lethal spawn-step collision still clears this lifecycle's old death flag. + if !alive(event) {return #{commands:[],state:state};} + state.units[key]=#{age:0,direction:1,aim:0,phase:1,max_health:spawn_health(event)}; + #{commands:[#{op:"velocity",entity:event.entity,vx:0,vy:2}],state:state} +} +fn on_tick(event,state,random) { + if event.health<=0 || !alive(event) {return #{commands:[],state:state};} + if !state.contains("units") {state.units=#{};} + let key=event.entity.to_string(); + if !state.units.contains(key) {state.units[key]=#{age:0,direction:1,aim:0,phase:1,max_health:spawn_health(event)};} + if event.y<24 {return #{commands:[#{op:"velocity",entity:event.entity,vx:0,vy:2}],state:state};} + let u=state.units[key]; + if !u.contains("max_health") {u.max_health=spawn_health(event);} + if event.x>=156 {u.direction=-1;} if event.x<=60 {u.direction=1;} + let phase=if event.health>u.max_health/2 {1} else {2}; + // Each new phase begins a complete warning window, independent of the old + // period. This also safely upgrades checkpoints lacking the phase latch. + if !u.contains("phase") {u.phase=1;} + if phase!=u.phase {u.phase=phase;u.age=0;} + let period=if phase==1 {72} else {60}; + let cycle=u.age%period; + let commands=[#{op:"move",entity:event.entity,x:event.x,y:24},#{op:"velocity",entity:event.entity,vx:if cycle<14 {0} else {u.direction*1},vy:0}]; + if cycle==0 { + u.aim=if event.player_x=128 {let oldest=state.dead_order.remove(0);state.dead.remove(oldest);} + state.dead[key]=true;state.dead_order.push(key);state.units.remove(key); + let count=if event.objectives.contains("iron_coast_stage2_boss_3:defeated") {event.objectives["iron_coast_stage2_boss_3:defeated"]+1} else {1}; + #{commands:[#{op:"objective",key:"iron_coast_stage2_boss_3:defeated",value:count},#{op:"effect",x:event.x+20,y:event.y+40},#{op:"effect",x:event.x+84,y:event.y+40},#{op:"play_sound",sound:"iron_coast_stage2_boss_3:death"}],state:state} +} diff --git a/mods/iron_coast_stage2_boss_3/validation/Cargo.toml b/mods/iron_coast_stage2_boss_3/validation/Cargo.toml new file mode 100644 index 00000000..7a77214a --- /dev/null +++ b/mods/iron_coast_stage2_boss_3/validation/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "iron-coast-stage2-boss-3-validation" +version = "1.0.0" +edition = "2024" +publish = false + +[workspace] + +[dependencies] +raptor-replica = { path = "../../..", default-features = false } +serde_json = "1" + +[[bin]] +name = "validate" +path = "validate.rs" + +[[bin]] +name = "retained-state" +path = "retained_state.rs" diff --git a/mods/iron_coast_stage2_boss_3/validation/bounded-cache-review.md b/mods/iron_coast_stage2_boss_3/validation/bounded-cache-review.md new file mode 100644 index 00000000..e5b8e3a6 --- /dev/null +++ b/mods/iron_coast_stage2_boss_3/validation/bounded-cache-review.md @@ -0,0 +1,9 @@ +# Retained lifecycle cache correction + +The independent native-collision probe found an unbounded pre-correction retired-ID map that exhausted the Rhai object-map limit at distinct-lifetime index1009. Historical package folders and the previous four-package freeze are retained outside the distribution. + +The gameplay definitions, health, attack patterns, objectives, prices, images and sounds are unchanged. A separate independent timing probe also found that changing the old warning-clock modulo at half-health could release a low-phase volley after only two ticks. Bosses now latch their phase and restart its warning clock on a phase transition, preserving the advertised full 14-tick telegraph. The actual World regression tests transition immediately after the second high-phase warning at every difficulty, including an old checkpoint lacking the latch. The script now stores a FIFO of at most 128 recent retired IDs, removes reused IDs on spawn before checking their health, and migrates pre-FIFO states into a deterministic bounded subset. Boss clocks absent from the new World's snapshot are discarded; live peer clocks remain intact. + +The package-local retained-state proof checks real bundled Catalog activation and a test-only native stationary lethal projectile, 1,205 lives (1,200 unique plus five reused IDs), exact one-death rewards, current-lifecycle callback deduplication, nine JSON checkpoint/RNG roundtrips, old 960-ID cache migration and all four difficulty kills. Boss probes add 1,205 abandoned-live replays and simultaneous peer-clock preservation. This is a lifecycle stress proof, not a combat-balance shortcut. Normal mission acceptance and boss phase probes were rerun independently of this stress fixture. + +A duplicate callback for an entity retired more than 128 deaths ago is outside the retained guard window; the engine emits each real death once and queued callbacks are not delayed across 128 later deaths. Reusing an ID through an actual spawn always starts a fresh guarded lifecycle. diff --git a/mods/iron_coast_stage2_boss_3/validation/bounded-cli.log b/mods/iron_coast_stage2_boss_3/validation/bounded-cli.log new file mode 100644 index 00000000..83810a55 --- /dev/null +++ b/mods/iron_coast_stage2_boss_3/validation/bounded-cli.log @@ -0,0 +1 @@ +Validated 8 mods; 0 override(s) diff --git a/mods/iron_coast_stage2_boss_3/validation/bounded-normal.log b/mods/iron_coast_stage2_boss_3/validation/bounded-normal.log new file mode 100644 index 00000000..95f7b8bf --- /dev/null +++ b/mods/iron_coast_stage2_boss_3/validation/bounded-normal.log @@ -0,0 +1,7 @@ +iron_coast_stage2_boss_3: health 240, period 72, volley 2, warning14 ticks; arrival, bounds, two entities, checkpoint, absent/dead guard and once-only death passed +iron_coast_stage2_boss_3: health 120, period 60, volley 3, warning14 ticks; arrival, bounds, two entities, checkpoint, absent/dead guard and once-only death passed +real World difficulty0: spawnHP120, phase1 at arrival then phase2 at 60/half; no missing spawn health +real World difficulty1: spawnHP120, phase1 at arrival then phase2 at 60/half; no missing spawn health +real World difficulty2: spawnHP240, phase1 at arrival then phase2 at 120/half; no missing spawn health +real World difficulty3: spawnHP240, phase1 at arrival then phase2 at 120/half; no missing spawn health +real World lethal queued-spawn, saved-state reused ID and exact reward across three replays: passed diff --git a/mods/iron_coast_stage2_boss_3/validation/callback-world.log b/mods/iron_coast_stage2_boss_3/validation/callback-world.log new file mode 100644 index 00000000..95f7b8bf --- /dev/null +++ b/mods/iron_coast_stage2_boss_3/validation/callback-world.log @@ -0,0 +1,7 @@ +iron_coast_stage2_boss_3: health 240, period 72, volley 2, warning14 ticks; arrival, bounds, two entities, checkpoint, absent/dead guard and once-only death passed +iron_coast_stage2_boss_3: health 120, period 60, volley 3, warning14 ticks; arrival, bounds, two entities, checkpoint, absent/dead guard and once-only death passed +real World difficulty0: spawnHP120, phase1 at arrival then phase2 at 60/half; no missing spawn health +real World difficulty1: spawnHP120, phase1 at arrival then phase2 at 60/half; no missing spawn health +real World difficulty2: spawnHP240, phase1 at arrival then phase2 at 120/half; no missing spawn health +real World difficulty3: spawnHP240, phase1 at arrival then phase2 at 120/half; no missing spawn health +real World lethal queued-spawn, saved-state reused ID and exact reward across three replays: passed diff --git a/mods/iron_coast_stage2_boss_3/validation/cli.log b/mods/iron_coast_stage2_boss_3/validation/cli.log new file mode 100644 index 00000000..cf87e1b3 --- /dev/null +++ b/mods/iron_coast_stage2_boss_3/validation/cli.log @@ -0,0 +1 @@ +Validated 1 mods; 0 override(s) diff --git a/mods/iron_coast_stage2_boss_3/validation/combined-cli.log b/mods/iron_coast_stage2_boss_3/validation/combined-cli.log new file mode 100644 index 00000000..83810a55 --- /dev/null +++ b/mods/iron_coast_stage2_boss_3/validation/combined-cli.log @@ -0,0 +1 @@ +Validated 8 mods; 0 override(s) diff --git a/mods/iron_coast_stage2_boss_3/validation/compiler-binding.json b/mods/iron_coast_stage2_boss_3/validation/compiler-binding.json new file mode 100644 index 00000000..94e50e4e --- /dev/null +++ b/mods/iron_coast_stage2_boss_3/validation/compiler-binding.json @@ -0,0 +1,22 @@ +{ + "/home/quintine/Projects/RaptorReplica/RustRaptor/target/release/deps/libraptor_replica-f9adab78fd4d2969.rlib": { + "bytes": 13308296, + "sha256": "eb190ba6ad88d1939938a30c69bd1d8c705ecfb77eb12c36ae0686f10f82bae7", + "mtime_ns": 1791706754209530916 + }, + "/home/quintine/Projects/RaptorReplica/RustRaptor/target/release/deps/libserde_json-11c796c0bcf3a604.rlib": { + "bytes": 2057816, + "sha256": "7a13e07716f46f559cb9acf05c81ce0845e5633dfd3d77e6020e14af31a3a878", + "mtime_ns": 1791706698162048372 + }, + "/home/quintine/Projects/RaptorReplica/RustRaptor/mods/iron_coast_stage2_boss_3/validation/validate.rs": { + "bytes": 12304, + "sha256": "4e0ff775ea5ab4e958c51096c6862e95bb87967c6e5ecbe52656511e5d030256", + "mtime_ns": 1791707446271702479 + }, + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/boss-3-validate": { + "bytes": 7705448, + "sha256": "15cac0cb917453d2fe22c86a1031add87d59244e5175a3d22b3a6f2533db6f7b", + "mtime_ns": 1791708347325962780 + } +} diff --git a/mods/iron_coast_stage2_boss_3/validation/retained-state-compiler-binding.json b/mods/iron_coast_stage2_boss_3/validation/retained-state-compiler-binding.json new file mode 100644 index 00000000..5a95b9e9 --- /dev/null +++ b/mods/iron_coast_stage2_boss_3/validation/retained-state-compiler-binding.json @@ -0,0 +1,22 @@ +{ + "/home/quintine/Projects/RaptorReplica/RustRaptor/target/release/deps/libraptor_replica-f9adab78fd4d2969.rlib": { + "bytes": 13308296, + "sha256": "eb190ba6ad88d1939938a30c69bd1d8c705ecfb77eb12c36ae0686f10f82bae7", + "mtime_ns": 1791706754209530916 + }, + "/home/quintine/Projects/RaptorReplica/RustRaptor/target/release/deps/libserde_json-11c796c0bcf3a604.rlib": { + "bytes": 2057816, + "sha256": "7a13e07716f46f559cb9acf05c81ce0845e5633dfd3d77e6020e14af31a3a878", + "mtime_ns": 1791706698162048372 + }, + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/retained-state": { + "bytes": 8421248, + "sha256": "ece9f14a0a69754c8515ccc1c3c98968b8023b1978ad36497028c11208abe1e8", + "mtime_ns": 1791708664346644142 + }, + "/home/quintine/Projects/RaptorReplica/RustRaptor/mods/iron_coast_stage2_boss_3/validation/retained_state.rs": { + "bytes": 12558, + "sha256": "e1c4f9f1d78ba98c423cfe41cd90eb72a811398a7ba4dc334e342b89336f5a64", + "mtime_ns": 1791708663728658563 + } +} diff --git a/mods/iron_coast_stage2_boss_3/validation/retained-state.json b/mods/iron_coast_stage2_boss_3/validation/retained-state.json new file mode 100644 index 00000000..3c5328d4 --- /dev/null +++ b/mods/iron_coast_stage2_boss_3/validation/retained-state.json @@ -0,0 +1,86 @@ +{ + "abandoned_live_replays": 1205, + "actual_native_collision_lives": 1205, + "actual_phase_transition_warnings": [ + { + "actual_spawn_health": 120, + "difficulty": 0, + "high_phase_warnings": [ + 1, + 73 + ], + "new_phase_warning_ticks": 14, + "old_phase_latch_absent": true, + "phase2_release": 88, + "phase2_warning": 74 + }, + { + "actual_spawn_health": 120, + "difficulty": 1, + "high_phase_warnings": [ + 1, + 73 + ], + "new_phase_warning_ticks": 14, + "old_phase_latch_absent": false, + "phase2_release": 88, + "phase2_warning": 74 + }, + { + "actual_spawn_health": 240, + "difficulty": 2, + "high_phase_warnings": [ + 1, + 73 + ], + "new_phase_warning_ticks": 14, + "old_phase_latch_absent": false, + "phase2_release": 88, + "phase2_warning": 74 + }, + { + "actual_spawn_health": 240, + "difficulty": 3, + "high_phase_warnings": [ + 1, + 73 + ], + "new_phase_warning_ticks": 14, + "old_phase_latch_absent": false, + "phase2_release": 88, + "phase2_warning": 74 + } + ], + "checkpoint_json_roundtrips": 9, + "difficulty_kills": [ + 0, + 1, + 2, + 3 + ], + "distinct_ids": 1200, + "duplicate_callback_commands": 0, + "enabled": [ + "iron_coast_stage2_boss_3" + ], + "fixture": "actual bundled Catalog; test-only stationary lethal projectile; native World collision, death, reward and retained ScriptRuntime", + "legacy_960_guard_migration": true, + "maximum_abandoned_state_bytes": 2790, + "maximum_death_state_bytes": 2724, + "migration_state_bytes": 2724, + "owner": "iron_coast_stage2_boss_3", + "package_pins_at_execution": [ + { + "hash": "24283836295cf2c6a6dc84b7208db288189f65a5e5540cde385131c0e4b04fe1", + "id": "iron_coast_stage2_boss_3", + "version": "1.0.0" + } + ], + "retired_guard_capacity": 128, + "reused_id_lives": 5, + "reward_per_life": 2400, + "scope": "callback lifecycle/bounded-state proof, not mission combat balance", + "target_shield_restore": 0, + "two_live_clocks_retained": true, + "unit": "iron_coast_stage2_boss_3:unit" +} \ No newline at end of file diff --git a/mods/iron_coast_stage2_boss_3/validation/retained-state.log b/mods/iron_coast_stage2_boss_3/validation/retained-state.log new file mode 100644 index 00000000..6145e280 --- /dev/null +++ b/mods/iron_coast_stage2_boss_3/validation/retained-state.log @@ -0,0 +1,16 @@ +iron_coast_stage2_boss_3 actual difficulty0: health transition after high warning73; new warning74 release88, full14ticks +iron_coast_stage2_boss_3 actual difficulty1: health transition after high warning73; new warning74 release88, full14ticks +iron_coast_stage2_boss_3 actual difficulty2: health transition after high warning73; new warning74 release88, full14ticks +iron_coast_stage2_boss_3 actual difficulty3: health transition after high warning73; new warning74 release88, full14ticks +iron_coast_stage2_boss_3 retained native kills=1; statebytes=57 retired=1 +iron_coast_stage2_boss_3 retained native kills=129; statebytes=2724 retired=128 +iron_coast_stage2_boss_3 retained native kills=257; statebytes=2724 retired=128 +iron_coast_stage2_boss_3 retained native kills=385; statebytes=2724 retired=128 +iron_coast_stage2_boss_3 retained native kills=513; statebytes=2724 retired=128 +iron_coast_stage2_boss_3 retained native kills=641; statebytes=2724 retired=128 +iron_coast_stage2_boss_3 retained native kills=769; statebytes=2724 retired=128 +iron_coast_stage2_boss_3 retained native kills=897; statebytes=2724 retired=128 +iron_coast_stage2_boss_3 retained native kills=1025; statebytes=2724 retired=128 +iron_coast_stage2_boss_3 retained native kills=1153; statebytes=2724 retired=128 +iron_coast_stage2_boss_3 retained native kills=1205; statebytes=2724 retired=128 +iron_coast_stage2_boss_3: all actual collision/reward, migration, deduplication, retained-state and abandoned-live checks passed diff --git a/mods/iron_coast_stage2_boss_3/validation/retained_state.rs b/mods/iron_coast_stage2_boss_3/validation/retained_state.rs new file mode 100644 index 00000000..910b75ff --- /dev/null +++ b/mods/iron_coast_stage2_boss_3/validation/retained_state.rs @@ -0,0 +1,305 @@ +//! Real native lethal-collision stress with retained serializable Rhai state. +use raptor_replica::{ + assets::Catalog, + content::{ContentPack, Registry}, + modding::{self, ActiveMods, Discovery, ScriptRuntime}, + persistence::Pilot, + simulation::{Input, Projectile, World}, +}; +use serde_json::{Value, json}; +use std::{ + collections::{BTreeMap, BTreeSet}, + path::PathBuf, +}; +type Result = std::result::Result>; +fn closure(d: &Discovery, id: &str, out: &mut BTreeSet) { + if !out.insert(id.into()) { + return; + } + for dep in d.mods[id].manifest.dependencies.keys() { + closure(d, dep, out); + } +} +fn input() -> Input { + Input { + absolute: Some([282, 160]), + ..Input::default() + } +} +fn pilot(difficulty: u32) -> Pilot { + let mut p = Pilot::default(); + p.difficulty = difficulty; + p.credits = 10000; + p.inventory.insert("base:energy".into(), 75); + p +} +fn restore(active: &mut ActiveMods, discovery: &Discovery, enabled: &[String]) -> Result<()> { + let cp = active.scripts.checkpoints(); + let encoded = serde_json::to_vec(&cp)?; + let mut scripts = ScriptRuntime::new(); + for owner in enabled { + for path in &discovery.mods[owner].manifest.scripts { + scripts.add( + owner, + path, + &std::fs::read_to_string(discovery.mods[owner].root.join(path))?, + )?; + } + } + scripts.restore(serde_json::from_slice(&encoded)?); + active.scripts = scripts; + Ok(()) +} +fn event(id: u64, hp: i32, key: &str, count: i32) -> Value { + json!({"entity":id,"x":88,"y":24,"health":hp,"tick":999,"player_x":282,"player_y":160,"entities":[{"entity":id,"health":hp}],"objectives":{key:count}}) +} +fn guard(active: &ActiveMods, key: &str) -> usize { + let state = &active.scripts.states[key]; + let dead = state["dead"].as_object().unwrap(); + let fifo = state["dead_order"].as_array().unwrap(); + assert!(dead.len() <= 128); + assert!(fifo.len() <= 128); + assert_eq!(dead.len(), fifo.len()); + let unique = fifo + .iter() + .map(|v| v.as_str().unwrap()) + .collect::>(); + assert_eq!(unique.len(), fifo.len()); + assert_eq!( + dead.keys().map(|v| v.as_str()).collect::>(), + unique + ); + if let Some(units) = state.get("units") { + assert!(units.as_object().unwrap().is_empty()); + } + serde_json::to_vec(state).unwrap().len() +} +fn kill( + active: &mut ActiveMods, + unit: &str, + id: u64, + objective: &str, + reward: u32, + target: bool, + difficulty: u32, +) -> Result { + let mut w = World::new( + &"review:retained".into(), + &pilot(difficulty), + &active.registry, + )?; + w.next_entity = id; + let y = if target { 60 } else { 24 }; + w.projectiles.push(Projectile { + entity: 500000, + weapon: "review:lethal".into(), + x: 90, + y: y + 6, + px: 90, + py: y + 6, + vx: 0, + vy: 0, + hostile: false, + age: 0, + legacy: None, + legacy_enemy: None, + }); + for _ in 0..3 { + w.step(input(), &active.registry, &mut active.scripts)?; + } + assert!(w.enemies.is_empty(), "{unit} survived"); + assert_eq!(w.objectives.get(objective), Some(&1)); + assert_eq!(w.player.credits, 10000 + reward); + assert_eq!(w.player.shield, if target { 87 } else { 75 }); + w.step(input(), &active.registry, &mut active.scripts)?; + assert_eq!(w.objectives.get(objective), Some(&1)); + assert_eq!(w.player.credits, 10000 + reward); + Ok(w) +} +fn phase_warnings(active: &mut ActiveMods, owner: &str, key: &str) -> Result> { + let warning = format!("{owner}:warning"); + let objective = format!("{owner}:phase"); + let mut rows = vec![]; + for difficulty in 0..=3 { + let mut w = World::new( + &"review:retained".into(), + &pilot(difficulty), + &active.registry, + )?; + w.next_entity = 95000 + difficulty as u64; + let mut high_warnings = vec![]; + while high_warnings.len() < 2 { + assert!(w.tick < 100); + w.step(input(), &active.registry, &mut active.scripts)?; + if w.mod_sounds.iter().any(|s| s.0 == warning) { + high_warnings.push(w.tick); + } + w.projectiles.retain(|p| !p.hostile); + } + let entity = w.enemies[0].entity; + let max_hp = w.enemies[0].health; + w.enemies[0].health = max_hp / 2; + // Exercise the upgrade path for a saved pre-latch live entity as well. + if difficulty == 0 { + active.scripts.states.get_mut(key).unwrap()["units"][entity.to_string()] + .as_object_mut() + .unwrap() + .remove("phase"); + } + let mut new_warning = 0; + let mut release = 0; + for offset in 0..=14 { + w.step(input(), &active.registry, &mut active.scripts)?; + let warnings = w.mod_sounds.iter().filter(|s| s.0 == warning).count(); + let shots = w + .projectiles + .iter() + .filter(|p| p.hostile && p.age == 0) + .count(); + if offset == 0 { + assert_eq!(warnings, 1); + new_warning = w.tick; + assert_eq!(w.objectives.get(&objective), Some(&2)); + } else { + assert_eq!(warnings, 0); + } + if offset < 14 { + assert_eq!(shots, 0, "new health phase fired before full warning"); + } else { + assert_eq!(shots, if owner.ends_with('3') { 3 } else { 4 }); + release = w.tick; + } + w.projectiles.retain(|p| !p.hostile); + } + assert_eq!(release - new_warning, 14); + println!( + "{owner} actual difficulty{difficulty}: health transition after high warning{}; new warning{new_warning} release{release}, full14ticks", + high_warnings[1] + ); + rows.push(json!({"difficulty":difficulty,"actual_spawn_health":max_hp,"high_phase_warnings":high_warnings,"phase2_warning":new_warning,"phase2_release":release,"new_phase_warning_ticks":release-new_warning,"old_phase_latch_absent":difficulty==0})); + } + Ok(rows) +} +fn main() -> Result<()> { + let package = PathBuf::from(std::env::args().nth(1).expect("pass own package")); + let package = package.canonicalize()?; + let owner = package.file_name().unwrap().to_str().unwrap(); + let target = owner.contains("mission"); + let hook = if target { + "scripts/target.rhai" + } else { + "scripts/ai.rhai" + }; + let key = format!("{owner}/{hook}"); + let unit = format!("{owner}:{}", if target { "target" } else { "unit" }); + let objective = format!( + "{owner}:{}", + if target { + "targets_destroyed" + } else { + "defeated" + } + ); + let root = package.parent().unwrap().parent().unwrap(); + let cat = Catalog::open(&root.join("data"))?; + let mut base = Registry::base(&cat)?; + let content: ContentPack = serde_json::from_value( + json!({"missions":[{"id":"review:retained","name":"Test-only retained collision fixture","duration":10000,"auto_complete":false,"spawns":[{"tick":0,"enemy":unit,"x":88,"y":if target{60}else{24}}]}],"weapons":[{"id":"review:lethal","name":"Test-only stationary lethal projectile","damage":10000,"speed":0,"cooldown":1,"target":"all","behavior":"straight"}]}), + )?; + base.apply(content, "review")?; + let discovery = modding::discover(&root.join("mods")); + let mut enabled = BTreeSet::new(); + closure(&discovery, owner, &mut enabled); + let enabled = enabled.into_iter().collect::>(); + let mut a = ActiveMods::build(&base, &discovery, &enabled, Some(&cat))?; + let reward = a.registry.enemies[&unit.as_str().into()].reward; + let phase_transitions = if target { + vec![] + } else { + phase_warnings(&mut a, owner, &key)? + }; + let mut max_bytes = 0; + for life in 0..1205u64 { + let id = if life >= 1200 { 10000 } else { 10000 + life }; + let world = kill(&mut a, &unit, id, &objective, reward, target, 2)?; + let commands = + a.scripts + .invoke(owner, hook, "on_death", &event(id, 0, &objective, 1), 303)?; + assert!(commands.is_empty(), "duplicate death emitted commands"); + assert_eq!(world.player.credits, 10000 + reward); + max_bytes = max_bytes.max(guard(&a, &key)); + if life % 137 == 0 { + restore(&mut a, &discovery, &enabled)?; + } + if life % 128 == 0 || life == 1204 { + println!( + "{owner} retained native kills={}; statebytes={} retired={}", + life + 1, + guard(&a, &key), + a.scripts.states[&key]["dead"].as_object().unwrap().len() + ); + } + } + // Earlier pre-FIFO checkpoints migrate within the real engine limits. This + // includes a death flag for the entity killed before queued on_spawn executes. + let old_dead = (0..960) + .map(|n| (format!("{}", 60000 + n), json!(true))) + .collect::>(); + a.scripts + .states + .insert(key.clone(), json!({"dead":old_dead,"units":{}})); + restore(&mut a, &discovery, &enabled)?; + kill(&mut a, &unit, 60001, &objective, reward, target, 2)?; + assert_eq!(a.scripts.states[&key]["dead"]["60001"], json!(true)); + guard(&a, &key); + let migrated_state_bytes = serde_json::to_vec(&a.scripts.states[&key])?.len(); + for difficulty in 0..=3 { + kill( + &mut a, + &unit, + 70000 + difficulty as u64, + &objective, + reward, + target, + difficulty, + )?; + guard(&a, &key); + } + // Two live same-definition entities keep separate state; abandoned-world + // entity clocks are discarded at the next actual spawn instead of accumulating. + let mut abandoned_peak = 0; + if !target { + for life in 0..1205u64 { + let mut w = World::new(&"review:retained".into(), &pilot(2), &a.registry)?; + w.next_entity = 80000 + life; + w.step(input(), &a.registry, &mut a.scripts)?; + assert_eq!(w.enemies.len(), 1); + assert_eq!( + a.scripts.states[&key]["units"].as_object().unwrap().len(), + 1 + ); + abandoned_peak = abandoned_peak.max(serde_json::to_vec(&a.scripts.states[&key])?.len()); + } + let mut e1 = event(90000, 240, &objective, 0); + e1["entities"] = json!([{"entity":90000,"health":240}]); + a.scripts.invoke(owner, hook, "on_spawn", &e1, 303)?; + for _ in 0..20 { + a.scripts.invoke(owner, hook, "on_tick", &e1, 303)?; + } + let age = a.scripts.states[&key]["units"]["90000"]["age"].clone(); + let mut e2 = event(90001, 240, &objective, 0); + e2["entities"] = json!([{"entity":90000,"health":240},{"entity":90001,"health":240}]); + a.scripts.invoke(owner, hook, "on_spawn", &e2, 303)?; + assert_eq!(a.scripts.states[&key]["units"]["90000"]["age"], age); + assert_eq!(a.scripts.states[&key]["units"]["90001"]["age"], 0); + } + let report = json!({"fixture":"actual bundled Catalog; test-only stationary lethal projectile; native World collision, death, reward and retained ScriptRuntime","owner":owner,"unit":unit,"actual_native_collision_lives":1205,"distinct_ids":1200,"reused_id_lives":5,"checkpoint_json_roundtrips":9,"maximum_death_state_bytes":max_bytes,"actual_phase_transition_warnings":phase_transitions,"retired_guard_capacity":128,"duplicate_callback_commands":0,"reward_per_life":reward,"target_shield_restore":if target {12}else{0},"legacy_960_guard_migration":true,"migration_state_bytes":migrated_state_bytes,"difficulty_kills":[0,1,2,3],"abandoned_live_replays":if target {0}else{1205},"maximum_abandoned_state_bytes":abandoned_peak,"two_live_clocks_retained":!target,"enabled":enabled,"package_pins_at_execution":a.pins,"scope":"callback lifecycle/bounded-state proof, not mission combat balance"}); + std::fs::write( + package.join("validation/retained-state.json"), + serde_json::to_vec_pretty(&report)?, + )?; + println!( + "{owner}: all actual collision/reward, migration, deduplication, retained-state and abandoned-live checks passed" + ); + Ok(()) +} diff --git a/mods/iron_coast_stage2_boss_3/validation/validate.rs b/mods/iron_coast_stage2_boss_3/validation/validate.rs new file mode 100644 index 00000000..37727b5b --- /dev/null +++ b/mods/iron_coast_stage2_boss_3/validation/validate.rs @@ -0,0 +1,294 @@ +//! Package-local real callback and World lifecycle acceptance; no production mutation. +use raptor_replica::{ + content::{ContentPack, Registry}, + modding::{self, ActiveMods, Command, ScriptRuntime}, + persistence::Pilot, + simulation::{Input, World}, +}; +use serde_json::{Value, json}; +use std::path::Path; +fn runtime(package: &Path, owner: &str) -> ScriptRuntime { + let mut ai = ScriptRuntime::new(); + ai.add( + owner, + "scripts/ai.rhai", + &std::fs::read_to_string(package.join("scripts/ai.rhai")).unwrap(), + ) + .unwrap(); + ai +} +fn event(id: u64, x: i32, y: i32, hp: i32) -> Value { + json!({"entity":id,"x":x,"y":y,"health":hp,"tick":999,"player_x":144,"player_y":160,"entities":[{"entity":id,"health":hp}],"objectives":{}}) +} +fn call(ai: &mut ScriptRuntime, owner: &str, hook: &str, event: Value) -> Vec { + ai.invoke(owner, "scripts/ai.rhai", hook, &event, 303) + .unwrap() +} +fn lethal_spawn(package: &Path, owner: &str, reward: u32) { + let unit = format!("{owner}:unit"); + let objective = format!("{owner}:defeated"); + let mut base = Registry::default(); + let content:ContentPack=serde_json::from_value(json!({"weapons":[{"id":"base:projectile_forward_guns","name":"Forward Guns","damage":1,"speed":8,"cooldown":2,"behavior":"straight","target":"all"}],"items":[{"id":"base:forward_guns","name":"Forward Guns","price":0,"weapon":"base:projectile_forward_guns"},{"id":"base:energy","name":"Shield","price":0,"max_count":100}],"missions":[{"id":"base:sector_1_wave_1","name":"Spawn lifecycle regression","duration":500,"auto_complete":false,"spawns":[{"tick":0,"enemy":unit,"x":108,"y":120}]}]})).unwrap(); + base.apply(content, "base").unwrap(); + let discovery = modding::discover(package.parent().unwrap()); + let mut active = ActiveMods::build(&base, &discovery, &[owner.into()], None).unwrap(); + active + .registry + .enemies + .get_mut(&unit.as_str().into()) + .unwrap() + .health = 1; + let mut pilot = Pilot::default(); + pilot.difficulty = 2; + pilot.credits = 0; + let mut old_id = None; + for n in 0..3 { + let mut world = World::new(&pilot.mission, &pilot, &active.registry).unwrap(); + world + .step( + Input { + fire: true, + absolute: Some([144, 160]), + ..Input::default() + }, + &active.registry, + &mut active.scripts, + ) + .unwrap(); + assert!( + world.enemies.iter().all(|e| e.health <= 0), + "projectile must kill during spawn-step before queued on_spawn" + ); + assert!(world.projectiles.is_empty()); + assert!( + world.mod_sounds.is_empty(), + "dead arrival must not warn/fire" + ); + world + .step(Input::default(), &active.registry, &mut active.scripts) + .unwrap(); + assert!( + world.enemies.is_empty(), + "ground death is collected next tick" + ); + assert_eq!( + world.objectives.get(&objective), + Some(&1), + "reused entity lifecycle {n}" + ); + assert_eq!(world.player.credits, reward); + assert!(world.projectiles.is_empty()); + assert_eq!( + world.mod_sounds, + vec![format!("{owner}:death").as_str().into()] + ); + let cp = active.scripts.checkpoints(); + let key = format!("{owner}/scripts/ai.rhai"); + let state = &cp.0[&key]; + let keys = state["dead"] + .as_object() + .unwrap() + .keys() + .collect::>(); + assert_eq!(keys.len(), 1); + if let Some(ref old) = old_id { + assert_eq!(old, keys[0]); + } else { + old_id = Some(keys[0].clone()); + } + assert!(state["units"].as_object().unwrap().is_empty()); + world + .step(Input::default(), &active.registry, &mut active.scripts) + .unwrap(); + assert_eq!(world.player.credits, reward); + assert_eq!(world.objectives.get(&objective), Some(&1)); + let mut restored = runtime(package, owner); + restored.restore(cp); + active.scripts = restored; + } +} + +fn real_difficulty_phases(package: &Path, owner: &str, max_hp: i32) { + let unit = format!("{owner}:unit"); + let phase = format!("{owner}:phase"); + let mut base = Registry::default(); + let content:ContentPack=serde_json::from_value(json!({"items":[{"id":"base:energy","name":"Shield","price":0,"max_count":100}],"missions":[{"id":"base:sector_1_wave_1","name":"Actual difficulty health contract","duration":500,"auto_complete":false,"spawns":[{"tick":0,"enemy":unit,"x":108,"y":24}]}]})).unwrap(); + base.apply(content, "base").unwrap(); + let discovery = modding::discover(package.parent().unwrap()); + let mut active = ActiveMods::build(&base, &discovery, &[owner.into()], None).unwrap(); + for difficulty in 0..=3 { + let mut pilot = Pilot::default(); + pilot.difficulty = difficulty; + let mut world = World::new(&pilot.mission, &pilot, &active.registry).unwrap(); + let expected = if difficulty <= 1 { max_hp / 2 } else { max_hp }; + for _ in 0..3 { + world + .step( + Input { + absolute: Some([5, 160]), + ..Input::default() + }, + &active.registry, + &mut active.scripts, + ) + .unwrap(); + } + assert_eq!(world.enemies[0].health, expected); + assert_eq!(world.objectives.get(&phase), Some(&1)); + let key = format!("{owner}/scripts/ai.rhai"); + assert_eq!( + active.scripts.checkpoints().0[&key]["units"][world.enemies[0].entity.to_string()]["max_health"], + json!(expected) + ); + world.enemies[0].health = expected / 2; + for _ in 0..80 { + world + .step( + Input { + absolute: Some([5, 160]), + ..Input::default() + }, + &active.registry, + &mut active.scripts, + ) + .unwrap(); + } + assert_eq!(world.objectives.get(&phase), Some(&2)); + assert!(world.enemies[0].health > 0); + println!( + "real World difficulty{difficulty}: spawnHP{expected}, phase1 at arrival then phase2 at {}/half; no missing spawn health", + expected / 2 + ); + } +} + +fn main() { + let path = std::env::args().nth(1).expect("pass own package"); + let package = Path::new(&path); + let owner = package.file_name().unwrap().to_str().unwrap(); + let stage = if owner.ends_with('3') { 3 } else { 4 }; + let max_hp = if stage == 3 { 240 } else { 280 }; + for (hp, period, count) in [ + (max_hp, if stage == 3 { 72 } else { 76 }, 2), + ( + max_hp / 2, + if stage == 3 { 60 } else { 64 }, + if stage == 3 { 3 } else { 4 }, + ), + ] { + let mut ai = runtime(package, owner); + call(&mut ai, owner, "on_spawn", event(1, 108, -72, max_hp)); + for _ in 0..20 { + assert!( + !call(&mut ai, owner, "on_tick", event(1, 108, -72, hp)) + .iter() + .any(|c| matches!(c, Command::Projectile { .. } | Command::PlaySound { .. })) + ); + } + let mut warnings = vec![]; + let mut volleys = vec![]; + for tick in 1..=period * 2 { + let commands = call(&mut ai, owner, "on_tick", event(1, 108, 24, hp)); + if commands.iter().any( + |c| matches!(c,Command::PlaySound{sound} if sound==&format!("{owner}:warning")), + ) { + warnings.push(tick); + assert_eq!( + commands + .iter() + .filter(|c| matches!(c, Command::Arc { ticks: 8, .. })) + .count(), + 2 + ); + } + let projectiles = commands + .iter() + .filter(|c| matches!(c, Command::Projectile { .. })) + .collect::>(); + if !projectiles.is_empty() { + assert_eq!(projectiles.len(), count); + for p in projectiles { + if let Command::Projectile { + weapon, + y, + vy, + hostile, + .. + } = p + { + assert_eq!(weapon, &format!("{owner}:shell")); + assert_eq!( + (*y, *vy, *hostile), + if stage == 3 { + (86, 3, true) + } else { + (78, 4, true) + } + ); + } + } + volleys.push(tick); + } + } + assert_eq!(warnings, vec![1, 1 + period]); + assert_eq!(volleys, vec![15, 15 + period]); + let max_x = if stage == 3 { 156 } else { 148 }; + let min_x = if stage == 3 { 60 } else { 68 }; + for (x, negative) in [(max_x, true), (min_x, false)] { + let c = call(&mut ai, owner, "on_tick", event(1, x, 24, hp)); + assert!(c.iter().any(|c| matches!(c, Command::Move { y: 24, .. }))); /* warning pauses are allowed; direction inspected after next warning */ + for _ in 0..16 { + let c = call(&mut ai, owner, "on_tick", event(1, x, 24, hp)); + if c.iter() + .any(|c| matches!(c,Command::Velocity{vx,..} if *vx!=0)) + { + assert!(c.iter().any(|c|matches!(c,Command::Velocity{vx,vy:0,..} if if negative{*vx<0}else{*vx>0}))); + break; + } + } + } + call(&mut ai, owner, "on_spawn", event(2, 108, 24, hp)); + assert!( + !call(&mut ai, owner, "on_tick", event(2, 108, 24, hp)) + .iter() + .any(|c| matches!(c, Command::Projectile { .. })) + ); + let mut restored = runtime(package, owner); + restored.restore(ai.checkpoints()); + for _ in 0..133 { + assert_eq!( + serde_json::to_value(call(&mut ai, owner, "on_tick", event(1, 108, 24, hp))) + .unwrap(), + serde_json::to_value(call(&mut restored, owner, "on_tick", event(1, 108, 24, hp))) + .unwrap() + ); + } + assert!(call(&mut ai, owner, "on_tick", event(1, 108, 24, 0)).is_empty()); + let mut missing = event(1, 108, 24, hp); + missing["entities"] = json!([]); + assert!(call(&mut ai, owner, "on_tick", missing).is_empty()); + let death = call(&mut ai, owner, "on_death", event(1, 108, 24, 0)); + assert!(death.iter().any( + |c| matches!(c,Command::Objective{key,value:1} if key==&format!("{owner}:defeated")) + )); + assert!( + !death + .iter() + .any(|c| matches!(c, Command::Complete | Command::Credits { .. })) + ); + assert!(call(&mut ai, owner, "on_death", event(1, 108, 24, 0)).is_empty()); + let mut second = event(2, 108, 24, 0); + second["objectives"] = json!({format!("{owner}:defeated"):1}); + assert!(call(&mut ai, owner, "on_death", second).iter().any( + |c| matches!(c,Command::Objective{key,value:2} if key==&format!("{owner}:defeated")) + )); + println!( + "{owner}: health {hp}, period {period}, volley {count}, warning14 ticks; arrival, bounds, two entities, checkpoint, absent/dead guard and once-only death passed" + ); + } + real_difficulty_phases(package, owner, max_hp); + lethal_spawn(package, owner, if stage == 3 { 2400 } else { 2800 }); + println!( + "real World lethal queued-spawn, saved-state reused ID and exact reward across three replays: passed" + ); +} diff --git a/mods/iron_coast_stage2_boss_4/README.md b/mods/iron_coast_stage2_boss_4/README.md new file mode 100644 index 00000000..a4b58a79 --- /dev/null +++ b/mods/iron_coast_stage2_boss_4/README.md @@ -0,0 +1,15 @@ +# Iron Coast II — Floodgate + +Independent API1 enemy package: enable this mod alone to make `iron_coast_stage2_boss_4:unit` available to missions. It does not add a playable campaign, shop item, dependency, override or equipment grant. Mission4 uses this boss; other mod missions can reference the unit and its `:defeated` objective. + +Floodgate is a104×64 ground boss with280 normal health and2800 credit reward. It enters at2pixels per tick then holds y24, patrolling x68–148 at2pixels per tick. Each salvo gives a14-tick visual/audio warning and movement pause. Two outward3-damage shells leave a central safe lane every76ticks above halfhealth; below halfhealth two extra inward-positioned outward shells join a64-tick cycle. All projectiles have finite standard collision behavior. The actual spawn-health snapshot defines the half-health transition, so easier difficulty begins in the first phase despite the engine halving starting health. + +State is deterministic and per entity. Arrival and fire clocks are independent. Dead or missing snapshots cannot shoot; actual deaths increment `iron_coast_stage2_boss_4:defeated` once, while despawn/escape never count. Spawn clears reused entity-ID flags before checking the live snapshot, allowing saved-state mission replays even when the engine collects a ground projectile death on the following step. The boss never completes a mission or pays a script credit reward; the engine grants its one defined reward. + +The unit and shell have genuine transparent SD/8×HD PNGs and untouched builtin masters, with tracked `prompts/`, per-art provenance, `asset-report.json`, `audio-recipe.json` and `build_assets.py`. Runtime-invisible alpha padding is cropped at16 while runtime alpha128samples remain inside the fitted logical canvas. Generated warning/shot/death WAVs are original seeded mono16-bit22050Hz synthesis. The recipe defaults to the bundled `RustRaptor/data/misc/PALETTE_DAT`; decoded original style references remain outside the package. + +From `RustRaptor/`, run `target/release/raptor-rust --data data --mods mods --validate-mods iron_coast_stage2_boss_4` and `cargo run --manifest-path mods/iron_coast_stage2_boss_4/validation/Cargo.toml --target-dir target/mod-validation --bin validate --release -- mods/iron_coast_stage2_boss_4`. The local probe checks exact warning/volley timing and phase sizes, independent entities, arrival/bounds, deterministic saved state, dead/missing guards, actual difficulty0–3 health transitions and three reused-ID lethal-spawn/reward replays. Mission-level combat balance and SD/HD scene evidence are supplied with Mission4. + +Retired death guards are bounded to the most recent128 entity IDs, including deterministic migration of older checkpoints. Spawn resets a reused ID before any alive check; duplicate deaths for the current lifecycle emit no commands. A new World also discards clocks of absent entities while retaining live peers. The `retained-state` validation binary exercises1,205 actual-catalog/native lethal-collision lives, including1,200 distinct IDs, five reused-ID lives, JSON state/RNG restoration, a960-guard old checkpoint, duplicate callbacks, exact rewards and difficulty0–3. It additionally checks1,205 abandoned-live World resets and two independent live clocks. Run it from `RustRaptor/` with `cargo run --manifest-path mods/iron_coast_stage2_boss_4/validation/Cargo.toml --target-dir target/mod-validation --bin retained-state --release -- mods/iron_coast_stage2_boss_4`. The corresponding `validation/retained-state.json` records actual observations; package pins there identify the activation before generated proof files were finalized. The final external freeze ledger binds the complete resulting package. + +A health-phase change restarts its per-entity warning clock and immediately telegraphs the new phase. It cannot shorten the14-tick charge by changing the modulo period. The actual World regression lowers health immediately after the second high-health warning at all four difficulties and verifies a fresh warning followed by exactly14ticks before release; it also upgrades an old checkpoint lacking the phase latch. diff --git a/mods/iron_coast_stage2_boss_4/art/shell-hd.png b/mods/iron_coast_stage2_boss_4/art/shell-hd.png new file mode 100644 index 00000000..ff14320d Binary files /dev/null and b/mods/iron_coast_stage2_boss_4/art/shell-hd.png differ diff --git a/mods/iron_coast_stage2_boss_4/art/shell-sd.png b/mods/iron_coast_stage2_boss_4/art/shell-sd.png new file mode 100644 index 00000000..3de8c530 Binary files /dev/null and b/mods/iron_coast_stage2_boss_4/art/shell-sd.png differ diff --git a/mods/iron_coast_stage2_boss_4/art/shell-source-v1.png b/mods/iron_coast_stage2_boss_4/art/shell-source-v1.png new file mode 100644 index 00000000..27779a61 Binary files /dev/null and b/mods/iron_coast_stage2_boss_4/art/shell-source-v1.png differ diff --git a/mods/iron_coast_stage2_boss_4/art/shell-v2-source-v1.png b/mods/iron_coast_stage2_boss_4/art/shell-v2-source-v1.png new file mode 100644 index 00000000..3942617a Binary files /dev/null and b/mods/iron_coast_stage2_boss_4/art/shell-v2-source-v1.png differ diff --git a/mods/iron_coast_stage2_boss_4/art/unit-hd.png b/mods/iron_coast_stage2_boss_4/art/unit-hd.png new file mode 100644 index 00000000..7d2dd9f9 Binary files /dev/null and b/mods/iron_coast_stage2_boss_4/art/unit-hd.png differ diff --git a/mods/iron_coast_stage2_boss_4/art/unit-sd.png b/mods/iron_coast_stage2_boss_4/art/unit-sd.png new file mode 100644 index 00000000..5d2b08f6 Binary files /dev/null and b/mods/iron_coast_stage2_boss_4/art/unit-sd.png differ diff --git a/mods/iron_coast_stage2_boss_4/art/unit-source-v1.png b/mods/iron_coast_stage2_boss_4/art/unit-source-v1.png new file mode 100644 index 00000000..1b930d07 Binary files /dev/null and b/mods/iron_coast_stage2_boss_4/art/unit-source-v1.png differ diff --git a/mods/iron_coast_stage2_boss_4/asset-report.json b/mods/iron_coast_stage2_boss_4/asset-report.json new file mode 100644 index 00000000..5349a785 --- /dev/null +++ b/mods/iron_coast_stage2_boss_4/asset-report.json @@ -0,0 +1,126 @@ +{ + "palette_sha256": "1cf6adb926d1dee1888b3e3d33b51a7049b3e5eb5f90a3067ef71c8970547204", + "ordinary_palette_entries_only": true, + "audio": { + "warning": { + "path": "audio/warning.wav", + "sha256": "70865f6e434074019ffb06dcf2e7c9304347286bbdca61ccdbb4c23739aaaa66", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "samples": 7938, + "seconds": 0.36, + "seed": 2932, + "peak": 15728, + "recipe": "deterministic seeded chirp/noise, original synthesis, no recordings" + }, + "shot": { + "path": "audio/shot.wav", + "sha256": "c0741c7e5ab40386855ebf0b61b628b24d44777e2315e187eecf9f542c45dc5b", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "samples": 4410, + "seconds": 0.2, + "seed": 2933, + "peak": 20316, + "recipe": "deterministic seeded chirp/noise, original synthesis, no recordings" + }, + "death": { + "path": "audio/death.wav", + "sha256": "0a407eedc9a9d5869362a62e3134c8ba55ecdd91e6c79f9b0158134b03261be6", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "samples": 20948, + "seconds": 0.9500226757369614, + "seed": 2934, + "peak": 20316, + "recipe": "deterministic seeded chirp/noise, original synthesis, no recordings" + } + }, + "unit": { + "master": "art/unit-source-v1.png", + "master_sha256": "e36cb66cdea0d1a9cc4a4ac1056e2d34786d8009d1851749e3d63760f5db2c00", + "master_size": [ + 1599, + 984 + ], + "crop_runtime_invisible_padding": [ + 141, + 134, + 1458, + 824 + ], + "crop_threshold": 16, + "runtime_alpha_threshold": 128, + "logical_canvas": [ + 104, + 64 + ], + "hd_canvas": [ + 832, + 512 + ], + "sd_bounds": [ + 3, + 6, + 101, + 58 + ], + "hd_bounds": [ + 24, + 50, + 808, + 461 + ], + "frame_count": 1, + "origin": [ + 0, + 0 + ], + "generated_art_repainted": false + }, + "shell": { + "master": "art/shell-v2-source-v1.png", + "master_sha256": "2f512c5ed0c993da8988dca809a522946d13bbbbe8b288b62361dc5ec4add8e7", + "master_size": [ + 1620, + 971 + ], + "crop_runtime_invisible_padding": [ + 725, + 263, + 896, + 709 + ], + "crop_threshold": 16, + "runtime_alpha_threshold": 128, + "logical_canvas": [ + 8, + 8 + ], + "hd_canvas": [ + 64, + 64 + ], + "sd_bounds": [ + 3, + 1, + 5, + 7 + ], + "hd_bounds": [ + 23, + 8, + 41, + 56 + ], + "frame_count": 1, + "origin": [ + 0, + 0 + ], + "generated_art_repainted": false + } +} diff --git a/mods/iron_coast_stage2_boss_4/audio-recipe.json b/mods/iron_coast_stage2_boss_4/audio-recipe.json new file mode 100644 index 00000000..e9e901c7 --- /dev/null +++ b/mods/iron_coast_stage2_boss_4/audio-recipe.json @@ -0,0 +1,38 @@ +{ + "warning": { + "path": "audio/warning.wav", + "sha256": "70865f6e434074019ffb06dcf2e7c9304347286bbdca61ccdbb4c23739aaaa66", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "samples": 7938, + "seconds": 0.36, + "seed": 2932, + "peak": 15728, + "recipe": "deterministic seeded chirp/noise, original synthesis, no recordings" + }, + "shot": { + "path": "audio/shot.wav", + "sha256": "c0741c7e5ab40386855ebf0b61b628b24d44777e2315e187eecf9f542c45dc5b", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "samples": 4410, + "seconds": 0.2, + "seed": 2933, + "peak": 20316, + "recipe": "deterministic seeded chirp/noise, original synthesis, no recordings" + }, + "death": { + "path": "audio/death.wav", + "sha256": "0a407eedc9a9d5869362a62e3134c8ba55ecdd91e6c79f9b0158134b03261be6", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "samples": 20948, + "seconds": 0.9500226757369614, + "seed": 2934, + "peak": 20316, + "recipe": "deterministic seeded chirp/noise, original synthesis, no recordings" + } +} diff --git a/mods/iron_coast_stage2_boss_4/audio/death.wav b/mods/iron_coast_stage2_boss_4/audio/death.wav new file mode 100644 index 00000000..143003e0 Binary files /dev/null and b/mods/iron_coast_stage2_boss_4/audio/death.wav differ diff --git a/mods/iron_coast_stage2_boss_4/audio/shot.wav b/mods/iron_coast_stage2_boss_4/audio/shot.wav new file mode 100644 index 00000000..21bc1d1e Binary files /dev/null and b/mods/iron_coast_stage2_boss_4/audio/shot.wav differ diff --git a/mods/iron_coast_stage2_boss_4/audio/warning.wav b/mods/iron_coast_stage2_boss_4/audio/warning.wav new file mode 100644 index 00000000..796f9a8e Binary files /dev/null and b/mods/iron_coast_stage2_boss_4/audio/warning.wav differ diff --git a/mods/iron_coast_stage2_boss_4/build_assets.py b/mods/iron_coast_stage2_boss_4/build_assets.py new file mode 100644 index 00000000..6786d7b8 --- /dev/null +++ b/mods/iron_coast_stage2_boss_4/build_assets.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python3 +"""Reproduce packaged artwork footprints and seeded local PCM audio. + +Builtin imagegen masters are preserved byte-for-byte. This recipe only crops +empty/runtime-subthreshold transparent padding, fits/resamples canvases, splits joined terrain and +quantizes SD to ordinary game palette colors; it never paints generated pixels. +""" +from pathlib import Path +import argparse,hashlib,json,math,random,struct,wave +from PIL import Image,ImageOps +ROOT=Path(__file__).resolve().parent +hashfile=lambda p:hashlib.sha256(p.read_bytes()).hexdigest() +def palette(path): + raw=path.read_bytes();assert len(raw)==768 + colors=[(min(v,63)<<2)|(min(v,63)>>4) for v in raw] + colors[720:]=colors[:48];im=Image.new('P',(1,1));im.putpalette(colors);return im + +def sd(im,size,pal): + im=im.convert('RGBA').resize(size,Image.Resampling.BOX);alpha=im.getchannel('A').point(lambda v:255 if v>=128 else 0) + out=im.convert('RGB').quantize(palette=pal,dither=Image.Dither.NONE).convert('RGBA');out.putalpha(alpha);return out + +def footprint(stem,logical,pal): + p=ROOT/'art'/f'{stem}-source-v1.png' + if stem=='shell' and (ROOT/'art/shell-v2-source-v1.png').exists():p=ROOT/'art/shell-v2-source-v1.png' + raw=Image.open(p).convert('RGBA');assert raw.getchannel('A').getextrema()[0]==0,'genuine transparent master required' + # Keep every visible alpha>=128 sample. Imagegen adds isolated alpha1 noise + # across the canvas; threshold16 bounds remove only runtime-invisible padding, + # while the raw master and its original alpha remain untouched. + box=raw.getchannel('A').point(lambda v:255 if v>=16 else 0).getbbox();assert box;assert raw.getchannel('A').point(lambda v:255 if v>=128 else 0).getbbox();crop=raw.crop(box);size=tuple(v*8 for v in logical);margin=8 if stem=='shell' else 24 + hd=Image.new('RGBA',size);fitted=ImageOps.contain(crop,(size[0]-margin*2,size[1]-margin*2),Image.Resampling.LANCZOS);hd.alpha_composite(fitted,((size[0]-fitted.width)//2,(size[1]-fitted.height)//2));low=sd(hd,logical,pal) + for suffix,im in [('hd',hd),('sd',low)]: + bounds=im.getchannel('A').point(lambda v:255 if v>=128 else 0).getbbox();assert bounds and bounds[0]>0 and bounds[1]>0 and bounds[2]=128 else 0).getbbox()),'frame_count':1,'origin':[0,0],'generated_art_repainted':False} + +def synth(name,duration,seed,mode): + rate=22050;rng=random.Random(seed);count=round(rate*duration);phase=0;slow=0;v=[] + for i in range(count): + u=i/(count-1);t=i/rate;noise=rng.uniform(-1,1);slow=slow*.90+noise*.10 + if mode=='warning':freq=440+220*int(u*2);signal=math.sin(phase)*.60+math.sin(phase*2)*.15;env=math.sin(math.pi*u)**1.4 + elif mode=='shot':freq=440*(1-u)**2+65;signal=math.sin(phase)*.5+noise*.20+math.sin(phase*2.13)*.13;env=math.exp(-5*u) + elif mode=='death':freq=75-50*u;signal=slow*.6+noise*.18+math.sin(phase)*.25;env=math.exp(-4.5*u) + else: + notes=[294,370,440,587] if mode=='victory' else [220,294,440];freq=notes[min(len(notes)-1,int(u*len(notes)))];signal=math.sin(phase)*.65+math.sin(phase*2)*.12;env=min(1,(u*len(notes)%1)*20)*(1-u)**.6 + phase+=2*math.pi*freq/rate;env*=min(1,t/.004)*min(1,(count-1-i)/(rate*.005));v.append(signal*max(0,env)) + peak=max(abs(x) for x in v);target=.48 if mode=='warning' else .62;pcm=[round(x/peak*32767*target) for x in v];p=ROOT/'audio'/f'{name}.wav' + with wave.open(str(p),'wb') as w:w.setnchannels(1);w.setsampwidth(2);w.setframerate(rate);w.writeframes(struct.pack('<'+'h'*count,*pcm)) + return {'path':str(p.relative_to(ROOT)),'sha256':hashfile(p),'sample_rate':rate,'bits':16,'channels':1,'samples':count,'seconds':count/rate,'seed':seed,'peak':max(abs(x) for x in pcm),'recipe':'deterministic seeded chirp/noise, original synthesis, no recordings'} + +def main(): + ap=argparse.ArgumentParser();ap.add_argument('--palette',type=Path,default=ROOT.parents[1]/'data/misc/PALETTE_DAT');ap.add_argument('--audio-only',action='store_true');a=ap.parse_args();is_boss='boss' in ROOT.name;stage=int(ROOT.name[-1]);sounds={} + sound_specs=[('warning',.36,'warning'),('shot',.20,'shot'),('death',.95,'death')] if is_boss else [('approach',.78,'tone'),('target_alarm',.42,'warning'),('boss_alarm',.65,'warning'),('salvage',.32,'tone'),('victory',1.10,'victory')] + for i,(n,d,m) in enumerate(sound_specs):sounds[n]=synth(n,d,stage*733+i,m) + (ROOT/'audio-recipe.json').write_text(json.dumps(sounds,indent=2)+'\n') + if a.audio_only:return + pal=palette(a.palette);report={'palette_sha256':hashfile(a.palette),'ordinary_palette_entries_only':True,'audio':sounds} + if is_boss: + report['unit']=footprint('unit',(104,72 if stage==3 else 64),pal);report['shell']=footprint('shell',(8,8),pal) + else: + report['target']=footprint('target',(32,32),pal);p=ROOT/'art/terrain-source-v1.png';source=Image.open(p).convert('RGBA');assert source.getchannel('A').getextrema()[0]>=128,'terrain must be fully opaque' + hd=ImageOps.fit(source,(1152,2048),Image.Resampling.LANCZOS);low=sd(hd,(288,512),pal);tiles=0 + for reverse in [False,True]: + hi=ImageOps.flip(hd) if reverse else hd;lo=ImageOps.flip(low) if reverse else low + for row in range(16): + for col in range(9): + hi.crop((col*128,row*128,(col+1)*128,(row+1)*128)).save(ROOT/'art'/f'tile-{tiles:03}-hd.png');lo.crop((col*32,row*32,(col+1)*32,(row+1)*32)).save(ROOT/'art'/f'tile-{tiles:03}-sd.png');tiles+=1 + for im in [hd,low]:assert im.crop((0,im.height-1,im.width,im.height)).tobytes()==ImageOps.flip(im).crop((0,0,im.width,1)).tobytes() + # Briefing is a truthful wide crop of the generated terrain, not new artwork. + briefing=ImageOps.fit(source,(1280,800),Image.Resampling.LANCZOS);briefing.save(ROOT/'art/briefing-hd.png');sd(briefing,(320,200),pal).save(ROOT/'art/briefing-sd.png');low.save(ROOT/'art/terrain-preview-sd.png');hd.save(ROOT/'art/terrain-preview-hd.png') + report['terrain']={'master_sha256':hashfile(p),'master_size':list(source.size),'logical_joined_size':[288,512],'hd_joined_size':[1152,2048],'tiles':tiles,'period_rows':32,'repeat':'forward16 rows then reflected16 rows, both periodboundaries identical','joined_before_quantizing_and_splitting':True,'seam_checks':True,'briefing':'320x200 /1280x800 central wide crop from same genuine terrain master'} + (ROOT/'asset-report.json').write_text(json.dumps(report,indent=2)+'\n');print(ROOT.name,'assets/sounds ready') +if __name__=='__main__':main() diff --git a/mods/iron_coast_stage2_boss_4/content.json b/mods/iron_coast_stage2_boss_4/content.json new file mode 100644 index 00000000..83bd232b --- /dev/null +++ b/mods/iron_coast_stage2_boss_4/content.json @@ -0,0 +1,69 @@ +{ + "weapons": [ + { + "id": "iron_coast_stage2_boss_4:shell", + "name": "Floodgate defense shell", + "damage": 3, + "speed": 4, + "cooldown": 64, + "behavior": "straight", + "target": "all", + "art": { + "png": "art/shell-sd.png", + "hd_png": "art/shell-hd.png", + "logical_width": 8, + "logical_height": 8, + "frames": 1 + } + } + ], + "enemies": [ + { + "id": "iron_coast_stage2_boss_4:unit", + "name": "Floodgate", + "health": 280, + "speed": 0, + "reward": 2800, + "ground": true, + "boss": true, + "cooldown": 64, + "art": { + "png": "art/unit-sd.png", + "hd_png": "art/unit-hd.png", + "logical_width": 104, + "logical_height": 64, + "frames": 1 + }, + "script": "scripts/ai.rhai" + } + ], + "sounds": [ + { + "id": "iron_coast_stage2_boss_4:warning", + "name": "Warning", + "file": "audio/warning.wav", + "volume": 70, + "pan": 127, + "pitch": 128, + "priority": 2 + }, + { + "id": "iron_coast_stage2_boss_4:shot", + "name": "Shot", + "file": "audio/shot.wav", + "volume": 85, + "pan": 127, + "pitch": 128, + "priority": 2 + }, + { + "id": "iron_coast_stage2_boss_4:death", + "name": "Death", + "file": "audio/death.wav", + "volume": 100, + "pan": 127, + "pitch": 128, + "priority": 2 + } + ] +} diff --git a/mods/iron_coast_stage2_boss_4/mod.toml b/mods/iron_coast_stage2_boss_4/mod.toml new file mode 100644 index 00000000..ecd0c8dd --- /dev/null +++ b/mods/iron_coast_stage2_boss_4/mod.toml @@ -0,0 +1,7 @@ +id = "iron_coast_stage2_boss_4" +name = "Iron Coast II — Floodgate" +version = "1.0.0" +api_version = 1 +description = "Distinct telegraphed Floodgate boss with two health phases, persistent onscreen patrol, SD/HD artwork and original synthesized sounds." +content = "content.json" +scripts = ["scripts/ai.rhai"] diff --git a/mods/iron_coast_stage2_boss_4/prompts/shell-v1.txt b/mods/iron_coast_stage2_boss_4/prompts/shell-v1.txt new file mode 100644 index 00000000..323024e3 --- /dev/null +++ b/mods/iron_coast_stage2_boss_4/prompts/shell-v1.txt @@ -0,0 +1,4 @@ +Use case: stylized-concept +Asset type: new Iron Coast II game sprite/terrain master +Style reference is the original Raptor contact sheet: exact top-down mechanical vehicle/terrain shapes, muted gray-bronze steel, worn panels, dark outlines, compact DOS-shooter readability. Create original new artwork matching that visual language with cleaner high-resolution detail, not a copy or a photograph. +Primary request: One isolated compact enemy defense projectile for an8x8logical sprite: downward-facing short electric-blue steel sabot shell, pointed tip down, tiny warm pale core, narrow dark gray casing and restrained cyan accent. Orthographic top view, clear simple silhouette, no explosive burst, no expansive bloom, no long trail. Large transparent canvas with generous empty padding around the single shell. SD reduction must stay readable. No text, labels or scenery. diff --git a/mods/iron_coast_stage2_boss_4/prompts/shell-v2.txt b/mods/iron_coast_stage2_boss_4/prompts/shell-v2.txt new file mode 100644 index 00000000..39139194 --- /dev/null +++ b/mods/iron_coast_stage2_boss_4/prompts/shell-v2.txt @@ -0,0 +1 @@ +Create one original Raptor-compatible hostile defense projectile sprite, transparent background, directly top-down, pointing straight DOWN towards the player. Use the attached original Raptor contact sheet only as style guidance. One compact short broad amber-orange tracer shell with a small dark-steel top cap and a prominent pale yellow-white hot core occupying the lower half; broad orange outlines, not a thin cyan spear. It will be rendered in only an 8 by 8 logical canvas, so shape must be very simple, visually high-contrast and clearly readable against dark teal water and gray industrial concrete. Sprite roughly four times taller than wide, actual opaque hot core thickness at least one quarter of shell width. Strong classic 1990s Apogee pixel-art materials, crisp controlled hard edges, no surrounding glow haze, no background, no lettering, no extra sparks, no duplicate sprites. Center the single isolated shell with transparent padding on all sides. The final actual core must remain very bright at a tiny pixel presentation. diff --git a/mods/iron_coast_stage2_boss_4/prompts/unit-v1.txt b/mods/iron_coast_stage2_boss_4/prompts/unit-v1.txt new file mode 100644 index 00000000..0bbfa517 --- /dev/null +++ b/mods/iron_coast_stage2_boss_4/prompts/unit-v1.txt @@ -0,0 +1,4 @@ +Use case: stylized-concept +Asset type: new Iron Coast II game sprite/terrain master +Style reference is the original Raptor contact sheet: exact top-down mechanical vehicle/terrain shapes, muted gray-bronze steel, worn panels, dark outlines, compact DOS-shooter readability. Create original new artwork matching that visual language with cleaner high-resolution detail, not a copy or a photograph. +Primary request: Original Floodgate boss: mobile dam defense platform, strict orthographic top view, downscreen-facing broad amphibious rectangular104x64 logical silhouette, four pontoon/tread corner feet, two long side battery turrets and a central dam-gate control cabin, flat deck grilles, teal hydraulic lines with restrained amber hazard bands. Muted dark gray steel with teal details, visibly distinct from the Stormglass crawler. Whole silhouette centered with generous transparent outer padding. No landscape, no perspective, no smoke, no shadow outside hull, no text, no UI. diff --git a/mods/iron_coast_stage2_boss_4/provenance-shell-v2.json b/mods/iron_coast_stage2_boss_4/provenance-shell-v2.json new file mode 100644 index 00000000..decd46f0 --- /dev/null +++ b/mods/iron_coast_stage2_boss_4/provenance-shell-v2.json @@ -0,0 +1,40 @@ +{ + "generator": "built-in image_gen.imagegen", + "owner": "/root/iron_coast_3", + "job_id": "stage2-shell-readable-v2", + "utc": "2026-10-11T08:28:36.806092+00:00", + "default_output": "/home/quintine/.codex/generated_images/01a1245d-8d97-74e2-9a2c-02e88a570589/exec-225e6e18-97a0-4348-880b-4aaddb90fa21.png", + "raw_master": "art/shell-v2-source-v1.png", + "raw_sha256": "2f512c5ed0c993da8988dca809a522946d13bbbbe8b288b62361dc5ec4add8e7", + "prompt": "prompts/shell-v2.txt", + "prompt_sha256": "763879d9caf0c1fa18c3d053ce2efde45a12c9b2297a7b2fd988b5dc0a81df67", + "style_reference_role": "Original Raptor style only; decoded style reference is intentionally external to authored mod.", + "reference_sha256": "685307409d68baa9413975b59427c74d29f6a09b2b039a3d88ee69abf19e9a9d", + "original_style_source_hashes": [ + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/enemies-200cc-200cd/sources/200cc.png", + "sha256": "c3f92b8a04370029652cfff20dc00ec41228c5adead37affaacd3b9511bb520d", + "role": "Original Raptor style reference; not copied into authored mods." + }, + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/enemies-2008d-2008d/sources/2008d.png", + "sha256": "419514e3b7cbd9fb7283f0550f12991f5570c2de16c367330fa2e8a9b6bb3725", + "role": "Original Raptor style reference; not copied into authored mods." + }, + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/bosses-10310-10310/sources/10310.png", + "sha256": "39404e604c4d535e868ffea924ba206c690e19f7df9c289ce14612cb2451bbef", + "role": "Original Raptor style reference; not copied into authored mods." + }, + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/terrain-10360-1036f/sources/10360.png", + "sha256": "ee5348dbdf57952027349c64cd13c9d2991a33b0378a54f4750622d9bff50dc0", + "role": "Original Raptor style reference; not copied into authored mods." + } + ], + "transparent_background_requested": true, + "gate_lease": "17ea3caa-bd34-4055-8fcb-fe6aee83f390", + "gate_outcome": "success", + "source_pixels_modified": false, + "shared_duplicate": "Bundled exact same original generated master as Stormglass shell; no runtime dependency" +} diff --git a/mods/iron_coast_stage2_boss_4/provenance-shell.json b/mods/iron_coast_stage2_boss_4/provenance-shell.json new file mode 100644 index 00000000..646fdfe9 --- /dev/null +++ b/mods/iron_coast_stage2_boss_4/provenance-shell.json @@ -0,0 +1,40 @@ +{ + "generator": "built-in image_gen.imagegen", + "owner": "/root/iron_coast_3", + "job_id": "stage2-shell", + "utc": "2026-10-11T08:13:24.506440+00:00", + "default_output": "/home/quintine/.codex/generated_images/01a1245d-8d97-74e2-9a2c-02e88a570589/exec-76856a96-5638-498c-a52e-4de830611a56.png", + "raw_master": "art/shell-source-v1.png", + "raw_sha256": "097d9ed2ac5be5fd2d749a306391cea1619b53e3eefebd8081e20d05433e8189", + "prompt": "prompts/shell-v1.txt", + "prompt_sha256": "02435865b7a8780486235080ab0cff91199b32eb2cbb7e776c78e8c1ccf9f9f3", + "style_reference_role": "Original Raptor style only; decoded style reference is intentionally external to authored mod.", + "reference_sha256": "685307409d68baa9413975b59427c74d29f6a09b2b039a3d88ee69abf19e9a9d", + "original_style_source_hashes": [ + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/enemies-200cc-200cd/sources/200cc.png", + "sha256": "c3f92b8a04370029652cfff20dc00ec41228c5adead37affaacd3b9511bb520d", + "role": "Original Raptor style reference; not copied into authored mods." + }, + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/enemies-2008d-2008d/sources/2008d.png", + "sha256": "419514e3b7cbd9fb7283f0550f12991f5570c2de16c367330fa2e8a9b6bb3725", + "role": "Original Raptor style reference; not copied into authored mods." + }, + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/bosses-10310-10310/sources/10310.png", + "sha256": "39404e604c4d535e868ffea924ba206c690e19f7df9c289ce14612cb2451bbef", + "role": "Original Raptor style reference; not copied into authored mods." + }, + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/terrain-10360-1036f/sources/10360.png", + "sha256": "ee5348dbdf57952027349c64cd13c9d2991a33b0378a54f4750622d9bff50dc0", + "role": "Original Raptor style reference; not copied into authored mods." + } + ], + "transparent_background_requested": true, + "gate_lease": "1cdecd31-b10e-44d7-aa33-29396970ce2f", + "gate_outcome": "success", + "source_pixels_modified": false, + "shared_original_master": "Same genuine shell design used independently by both Stage2 boss packages; duplicate final source bundled, no runtime dependency." +} diff --git a/mods/iron_coast_stage2_boss_4/provenance-unit.json b/mods/iron_coast_stage2_boss_4/provenance-unit.json new file mode 100644 index 00000000..f7ace298 --- /dev/null +++ b/mods/iron_coast_stage2_boss_4/provenance-unit.json @@ -0,0 +1,39 @@ +{ + "generator": "built-in image_gen.imagegen", + "owner": "/root/iron_coast_3", + "job_id": "stage2-boss4", + "utc": "2026-10-11T08:12:39.504896+00:00", + "default_output": "/home/quintine/.codex/generated_images/01a1245d-8d97-74e2-9a2c-02e88a570589/exec-03fe0e63-f74b-44f5-9e2e-8c849e348bab.png", + "raw_master": "art/unit-source-v1.png", + "raw_sha256": "e36cb66cdea0d1a9cc4a4ac1056e2d34786d8009d1851749e3d63760f5db2c00", + "prompt": "prompts/unit-v1.txt", + "prompt_sha256": "92da9a4f5fcf7431f09282a67e59ed8488b0715ad61a22ac1640248ebcd6689c", + "style_reference_role": "Original Raptor style only; decoded style reference is intentionally external to authored mod.", + "reference_sha256": "685307409d68baa9413975b59427c74d29f6a09b2b039a3d88ee69abf19e9a9d", + "original_style_source_hashes": [ + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/enemies-200cc-200cd/sources/200cc.png", + "sha256": "c3f92b8a04370029652cfff20dc00ec41228c5adead37affaacd3b9511bb520d", + "role": "Original Raptor style reference; not copied into authored mods." + }, + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/enemies-2008d-2008d/sources/2008d.png", + "sha256": "419514e3b7cbd9fb7283f0550f12991f5570c2de16c367330fa2e8a9b6bb3725", + "role": "Original Raptor style reference; not copied into authored mods." + }, + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/bosses-10310-10310/sources/10310.png", + "sha256": "39404e604c4d535e868ffea924ba206c690e19f7df9c289ce14612cb2451bbef", + "role": "Original Raptor style reference; not copied into authored mods." + }, + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/terrain-10360-1036f/sources/10360.png", + "sha256": "ee5348dbdf57952027349c64cd13c9d2991a33b0378a54f4750622d9bff50dc0", + "role": "Original Raptor style reference; not copied into authored mods." + } + ], + "transparent_background_requested": true, + "gate_lease": "7a05a680-15d2-4bb5-93b9-1101b8474981", + "gate_outcome": "success", + "source_pixels_modified": false +} diff --git a/mods/iron_coast_stage2_boss_4/scripts/ai.rhai b/mods/iron_coast_stage2_boss_4/scripts/ai.rhai new file mode 100644 index 00000000..e08033d5 --- /dev/null +++ b/mods/iron_coast_stage2_boss_4/scripts/ai.rhai @@ -0,0 +1,79 @@ +// Deterministic per-entity patrol, health phases and visible/audio warning windows. +fn alive(event) { for unit in event.entities { if unit.entity==event.entity && unit.health>0 { return true; } } false } +fn spawn_health(event) { for unit in event.entities { if unit.entity==event.entity {return unit.health.max(1);} } 1 } +// At most128 retired IDs survive checkpoint/replay. Upgrade older checkpoints +// without a FIFO by retaining a deterministic bounded subset of their guards. +fn ready(state) { + if !state.contains("units") {state.units=#{};} + if !state.contains("dead") {state.dead=#{};} + if !state.contains("dead_order") { + let retained=#{};let order=[]; + for key in state.dead.keys() { + if order.len()>=128 {let oldest=order.remove(0);retained.remove(oldest);} + retained[key]=true;order.push(key); + } + state.dead=retained;state.dead_order=order; + } + state +} +fn on_spawn(event,state,random) { + state=ready(state); + // Discard clocks of entities absent from this World after an abandoned run. + // Existing live peers retain their independent clocks. + let live_units=#{}; + for unit in event.entities { + let unit_key=unit.entity.to_string(); + if unit.health>0 && state.units.contains(unit_key) {live_units[unit_key]=state.units[unit_key];} + } + state.units=live_units; + let key=event.entity.to_string();state.dead.remove(key);state.units.remove(key); + let keep=[];for old in state.dead_order {if old!=key {keep.push(old);}}state.dead_order=keep; + // A lethal spawn-step collision still clears this lifecycle's old death flag. + if !alive(event) {return #{commands:[],state:state};} + state.units[key]=#{age:0,direction:1,aim:0,phase:1,max_health:spawn_health(event)}; + #{commands:[#{op:"velocity",entity:event.entity,vx:0,vy:2}],state:state} +} +fn on_tick(event,state,random) { + if event.health<=0 || !alive(event) {return #{commands:[],state:state};} + if !state.contains("units") {state.units=#{};} + let key=event.entity.to_string(); + if !state.units.contains(key) {state.units[key]=#{age:0,direction:1,aim:0,phase:1,max_health:spawn_health(event)};} + if event.y<24 {return #{commands:[#{op:"velocity",entity:event.entity,vx:0,vy:2}],state:state};} + let u=state.units[key]; + if !u.contains("max_health") {u.max_health=spawn_health(event);} + if event.x>=148 {u.direction=-1;} if event.x<=68 {u.direction=1;} + let phase=if event.health>u.max_health/2 {1} else {2}; + // Each new phase begins a complete warning window, independent of the old + // period. This also safely upgrades checkpoints lacking the phase latch. + if !u.contains("phase") {u.phase=1;} + if phase!=u.phase {u.phase=phase;u.age=0;} + let period=if phase==1 {76} else {64}; + let cycle=u.age%period; + let commands=[#{op:"move",entity:event.entity,x:event.x,y:24},#{op:"velocity",entity:event.entity,vx:if cycle<14 {0} else {u.direction*2},vy:0}]; + if cycle==0 { + u.aim=if event.player_x=128 {let oldest=state.dead_order.remove(0);state.dead.remove(oldest);} + state.dead[key]=true;state.dead_order.push(key);state.units.remove(key); + let count=if event.objectives.contains("iron_coast_stage2_boss_4:defeated") {event.objectives["iron_coast_stage2_boss_4:defeated"]+1} else {1}; + #{commands:[#{op:"objective",key:"iron_coast_stage2_boss_4:defeated",value:count},#{op:"effect",x:event.x+20,y:event.y+40},#{op:"effect",x:event.x+84,y:event.y+40},#{op:"play_sound",sound:"iron_coast_stage2_boss_4:death"}],state:state} +} diff --git a/mods/iron_coast_stage2_boss_4/validation/Cargo.toml b/mods/iron_coast_stage2_boss_4/validation/Cargo.toml new file mode 100644 index 00000000..acab8bd9 --- /dev/null +++ b/mods/iron_coast_stage2_boss_4/validation/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "iron-coast-stage2-boss-4-validation" +version = "1.0.0" +edition = "2024" +publish = false + +[workspace] + +[dependencies] +raptor-replica = { path = "../../..", default-features = false } +serde_json = "1" + +[[bin]] +name = "validate" +path = "validate.rs" + +[[bin]] +name = "retained-state" +path = "retained_state.rs" diff --git a/mods/iron_coast_stage2_boss_4/validation/bounded-cache-review.md b/mods/iron_coast_stage2_boss_4/validation/bounded-cache-review.md new file mode 100644 index 00000000..e5b8e3a6 --- /dev/null +++ b/mods/iron_coast_stage2_boss_4/validation/bounded-cache-review.md @@ -0,0 +1,9 @@ +# Retained lifecycle cache correction + +The independent native-collision probe found an unbounded pre-correction retired-ID map that exhausted the Rhai object-map limit at distinct-lifetime index1009. Historical package folders and the previous four-package freeze are retained outside the distribution. + +The gameplay definitions, health, attack patterns, objectives, prices, images and sounds are unchanged. A separate independent timing probe also found that changing the old warning-clock modulo at half-health could release a low-phase volley after only two ticks. Bosses now latch their phase and restart its warning clock on a phase transition, preserving the advertised full 14-tick telegraph. The actual World regression tests transition immediately after the second high-phase warning at every difficulty, including an old checkpoint lacking the latch. The script now stores a FIFO of at most 128 recent retired IDs, removes reused IDs on spawn before checking their health, and migrates pre-FIFO states into a deterministic bounded subset. Boss clocks absent from the new World's snapshot are discarded; live peer clocks remain intact. + +The package-local retained-state proof checks real bundled Catalog activation and a test-only native stationary lethal projectile, 1,205 lives (1,200 unique plus five reused IDs), exact one-death rewards, current-lifecycle callback deduplication, nine JSON checkpoint/RNG roundtrips, old 960-ID cache migration and all four difficulty kills. Boss probes add 1,205 abandoned-live replays and simultaneous peer-clock preservation. This is a lifecycle stress proof, not a combat-balance shortcut. Normal mission acceptance and boss phase probes were rerun independently of this stress fixture. + +A duplicate callback for an entity retired more than 128 deaths ago is outside the retained guard window; the engine emits each real death once and queued callbacks are not delayed across 128 later deaths. Reusing an ID through an actual spawn always starts a fresh guarded lifecycle. diff --git a/mods/iron_coast_stage2_boss_4/validation/bounded-cli.log b/mods/iron_coast_stage2_boss_4/validation/bounded-cli.log new file mode 100644 index 00000000..83810a55 --- /dev/null +++ b/mods/iron_coast_stage2_boss_4/validation/bounded-cli.log @@ -0,0 +1 @@ +Validated 8 mods; 0 override(s) diff --git a/mods/iron_coast_stage2_boss_4/validation/bounded-normal.log b/mods/iron_coast_stage2_boss_4/validation/bounded-normal.log new file mode 100644 index 00000000..515034ba --- /dev/null +++ b/mods/iron_coast_stage2_boss_4/validation/bounded-normal.log @@ -0,0 +1,7 @@ +iron_coast_stage2_boss_4: health 280, period 76, volley 2, warning14 ticks; arrival, bounds, two entities, checkpoint, absent/dead guard and once-only death passed +iron_coast_stage2_boss_4: health 140, period 64, volley 4, warning14 ticks; arrival, bounds, two entities, checkpoint, absent/dead guard and once-only death passed +real World difficulty0: spawnHP140, phase1 at arrival then phase2 at 70/half; no missing spawn health +real World difficulty1: spawnHP140, phase1 at arrival then phase2 at 70/half; no missing spawn health +real World difficulty2: spawnHP280, phase1 at arrival then phase2 at 140/half; no missing spawn health +real World difficulty3: spawnHP280, phase1 at arrival then phase2 at 140/half; no missing spawn health +real World lethal queued-spawn, saved-state reused ID and exact reward across three replays: passed diff --git a/mods/iron_coast_stage2_boss_4/validation/callback-world.log b/mods/iron_coast_stage2_boss_4/validation/callback-world.log new file mode 100644 index 00000000..515034ba --- /dev/null +++ b/mods/iron_coast_stage2_boss_4/validation/callback-world.log @@ -0,0 +1,7 @@ +iron_coast_stage2_boss_4: health 280, period 76, volley 2, warning14 ticks; arrival, bounds, two entities, checkpoint, absent/dead guard and once-only death passed +iron_coast_stage2_boss_4: health 140, period 64, volley 4, warning14 ticks; arrival, bounds, two entities, checkpoint, absent/dead guard and once-only death passed +real World difficulty0: spawnHP140, phase1 at arrival then phase2 at 70/half; no missing spawn health +real World difficulty1: spawnHP140, phase1 at arrival then phase2 at 70/half; no missing spawn health +real World difficulty2: spawnHP280, phase1 at arrival then phase2 at 140/half; no missing spawn health +real World difficulty3: spawnHP280, phase1 at arrival then phase2 at 140/half; no missing spawn health +real World lethal queued-spawn, saved-state reused ID and exact reward across three replays: passed diff --git a/mods/iron_coast_stage2_boss_4/validation/cli.log b/mods/iron_coast_stage2_boss_4/validation/cli.log new file mode 100644 index 00000000..cf87e1b3 --- /dev/null +++ b/mods/iron_coast_stage2_boss_4/validation/cli.log @@ -0,0 +1 @@ +Validated 1 mods; 0 override(s) diff --git a/mods/iron_coast_stage2_boss_4/validation/combined-cli.log b/mods/iron_coast_stage2_boss_4/validation/combined-cli.log new file mode 100644 index 00000000..83810a55 --- /dev/null +++ b/mods/iron_coast_stage2_boss_4/validation/combined-cli.log @@ -0,0 +1 @@ +Validated 8 mods; 0 override(s) diff --git a/mods/iron_coast_stage2_boss_4/validation/compiler-binding.json b/mods/iron_coast_stage2_boss_4/validation/compiler-binding.json new file mode 100644 index 00000000..fabcb398 --- /dev/null +++ b/mods/iron_coast_stage2_boss_4/validation/compiler-binding.json @@ -0,0 +1,22 @@ +{ + "/home/quintine/Projects/RaptorReplica/RustRaptor/target/release/deps/libraptor_replica-f9adab78fd4d2969.rlib": { + "bytes": 13308296, + "sha256": "eb190ba6ad88d1939938a30c69bd1d8c705ecfb77eb12c36ae0686f10f82bae7", + "mtime_ns": 1791706754209530916 + }, + "/home/quintine/Projects/RaptorReplica/RustRaptor/target/release/deps/libserde_json-11c796c0bcf3a604.rlib": { + "bytes": 2057816, + "sha256": "7a13e07716f46f559cb9acf05c81ce0845e5633dfd3d77e6020e14af31a3a878", + "mtime_ns": 1791706698162048372 + }, + "/home/quintine/Projects/RaptorReplica/RustRaptor/mods/iron_coast_stage2_boss_4/validation/validate.rs": { + "bytes": 12304, + "sha256": "4e0ff775ea5ab4e958c51096c6862e95bb87967c6e5ecbe52656511e5d030256", + "mtime_ns": 1791708347396087135 + }, + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/boss-4-validate": { + "bytes": 7705448, + "sha256": "7e9d511b170863d791bf3ebf97da267782bf62e76c7d1ccb263009ceed95fdf4", + "mtime_ns": 1791708347831951254 + } +} diff --git a/mods/iron_coast_stage2_boss_4/validation/retained-state-compiler-binding.json b/mods/iron_coast_stage2_boss_4/validation/retained-state-compiler-binding.json new file mode 100644 index 00000000..991d8049 --- /dev/null +++ b/mods/iron_coast_stage2_boss_4/validation/retained-state-compiler-binding.json @@ -0,0 +1,22 @@ +{ + "/home/quintine/Projects/RaptorReplica/RustRaptor/target/release/deps/libraptor_replica-f9adab78fd4d2969.rlib": { + "bytes": 13308296, + "sha256": "eb190ba6ad88d1939938a30c69bd1d8c705ecfb77eb12c36ae0686f10f82bae7", + "mtime_ns": 1791706754209530916 + }, + "/home/quintine/Projects/RaptorReplica/RustRaptor/target/release/deps/libserde_json-11c796c0bcf3a604.rlib": { + "bytes": 2057816, + "sha256": "7a13e07716f46f559cb9acf05c81ce0845e5633dfd3d77e6020e14af31a3a878", + "mtime_ns": 1791706698162048372 + }, + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/retained-state": { + "bytes": 8421248, + "sha256": "ece9f14a0a69754c8515ccc1c3c98968b8023b1978ad36497028c11208abe1e8", + "mtime_ns": 1791708664346644142 + }, + "/home/quintine/Projects/RaptorReplica/RustRaptor/mods/iron_coast_stage2_boss_4/validation/retained_state.rs": { + "bytes": 12558, + "sha256": "e1c4f9f1d78ba98c423cfe41cd90eb72a811398a7ba4dc334e342b89336f5a64", + "mtime_ns": 1791708663747658120 + } +} diff --git a/mods/iron_coast_stage2_boss_4/validation/retained-state.json b/mods/iron_coast_stage2_boss_4/validation/retained-state.json new file mode 100644 index 00000000..b0e8b8e1 --- /dev/null +++ b/mods/iron_coast_stage2_boss_4/validation/retained-state.json @@ -0,0 +1,86 @@ +{ + "abandoned_live_replays": 1205, + "actual_native_collision_lives": 1205, + "actual_phase_transition_warnings": [ + { + "actual_spawn_health": 140, + "difficulty": 0, + "high_phase_warnings": [ + 1, + 77 + ], + "new_phase_warning_ticks": 14, + "old_phase_latch_absent": true, + "phase2_release": 92, + "phase2_warning": 78 + }, + { + "actual_spawn_health": 140, + "difficulty": 1, + "high_phase_warnings": [ + 1, + 77 + ], + "new_phase_warning_ticks": 14, + "old_phase_latch_absent": false, + "phase2_release": 92, + "phase2_warning": 78 + }, + { + "actual_spawn_health": 280, + "difficulty": 2, + "high_phase_warnings": [ + 1, + 77 + ], + "new_phase_warning_ticks": 14, + "old_phase_latch_absent": false, + "phase2_release": 92, + "phase2_warning": 78 + }, + { + "actual_spawn_health": 280, + "difficulty": 3, + "high_phase_warnings": [ + 1, + 77 + ], + "new_phase_warning_ticks": 14, + "old_phase_latch_absent": false, + "phase2_release": 92, + "phase2_warning": 78 + } + ], + "checkpoint_json_roundtrips": 9, + "difficulty_kills": [ + 0, + 1, + 2, + 3 + ], + "distinct_ids": 1200, + "duplicate_callback_commands": 0, + "enabled": [ + "iron_coast_stage2_boss_4" + ], + "fixture": "actual bundled Catalog; test-only stationary lethal projectile; native World collision, death, reward and retained ScriptRuntime", + "legacy_960_guard_migration": true, + "maximum_abandoned_state_bytes": 2790, + "maximum_death_state_bytes": 2724, + "migration_state_bytes": 2724, + "owner": "iron_coast_stage2_boss_4", + "package_pins_at_execution": [ + { + "hash": "15e83a8cf65d8c7d1b9ac89328c63bc5628699f233cd82e0b63c28c30412bb61", + "id": "iron_coast_stage2_boss_4", + "version": "1.0.0" + } + ], + "retired_guard_capacity": 128, + "reused_id_lives": 5, + "reward_per_life": 2800, + "scope": "callback lifecycle/bounded-state proof, not mission combat balance", + "target_shield_restore": 0, + "two_live_clocks_retained": true, + "unit": "iron_coast_stage2_boss_4:unit" +} \ No newline at end of file diff --git a/mods/iron_coast_stage2_boss_4/validation/retained-state.log b/mods/iron_coast_stage2_boss_4/validation/retained-state.log new file mode 100644 index 00000000..f2172e15 --- /dev/null +++ b/mods/iron_coast_stage2_boss_4/validation/retained-state.log @@ -0,0 +1,16 @@ +iron_coast_stage2_boss_4 actual difficulty0: health transition after high warning77; new warning78 release92, full14ticks +iron_coast_stage2_boss_4 actual difficulty1: health transition after high warning77; new warning78 release92, full14ticks +iron_coast_stage2_boss_4 actual difficulty2: health transition after high warning77; new warning78 release92, full14ticks +iron_coast_stage2_boss_4 actual difficulty3: health transition after high warning77; new warning78 release92, full14ticks +iron_coast_stage2_boss_4 retained native kills=1; statebytes=57 retired=1 +iron_coast_stage2_boss_4 retained native kills=129; statebytes=2724 retired=128 +iron_coast_stage2_boss_4 retained native kills=257; statebytes=2724 retired=128 +iron_coast_stage2_boss_4 retained native kills=385; statebytes=2724 retired=128 +iron_coast_stage2_boss_4 retained native kills=513; statebytes=2724 retired=128 +iron_coast_stage2_boss_4 retained native kills=641; statebytes=2724 retired=128 +iron_coast_stage2_boss_4 retained native kills=769; statebytes=2724 retired=128 +iron_coast_stage2_boss_4 retained native kills=897; statebytes=2724 retired=128 +iron_coast_stage2_boss_4 retained native kills=1025; statebytes=2724 retired=128 +iron_coast_stage2_boss_4 retained native kills=1153; statebytes=2724 retired=128 +iron_coast_stage2_boss_4 retained native kills=1205; statebytes=2724 retired=128 +iron_coast_stage2_boss_4: all actual collision/reward, migration, deduplication, retained-state and abandoned-live checks passed diff --git a/mods/iron_coast_stage2_boss_4/validation/retained_state.rs b/mods/iron_coast_stage2_boss_4/validation/retained_state.rs new file mode 100644 index 00000000..910b75ff --- /dev/null +++ b/mods/iron_coast_stage2_boss_4/validation/retained_state.rs @@ -0,0 +1,305 @@ +//! Real native lethal-collision stress with retained serializable Rhai state. +use raptor_replica::{ + assets::Catalog, + content::{ContentPack, Registry}, + modding::{self, ActiveMods, Discovery, ScriptRuntime}, + persistence::Pilot, + simulation::{Input, Projectile, World}, +}; +use serde_json::{Value, json}; +use std::{ + collections::{BTreeMap, BTreeSet}, + path::PathBuf, +}; +type Result = std::result::Result>; +fn closure(d: &Discovery, id: &str, out: &mut BTreeSet) { + if !out.insert(id.into()) { + return; + } + for dep in d.mods[id].manifest.dependencies.keys() { + closure(d, dep, out); + } +} +fn input() -> Input { + Input { + absolute: Some([282, 160]), + ..Input::default() + } +} +fn pilot(difficulty: u32) -> Pilot { + let mut p = Pilot::default(); + p.difficulty = difficulty; + p.credits = 10000; + p.inventory.insert("base:energy".into(), 75); + p +} +fn restore(active: &mut ActiveMods, discovery: &Discovery, enabled: &[String]) -> Result<()> { + let cp = active.scripts.checkpoints(); + let encoded = serde_json::to_vec(&cp)?; + let mut scripts = ScriptRuntime::new(); + for owner in enabled { + for path in &discovery.mods[owner].manifest.scripts { + scripts.add( + owner, + path, + &std::fs::read_to_string(discovery.mods[owner].root.join(path))?, + )?; + } + } + scripts.restore(serde_json::from_slice(&encoded)?); + active.scripts = scripts; + Ok(()) +} +fn event(id: u64, hp: i32, key: &str, count: i32) -> Value { + json!({"entity":id,"x":88,"y":24,"health":hp,"tick":999,"player_x":282,"player_y":160,"entities":[{"entity":id,"health":hp}],"objectives":{key:count}}) +} +fn guard(active: &ActiveMods, key: &str) -> usize { + let state = &active.scripts.states[key]; + let dead = state["dead"].as_object().unwrap(); + let fifo = state["dead_order"].as_array().unwrap(); + assert!(dead.len() <= 128); + assert!(fifo.len() <= 128); + assert_eq!(dead.len(), fifo.len()); + let unique = fifo + .iter() + .map(|v| v.as_str().unwrap()) + .collect::>(); + assert_eq!(unique.len(), fifo.len()); + assert_eq!( + dead.keys().map(|v| v.as_str()).collect::>(), + unique + ); + if let Some(units) = state.get("units") { + assert!(units.as_object().unwrap().is_empty()); + } + serde_json::to_vec(state).unwrap().len() +} +fn kill( + active: &mut ActiveMods, + unit: &str, + id: u64, + objective: &str, + reward: u32, + target: bool, + difficulty: u32, +) -> Result { + let mut w = World::new( + &"review:retained".into(), + &pilot(difficulty), + &active.registry, + )?; + w.next_entity = id; + let y = if target { 60 } else { 24 }; + w.projectiles.push(Projectile { + entity: 500000, + weapon: "review:lethal".into(), + x: 90, + y: y + 6, + px: 90, + py: y + 6, + vx: 0, + vy: 0, + hostile: false, + age: 0, + legacy: None, + legacy_enemy: None, + }); + for _ in 0..3 { + w.step(input(), &active.registry, &mut active.scripts)?; + } + assert!(w.enemies.is_empty(), "{unit} survived"); + assert_eq!(w.objectives.get(objective), Some(&1)); + assert_eq!(w.player.credits, 10000 + reward); + assert_eq!(w.player.shield, if target { 87 } else { 75 }); + w.step(input(), &active.registry, &mut active.scripts)?; + assert_eq!(w.objectives.get(objective), Some(&1)); + assert_eq!(w.player.credits, 10000 + reward); + Ok(w) +} +fn phase_warnings(active: &mut ActiveMods, owner: &str, key: &str) -> Result> { + let warning = format!("{owner}:warning"); + let objective = format!("{owner}:phase"); + let mut rows = vec![]; + for difficulty in 0..=3 { + let mut w = World::new( + &"review:retained".into(), + &pilot(difficulty), + &active.registry, + )?; + w.next_entity = 95000 + difficulty as u64; + let mut high_warnings = vec![]; + while high_warnings.len() < 2 { + assert!(w.tick < 100); + w.step(input(), &active.registry, &mut active.scripts)?; + if w.mod_sounds.iter().any(|s| s.0 == warning) { + high_warnings.push(w.tick); + } + w.projectiles.retain(|p| !p.hostile); + } + let entity = w.enemies[0].entity; + let max_hp = w.enemies[0].health; + w.enemies[0].health = max_hp / 2; + // Exercise the upgrade path for a saved pre-latch live entity as well. + if difficulty == 0 { + active.scripts.states.get_mut(key).unwrap()["units"][entity.to_string()] + .as_object_mut() + .unwrap() + .remove("phase"); + } + let mut new_warning = 0; + let mut release = 0; + for offset in 0..=14 { + w.step(input(), &active.registry, &mut active.scripts)?; + let warnings = w.mod_sounds.iter().filter(|s| s.0 == warning).count(); + let shots = w + .projectiles + .iter() + .filter(|p| p.hostile && p.age == 0) + .count(); + if offset == 0 { + assert_eq!(warnings, 1); + new_warning = w.tick; + assert_eq!(w.objectives.get(&objective), Some(&2)); + } else { + assert_eq!(warnings, 0); + } + if offset < 14 { + assert_eq!(shots, 0, "new health phase fired before full warning"); + } else { + assert_eq!(shots, if owner.ends_with('3') { 3 } else { 4 }); + release = w.tick; + } + w.projectiles.retain(|p| !p.hostile); + } + assert_eq!(release - new_warning, 14); + println!( + "{owner} actual difficulty{difficulty}: health transition after high warning{}; new warning{new_warning} release{release}, full14ticks", + high_warnings[1] + ); + rows.push(json!({"difficulty":difficulty,"actual_spawn_health":max_hp,"high_phase_warnings":high_warnings,"phase2_warning":new_warning,"phase2_release":release,"new_phase_warning_ticks":release-new_warning,"old_phase_latch_absent":difficulty==0})); + } + Ok(rows) +} +fn main() -> Result<()> { + let package = PathBuf::from(std::env::args().nth(1).expect("pass own package")); + let package = package.canonicalize()?; + let owner = package.file_name().unwrap().to_str().unwrap(); + let target = owner.contains("mission"); + let hook = if target { + "scripts/target.rhai" + } else { + "scripts/ai.rhai" + }; + let key = format!("{owner}/{hook}"); + let unit = format!("{owner}:{}", if target { "target" } else { "unit" }); + let objective = format!( + "{owner}:{}", + if target { + "targets_destroyed" + } else { + "defeated" + } + ); + let root = package.parent().unwrap().parent().unwrap(); + let cat = Catalog::open(&root.join("data"))?; + let mut base = Registry::base(&cat)?; + let content: ContentPack = serde_json::from_value( + json!({"missions":[{"id":"review:retained","name":"Test-only retained collision fixture","duration":10000,"auto_complete":false,"spawns":[{"tick":0,"enemy":unit,"x":88,"y":if target{60}else{24}}]}],"weapons":[{"id":"review:lethal","name":"Test-only stationary lethal projectile","damage":10000,"speed":0,"cooldown":1,"target":"all","behavior":"straight"}]}), + )?; + base.apply(content, "review")?; + let discovery = modding::discover(&root.join("mods")); + let mut enabled = BTreeSet::new(); + closure(&discovery, owner, &mut enabled); + let enabled = enabled.into_iter().collect::>(); + let mut a = ActiveMods::build(&base, &discovery, &enabled, Some(&cat))?; + let reward = a.registry.enemies[&unit.as_str().into()].reward; + let phase_transitions = if target { + vec![] + } else { + phase_warnings(&mut a, owner, &key)? + }; + let mut max_bytes = 0; + for life in 0..1205u64 { + let id = if life >= 1200 { 10000 } else { 10000 + life }; + let world = kill(&mut a, &unit, id, &objective, reward, target, 2)?; + let commands = + a.scripts + .invoke(owner, hook, "on_death", &event(id, 0, &objective, 1), 303)?; + assert!(commands.is_empty(), "duplicate death emitted commands"); + assert_eq!(world.player.credits, 10000 + reward); + max_bytes = max_bytes.max(guard(&a, &key)); + if life % 137 == 0 { + restore(&mut a, &discovery, &enabled)?; + } + if life % 128 == 0 || life == 1204 { + println!( + "{owner} retained native kills={}; statebytes={} retired={}", + life + 1, + guard(&a, &key), + a.scripts.states[&key]["dead"].as_object().unwrap().len() + ); + } + } + // Earlier pre-FIFO checkpoints migrate within the real engine limits. This + // includes a death flag for the entity killed before queued on_spawn executes. + let old_dead = (0..960) + .map(|n| (format!("{}", 60000 + n), json!(true))) + .collect::>(); + a.scripts + .states + .insert(key.clone(), json!({"dead":old_dead,"units":{}})); + restore(&mut a, &discovery, &enabled)?; + kill(&mut a, &unit, 60001, &objective, reward, target, 2)?; + assert_eq!(a.scripts.states[&key]["dead"]["60001"], json!(true)); + guard(&a, &key); + let migrated_state_bytes = serde_json::to_vec(&a.scripts.states[&key])?.len(); + for difficulty in 0..=3 { + kill( + &mut a, + &unit, + 70000 + difficulty as u64, + &objective, + reward, + target, + difficulty, + )?; + guard(&a, &key); + } + // Two live same-definition entities keep separate state; abandoned-world + // entity clocks are discarded at the next actual spawn instead of accumulating. + let mut abandoned_peak = 0; + if !target { + for life in 0..1205u64 { + let mut w = World::new(&"review:retained".into(), &pilot(2), &a.registry)?; + w.next_entity = 80000 + life; + w.step(input(), &a.registry, &mut a.scripts)?; + assert_eq!(w.enemies.len(), 1); + assert_eq!( + a.scripts.states[&key]["units"].as_object().unwrap().len(), + 1 + ); + abandoned_peak = abandoned_peak.max(serde_json::to_vec(&a.scripts.states[&key])?.len()); + } + let mut e1 = event(90000, 240, &objective, 0); + e1["entities"] = json!([{"entity":90000,"health":240}]); + a.scripts.invoke(owner, hook, "on_spawn", &e1, 303)?; + for _ in 0..20 { + a.scripts.invoke(owner, hook, "on_tick", &e1, 303)?; + } + let age = a.scripts.states[&key]["units"]["90000"]["age"].clone(); + let mut e2 = event(90001, 240, &objective, 0); + e2["entities"] = json!([{"entity":90000,"health":240},{"entity":90001,"health":240}]); + a.scripts.invoke(owner, hook, "on_spawn", &e2, 303)?; + assert_eq!(a.scripts.states[&key]["units"]["90000"]["age"], age); + assert_eq!(a.scripts.states[&key]["units"]["90001"]["age"], 0); + } + let report = json!({"fixture":"actual bundled Catalog; test-only stationary lethal projectile; native World collision, death, reward and retained ScriptRuntime","owner":owner,"unit":unit,"actual_native_collision_lives":1205,"distinct_ids":1200,"reused_id_lives":5,"checkpoint_json_roundtrips":9,"maximum_death_state_bytes":max_bytes,"actual_phase_transition_warnings":phase_transitions,"retired_guard_capacity":128,"duplicate_callback_commands":0,"reward_per_life":reward,"target_shield_restore":if target {12}else{0},"legacy_960_guard_migration":true,"migration_state_bytes":migrated_state_bytes,"difficulty_kills":[0,1,2,3],"abandoned_live_replays":if target {0}else{1205},"maximum_abandoned_state_bytes":abandoned_peak,"two_live_clocks_retained":!target,"enabled":enabled,"package_pins_at_execution":a.pins,"scope":"callback lifecycle/bounded-state proof, not mission combat balance"}); + std::fs::write( + package.join("validation/retained-state.json"), + serde_json::to_vec_pretty(&report)?, + )?; + println!( + "{owner}: all actual collision/reward, migration, deduplication, retained-state and abandoned-live checks passed" + ); + Ok(()) +} diff --git a/mods/iron_coast_stage2_boss_4/validation/validate.rs b/mods/iron_coast_stage2_boss_4/validation/validate.rs new file mode 100644 index 00000000..37727b5b --- /dev/null +++ b/mods/iron_coast_stage2_boss_4/validation/validate.rs @@ -0,0 +1,294 @@ +//! Package-local real callback and World lifecycle acceptance; no production mutation. +use raptor_replica::{ + content::{ContentPack, Registry}, + modding::{self, ActiveMods, Command, ScriptRuntime}, + persistence::Pilot, + simulation::{Input, World}, +}; +use serde_json::{Value, json}; +use std::path::Path; +fn runtime(package: &Path, owner: &str) -> ScriptRuntime { + let mut ai = ScriptRuntime::new(); + ai.add( + owner, + "scripts/ai.rhai", + &std::fs::read_to_string(package.join("scripts/ai.rhai")).unwrap(), + ) + .unwrap(); + ai +} +fn event(id: u64, x: i32, y: i32, hp: i32) -> Value { + json!({"entity":id,"x":x,"y":y,"health":hp,"tick":999,"player_x":144,"player_y":160,"entities":[{"entity":id,"health":hp}],"objectives":{}}) +} +fn call(ai: &mut ScriptRuntime, owner: &str, hook: &str, event: Value) -> Vec { + ai.invoke(owner, "scripts/ai.rhai", hook, &event, 303) + .unwrap() +} +fn lethal_spawn(package: &Path, owner: &str, reward: u32) { + let unit = format!("{owner}:unit"); + let objective = format!("{owner}:defeated"); + let mut base = Registry::default(); + let content:ContentPack=serde_json::from_value(json!({"weapons":[{"id":"base:projectile_forward_guns","name":"Forward Guns","damage":1,"speed":8,"cooldown":2,"behavior":"straight","target":"all"}],"items":[{"id":"base:forward_guns","name":"Forward Guns","price":0,"weapon":"base:projectile_forward_guns"},{"id":"base:energy","name":"Shield","price":0,"max_count":100}],"missions":[{"id":"base:sector_1_wave_1","name":"Spawn lifecycle regression","duration":500,"auto_complete":false,"spawns":[{"tick":0,"enemy":unit,"x":108,"y":120}]}]})).unwrap(); + base.apply(content, "base").unwrap(); + let discovery = modding::discover(package.parent().unwrap()); + let mut active = ActiveMods::build(&base, &discovery, &[owner.into()], None).unwrap(); + active + .registry + .enemies + .get_mut(&unit.as_str().into()) + .unwrap() + .health = 1; + let mut pilot = Pilot::default(); + pilot.difficulty = 2; + pilot.credits = 0; + let mut old_id = None; + for n in 0..3 { + let mut world = World::new(&pilot.mission, &pilot, &active.registry).unwrap(); + world + .step( + Input { + fire: true, + absolute: Some([144, 160]), + ..Input::default() + }, + &active.registry, + &mut active.scripts, + ) + .unwrap(); + assert!( + world.enemies.iter().all(|e| e.health <= 0), + "projectile must kill during spawn-step before queued on_spawn" + ); + assert!(world.projectiles.is_empty()); + assert!( + world.mod_sounds.is_empty(), + "dead arrival must not warn/fire" + ); + world + .step(Input::default(), &active.registry, &mut active.scripts) + .unwrap(); + assert!( + world.enemies.is_empty(), + "ground death is collected next tick" + ); + assert_eq!( + world.objectives.get(&objective), + Some(&1), + "reused entity lifecycle {n}" + ); + assert_eq!(world.player.credits, reward); + assert!(world.projectiles.is_empty()); + assert_eq!( + world.mod_sounds, + vec![format!("{owner}:death").as_str().into()] + ); + let cp = active.scripts.checkpoints(); + let key = format!("{owner}/scripts/ai.rhai"); + let state = &cp.0[&key]; + let keys = state["dead"] + .as_object() + .unwrap() + .keys() + .collect::>(); + assert_eq!(keys.len(), 1); + if let Some(ref old) = old_id { + assert_eq!(old, keys[0]); + } else { + old_id = Some(keys[0].clone()); + } + assert!(state["units"].as_object().unwrap().is_empty()); + world + .step(Input::default(), &active.registry, &mut active.scripts) + .unwrap(); + assert_eq!(world.player.credits, reward); + assert_eq!(world.objectives.get(&objective), Some(&1)); + let mut restored = runtime(package, owner); + restored.restore(cp); + active.scripts = restored; + } +} + +fn real_difficulty_phases(package: &Path, owner: &str, max_hp: i32) { + let unit = format!("{owner}:unit"); + let phase = format!("{owner}:phase"); + let mut base = Registry::default(); + let content:ContentPack=serde_json::from_value(json!({"items":[{"id":"base:energy","name":"Shield","price":0,"max_count":100}],"missions":[{"id":"base:sector_1_wave_1","name":"Actual difficulty health contract","duration":500,"auto_complete":false,"spawns":[{"tick":0,"enemy":unit,"x":108,"y":24}]}]})).unwrap(); + base.apply(content, "base").unwrap(); + let discovery = modding::discover(package.parent().unwrap()); + let mut active = ActiveMods::build(&base, &discovery, &[owner.into()], None).unwrap(); + for difficulty in 0..=3 { + let mut pilot = Pilot::default(); + pilot.difficulty = difficulty; + let mut world = World::new(&pilot.mission, &pilot, &active.registry).unwrap(); + let expected = if difficulty <= 1 { max_hp / 2 } else { max_hp }; + for _ in 0..3 { + world + .step( + Input { + absolute: Some([5, 160]), + ..Input::default() + }, + &active.registry, + &mut active.scripts, + ) + .unwrap(); + } + assert_eq!(world.enemies[0].health, expected); + assert_eq!(world.objectives.get(&phase), Some(&1)); + let key = format!("{owner}/scripts/ai.rhai"); + assert_eq!( + active.scripts.checkpoints().0[&key]["units"][world.enemies[0].entity.to_string()]["max_health"], + json!(expected) + ); + world.enemies[0].health = expected / 2; + for _ in 0..80 { + world + .step( + Input { + absolute: Some([5, 160]), + ..Input::default() + }, + &active.registry, + &mut active.scripts, + ) + .unwrap(); + } + assert_eq!(world.objectives.get(&phase), Some(&2)); + assert!(world.enemies[0].health > 0); + println!( + "real World difficulty{difficulty}: spawnHP{expected}, phase1 at arrival then phase2 at {}/half; no missing spawn health", + expected / 2 + ); + } +} + +fn main() { + let path = std::env::args().nth(1).expect("pass own package"); + let package = Path::new(&path); + let owner = package.file_name().unwrap().to_str().unwrap(); + let stage = if owner.ends_with('3') { 3 } else { 4 }; + let max_hp = if stage == 3 { 240 } else { 280 }; + for (hp, period, count) in [ + (max_hp, if stage == 3 { 72 } else { 76 }, 2), + ( + max_hp / 2, + if stage == 3 { 60 } else { 64 }, + if stage == 3 { 3 } else { 4 }, + ), + ] { + let mut ai = runtime(package, owner); + call(&mut ai, owner, "on_spawn", event(1, 108, -72, max_hp)); + for _ in 0..20 { + assert!( + !call(&mut ai, owner, "on_tick", event(1, 108, -72, hp)) + .iter() + .any(|c| matches!(c, Command::Projectile { .. } | Command::PlaySound { .. })) + ); + } + let mut warnings = vec![]; + let mut volleys = vec![]; + for tick in 1..=period * 2 { + let commands = call(&mut ai, owner, "on_tick", event(1, 108, 24, hp)); + if commands.iter().any( + |c| matches!(c,Command::PlaySound{sound} if sound==&format!("{owner}:warning")), + ) { + warnings.push(tick); + assert_eq!( + commands + .iter() + .filter(|c| matches!(c, Command::Arc { ticks: 8, .. })) + .count(), + 2 + ); + } + let projectiles = commands + .iter() + .filter(|c| matches!(c, Command::Projectile { .. })) + .collect::>(); + if !projectiles.is_empty() { + assert_eq!(projectiles.len(), count); + for p in projectiles { + if let Command::Projectile { + weapon, + y, + vy, + hostile, + .. + } = p + { + assert_eq!(weapon, &format!("{owner}:shell")); + assert_eq!( + (*y, *vy, *hostile), + if stage == 3 { + (86, 3, true) + } else { + (78, 4, true) + } + ); + } + } + volleys.push(tick); + } + } + assert_eq!(warnings, vec![1, 1 + period]); + assert_eq!(volleys, vec![15, 15 + period]); + let max_x = if stage == 3 { 156 } else { 148 }; + let min_x = if stage == 3 { 60 } else { 68 }; + for (x, negative) in [(max_x, true), (min_x, false)] { + let c = call(&mut ai, owner, "on_tick", event(1, x, 24, hp)); + assert!(c.iter().any(|c| matches!(c, Command::Move { y: 24, .. }))); /* warning pauses are allowed; direction inspected after next warning */ + for _ in 0..16 { + let c = call(&mut ai, owner, "on_tick", event(1, x, 24, hp)); + if c.iter() + .any(|c| matches!(c,Command::Velocity{vx,..} if *vx!=0)) + { + assert!(c.iter().any(|c|matches!(c,Command::Velocity{vx,vy:0,..} if if negative{*vx<0}else{*vx>0}))); + break; + } + } + } + call(&mut ai, owner, "on_spawn", event(2, 108, 24, hp)); + assert!( + !call(&mut ai, owner, "on_tick", event(2, 108, 24, hp)) + .iter() + .any(|c| matches!(c, Command::Projectile { .. })) + ); + let mut restored = runtime(package, owner); + restored.restore(ai.checkpoints()); + for _ in 0..133 { + assert_eq!( + serde_json::to_value(call(&mut ai, owner, "on_tick", event(1, 108, 24, hp))) + .unwrap(), + serde_json::to_value(call(&mut restored, owner, "on_tick", event(1, 108, 24, hp))) + .unwrap() + ); + } + assert!(call(&mut ai, owner, "on_tick", event(1, 108, 24, 0)).is_empty()); + let mut missing = event(1, 108, 24, hp); + missing["entities"] = json!([]); + assert!(call(&mut ai, owner, "on_tick", missing).is_empty()); + let death = call(&mut ai, owner, "on_death", event(1, 108, 24, 0)); + assert!(death.iter().any( + |c| matches!(c,Command::Objective{key,value:1} if key==&format!("{owner}:defeated")) + )); + assert!( + !death + .iter() + .any(|c| matches!(c, Command::Complete | Command::Credits { .. })) + ); + assert!(call(&mut ai, owner, "on_death", event(1, 108, 24, 0)).is_empty()); + let mut second = event(2, 108, 24, 0); + second["objectives"] = json!({format!("{owner}:defeated"):1}); + assert!(call(&mut ai, owner, "on_death", second).iter().any( + |c| matches!(c,Command::Objective{key,value:2} if key==&format!("{owner}:defeated")) + )); + println!( + "{owner}: health {hp}, period {period}, volley {count}, warning14 ticks; arrival, bounds, two entities, checkpoint, absent/dead guard and once-only death passed" + ); + } + real_difficulty_phases(package, owner, max_hp); + lethal_spawn(package, owner, if stage == 3 { 2400 } else { 2800 }); + println!( + "real World lethal queued-spawn, saved-state reused ID and exact reward across three replays: passed" + ); +} diff --git a/mods/iron_coast_stage2_boss_5/README.md b/mods/iron_coast_stage2_boss_5/README.md new file mode 100644 index 00000000..2596ecac --- /dev/null +++ b/mods/iron_coast_stage2_boss_5/README.md @@ -0,0 +1,51 @@ +# Skybreaker — Black Tide boss 5 + +Independent local enemy mod `iron_coast_stage2_boss_5:unit`; no dependencies, no item +or mission overrides. Enable it alone in **Mods** for other content to spawn it. +It has no standalone mission; `iron_coast_stage2_mission_5` supplies its encounter. + +300 health at difficulties 2/3, 150 at 0/1; 6,000-credit actual-death reward. +Its logical canvas is 112×56, with a stable padded transparent +SD PNG and a 4× HD PNG. It is airborne. +Both artwork modes use the same collision dimensions. It enters the y 24 band +and patrols horizontally at 1px/tick over x 80..136. +It remains until killed rather than scrolling or timing out. + +Each instance has its own serializable attack clock and actual starting-health +snapshot. The 84-tick cycle warns at age 36, +fires staggered outward left/right damage 3 shells at ages +50/58, then below half starting health adds +an aimed damage 4 center shot at age 66. Speeds are 4/3 respectively; +the center aim is bounded to ±2 horizontal velocity. One artwork frame is used; +the attack pattern and warning identify the phase. There is no native default +projectile or legacy movement. Projectiles reference original enemy-shell art. + +Only actual death increments `iron_coast_stage2_boss_5:defeated`, clears instance state +and plays the destruction cue. The boss never completes a mission, changes +inventory or awards a separate scripted credit bonus. Removed/dead units emit +no ghost shots. Simultaneous instances keep independent clocks; new spawns +remove stale clocks from a previous mission and reset reused IDs safely. + +[`provenance.json`](provenance.json) binds the genuine built-in image generation +request and untouched `sources/raw-v1.png`. Whole-canvas proportional fitting, +resampling and ordinary-palette SD conversion are the only sprite derivatives. +Original reference sheets remain external, recorded by path and hash. +[`tools/build_assets.py`](tools/build_assets.py) reproduces SD/HD art and the +original 22050Hz PCM16 warning, cannon and death cues. It reads only bundled +RustRaptor `data/misc/PALETTE_DAT`. No third-party recording was used. + +Validation from RustRaptor: + +```sh +cargo run --release --locked --no-default-features -- --data data --mods mods --validate-mods iron_coast_stage2_boss_5 +CARGO_TARGET_DIR=target cargo test --locked --manifest-path mods/iron_coast_stage2_boss_5/validation/Cargo.toml --lib +``` + +Four portable tests cover warning/attack order and command bounds, +serialized continuation and independent clocks, dead-unit guards, restart +flags and one-time mission bonuses, plus actual World boss persistence through +600 ticks, relative phase transitions at all four difficulties, genuine lethal +damage, one death reward/objective and 120 ticks without ghost fire. The local +real-catalog acceptance runner checks the complete associated mission, full +inventories and replays. Actual indexed SD/HD artwork and all three cues were +checked via Rust decoding/mixing; live aggregate-scene captures are separate. diff --git a/mods/iron_coast_stage2_boss_5/art-preview.png b/mods/iron_coast_stage2_boss_5/art-preview.png new file mode 100644 index 00000000..259115dd Binary files /dev/null and b/mods/iron_coast_stage2_boss_5/art-preview.png differ diff --git a/mods/iron_coast_stage2_boss_5/art-qa.json b/mods/iron_coast_stage2_boss_5/art-qa.json new file mode 100644 index 00000000..25ae8481 --- /dev/null +++ b/mods/iron_coast_stage2_boss_5/art-qa.json @@ -0,0 +1,60 @@ +{ + "files": { + "unit-hd.png": { + "opaque_bounds": [ + 34, + 36, + 414, + 186 + ], + "sha256": "72dd1a498dbfc9be8626be76c5f29880875bf9dde35f6b6d2bc4d8112529447b", + "size": [ + 448, + 224 + ], + "transparent_pixels": 69532 + }, + "unit-sd.png": { + "opaque_bounds": [ + 9, + 9, + 103, + 47 + ], + "sha256": "924369d0d8ab2e084b7a7c0a1a881cadf6aea71b2afa7676ef42ae148e32a669", + "size": [ + 112, + 56 + ], + "transparent_pixels": 4348 + } + }, + "ordinary_palette": { + "ordinary_indices": [ + 0, + 239 + ], + "sha256": "1cf6adb926d1dee1888b3e3d33b51a7049b3e5eb5f90a3067ef71c8970547204", + "source": "PALETTE_DAT" + }, + "raw_sha256": "dec2fcb94a0ad8f280c8eadc9f10be7f54f777ff4e4ba829714335e446dd3deb", + "raw_size": [ + 1774, + 887 + ], + "recipe": { + "frames": 1, + "hd_scale": 4, + "logical_canvas": [ + 112, + 56 + ], + "method": "Fit complete untouched RGBA master proportionally into fixed padded canvas; no silhouette crop, alpha removal or painted changes.", + "origin": [ + 0, + 0 + ] + }, + "recipe_sha256": "3482e6671b8d6ec63d0f8c1df15fd288ae5d9af8fab19f11f9932ea0837a4f77", + "visual_status": "Both generated masters and derivedSD/HD reviewed; actual Rust indexed SD/HD outputs inspected independently in isolated reference evidence. No live-scene/1080p claim." +} diff --git a/mods/iron_coast_stage2_boss_5/art/unit-hd.png b/mods/iron_coast_stage2_boss_5/art/unit-hd.png new file mode 100644 index 00000000..14183b2a Binary files /dev/null and b/mods/iron_coast_stage2_boss_5/art/unit-hd.png differ diff --git a/mods/iron_coast_stage2_boss_5/art/unit-sd.png b/mods/iron_coast_stage2_boss_5/art/unit-sd.png new file mode 100644 index 00000000..b1f07f14 Binary files /dev/null and b/mods/iron_coast_stage2_boss_5/art/unit-sd.png differ diff --git a/mods/iron_coast_stage2_boss_5/audio-recipe.json b/mods/iron_coast_stage2_boss_5/audio-recipe.json new file mode 100644 index 00000000..eb892955 --- /dev/null +++ b/mods/iron_coast_stage2_boss_5/audio-recipe.json @@ -0,0 +1,50 @@ +{ + "files": { + "death": { + "bits": 16, + "channels": 1, + "duration_seconds": 0.9, + "file": "audio/death.wav", + "first_last_samples": [ + 0, + 0 + ], + "peak": 22282, + "rms": 3334.061311588026, + "sample_rate": 22050, + "seed": 5102, + "sha256": "98f53d5881a61191488e93375478d018202f0999b78b8f1c7e62415769f25c1d" + }, + "shot": { + "bits": 16, + "channels": 1, + "duration_seconds": 0.19, + "file": "audio/shot.wav", + "first_last_samples": [ + 0, + 0 + ], + "peak": 22282, + "rms": 4254.316188809612, + "sample_rate": 22050, + "seed": 5101, + "sha256": "a1c92f4f5645460011e1df4a1a702e276a04dd576fb75f64bde505c87cfc1acb" + }, + "warning": { + "bits": 16, + "channels": 1, + "duration_seconds": 0.28, + "file": "audio/warning.wav", + "first_last_samples": [ + 0, + 0 + ], + "peak": 22282, + "rms": 6785.139084846579, + "sample_rate": 22050, + "seed": 5100, + "sha256": "145f14873499614ee86bf08e4731053d9e29d90f9a65a6f49ed3a6c07cb1a6f6" + } + }, + "generator": "tools/build_assets.py deterministic sinusoidal chirps, seeded noise and faded envelopes; no recorded audio or third-party samples" +} diff --git a/mods/iron_coast_stage2_boss_5/audio/death.wav b/mods/iron_coast_stage2_boss_5/audio/death.wav new file mode 100644 index 00000000..8968d874 Binary files /dev/null and b/mods/iron_coast_stage2_boss_5/audio/death.wav differ diff --git a/mods/iron_coast_stage2_boss_5/audio/shot.wav b/mods/iron_coast_stage2_boss_5/audio/shot.wav new file mode 100644 index 00000000..bd1fd869 Binary files /dev/null and b/mods/iron_coast_stage2_boss_5/audio/shot.wav differ diff --git a/mods/iron_coast_stage2_boss_5/audio/warning.wav b/mods/iron_coast_stage2_boss_5/audio/warning.wav new file mode 100644 index 00000000..94567095 Binary files /dev/null and b/mods/iron_coast_stage2_boss_5/audio/warning.wav differ diff --git a/mods/iron_coast_stage2_boss_5/content.json b/mods/iron_coast_stage2_boss_5/content.json new file mode 100644 index 00000000..1296b565 --- /dev/null +++ b/mods/iron_coast_stage2_boss_5/content.json @@ -0,0 +1,76 @@ +{ + "weapons": [ + { + "id": "iron_coast_stage2_boss_5:shell", + "name": "Skybreaker heavy cannon", + "damage": 3, + "speed": 4, + "cooldown": 84, + "behavior": "straight", + "target": "all", + "art": { + "asset": 66006, + "logical_width": 8, + "logical_height": 8, + "frames": 2 + } + }, + { + "id": "iron_coast_stage2_boss_5:core", + "name": "Skybreaker center cannon", + "damage": 4, + "speed": 3, + "cooldown": 84, + "behavior": "straight", + "target": "all", + "art": { + "asset": 66006, + "logical_width": 8, + "logical_height": 8, + "frames": 2 + } + } + ], + "enemies": [ + { + "id": "iron_coast_stage2_boss_5:unit", + "name": "Skybreaker", + "health": 300, + "speed": 0, + "reward": 6000, + "ground": false, + "boss": true, + "cooldown": 84, + "art": { + "png": "art/unit-sd.png", + "hd_png": "art/unit-hd.png", + "logical_width": 112, + "logical_height": 56 + }, + "script": "scripts/ai.rhai" + } + ], + "sounds": [ + { + "id": "iron_coast_stage2_boss_5:warning", + "name": "Skybreaker warning", + "file": "audio/warning.wav", + "volume": 76, + "priority": 3 + }, + { + "id": "iron_coast_stage2_boss_5:shot", + "name": "Skybreaker shot", + "file": "audio/shot.wav", + "volume": 88, + "priority": 3 + }, + { + "id": "iron_coast_stage2_boss_5:death", + "name": "Skybreaker death", + "file": "audio/death.wav", + "volume": 110, + "priority": 2 + } + ] +} diff --git a/mods/iron_coast_stage2_boss_5/mod.toml b/mods/iron_coast_stage2_boss_5/mod.toml new file mode 100644 index 00000000..0a9721cc --- /dev/null +++ b/mods/iron_coast_stage2_boss_5/mod.toml @@ -0,0 +1,7 @@ +id = "iron_coast_stage2_boss_5" +name = "Black Tide — Skybreaker" +version = "1.0.0" +api_version = 1 +description = "Independent airborne flying-wing fortress with persistent patrol, telegraphed volleys and generated SD/HD artwork." +content = "content.json" +scripts = ["scripts/ai.rhai"] diff --git a/mods/iron_coast_stage2_boss_5/prompts/request-v1.json b/mods/iron_coast_stage2_boss_5/prompts/request-v1.json new file mode 100644 index 00000000..2d8c3ca2 --- /dev/null +++ b/mods/iron_coast_stage2_boss_5/prompts/request-v1.json @@ -0,0 +1,8 @@ +{ + "prompt": "Use case: stylized-concept\nAsset type: new transparent top-down Raptor-compatible boss sprite, Skybreaker airborne flying-wing fortress.\nInput images: the two original Raptor boss reference sheets are style references only, not edit targets. Match their top-down orthographic metallic construction and legible small sprite language, while designing a genuinely different wide aircraft.\nSubject: a broad swept flying wing with a stout central armored fuselage, twin inset jet intakes and two integrated forward weapon pods. It flies toward the bottom of the image. Slate gunmetal, pale steel panel edges, subtle oxidized copper, very small cool cyan instrument accents; restrained hard-edged material detail and overhead upper-left light. Combat-worn industrial military craft.\nComposition: ONE complete aircraft on an entirely transparent landscape canvas, perfectly top-down with zero perspective tilt. Native logical canvas 112 by 56, horizontal wings spanning most width with ample clear alpha margin on all four edges. Aircraft centered, facing down, bilateral wing geometry, stable silhouette. No separate shadow outside the aircraft, no smoke/exhaust plume, no projectiles, no lettering, no scenery, no checkerboard. Occupied near-black aircraft metal remains opaque. Produce sharp fine HD detail within a readable old-game silhouette; no glossy photoreal rendering or diagonal camera.\n", + "referenced_image_paths": [ + "/home/quintine/Projects/RaptorReplica/data/hd/jobs/bosses-10310-10310/source-sheet.png", + "/home/quintine/Projects/RaptorReplica/data/hd/jobs/bosses-200ad-200ad/source-sheet.png" + ], + "transparent_background": true +} diff --git a/mods/iron_coast_stage2_boss_5/prompts/v1.txt b/mods/iron_coast_stage2_boss_5/prompts/v1.txt new file mode 100644 index 00000000..f503f9ca --- /dev/null +++ b/mods/iron_coast_stage2_boss_5/prompts/v1.txt @@ -0,0 +1,5 @@ +Use case: stylized-concept +Asset type: new transparent top-down Raptor-compatible boss sprite, Skybreaker airborne flying-wing fortress. +Input images: the two original Raptor boss reference sheets are style references only, not edit targets. Match their top-down orthographic metallic construction and legible small sprite language, while designing a genuinely different wide aircraft. +Subject: a broad swept flying wing with a stout central armored fuselage, twin inset jet intakes and two integrated forward weapon pods. It flies toward the bottom of the image. Slate gunmetal, pale steel panel edges, subtle oxidized copper, very small cool cyan instrument accents; restrained hard-edged material detail and overhead upper-left light. Combat-worn industrial military craft. +Composition: ONE complete aircraft on an entirely transparent landscape canvas, perfectly top-down with zero perspective tilt. Native logical canvas 112 by 56, horizontal wings spanning most width with ample clear alpha margin on all four edges. Aircraft centered, facing down, bilateral wing geometry, stable silhouette. No separate shadow outside the aircraft, no smoke/exhaust plume, no projectiles, no lettering, no scenery, no checkerboard. Occupied near-black aircraft metal remains opaque. Produce sharp fine HD detail within a readable old-game silhouette; no glossy photoreal rendering or diagonal camera. diff --git a/mods/iron_coast_stage2_boss_5/provenance.json b/mods/iron_coast_stage2_boss_5/provenance.json new file mode 100644 index 00000000..6927427e --- /dev/null +++ b/mods/iron_coast_stage2_boss_5/provenance.json @@ -0,0 +1,20 @@ +{ + "begun_utc": "2026-10-11 08:08:56 UTC", + "ended_utc": "2026-10-11 08:09:25 UTC", + "gate_lease": "cca562c9-e43b-4d9a-8c14-3cb5e12b14e6", + "generator_raw": "/home/quintine/.codex/generated_images/01a1245d-ddd6-7c41-8bab-0a08c2b68f4d/exec-4894cd15-9b47-4228-a243-2f3c5721b83a.png", + "mode": "built-in", + "notes": "Original style references remain external; source references are not bundled original artwork.", + "outcome": "success", + "prompt": "prompts/v1.txt", + "prompt_sha256": "dbf693cbcac36f6aade54758a3030b80407d39bca4f69d2abd88cbca5fc5cf8d", + "raw_copy": "sources/raw-v1.png", + "raw_sha256": "dec2fcb94a0ad8f280c8eadc9f10be7f54f777ff4e4ba829714335e446dd3deb", + "reference_hashes": { + "/home/quintine/Projects/RaptorReplica/data/hd/jobs/bosses-10310-10310/source-sheet.png": "f3135c73dc38faae087115f122e62417b845d01260586c5ff35d78dea3b68608", + "/home/quintine/Projects/RaptorReplica/data/hd/jobs/bosses-200ad-200ad/source-sheet.png": "29a4f33e50f25d866f692dad8751f9eaa90a9c87bf2bad2527ba5249f0b3663f" + }, + "request": "prompts/request-v1.json", + "tool": "image_gen.imagegen", + "transparent_background": true +} diff --git a/mods/iron_coast_stage2_boss_5/scripts/ai.rhai b/mods/iron_coast_stage2_boss_5/scripts/ai.rhai new file mode 100644 index 00000000..6040f2f7 --- /dev/null +++ b/mods/iron_coast_stage2_boss_5/scripts/ai.rhai @@ -0,0 +1,57 @@ +// Each real instance has a bounded serializable clock. No native/legacy behavior. +fn alive(event) { + for e in event.entities { if e.entity == event.entity && e.health > 0 { return true; } } + false +} +fn on_spawn(event, state, random) { + if !alive(event) { return #{commands:[],state:state}; } + let retained = #{}; + // Discard entries from earlier failed/replayed missions; preserve simultaneous instances. + if state.contains("units") { + for e in event.entities { + let key = e.entity.to_string(); + if e.definition == "iron_coast_stage2_boss_5:unit" && state.units.contains(key) { retained[key] = state.units[key]; } + } + } + state.units = retained; + let max_health = 1; + for e in event.entities { if e.entity == event.entity { max_health = e.health; } } + state.units[event.entity.to_string()] = #{age:0,direction:1,max_health:max_health}; + #{commands:[#{op:"velocity",entity:event.entity,vx:0,vy:2}],state:state} +} +fn on_tick(event, state, random) { + if event.health <= 0 || !alive(event) { return #{commands:[],state:state}; } + let key = event.entity.to_string(); + if !state.contains("units") { state.units = #{}; } + if !state.units.contains(key) { state.units[key] = #{age:0,direction:1,max_health:event.health}; } + let u = state.units[key]; + if !u.contains("max_health") { u.max_health = event.health; } + if event.y < 24 { return #{commands:[#{op:"velocity",entity:event.entity,vx:0,vy:2}],state:state}; } + u.age += 1; + if event.x >= 136 { u.direction = -1; } + if event.x <= 80 { u.direction = 1; } + let commands = [#{op:"move",entity:event.entity,x:event.x,y:24},#{op:"velocity",entity:event.entity,vx:u.direction,vy:0}]; + let phase = u.age % 84; + if phase == 36 { commands.push(#{op:"play_sound",sound:"iron_coast_stage2_boss_5:warning"}); } + if phase == 50 { + commands.push(#{op:"projectile",weapon:"iron_coast_stage2_boss_5:shell",x:event.x+28,y:event.y+48,vx:-1,vy:4,hostile:true}); + commands.push(#{op:"play_sound",sound:"iron_coast_stage2_boss_5:shot"}); + } + if phase == 58 { + commands.push(#{op:"projectile",weapon:"iron_coast_stage2_boss_5:shell",x:event.x+80,y:event.y+48,vx:1,vy:4,hostile:true}); + commands.push(#{op:"play_sound",sound:"iron_coast_stage2_boss_5:shot"}); + } + if phase == 66 && event.health <= u.max_health / 2 { + let aim = (event.player_x - event.x - 40) / 48; + let vx = if aim < -2 { -2 } else if aim > 2 { 2 } else { aim }; + commands.push(#{op:"projectile",weapon:"iron_coast_stage2_boss_5:core",x:event.x+52,y:event.y+48,vx:vx,vy:3,hostile:true}); + commands.push(#{op:"play_sound",sound:"iron_coast_stage2_boss_5:shot"}); + } + state.units[key] = u; + #{commands:commands,state:state} +} +fn on_death(event, state, random) { + if state.contains("units") { state.units.remove(event.entity.to_string()); } + let n = if event.objectives.contains("iron_coast_stage2_boss_5:defeated") { event.objectives["iron_coast_stage2_boss_5:defeated"] + 1 } else { 1 }; + #{commands:[#{op:"objective",key:"iron_coast_stage2_boss_5:defeated",value:n},#{op:"effect",x:event.x+28,y:event.y+40},#{op:"effect",x:event.x+80,y:event.y+40},#{op:"play_sound",sound:"iron_coast_stage2_boss_5:death"}],state:state} +} diff --git a/mods/iron_coast_stage2_boss_5/sources/raw-v1.png b/mods/iron_coast_stage2_boss_5/sources/raw-v1.png new file mode 100644 index 00000000..cd10de64 Binary files /dev/null and b/mods/iron_coast_stage2_boss_5/sources/raw-v1.png differ diff --git a/mods/iron_coast_stage2_boss_5/tools/build_assets.py b/mods/iron_coast_stage2_boss_5/tools/build_assets.py new file mode 100644 index 00000000..56f6f52e --- /dev/null +++ b/mods/iron_coast_stage2_boss_5/tools/build_assets.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python3 +"""Prepare game assets from unchanged generated masters and synthesize PCM cues. + +Requires Pillow. Original Raptor reference images stay external. The original +palette is read only for ordinary-color SD quantization; final assets are local. +No generated RGB is retouched: whole-canvas proportional fit, resampling, +cropping into tiles and reflected terrain repetition are explicit derivatives. +""" +from pathlib import Path +import json,hashlib,math,random,struct,wave +from PIL import Image,ImageOps,ImageDraw +ROOT=Path(__file__).resolve().parent.parent +NUMBER=int(ROOT.name.rsplit('_',1)[1]);IS_BOSS='_boss_'in ROOT.name +sha=lambda p:hashlib.sha256(p.read_bytes()).hexdigest() +write=lambda p,j:p.write_text(json.dumps(j,indent=2,sort_keys=True)+'\n') + +def palette(): + path=ROOT.parents[1]/'data/misc/PALETTE_DAT' + b=path.read_bytes();assert len(b)==768 + rgb=[(min(v,63)<<2)|(min(v,63)>>4)for v in b[:720]] + image=Image.new('P',(1,1));image.putpalette(rgb+[0]*48) + return image,{'source':'PALETTE_DAT','sha256':sha(path),'ordinary_indices':[0,239]} + +def sd_quantize(image,pal): + a=image.getchannel('A')if image.mode=='RGBA'else None + # Duplicate palette0 in unused slots so quantization cannot create a reserved class. + pal=pal.copy();p=pal.getpalette();p[720:768]=p[:3]*16;pal.putpalette(p) + q=image.convert('RGB').quantize(palette=pal,dither=Image.Dither.NONE).convert('RGBA') + if a is not None:q.putalpha(a) + return q + +def artwork(): + raw=ROOT/'sources/raw-v1.png';source=Image.open(raw).convert('RGBA');pal,binding=palette();files={} + def save(name,img): + p=ROOT/'art'/name;img.save(p);alpha=img.getchannel('A');mask=alpha.point(lambda a:255 if a>=128 else 0) + files[name]={'size':list(img.size),'sha256':sha(p),'opaque_bounds':list(mask.getbbox())if mask.getbbox()else None,'transparent_pixels':sum(a<128 for a in alpha.get_flattened_data())} + if IS_BOSS: + logical=(112,56 if NUMBER==5 else 72);target=tuple(v*4 for v in logical) + assert source.getchannel('A').getextrema()[0]==0 and source.getchannel('A').getextrema()[1]>=128,'Real generated alpha required' + fit=ImageOps.contain(source,(target[0]-32,target[1]-32),Image.Resampling.LANCZOS) + hd=Image.new('RGBA',target,(0,0,0,0));hd.alpha_composite(fit,((target[0]-fit.width)//2,(target[1]-fit.height)//2)) + sd=sd_quantize(hd.resize(logical,Image.Resampling.LANCZOS),pal) + save('unit-hd.png',hd);save('unit-sd.png',sd) + for name in ['unit-hd.png','unit-sd.png']: + bounds=files[name]['opaque_bounds'];size=files[name]['size'];assert bounds and min(bounds[:2])>=2 and bounds[2] PathBuf { + PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../..") + } + fn owner(number: u32, kind: &str) -> String { + format!("iron_coast_stage2_{kind}_{number}") + } + fn runtime(number: u32, kind: &str, script: &str) -> ScriptRuntime { + let mut runtime = ScriptRuntime::new(); + let package = owner(number, kind); + let source = std::fs::read_to_string(mods().join(&package).join(script)).unwrap(); + runtime.add(&package, script, &source).unwrap(); + runtime + } + fn invoke( + runtime: &mut ScriptRuntime, + number: u32, + kind: &str, + script: &str, + hook: &str, + event: &Value, + ) -> Vec { + runtime.begin_tick(); + runtime + .invoke(&owner(number, kind), script, hook, event, 1024) + .unwrap() + } + fn event(number: u32, entity: u64, tick: u64) -> Value { + let health = if number == 5 { 300 } else { 360 }; + json!({"entity":entity,"tick":tick,"x":104,"y":24,"health":health,"player_x":144,"player_y":160, + "entities":[{"entity":1,"health":health,"definition":format!("{}:unit",owner(number,"boss"))}, + {"entity":2,"health":health,"definition":format!("{}:unit",owner(number,"boss"))}],"objectives":{}}) + } + + #[test] + fn both_bosses_have_warned_staggered_attacks_and_no_ghost_commands() { + for number in [5, 6] { + let mut scripts = runtime(number, "boss", "scripts/ai.rhai"); + invoke( + &mut scripts, + number, + "boss", + "scripts/ai.rhai", + "on_spawn", + &event(number, 1, 0), + ); + let mut warnings = vec![]; + let mut shots = vec![]; + for tick in 1..=200 { + let mut e = event(number, 1, tick); + e["health"] = json!(50); // Also exercise the aimed low-health cannon. + let commands = invoke( + &mut scripts, + number, + "boss", + "scripts/ai.rhai", + "on_tick", + &e, + ); + assert!(commands.len() <= 4); + for command in commands { + match command { + Command::PlaySound { sound } if sound.ends_with(":warning") => { + warnings.push(tick) + } + Command::Projectile { + hostile, vx, vy, .. + } => { + assert!(hostile); + assert!((-2..=2).contains(&vx)); + assert!((3..=4).contains(&vy)); + shots.push(tick); + } + Command::Complete + | Command::Fail + | Command::GiveItem { .. } + | Command::ConsumeItem { .. } => { + panic!("boss must not alter mission outcome or inventory") + } + _ => {} + } + } + } + let (period, warn, left, right, core) = if number == 5 { + (84, 36, 50, 58, 66) + } else { + (96, 44, 60, 72, 84) + }; + assert_eq!( + warnings, + (0..3) + .map(|i| i * period + warn) + .filter(|t| *t <= 200) + .collect::>() + ); + assert_eq!( + shots, + (0..3) + .flat_map(|i| [i * period + left, i * period + right, i * period + core]) + .filter(|t| *t <= 200) + .collect::>() + ); + let saved = scripts.checkpoints(); + let mut restored = runtime(number, "boss", "scripts/ai.rhai"); + restored.restore(saved); + let e = event(number, 1, 201); + let a = invoke( + &mut scripts, + number, + "boss", + "scripts/ai.rhai", + "on_tick", + &e, + ); + let b = invoke( + &mut restored, + number, + "boss", + "scripts/ai.rhai", + "on_tick", + &e, + ); + assert_eq!( + serde_json::to_value(a).unwrap(), + serde_json::to_value(b).unwrap() + ); + assert_eq!(scripts.states, restored.states); + let before = scripts.states.clone(); + let mut gone = event(number, 1, 202); + gone["entities"] = json!([]); + assert!( + invoke( + &mut scripts, + number, + "boss", + "scripts/ai.rhai", + "on_tick", + &gone + ) + .is_empty() + ); + assert_eq!(scripts.states, before); + let mut dead = event(number, 1, 203); + dead["health"] = json!(0); + assert!( + invoke( + &mut scripts, + number, + "boss", + "scripts/ai.rhai", + "on_tick", + &dead + ) + .is_empty() + ); + } + } + + #[test] + fn reused_instances_start_with_fresh_clocks_and_simultaneous_ones_are_preserved() { + for number in [5, 6] { + let mut scripts = runtime(number, "boss", "scripts/ai.rhai"); + for entity in [1, 2] { + invoke( + &mut scripts, + number, + "boss", + "scripts/ai.rhai", + "on_spawn", + &event(number, entity, 0), + ); + } + for tick in 1..=40 { + invoke( + &mut scripts, + number, + "boss", + "scripts/ai.rhai", + "on_tick", + &event(number, 1, tick), + ); + } + let key = format!("{}/scripts/ai.rhai", owner(number, "boss")); + assert_eq!(scripts.states[&key]["units"]["1"]["age"], 40); + assert_eq!(scripts.states[&key]["units"]["2"]["age"], 0); + let mut restarted = event(number, 1, 0); + restarted["entities"].as_array_mut().unwrap().truncate(1); + invoke( + &mut scripts, + number, + "boss", + "scripts/ai.rhai", + "on_spawn", + &restarted, + ); + assert_eq!(scripts.states[&key]["units"]["1"]["age"], 0); + assert!(scripts.states[&key]["units"].get("2").is_none()); + } + } + + #[test] + fn mission_death_gates_pay_once_reset_every_flag_and_never_mutate_inventory() { + for number in [5, 6] { + let mut scripts = runtime(number, "mission", "scripts/mission.rhai"); + let package = owner(number, "mission"); + let mut e = json!({"tick":0,"objectives":{},"success":true}); + let start = invoke( + &mut scripts, + number, + "mission", + "scripts/mission.rhai", + "on_mission_start", + &e, + ); + for suffix in [ + "targets_destroyed", + "complete", + "field_repair", + "debrief", + "hazard_lane", + ] { + assert!(start.iter().any(|c|matches!(c,Command::Objective{key,value:0} if key==&format!("{package}:{suffix}")))); + } + e["tick"] = json!(3501); + let commands = invoke( + &mut scripts, + number, + "mission", + "scripts/mission.rhai", + "on_tick", + &e, + ); + assert!( + !commands.iter().any(|c| matches!(c, Command::Complete)), + "duration alone cannot complete a mission" + ); + e["objectives"] = json!({format!("{package}:targets_destroyed"):if number==5 {2}else{3},format!("{}:defeated",owner(number,"boss")):1}); + let reward = invoke( + &mut scripts, + number, + "mission", + "scripts/mission.rhai", + "on_tick", + &e, + ); + assert_eq!( + reward + .iter() + .filter(|c| matches!(c, Command::Complete)) + .count(), + 1 + ); + assert_eq!(reward.iter().filter(|c|matches!(c,Command::Credits{amount} if *amount==if number==5 {26000}else{32000})).count(),1); + let second = invoke( + &mut scripts, + number, + "mission", + "scripts/mission.rhai", + "on_tick", + &e, + ); + assert!( + !second + .iter() + .any(|c| matches!(c, Command::Complete | Command::Credits { .. })) + ); + for c in start.iter().chain(reward.iter()).chain(second.iter()) { + assert!(!matches!( + c, + Command::GiveItem { .. } | Command::ConsumeItem { .. } + )); + } + invoke( + &mut scripts, + number, + "mission", + "scripts/mission.rhai", + "on_mission_end", + &e, + ); + invoke( + &mut scripts, + number, + "mission", + "scripts/mission.rhai", + "on_mission_start", + &e, + ); + let key = format!("{package}/scripts/mission.rhai"); + assert_eq!( + scripts.states[&key], + json!({"complete":false,"repair":false,"boss_warning":false}) + ); + } + } + + fn base() -> Registry { + let mut base = Registry::default(); + let pack:ContentPack=serde_json::from_value(json!({ + "weapons":[{"id":"base:test_gun","name":"Fixture gun","damage":1,"speed":8,"cooldown":2,"behavior":"straight","target":"all"}], + "items":[{"id":"base:forward_guns","name":"Fixture guns","price":0,"max_count":1,"weapon":"base:test_gun"},{"id":"base:energy","name":"Shield","price":10000,"max_count":100}], + "missions":[{"id":"base:sector_1_wave_1","name":"Persistence fixture","duration":2,"auto_complete":false}] + })).unwrap(); + base.apply(pack, "base").unwrap(); + base.validate().unwrap(); + base + } + + #[test] + fn real_simulation_persists_bosses_then_pays_actual_death_reward_once() { + let discovery = modding::discover(&mods()); + for number in [5, 6] { + let package = owner(number, "boss"); + let mut active = + ActiveMods::build(&base(), &discovery, &[package.clone()], None).unwrap(); + for difficulty in 0..=3 { + active.scripts.restore(Default::default()); + let pilot = Pilot { + difficulty, + ..Pilot::default() + }; + let mut world = + World::new(&"base:sector_1_wave_1".into(), &pilot, &active.registry).unwrap(); + world.player.x = 0; + world + .apply_commands( + &[Command::Spawn { + enemy: format!("{package}:unit"), + x: 104, + y: -24, + }], + &active.registry, + ) + .unwrap(); + let maximum = world.enemies[0].health; + assert_eq!( + maximum, + if difficulty <= 1 { + if number == 5 { 150 } else { 180 } + } else { + if number == 5 { 300 } else { 360 } + } + ); + let mut warnings = 0; + let mut shots = 0; + let mut core_seen = false; + for _ in 0..300 { + world + .step(Input::default(), &active.registry, &mut active.scripts) + .unwrap(); + warnings += world + .mod_sounds + .iter() + .filter(|s| s.0.ends_with(":warning")) + .count(); + shots += world + .mod_sounds + .iter() + .filter(|s| s.0.ends_with(":shot")) + .count(); + core_seen |= world + .projectiles + .iter() + .any(|p| p.weapon.0.ends_with(":core")); + } + assert!( + !core_seen, + "difficulty{difficulty}: full-health boss must not begin in its second phase" + ); + let entity = world.enemies[0].entity; + world + .apply_commands( + &[Command::Damage { + entity, + amount: maximum / 2, + }], + &active.registry, + ) + .unwrap(); + for _ in 0..300 { + world + .step(Input::default(), &active.registry, &mut active.scripts) + .unwrap(); + warnings += world + .mod_sounds + .iter() + .filter(|s| s.0.ends_with(":warning")) + .count(); + shots += world + .mod_sounds + .iter() + .filter(|s| s.0.ends_with(":shot")) + .count(); + core_seen |= world + .projectiles + .iter() + .any(|p| p.weapon.0.ends_with(":core")); + } + assert!( + core_seen, + "difficulty{difficulty}: real half-health damage must unlock aimed core cannon" + ); + assert_eq!(world.outcome, Outcome::Playing); + assert_eq!(world.enemies.len(), 1); + assert_eq!(world.enemies[0].y, 24); + assert!(warnings >= 5 && shots >= 10); + let entity = world.enemies[0].entity; + world + .apply_commands( + &[Command::Damage { + entity, + amount: if number == 5 { 300 } else { 360 }, + }], + &active.registry, + ) + .unwrap(); + world + .step(Input::default(), &active.registry, &mut active.scripts) + .unwrap(); + assert!(world.enemies.is_empty()); + assert_eq!(world.objectives[&format!("{package}:defeated")], 1); + assert_eq!( + world.player.credits, + pilot.credits + if number == 5 { 6000 } else { 7500 } + ); + assert!(world.mod_sounds.iter().any(|s| s.0.ends_with(":death"))); + for _ in 0..120 { + world + .step(Input::default(), &active.registry, &mut active.scripts) + .unwrap(); + assert!(!world.mod_sounds.iter().any(|s| s.0.ends_with(":shot"))); + } + assert_eq!(world.objectives[&format!("{package}:defeated")], 1); + assert_eq!(world.outcome, Outcome::Playing); + } + } + } +} diff --git a/mods/iron_coast_stage2_boss_5/validation/src/main.rs b/mods/iron_coast_stage2_boss_5/validation/src/main.rs new file mode 100644 index 00000000..df4491e4 --- /dev/null +++ b/mods/iron_coast_stage2_boss_5/validation/src/main.rs @@ -0,0 +1,426 @@ +//! Real-catalog acceptance and indexed-art proof; never touches user profiles. +use raptor_replica::{ + assets::{Catalog, Sprite, TRANSPARENT}, + audio::Mixer, + content::{ContentPack, Registry, art_sprite_variant}, + modding::{self, ActiveMods, Command}, + persistence::Pilot, + simulation::{Input, Outcome, World}, + sound, +}; +use serde_json::{Value, json}; +use sha2::{Digest, Sha256}; +use std::{ + collections::{BTreeMap, BTreeSet}, + fs, + path::{Path, PathBuf}, +}; + +fn root() -> PathBuf { + PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../../..") +} +fn owner(n: u32, kind: &str) -> String { + format!("iron_coast_stage2_{kind}_{n}") +} +fn sha(path: &Path) -> String { + format!("{:x}", Sha256::digest(fs::read(path).unwrap())) +} +fn base(catalog: &Catalog) -> Registry { + let mut registry = Registry::base(catalog).unwrap(); + let pack:ContentPack=serde_json::from_value(json!({"items":(0..20).map(|n|json!({"id":format!("fixture:filler_{n}"),"name":"Neutral full-slot fixture","price":0,"max_count":1})).collect::>()})).unwrap(); + registry.apply(pack, "fixture").unwrap(); + registry.validate().unwrap(); + registry +} +fn active(n: u32, catalog: &Catalog) -> ActiveMods { + let mut enabled = vec![ + owner(n, "mission"), + owner(n, "boss"), + "iron_coast_stage2_music".into(), + "iron_coast_stage2_siege".into(), + ]; + enabled.push( + if n == 5 { + "iron_coast_stage2_interceptor" + } else { + "iron_coast_stage2_skimmer" + } + .into(), + ); + let discovery = modding::discover(&root().join("mods")); + ActiveMods::build(&base(catalog), &discovery, &enabled, Some(catalog)).unwrap() +} +fn input(world: &World) -> Input { + let desired = world + .enemies + .iter() + .filter(|e| e.health > 0 && e.y >= 0) + .max_by_key(|e| e.y) + .map(|e| e.x + e.width / 2 - 16) + .unwrap_or(144); + Input { + fire: true, + absolute: Some([ + world.player.x + (desired - world.player.x).clamp(-4, 4), + 160, + ]), + ..Input::default() + } +} +fn play( + n: u32, + active: &mut ActiveMods, + shield: u32, + credits: u32, + difficulty: u32, + full: bool, +) -> Value { + active.scripts.restore(Default::default()); + let mut pilot = Pilot { + credits, + difficulty, + ..Pilot::default() + }; + pilot.inventory.insert("base:energy".into(), shield); + if full { + for i in 0..20 { + if pilot.inventory_slots() >= 20 { + break; + } + pilot + .inventory + .insert(format!("fixture:filler_{i}").as_str().into(), 1); + } + } + let inventory = pilot.inventory.clone(); + let mission = owner(n, "mission"); + let boss = owner(n, "boss"); + let mut world = World::new( + &format!("{mission}:mission_{n:02}").as_str().into(), + &pilot, + &active.registry, + ) + .unwrap(); + let mut previous = BTreeMap::new(); + let mut moving = BTreeSet::new(); + let mut digests = Vec::new(); + let mut damage = 0; + let mut sounds = 0; + let mut max_enemies = 0; + for _ in 0..5000 { + let before = world.player.shield; + world + .step(input(&world), &active.registry, &mut active.scripts) + .unwrap(); + damage += (before - world.player.shield).max(0); + sounds += world.mod_sounds.len(); + max_enemies = max_enemies.max(world.enemies.len()); + for e in &world.enemies { + if e.definition.0.starts_with("base:enemy_") { + assert!(active.registry.enemies[&e.definition].legacy.is_some()); + if let Some(old) = previous.insert((e.definition.clone(), e.entity), (e.x, e.y)) { + if old != (e.x, e.y) { + moving.insert(e.definition.0.clone()); + } + } + } + } + digests.push(world.digest()); + if world.outcome != Outcome::Playing { + break; + } + } + assert_eq!( + world.outcome, + Outcome::Complete, + "mission{n} difficulty{difficulty}: tick{} shield{} objectives{:?}", + world.tick, + world.player.shield, + world.objectives + ); + assert!( + (2300..=3500).contains(&world.tick), + "completion pacing outside intended window: {}", + world.tick + ); + assert!( + !moving.is_empty(), + "native classic enemies must be observed moving" + ); + assert_eq!( + world.objectives[&format!("{mission}:targets_destroyed")], + if n == 5 { 2 } else { 3 } + ); + assert_eq!(world.objectives[&format!("{boss}:defeated")], 1); + assert_eq!(world.objectives[&format!("{mission}:complete")], 1); + assert_eq!(world.objectives[&format!("{mission}:debrief")], 1); + for (id, count) in inventory { + if id.0 != "base:energy" { + assert_eq!(world.player.inventory.get(&id), Some(&count)); + } + } + let final_credits = world.player.credits; + world + .step(Input::default(), &active.registry, &mut active.scripts) + .unwrap(); + assert_eq!(world.player.credits, final_credits); + json!({"starting_shield":shield,"starting_credits":credits,"difficulty":difficulty,"full_20_slots":full,"tick":world.tick, + "ending_shield":world.player.shield,"ending_credits":world.player.credits,"observed_damage":damage,"mod_sound_events":sounds, + "max_enemies":max_enemies,"moving_native_definitions":moving,"objectives":world.objectives,"digest":world.digest(), + "input_policy":"Forward guns only, always Fire, bottom y160, closest visible enemy aim with max4 horizontal pixels per tick", + "step_digest_sha256":format!("{:x}",Sha256::digest(digests.join("\n")))}) +} +fn preserved_full_slots(n: u32, active: &mut ActiveMods) { + for reserves in [0, 4] { + active.scripts.restore(Default::default()); + let mut pilot = Pilot::default(); + pilot.inventory.insert("base:energy".into(), 75); + if reserves > 0 { + pilot.inventory.insert("base:super_shield".into(), 100); + pilot.super_shield_reserves = vec![100; reserves]; + } + for i in 0..20 { + if pilot.inventory_slots() >= 20 { + break; + } + pilot + .inventory + .insert(format!("fixture:filler_{i}").as_str().into(), 1); + } + assert_eq!(pilot.inventory_slots(), 20); + let mut world = World::new( + &format!("{}:mission_{n:02}", owner(n, "mission")) + .as_str() + .into(), + &pilot, + &active.registry, + ) + .unwrap(); + world + .step(Input::default(), &active.registry, &mut active.scripts) + .unwrap(); + assert_eq!(world.player.inventory, pilot.inventory); + assert_eq!( + world.player.super_shield_reserves, + pilot.super_shield_reserves + ); + } +} +fn reset_after_failure(n: u32, active: &mut ActiveMods) { + active.scripts.restore(Default::default()); + let pilot = Pilot::default(); + let name = owner(n, "mission"); + for run in 0..2 { + let mut world = World::new( + &format!("{name}:mission_{n:02}").as_str().into(), + &pilot, + &active.registry, + ) + .unwrap(); + world + .step(Input::default(), &active.registry, &mut active.scripts) + .unwrap(); + for suffix in [ + "targets_destroyed", + "complete", + "field_repair", + "debrief", + "hazard_lane", + ] { + assert_eq!(world.objectives[&format!("{name}:{suffix}")], 0); + } + if run == 0 { + world + .apply_commands( + &[Command::Damage { + entity: 0, + amount: 1000, + }], + &active.registry, + ) + .unwrap(); + world + .step(Input::default(), &active.registry, &mut active.scripts) + .unwrap(); + assert_eq!(world.outcome, Outcome::Failed); + } + } +} +fn pending_targets(n: u32, active: &mut ActiveMods) -> Value { + active.scripts.restore(Default::default()); + let mut pilot = Pilot::default(); + pilot.inventory.insert("base:super_shield".into(), 100); + pilot.super_shield_reserves = vec![100; 8]; + let mut world = World::new( + &format!("{}:mission_{n:02}", owner(n, "mission")) + .as_str() + .into(), + &pilot, + &active.registry, + ) + .unwrap(); + for _ in 0..5700 { + world + .step( + Input { + absolute: Some([0, 160]), + ..Input::default() + }, + &active.registry, + &mut active.scripts, + ) + .unwrap(); + } + assert_eq!(world.outcome, Outcome::Playing); + let targets = world + .enemies + .iter() + .filter(|e| e.definition.0 == format!("{}:target", owner(n, "mission"))) + .collect::>(); + assert_eq!(targets.len(), if n == 5 { 2 } else { 3 }); + assert!( + targets + .iter() + .all(|e| e.health > 0 && e.y == 28 && (0..288).contains(&e.x)) + ); + let boss = world + .enemies + .iter() + .find(|e| e.definition.0 == format!("{}:unit", owner(n, "boss"))) + .unwrap(); + assert_eq!(boss.y, 24); + json!({"tick":world.tick,"outcome":"playing","targets":targets.iter().map(|e|json!({"x":e.x,"y":e.y,"health":e.health})).collect::>(),"boss":{"x":boss.x,"y":boss.y,"health":boss.health}}) +} +fn rgba(sprite: &Sprite, palette: &[[u8; 3]; 256]) -> image::RgbaImage { + let mut pixels = Vec::with_capacity(sprite.pixels.len() * 4); + for index in &sprite.pixels { + if *index == TRANSPARENT { + pixels.extend([0, 0, 0, 0]); + } else { + pixels.extend([ + palette[*index as usize][0], + palette[*index as usize][1], + palette[*index as usize][2], + 255, + ]); + } + } + image::RgbaImage::from_raw(sprite.width as u32, sprite.height as u32, pixels).unwrap() +} +fn art_audio(n: u32, active: &ActiveMods, catalog: &Catalog, out: &Path) -> Value { + let palette = catalog.palette().unwrap(); + let mut paths = Vec::new(); + let mut sound_checks = Vec::new(); + for kind in ["boss", "mission"] { + let package = owner(n, kind); + let dir = out.join(&package); + fs::create_dir_all(&dir).unwrap(); + let id = if kind == "boss" { + format!("{package}:unit") + } else { + format!("{package}:mission_{n:02}") + }; + let art = active.registry.art(&id.as_str().into()).unwrap(); + for hd in [false, true] { + let sprite = + art_sprite_variant(catalog, &active.registry, &package, art, 0, hd).unwrap(); + let file = dir.join(if hd { + "indexed-hd.png" + } else { + "indexed-sd.png" + }); + rgba(&sprite, &palette).save(&file).unwrap(); + paths.push(json!({"file":file,"sha256":sha(&file),"width":sprite.width,"height":sprite.height,"reserved_indices":sprite.pixels.iter().filter(|p|(240..=255).contains(*p)).count()})); + } + if kind == "mission" { + let m = &active.registry.missions[&id.as_str().into()]; + for hd in [false, true] { + let size = if hd { 128 } else { 32 }; + let mut joined = image::RgbaImage::new(9 * size, 18 * size); + for (i, tile) in m.tiles.iter().enumerate() { + let s = + art_sprite_variant(catalog, &active.registry, &package, &tile.art, 0, hd) + .unwrap(); + image::imageops::replace( + &mut joined, + &rgba(&s, &palette), + (i % 9) as i64 * size as i64, + (i / 9) as i64 * size as i64, + ); + } + let file = dir.join(if hd { + "terrain-indexed-hd.png" + } else { + "terrain-indexed-sd.png" + }); + joined.save(&file).unwrap(); + paths.push(json!({"file":file,"sha256":sha(&file),"unique_tiles":m.tiles.len(),"width":joined.width(),"height":joined.height()})); + } + } + for (id, definition) in &active.registry.sounds { + if active.registry.owners[id] == package { + let path = active.registry.asset_roots[&package].join(&definition.file); + let sample = sound::decode(&fs::read(&path).unwrap()).unwrap(); + let mut mixer = Mixer::new(48000, &catalog.named("GENMIDI_OP2").unwrap()).unwrap(); + mixer.music_volume = 0; + mixer.sample( + sample, + 128, + 128, + definition.volume as i32, + definition.priority as i32, + ); + let mut buffer = vec![0_i16; 48000 * 2]; + mixer.mix(&mut buffer); + let nonzero = buffer.iter().filter(|p| **p != 0).count(); + assert!(nonzero > 32); + let peak = buffer.iter().map(|s| s.unsigned_abs()).max().unwrap(); + assert!(peak < 32767); + sound_checks.push(json!({"id":id,"wav_sha256":sha(&path),"nonzero_stereo_samples":nonzero,"mixer_peak":peak})); + } + } + } + json!({"actual_indexed_outputs":paths,"actual_mixer_cues":sound_checks,"renderer":"Current Rust art_sprite_variant/Sprite::png, original ordinary palette, no inferred SDL live-scene coverage"}) +} +fn main() { + let catalog = Catalog::open(root().join("data")).unwrap(); + let out = root().join(".reference/iron-coast-stage2-56-acceptance"); + fs::create_dir_all(&out).unwrap(); + let only_art = std::env::args().any(|a| a == "--art-only"); + let mut reports = Vec::new(); + for n in [5, 6] { + let mut active = active(n, &catalog); + let visual = art_audio(n, &active, &catalog, &out); + if only_art { + reports.push(json!({"mission":n,"visual_audio":visual})); + continue; + } + preserved_full_slots(n, &mut active); + reset_after_failure(n, &mut active); + let mut runs = Vec::new(); + for (shield, credits, difficulty, full) in [ + (75, 10000, 2, false), + (100, 0, 2, true), + (75, 10000, 0, false), + (75, 10000, 1, false), + (100, 0, 3, false), + ] { + runs.push(play(n, &mut active, shield, credits, difficulty, full)); + } + let repeated = play(n, &mut active, 75, 10000, 2, false); + assert_eq!( + runs[0]["step_digest_sha256"], + repeated["step_digest_sha256"] + ); + assert_eq!(runs[0]["digest"], repeated["digest"]); + let pending = pending_targets(n, &mut active); + reports.push(json!({"mission":n,"runs":runs,"exact_replay":true,"full20_plus4_reserves_preserved":true,"failed_attempt_restart_reset":true,"mandatory_targets_after_duration":pending,"visual_audio":visual,"pins":active.pins})); + } + let path = out.join(if only_art { + "visual-audio.json" + } else { + "acceptance.json" + }); + fs::write(&path, serde_json::to_vec_pretty(&reports).unwrap()).unwrap(); + println!("{}", path.display()); +} diff --git a/mods/iron_coast_stage2_boss_6/README.md b/mods/iron_coast_stage2_boss_6/README.md new file mode 100644 index 00000000..07116b2b --- /dev/null +++ b/mods/iron_coast_stage2_boss_6/README.md @@ -0,0 +1,51 @@ +# Emberwake — Black Tide boss 6 + +Independent local enemy mod `iron_coast_stage2_boss_6:unit`; no dependencies, no item +or mission overrides. Enable it alone in **Mods** for other content to spawn it. +It has no standalone mission; `iron_coast_stage2_mission_6` supplies its encounter. + +360 health at difficulties 2/3, 180 at 0/1; 7,500-credit actual-death reward. +Its logical canvas is 112×72, with a stable padded transparent +SD PNG and a 4× HD PNG. It is a ground battleship. +Both artwork modes use the same collision dimensions. It enters the y 24 band +and patrols horizontally at 1px/tick over x 88..112. +It remains until killed rather than scrolling or timing out. + +Each instance has its own serializable attack clock and actual starting-health +snapshot. The 96-tick cycle warns at age 44, +fires staggered outward left/right damage 3 shells at ages +60/72, then below half starting health adds +an aimed damage 4 center shot at age 84. Speeds are 4/3 respectively; +the center aim is bounded to ±2 horizontal velocity. One artwork frame is used; +the attack pattern and warning identify the phase. There is no native default +projectile or legacy movement. Projectiles reference original enemy-shell art. + +Only actual death increments `iron_coast_stage2_boss_6:defeated`, clears instance state +and plays the destruction cue. The boss never completes a mission, changes +inventory or awards a separate scripted credit bonus. Removed/dead units emit +no ghost shots. Simultaneous instances keep independent clocks; new spawns +remove stale clocks from a previous mission and reset reused IDs safely. + +[`provenance.json`](provenance.json) binds the genuine built-in image generation +request and untouched `sources/raw-v1.png`. Whole-canvas proportional fitting, +resampling and ordinary-palette SD conversion are the only sprite derivatives. +Original reference sheets remain external, recorded by path and hash. +[`tools/build_assets.py`](tools/build_assets.py) reproduces SD/HD art and the +original 22050Hz PCM16 warning, cannon and death cues. It reads only bundled +RustRaptor `data/misc/PALETTE_DAT`. No third-party recording was used. + +Validation from RustRaptor: + +```sh +cargo run --release --locked --no-default-features -- --data data --mods mods --validate-mods iron_coast_stage2_boss_6 +CARGO_TARGET_DIR=target cargo test --locked --manifest-path mods/iron_coast_stage2_boss_5/validation/Cargo.toml --lib +``` + +Four portable tests cover warning/attack order and command bounds, +serialized continuation and independent clocks, dead-unit guards, restart +flags and one-time mission bonuses, plus actual World boss persistence through +600 ticks, relative phase transitions at all four difficulties, genuine lethal +damage, one death reward/objective and 120 ticks without ghost fire. The local +real-catalog acceptance runner checks the complete associated mission, full +inventories and replays. Actual indexed SD/HD artwork and all three cues were +checked via Rust decoding/mixing; live aggregate-scene captures are separate. diff --git a/mods/iron_coast_stage2_boss_6/art-preview.png b/mods/iron_coast_stage2_boss_6/art-preview.png new file mode 100644 index 00000000..5501708d Binary files /dev/null and b/mods/iron_coast_stage2_boss_6/art-preview.png differ diff --git a/mods/iron_coast_stage2_boss_6/art-qa.json b/mods/iron_coast_stage2_boss_6/art-qa.json new file mode 100644 index 00000000..a9ca0fef --- /dev/null +++ b/mods/iron_coast_stage2_boss_6/art-qa.json @@ -0,0 +1,60 @@ +{ + "files": { + "unit-hd.png": { + "opaque_bounds": [ + 31, + 25, + 417, + 262 + ], + "sha256": "f9170e08b739393a0ee3fcb83f4564a44fa77d0e13ac4bc4abc1c9d95f70e378", + "size": [ + 448, + 288 + ], + "transparent_pixels": 70417 + }, + "unit-sd.png": { + "opaque_bounds": [ + 8, + 6, + 104, + 66 + ], + "sha256": "60238a9ed84282c758e934ddf9915a66d0b8315db6a86aa7dc5501bdf2813dbd", + "size": [ + 112, + 72 + ], + "transparent_pixels": 4400 + } + }, + "ordinary_palette": { + "ordinary_indices": [ + 0, + 239 + ], + "sha256": "1cf6adb926d1dee1888b3e3d33b51a7049b3e5eb5f90a3067ef71c8970547204", + "source": "PALETTE_DAT" + }, + "raw_sha256": "c16764c30d0ad17caf5a264c7c22207005761c4446afabc092b6446489d333ef", + "raw_size": [ + 1564, + 1006 + ], + "recipe": { + "frames": 1, + "hd_scale": 4, + "logical_canvas": [ + 112, + 72 + ], + "method": "Fit complete untouched RGBA master proportionally into fixed padded canvas; no silhouette crop, alpha removal or painted changes.", + "origin": [ + 0, + 0 + ] + }, + "recipe_sha256": "3482e6671b8d6ec63d0f8c1df15fd288ae5d9af8fab19f11f9932ea0837a4f77", + "visual_status": "Both generated masters and derivedSD/HD reviewed; actual Rust indexed SD/HD outputs inspected independently in isolated reference evidence. No live-scene/1080p claim." +} diff --git a/mods/iron_coast_stage2_boss_6/art/unit-hd.png b/mods/iron_coast_stage2_boss_6/art/unit-hd.png new file mode 100644 index 00000000..de35ee1e Binary files /dev/null and b/mods/iron_coast_stage2_boss_6/art/unit-hd.png differ diff --git a/mods/iron_coast_stage2_boss_6/art/unit-sd.png b/mods/iron_coast_stage2_boss_6/art/unit-sd.png new file mode 100644 index 00000000..7f7cb03d Binary files /dev/null and b/mods/iron_coast_stage2_boss_6/art/unit-sd.png differ diff --git a/mods/iron_coast_stage2_boss_6/audio-recipe.json b/mods/iron_coast_stage2_boss_6/audio-recipe.json new file mode 100644 index 00000000..44d3ccaf --- /dev/null +++ b/mods/iron_coast_stage2_boss_6/audio-recipe.json @@ -0,0 +1,50 @@ +{ + "files": { + "death": { + "bits": 16, + "channels": 1, + "duration_seconds": 0.9, + "file": "audio/death.wav", + "first_last_samples": [ + 0, + 0 + ], + "peak": 22282, + "rms": 3349.2885088320336, + "sample_rate": 22050, + "seed": 6102, + "sha256": "4de60da0935fe95e590d8552f86105bac18eacbdd403f8d4e116eb759a29a4ad" + }, + "shot": { + "bits": 16, + "channels": 1, + "duration_seconds": 0.19, + "file": "audio/shot.wav", + "first_last_samples": [ + 0, + 0 + ], + "peak": 22282, + "rms": 4079.843041899943, + "sample_rate": 22050, + "seed": 6101, + "sha256": "0dd2c70db82d4434a08601a96bc96e880fe1f6f1291ff68b30adbfb2353a211a" + }, + "warning": { + "bits": 16, + "channels": 1, + "duration_seconds": 0.28, + "file": "audio/warning.wav", + "first_last_samples": [ + 0, + 0 + ], + "peak": 22282, + "rms": 6785.139084846579, + "sample_rate": 22050, + "seed": 6100, + "sha256": "145f14873499614ee86bf08e4731053d9e29d90f9a65a6f49ed3a6c07cb1a6f6" + } + }, + "generator": "tools/build_assets.py deterministic sinusoidal chirps, seeded noise and faded envelopes; no recorded audio or third-party samples" +} diff --git a/mods/iron_coast_stage2_boss_6/audio/death.wav b/mods/iron_coast_stage2_boss_6/audio/death.wav new file mode 100644 index 00000000..bc817bc7 Binary files /dev/null and b/mods/iron_coast_stage2_boss_6/audio/death.wav differ diff --git a/mods/iron_coast_stage2_boss_6/audio/shot.wav b/mods/iron_coast_stage2_boss_6/audio/shot.wav new file mode 100644 index 00000000..a388dcc8 Binary files /dev/null and b/mods/iron_coast_stage2_boss_6/audio/shot.wav differ diff --git a/mods/iron_coast_stage2_boss_6/audio/warning.wav b/mods/iron_coast_stage2_boss_6/audio/warning.wav new file mode 100644 index 00000000..94567095 Binary files /dev/null and b/mods/iron_coast_stage2_boss_6/audio/warning.wav differ diff --git a/mods/iron_coast_stage2_boss_6/content.json b/mods/iron_coast_stage2_boss_6/content.json new file mode 100644 index 00000000..6a5788c7 --- /dev/null +++ b/mods/iron_coast_stage2_boss_6/content.json @@ -0,0 +1,76 @@ +{ + "weapons": [ + { + "id": "iron_coast_stage2_boss_6:shell", + "name": "Emberwake heavy cannon", + "damage": 3, + "speed": 4, + "cooldown": 96, + "behavior": "straight", + "target": "all", + "art": { + "asset": 66006, + "logical_width": 8, + "logical_height": 8, + "frames": 2 + } + }, + { + "id": "iron_coast_stage2_boss_6:core", + "name": "Emberwake center cannon", + "damage": 4, + "speed": 3, + "cooldown": 96, + "behavior": "straight", + "target": "all", + "art": { + "asset": 66006, + "logical_width": 8, + "logical_height": 8, + "frames": 2 + } + } + ], + "enemies": [ + { + "id": "iron_coast_stage2_boss_6:unit", + "name": "Emberwake", + "health": 360, + "speed": 0, + "reward": 7500, + "ground": true, + "boss": true, + "cooldown": 96, + "art": { + "png": "art/unit-sd.png", + "hd_png": "art/unit-hd.png", + "logical_width": 112, + "logical_height": 72 + }, + "script": "scripts/ai.rhai" + } + ], + "sounds": [ + { + "id": "iron_coast_stage2_boss_6:warning", + "name": "Emberwake warning", + "file": "audio/warning.wav", + "volume": 76, + "priority": 3 + }, + { + "id": "iron_coast_stage2_boss_6:shot", + "name": "Emberwake shot", + "file": "audio/shot.wav", + "volume": 88, + "priority": 3 + }, + { + "id": "iron_coast_stage2_boss_6:death", + "name": "Emberwake death", + "file": "audio/death.wav", + "volume": 110, + "priority": 2 + } + ] +} diff --git a/mods/iron_coast_stage2_boss_6/mod.toml b/mods/iron_coast_stage2_boss_6/mod.toml new file mode 100644 index 00000000..512f9b39 --- /dev/null +++ b/mods/iron_coast_stage2_boss_6/mod.toml @@ -0,0 +1,7 @@ +id = "iron_coast_stage2_boss_6" +name = "Black Tide — Emberwake" +version = "1.0.0" +api_version = 1 +description = "Independent armored repair-dock battleship with persistent patrol, telegraphed volleys and generated SD/HD artwork." +content = "content.json" +scripts = ["scripts/ai.rhai"] diff --git a/mods/iron_coast_stage2_boss_6/prompts/request-v1.json b/mods/iron_coast_stage2_boss_6/prompts/request-v1.json new file mode 100644 index 00000000..9cfba96c --- /dev/null +++ b/mods/iron_coast_stage2_boss_6/prompts/request-v1.json @@ -0,0 +1,8 @@ +{ + "prompt": "Use case: stylized-concept\nAsset type: new transparent top-down Raptor-compatible boss sprite, Emberwake heavy armored repair-dock battleship.\nInput images: original Raptor metallic boss sprites are style references only, not edit targets. Match original top-down orthographic military metal and the small-sprite readability.\nSubject: a broad rectangular floating armored industrial battleship, bow facing downward, with a thick central keel, four heavy turret housings, paired steel repair gantries along its flanks, raised heat-shield plates and two tiny amber foundry ports. Slate dark steel, pale gunmetal bevels, restrained rusty copper and a few orange furnace glints. Clearly a steel dock ship rather than an aircraft.\nComposition: ONE full battleship on an entirely transparent landscape canvas. Exact top-down overhead with zero perspective tilt, centered on a native logical canvas 112 by 72; keep safe alpha padding all edges. Symmetric naval hull with distinguishable bow/stern and crisp readable armor. No water, outside shadow, dock scenery, smoke/exhaust, projectiles, lettering or checkerboard. Original-game inspired material detail and upper-left overhead lighting; occupied near-black hull remains opaque. Fine HD panel work with an old-game legible silhouette.\n", + "referenced_image_paths": [ + "/home/quintine/Projects/RaptorReplica/data/hd/jobs/bosses-10310-10310/source-sheet.png", + "/home/quintine/Projects/RaptorReplica/data/hd/jobs/bosses-200ad-200ad/source-sheet.png" + ], + "transparent_background": true +} diff --git a/mods/iron_coast_stage2_boss_6/prompts/v1.txt b/mods/iron_coast_stage2_boss_6/prompts/v1.txt new file mode 100644 index 00000000..88c0695d --- /dev/null +++ b/mods/iron_coast_stage2_boss_6/prompts/v1.txt @@ -0,0 +1,5 @@ +Use case: stylized-concept +Asset type: new transparent top-down Raptor-compatible boss sprite, Emberwake heavy armored repair-dock battleship. +Input images: original Raptor metallic boss sprites are style references only, not edit targets. Match original top-down orthographic military metal and the small-sprite readability. +Subject: a broad rectangular floating armored industrial battleship, bow facing downward, with a thick central keel, four heavy turret housings, paired steel repair gantries along its flanks, raised heat-shield plates and two tiny amber foundry ports. Slate dark steel, pale gunmetal bevels, restrained rusty copper and a few orange furnace glints. Clearly a steel dock ship rather than an aircraft. +Composition: ONE full battleship on an entirely transparent landscape canvas. Exact top-down overhead with zero perspective tilt, centered on a native logical canvas 112 by 72; keep safe alpha padding all edges. Symmetric naval hull with distinguishable bow/stern and crisp readable armor. No water, outside shadow, dock scenery, smoke/exhaust, projectiles, lettering or checkerboard. Original-game inspired material detail and upper-left overhead lighting; occupied near-black hull remains opaque. Fine HD panel work with an old-game legible silhouette. diff --git a/mods/iron_coast_stage2_boss_6/provenance.json b/mods/iron_coast_stage2_boss_6/provenance.json new file mode 100644 index 00000000..935396c0 --- /dev/null +++ b/mods/iron_coast_stage2_boss_6/provenance.json @@ -0,0 +1,20 @@ +{ + "begun_utc": "2026-10-11 08:10:17 UTC", + "ended_utc": "2026-10-11 08:10:54 UTC", + "gate_lease": "e528bac8-9503-4e1a-9bf4-34d6f3678430", + "generator_raw": "/home/quintine/.codex/generated_images/01a1245d-ddd6-7c41-8bab-0a08c2b68f4d/exec-0f6c9b92-ddb7-4a84-81a1-5ec8a6b87e05.png", + "mode": "built-in", + "notes": "External original Raptor sheets are style references only.", + "outcome": "success", + "prompt": "prompts/v1.txt", + "prompt_sha256": "6154542b8dc73cdc9dc26b9f27dee4c30ecb8b371fae2c6c02212c073e21eca9", + "raw_copy": "sources/raw-v1.png", + "raw_sha256": "c16764c30d0ad17caf5a264c7c22207005761c4446afabc092b6446489d333ef", + "reference_hashes": { + "/home/quintine/Projects/RaptorReplica/data/hd/jobs/bosses-10310-10310/source-sheet.png": "f3135c73dc38faae087115f122e62417b845d01260586c5ff35d78dea3b68608", + "/home/quintine/Projects/RaptorReplica/data/hd/jobs/bosses-200ad-200ad/source-sheet.png": "29a4f33e50f25d866f692dad8751f9eaa90a9c87bf2bad2527ba5249f0b3663f" + }, + "request": "prompts/request-v1.json", + "tool": "image_gen.imagegen", + "transparent_background": true +} diff --git a/mods/iron_coast_stage2_boss_6/scripts/ai.rhai b/mods/iron_coast_stage2_boss_6/scripts/ai.rhai new file mode 100644 index 00000000..9ae23e46 --- /dev/null +++ b/mods/iron_coast_stage2_boss_6/scripts/ai.rhai @@ -0,0 +1,57 @@ +// Each real instance has a bounded serializable clock. No native/legacy behavior. +fn alive(event) { + for e in event.entities { if e.entity == event.entity && e.health > 0 { return true; } } + false +} +fn on_spawn(event, state, random) { + if !alive(event) { return #{commands:[],state:state}; } + let retained = #{}; + // Discard entries from earlier failed/replayed missions; preserve simultaneous instances. + if state.contains("units") { + for e in event.entities { + let key = e.entity.to_string(); + if e.definition == "iron_coast_stage2_boss_6:unit" && state.units.contains(key) { retained[key] = state.units[key]; } + } + } + state.units = retained; + let max_health = 1; + for e in event.entities { if e.entity == event.entity { max_health = e.health; } } + state.units[event.entity.to_string()] = #{age:0,direction:1,max_health:max_health}; + #{commands:[#{op:"velocity",entity:event.entity,vx:0,vy:2}],state:state} +} +fn on_tick(event, state, random) { + if event.health <= 0 || !alive(event) { return #{commands:[],state:state}; } + let key = event.entity.to_string(); + if !state.contains("units") { state.units = #{}; } + if !state.units.contains(key) { state.units[key] = #{age:0,direction:1,max_health:event.health}; } + let u = state.units[key]; + if !u.contains("max_health") { u.max_health = event.health; } + if event.y < 24 { return #{commands:[#{op:"velocity",entity:event.entity,vx:0,vy:2}],state:state}; } + u.age += 1; + if event.x >= 112 { u.direction = -1; } + if event.x <= 88 { u.direction = 1; } + let commands = [#{op:"move",entity:event.entity,x:event.x,y:24},#{op:"velocity",entity:event.entity,vx:u.direction,vy:0}]; + let phase = u.age % 96; + if phase == 44 { commands.push(#{op:"play_sound",sound:"iron_coast_stage2_boss_6:warning"}); } + if phase == 60 { + commands.push(#{op:"projectile",weapon:"iron_coast_stage2_boss_6:shell",x:event.x+28,y:event.y+64,vx:-1,vy:4,hostile:true}); + commands.push(#{op:"play_sound",sound:"iron_coast_stage2_boss_6:shot"}); + } + if phase == 72 { + commands.push(#{op:"projectile",weapon:"iron_coast_stage2_boss_6:shell",x:event.x+80,y:event.y+64,vx:1,vy:4,hostile:true}); + commands.push(#{op:"play_sound",sound:"iron_coast_stage2_boss_6:shot"}); + } + if phase == 84 && event.health <= u.max_health / 2 { + let aim = (event.player_x - event.x - 40) / 48; + let vx = if aim < -2 { -2 } else if aim > 2 { 2 } else { aim }; + commands.push(#{op:"projectile",weapon:"iron_coast_stage2_boss_6:core",x:event.x+52,y:event.y+64,vx:vx,vy:3,hostile:true}); + commands.push(#{op:"play_sound",sound:"iron_coast_stage2_boss_6:shot"}); + } + state.units[key] = u; + #{commands:commands,state:state} +} +fn on_death(event, state, random) { + if state.contains("units") { state.units.remove(event.entity.to_string()); } + let n = if event.objectives.contains("iron_coast_stage2_boss_6:defeated") { event.objectives["iron_coast_stage2_boss_6:defeated"] + 1 } else { 1 }; + #{commands:[#{op:"objective",key:"iron_coast_stage2_boss_6:defeated",value:n},#{op:"effect",x:event.x+28,y:event.y+40},#{op:"effect",x:event.x+80,y:event.y+40},#{op:"play_sound",sound:"iron_coast_stage2_boss_6:death"}],state:state} +} diff --git a/mods/iron_coast_stage2_boss_6/sources/raw-v1.png b/mods/iron_coast_stage2_boss_6/sources/raw-v1.png new file mode 100644 index 00000000..272838af Binary files /dev/null and b/mods/iron_coast_stage2_boss_6/sources/raw-v1.png differ diff --git a/mods/iron_coast_stage2_boss_6/tools/build_assets.py b/mods/iron_coast_stage2_boss_6/tools/build_assets.py new file mode 100644 index 00000000..56f6f52e --- /dev/null +++ b/mods/iron_coast_stage2_boss_6/tools/build_assets.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python3 +"""Prepare game assets from unchanged generated masters and synthesize PCM cues. + +Requires Pillow. Original Raptor reference images stay external. The original +palette is read only for ordinary-color SD quantization; final assets are local. +No generated RGB is retouched: whole-canvas proportional fit, resampling, +cropping into tiles and reflected terrain repetition are explicit derivatives. +""" +from pathlib import Path +import json,hashlib,math,random,struct,wave +from PIL import Image,ImageOps,ImageDraw +ROOT=Path(__file__).resolve().parent.parent +NUMBER=int(ROOT.name.rsplit('_',1)[1]);IS_BOSS='_boss_'in ROOT.name +sha=lambda p:hashlib.sha256(p.read_bytes()).hexdigest() +write=lambda p,j:p.write_text(json.dumps(j,indent=2,sort_keys=True)+'\n') + +def palette(): + path=ROOT.parents[1]/'data/misc/PALETTE_DAT' + b=path.read_bytes();assert len(b)==768 + rgb=[(min(v,63)<<2)|(min(v,63)>>4)for v in b[:720]] + image=Image.new('P',(1,1));image.putpalette(rgb+[0]*48) + return image,{'source':'PALETTE_DAT','sha256':sha(path),'ordinary_indices':[0,239]} + +def sd_quantize(image,pal): + a=image.getchannel('A')if image.mode=='RGBA'else None + # Duplicate palette0 in unused slots so quantization cannot create a reserved class. + pal=pal.copy();p=pal.getpalette();p[720:768]=p[:3]*16;pal.putpalette(p) + q=image.convert('RGB').quantize(palette=pal,dither=Image.Dither.NONE).convert('RGBA') + if a is not None:q.putalpha(a) + return q + +def artwork(): + raw=ROOT/'sources/raw-v1.png';source=Image.open(raw).convert('RGBA');pal,binding=palette();files={} + def save(name,img): + p=ROOT/'art'/name;img.save(p);alpha=img.getchannel('A');mask=alpha.point(lambda a:255 if a>=128 else 0) + files[name]={'size':list(img.size),'sha256':sha(p),'opaque_bounds':list(mask.getbbox())if mask.getbbox()else None,'transparent_pixels':sum(a<128 for a in alpha.get_flattened_data())} + if IS_BOSS: + logical=(112,56 if NUMBER==5 else 72);target=tuple(v*4 for v in logical) + assert source.getchannel('A').getextrema()[0]==0 and source.getchannel('A').getextrema()[1]>=128,'Real generated alpha required' + fit=ImageOps.contain(source,(target[0]-32,target[1]-32),Image.Resampling.LANCZOS) + hd=Image.new('RGBA',target,(0,0,0,0));hd.alpha_composite(fit,((target[0]-fit.width)//2,(target[1]-fit.height)//2)) + sd=sd_quantize(hd.resize(logical,Image.Resampling.LANCZOS),pal) + save('unit-hd.png',hd);save('unit-sd.png',sd) + for name in ['unit-hd.png','unit-sd.png']: + bounds=files[name]['opaque_bounds'];size=files[name]['size'];assert bounds and min(bounds[:2])>=2 and bounds[2] 0 { return true; } } + false +} +fn on_spawn(event,state,random) { + // A new spawn is a fresh lifecycle even when killed before dispatch. + if state.contains("last_death") && state.last_death == event.entity { state.remove("last_death"); } + if !alive(event) { return #{commands:[],state:state}; } + if !state.contains("units") { state.units = #{}; } + // Prune cursors from aborted/restarted worlds; retain simultaneous live carriers. + let live = #{}; + for unit in event.entities { if unit.definition == "iron_coast_stage2_boss_7:unit" { live[unit.entity.to_string()] = true; } } + for old in state.units.keys() { if !live.contains(old) { state.units.remove(old); } } + let spawn_health = 1; + for unit in event.entities { if unit.entity == event.entity { spawn_health = unit.health; } } + state.units[event.entity.to_string()] = #{age:0,volley:0,direction:1,phase:0,max_health:spawn_health}; + #{commands:[#{op:"velocity",entity:event.entity,vx:0,vy:2},#{op:"animation",entity:event.entity,frame:0}],state:state} +} +fn on_tick(event,state,random) { + if event.health <= 0 || !alive(event) { return #{commands:[],state:state}; } + let key = event.entity.to_string(); + if !state.contains("units") { state.units = #{}; } + let cursor = if state.units.contains(key) { state.units[key] } else { #{age:0,volley:0,direction:1,phase:0,max_health:event.health} }; + if event.y < 16 { + state.units[key] = cursor; + return #{commands:[#{op:"velocity",entity:event.entity,vx:0,vy:2}],state:state}; + } + let phase = if event.health * 2 <= cursor.max_health { 1 } else { 0 }; + let commands = [#{op:"move",entity:event.entity,x:event.x,y:16}]; + if event.x >= 116 { cursor.direction = -1; } + if event.x <= 60 { cursor.direction = 1; } + commands.push(#{op:"velocity",entity:event.entity,vx:cursor.direction,vy:0}); + if phase != cursor.phase { + cursor.phase = phase; + cursor.age = 0; + commands.push(#{op:"animation",entity:event.entity,frame:phase}); + commands.push(#{op:"objective",key:"iron_coast_stage2_boss_7:phase",value:phase+1}); + commands.push(#{op:"play_sound",sound:"iron_coast_stage2_boss_7:phase"}); + } + cursor.age += 1; + let period = if phase == 0 { 84 } else { 66 }; + let warning = 14; + if cursor.age % period == period-warning { + commands.push(#{op:"play_sound",sound:"iron_coast_stage2_boss_7:warning"}); + commands.push(#{op:"objective",key:"iron_coast_stage2_boss_7:safe_lane",value:cursor.volley % 2 + 1}); + let side = if cursor.volley % 2 == 0 { 12 } else { 76 }; + commands.push(#{op:"arc",x:event.x+side,y:16+88-10,to_x:event.x+side+24,to_y:16+88-10,ticks:8,anchor:event.entity,to_anchor:event.entity}); + } + if cursor.age % period == 0 { + // Fire one broadside at a time. The opposite half remains open. + let side = if cursor.volley % 2 == 0 { 12 } else { 76 }; + for i in 0..3 { + commands.push(#{op:"projectile",weapon:"iron_coast_stage2_boss_7:shell",x:event.x+side+i*10,y:16+88-8,vx:0,vy:3,hostile:true}); + } + // Below half health, outward diagonal flank shells still leave the middle + // and inactive broadside open; no aimed unavoidable point-blank projectile. + if phase == 1 { + commands.push(#{op:"projectile",weapon:"iron_coast_stage2_boss_7:shell",x:event.x+12,y:16+88-8,vx:-2,vy:3,hostile:true}); + commands.push(#{op:"projectile",weapon:"iron_coast_stage2_boss_7:shell",x:event.x+96,y:16+88-8,vx:2,vy:3,hostile:true}); + } + commands.push(#{op:"play_sound",sound:"iron_coast_stage2_boss_7:shot"}); + cursor.volley += 1; + } + state.units[key] = cursor; + #{commands:commands,state:state} +} +fn on_hit(event,state,random) { #{commands:[],state:state} } +fn on_death(event,state,random) { + if state.contains("last_death") && state.last_death == event.entity { return #{commands:[],state:state}; } + state.last_death = event.entity; + if state.contains("units") { state.units.remove(event.entity.to_string()); } + let count = if event.objectives.contains("iron_coast_stage2_boss_7:defeated") { event.objectives["iron_coast_stage2_boss_7:defeated"]+1 } else { 1 }; + #{commands:[#{op:"objective",key:"iron_coast_stage2_boss_7:defeated",value:count}, + #{op:"effect",x:event.x+28,y:event.y+88/2},#{op:"effect",x:event.x+84,y:event.y+88/2}, + #{op:"play_sound",sound:"iron_coast_stage2_boss_7:death"}],state:state} +} diff --git a/mods/iron_coast_stage2_boss_7/validation-summary.json b/mods/iron_coast_stage2_boss_7/validation-summary.json new file mode 100644 index 00000000..59eb803f --- /dev/null +++ b/mods/iron_coast_stage2_boss_7/validation-summary.json @@ -0,0 +1,192 @@ +{ + "status": "Author production acceptance passed; independent campaign/SD-HD Host review handled separately", + "package": "iron_coast_stage2_boss_7", + "version": "1.0.0", + "api_version": 1, + "actual_original_catalog": true, + "starter_fire_only": true, + "normal_movement_limit_pixels_per_tick": 4, + "near_shot_sidesteps": { + "hostile_y": [ + 136, + 188 + ], + "horizontal_distance_from_player_center": 24 + }, + "runs": [ + { + "boss_only": true, + "classic_ids": [], + "credits": 15000, + "difficulty": 0, + "digest": "e5aca1589b55c31281dfc382ec0d5f9fb01a4f7a24b6975dc8a97fe6e9175fdd", + "initial_credits": 10000, + "initial_shield": 75, + "inventory_preserved": true, + "inventory_slots": 2, + "maximum_live_enemies": 1, + "mission": 7, + "native_movement_ids": [], + "objectives": { + "iron_coast_stage2_boss_7:defeated": 1, + "iron_coast_stage2_boss_7:phase": 2, + "iron_coast_stage2_boss_7:safe_lane": 1 + }, + "outcome": "Playing", + "phase_frames": [ + 0, + 1 + ], + "rewards_once": true, + "shield": 75, + "sound_ids": [ + "iron_coast_stage2_boss_7:death", + "iron_coast_stage2_boss_7:phase", + "iron_coast_stage2_boss_7:shot", + "iron_coast_stage2_boss_7:warning" + ], + "tick": 147 + }, + { + "boss_only": true, + "classic_ids": [], + "credits": 15000, + "difficulty": 1, + "digest": "9de49462e7a59a0cbcfbd46afc24ddd42f608bbfc7b07f3d2466d45acdb5e30e", + "initial_credits": 10000, + "initial_shield": 75, + "inventory_preserved": true, + "inventory_slots": 2, + "maximum_live_enemies": 1, + "mission": 7, + "native_movement_ids": [], + "objectives": { + "iron_coast_stage2_boss_7:defeated": 1, + "iron_coast_stage2_boss_7:phase": 2, + "iron_coast_stage2_boss_7:safe_lane": 1 + }, + "outcome": "Playing", + "phase_frames": [ + 0, + 1 + ], + "rewards_once": true, + "shield": 75, + "sound_ids": [ + "iron_coast_stage2_boss_7:death", + "iron_coast_stage2_boss_7:phase", + "iron_coast_stage2_boss_7:shot", + "iron_coast_stage2_boss_7:warning" + ], + "tick": 147 + }, + { + "boss_only": true, + "classic_ids": [], + "credits": 15000, + "difficulty": 2, + "digest": "21d9b8ec00afa0244f781cb6c5c5568d9652f188200c29d7c09235993e323ebe", + "initial_credits": 10000, + "initial_shield": 75, + "inventory_preserved": true, + "inventory_slots": 2, + "maximum_live_enemies": 1, + "mission": 7, + "native_movement_ids": [], + "objectives": { + "iron_coast_stage2_boss_7:defeated": 1, + "iron_coast_stage2_boss_7:phase": 2, + "iron_coast_stage2_boss_7:safe_lane": 1 + }, + "outcome": "Playing", + "phase_frames": [ + 0, + 1 + ], + "rewards_once": true, + "shield": 75, + "sound_ids": [ + "iron_coast_stage2_boss_7:death", + "iron_coast_stage2_boss_7:phase", + "iron_coast_stage2_boss_7:shot", + "iron_coast_stage2_boss_7:warning" + ], + "tick": 287 + }, + { + "boss_only": true, + "classic_ids": [], + "credits": 15000, + "difficulty": 3, + "digest": "88904874de5850d9fa7be6741d13883e788bd26ff2b50aaf1e86aa9666987cc3", + "initial_credits": 10000, + "initial_shield": 75, + "inventory_preserved": true, + "inventory_slots": 2, + "maximum_live_enemies": 1, + "mission": 7, + "native_movement_ids": [], + "objectives": { + "iron_coast_stage2_boss_7:defeated": 1, + "iron_coast_stage2_boss_7:phase": 2, + "iron_coast_stage2_boss_7:safe_lane": 1 + }, + "outcome": "Playing", + "phase_frames": [ + 0, + 1 + ], + "rewards_once": true, + "shield": 75, + "sound_ids": [ + "iron_coast_stage2_boss_7:death", + "iron_coast_stage2_boss_7:phase", + "iron_coast_stage2_boss_7:shot", + "iron_coast_stage2_boss_7:warning" + ], + "tick": 287 + } + ], + "actual_production_mixer": [ + { + "actual_mixer_peak": 5888, + "actual_mixer_rms": 690.400834298453, + "muted_exact_zero": true, + "sound": "iron_coast_stage2_boss_7:death" + }, + { + "actual_mixer_peak": 6016, + "actual_mixer_rms": 1565.0945326081744, + "muted_exact_zero": true, + "sound": "iron_coast_stage2_boss_7:phase" + }, + { + "actual_mixer_peak": 5504, + "actual_mixer_rms": 312.4530044662717, + "muted_exact_zero": true, + "sound": "iron_coast_stage2_boss_7:shot" + }, + { + "actual_mixer_peak": 4864, + "actual_mixer_rms": 955.2234502984105, + "muted_exact_zero": true, + "sound": "iron_coast_stage2_boss_7:warning" + } + ], + "actual_mixer_cues_unclipped": true, + "actual_mute_exact_zero": true, + "per_entity_phase_isolation": true, + "actual_world_repeated_spawn_step_lethal_with_retained_state": true, + "death_and_rewards_once": true, + "PNG_source_and_output_dimensions_checked": true, + "external_proof_hashes": { + "validation-results.json": "d063d101d9e1d5cf1cb94240caba3ddef04b5183def5b6625ebe32d92951b28d", + "boss-validation-results.json": "ef20464533b00c35f63c1add0d3149dc9da341ec580f3221e389a62230143e0a", + "actual-audio-proof.json": "293e8f37a5e0ae776d6b0369207dc80f2e38b52c0c903de412bba9b4fbfc60d4", + "actual-mixer-all-cues.wav": "af00e983a61e1c26e1504a818fa524b31528fa8f44211cc6969bbc0f6e430124", + "asset-validation.json": "7a30c3aaf365a8ac16c97c1b519d93ca39f1723c96b1fac5f93fa88f7757a1f7", + "boss-art-contact.png": "444de75e4c171ddac84e2ae6f3f206e749e1fdc3a59d406aa4c66f7678519aa7", + "terrain-briefing-contact.png": "254895a2296d6972f9fa4132e21d95979b149be960600507633f44847398eb3b" + }, + "reference_visibility_limits": "Art contact sheets are author visual inspection. Sound proof uses actual mixer without a liveSDL occurrence claim. Root/independent Host screenshots bind final gameplay presentation separately." +} diff --git a/mods/iron_coast_stage2_boss_8/README.md b/mods/iron_coast_stage2_boss_8/README.md new file mode 100644 index 00000000..045b7c48 --- /dev/null +++ b/mods/iron_coast_stage2_boss_8/README.md @@ -0,0 +1,18 @@ +# Iron Coast II: Leviathan + +Separate API 1/version 1.0.0 boss mod, with no dependencies or overrides. + +- Enemy: `iron_coast_stage2_boss_8:unit`, health 360, reward 9000 credits (difficulty applies the normal engine health rules). +- Actual death objective: `iron_coast_stage2_boss_8:defeated`. Escape/despawn grants nothing. +- Persistent patrol is confined to x 60–116, y 4, so the complete carrier stays reachable. +- Three phases: closed reactor, open amber reactor below two-thirds health, red warning strips and blue ion coils below one-third. The first fan leaves the center open; later attacks rotate a full 32-pixel safe lane and add outward flanks in the final act. +- Every volley has an audible warning 18 simulation ticks ahead and cosmetic arcs at attacking pods. Shots travel 3 pixels/tick; no aiming at the player's instantaneous position, no contact explosion at the muzzle. +- Logical art 112×112, 3 phase frames; HD 4×; shell 6×12. Collision dimensions stay identical in SD/HD. + +Per-entity cursors isolate simultaneous bosses. Spawn callbacks reset reused IDs; actual deaths retire only that cursor and increment the public death counter once. `animation` pins a declared frame; phase state remains serializable. + +`art/generated-v1.png` is the untouched builtin output. Prompt and provenance bind the exact generator/reference hashes. The companion mission 8 `build_finale_assets.py` performs complete meaningful-alpha crops and proportional fits, then SD reduction; it also reproduces the seeded 22.05 kHz mono 16-bit warning/phase/shot/death WAVs. It does not repaint or stretch sprites. Reference/catalog images and gameplay screenshots remain outside the package. + +Acceptance source: `../iron_coast_stage2_mission_8/validation/`; standalone boss runs and both full sorties use the actual Catalog/World/Rhai and starter guns. Durable simulation/SD-HD captures are external review evidence; final metrics are copied into `validation-summary.json` after balance is frozen. + +Actual starter boss-only runs from 75 shield: 186 ticks at difficulties 0/1 and 366 at 2/3; 75/67 shield remains. Retained-state spawn-step lethal replays use the actual World and verify the counter and reward once on each new lifecycle. diff --git a/mods/iron_coast_stage2_boss_8/art-qa.json b/mods/iron_coast_stage2_boss_8/art-qa.json new file mode 100644 index 00000000..1b668770 --- /dev/null +++ b/mods/iron_coast_stage2_boss_8/art-qa.json @@ -0,0 +1,127 @@ +{ + "pipeline": "Complete meaningful-alpha cell crop with proportional fit; transparent centered padding; BOX SD reduction; no repaint", + "logical_size": [ + 112, + 112 + ], + "frames": 3, + "hd_scale": 4, + "origin": [ + 0, + 0 + ], + "crops": [ + { + "frame": 0, + "cell": [ + 0, + 0, + 512, + 768 + ], + "alpha16_crop": [ + 6, + 68, + 511, + 610 + ], + "source_occupied_bounds": [ + 9, + 70, + 508, + 607 + ], + "fit_size": [ + 395, + 424 + ] + }, + { + "frame": 1, + "cell": [ + 512, + 0, + 1024, + 768 + ], + "alpha16_crop": [ + 3, + 68, + 510, + 610 + ], + "source_occupied_bounds": [ + 6, + 71, + 506, + 607 + ], + "fit_size": [ + 397, + 424 + ] + }, + { + "frame": 2, + "cell": [ + 1024, + 0, + 1536, + 768 + ], + "alpha16_crop": [ + 0, + 67, + 507, + 610 + ], + "source_occupied_bounds": [ + 4, + 70, + 504, + 607 + ], + "fit_size": [ + 396, + 424 + ] + } + ], + "projectile_crop_in_lower_cell": [ + 744, + 38, + 792, + 163 + ], + "files": { + "art/unit-sd.png": { + "size": [ + 336, + 112 + ], + "sha256": "1bcd1672ede1667668234600f3528665da2704b4ccb90f1a04fa74e255432ecf" + }, + "art/unit-hd.png": { + "size": [ + 1344, + 448 + ], + "sha256": "c2fc5ceab44b869af905ef6bf35f292a2f0fc09808a849f8b298970390800858" + }, + "art/projectile-sd.png": { + "size": [ + 6, + 12 + ], + "sha256": "36b0259a2840865be4011cf31a82c3817483b849a36a9a7d72d1644317b82b81" + }, + "art/projectile-hd.png": { + "size": [ + 24, + 48 + ], + "sha256": "fcc6d3a532e1b2d62be6a5d18905cd08dd35f4f08e29040cf224942c2dc4509a" + } + }, + "phase_alignment": "Common centered logical canvas; collision bounds identical for every displayed phase" +} diff --git a/mods/iron_coast_stage2_boss_8/art/generated-v1.png b/mods/iron_coast_stage2_boss_8/art/generated-v1.png new file mode 100644 index 00000000..6df4973d Binary files /dev/null and b/mods/iron_coast_stage2_boss_8/art/generated-v1.png differ diff --git a/mods/iron_coast_stage2_boss_8/art/projectile-hd.png b/mods/iron_coast_stage2_boss_8/art/projectile-hd.png new file mode 100644 index 00000000..e4f784a5 Binary files /dev/null and b/mods/iron_coast_stage2_boss_8/art/projectile-hd.png differ diff --git a/mods/iron_coast_stage2_boss_8/art/projectile-sd.png b/mods/iron_coast_stage2_boss_8/art/projectile-sd.png new file mode 100644 index 00000000..b2fcdde4 Binary files /dev/null and b/mods/iron_coast_stage2_boss_8/art/projectile-sd.png differ diff --git a/mods/iron_coast_stage2_boss_8/art/prompt-v1.txt b/mods/iron_coast_stage2_boss_8/art/prompt-v1.txt new file mode 100644 index 00000000..34b6af64 --- /dev/null +++ b/mods/iron_coast_stage2_boss_8/art/prompt-v1.txt @@ -0,0 +1,2 @@ +Create a production game sprite sheet for LEVIATHAN, the final massive command carrier in Iron Coast II, a faithful HD Raptor: Call of the Shadows expansion. Attached original Raptor sprites are style references only. A uniquely recognizable enormous broad manta-shaped offshore command carrier, viewed strictly TOP DOWN orthographically, nose up, width:height near 9:5. Slate-black armor, muted titanium ribs, twin rear turbine housings, angular command spine, two broad triangular flight decks, RED bridge stripe and restrained amber lights, visible deep round central reactor well. Distinct from a rectangle or ordinary plane. Sharp carefully painted fine metal, neutral overhead illumination, dark military color palette, no background shadow, no perspective, no text or UI. +Transparent landscape sprite sheet 1536x1024: UPPER 75 percent is THREE equal side-by-side cells. All three are the EXACT same complete carrier outline, position and size with clear margin. LEFT phase 1 armored reactor shutters closed. MIDDLE phase 2 shutters open revealing restrained amber reactor coil and opened side cannons. RIGHT phase 3 red-orange warning strips illuminated and twin blue ion coils active, armor still same intact silhouette; no explosion or missing hull. Align hull edges, rear engines and center spine across three. LOWER 25 percent contains only ONE small cold cyan ion shell pointing down centered with ample transparent margins, for hostile shots. No other objects. All backgrounds genuinely transparent alpha. No grid outlines, labels, checkerboard or frame borders. diff --git a/mods/iron_coast_stage2_boss_8/art/provenance.json b/mods/iron_coast_stage2_boss_8/art/provenance.json new file mode 100644 index 00000000..5114cc88 --- /dev/null +++ b/mods/iron_coast_stage2_boss_8/art/provenance.json @@ -0,0 +1,26 @@ +{ + "generator": "OpenAI builtin imagegen; exact untouched PNGs preserved", + "utc": "2026-10-11", + "raws": [ + { + "version": 1, + "builtin_file": "/home/quintine/.codex/generated_images/01a1245e-048c-7e92-91d2-78de2e5900ab/exec-34a0f83d-4b85-46ed-b927-6681a113ed09.png", + "builtin_sha256": "e26622220f838f9872786a1d027d0c7f80e18990b1db80c13bfccc6f96839a5c", + "raw_file": "art/generated-v1.png", + "raw_sha256": "e26622220f838f9872786a1d027d0c7f80e18990b1db80c13bfccc6f96839a5c", + "prompt_file": "art/prompt-v1.txt", + "prompt_sha256": "0f580c3ea5a5d95f62144c615e800ed2ec581f935de2175a1c11742e5d9d72b8", + "reference_file": "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-stage2-finale/classic-reference.png", + "reference_sha256": "f093d720ff149c9f12bd12cc7e99e6123386bb5ce767c2676fcdf7a067c121d1", + "builtin_identity_verified": true, + "transparent_requested": true, + "rejected": false, + "gate_owner": "/root/iron_coast_6", + "gate_job": "stage2-leviathan-v1", + "gate_lease": "e5eae8a4-174b-43e7-9b11-c9fadf457ebf", + "gate_outcome": "success" + } + ], + "original_references": "External authentic catalog board; no decoded original reference pixels included in this package", + "historical_hold": null +} diff --git a/mods/iron_coast_stage2_boss_8/art/unit-hd.png b/mods/iron_coast_stage2_boss_8/art/unit-hd.png new file mode 100644 index 00000000..c8ac250c Binary files /dev/null and b/mods/iron_coast_stage2_boss_8/art/unit-hd.png differ diff --git a/mods/iron_coast_stage2_boss_8/art/unit-sd.png b/mods/iron_coast_stage2_boss_8/art/unit-sd.png new file mode 100644 index 00000000..04bbbc7e Binary files /dev/null and b/mods/iron_coast_stage2_boss_8/art/unit-sd.png differ diff --git a/mods/iron_coast_stage2_boss_8/audio-recipe.json b/mods/iron_coast_stage2_boss_8/audio-recipe.json new file mode 100644 index 00000000..0a6082e2 --- /dev/null +++ b/mods/iron_coast_stage2_boss_8/audio-recipe.json @@ -0,0 +1,49 @@ +{ + "generator": "build_finale_assets.py deterministic chirp/noise PCM synthesis; no recordings", + "files": { + "warning": { + "file": "audio/warning.wav", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "seconds": 0.32, + "seed": 8000, + "peak": 23592, + "rms": 11632.128475655247, + "sha256": "9b33b0ee424b6f6c852353911f50d854c58ce9d66611950e13096285317af84a" + }, + "phase": { + "file": "audio/phase.wav", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "seconds": 0.5500226757369614, + "seed": 8001, + "peak": 23592, + "rms": 11946.01845529649, + "sha256": "cfc6be3cb81064338dce2cb7be2622246ddb04ddf7a479f78d134d408573aecf" + }, + "shot": { + "file": "audio/shot.wav", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "seconds": 0.24997732426303854, + "seed": 8002, + "peak": 23592, + "rms": 3696.1639535983163, + "sha256": "3308b3f8b9f9f7dc84f4356af4533d5b0ec7490ef5446ab991976a7c70d670bf" + }, + "death": { + "file": "audio/death.wav", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "seconds": 1.2499773242630385, + "seed": 8003, + "peak": 23592, + "rms": 3548.2638661195024, + "sha256": "6f8a628fb8176bf93b6f28fcb48c9091ab63dd06e6da67bc76c179cb4c0b7bae" + } + } +} diff --git a/mods/iron_coast_stage2_boss_8/audio/death.wav b/mods/iron_coast_stage2_boss_8/audio/death.wav new file mode 100644 index 00000000..83484cfc Binary files /dev/null and b/mods/iron_coast_stage2_boss_8/audio/death.wav differ diff --git a/mods/iron_coast_stage2_boss_8/audio/phase.wav b/mods/iron_coast_stage2_boss_8/audio/phase.wav new file mode 100644 index 00000000..01b38966 Binary files /dev/null and b/mods/iron_coast_stage2_boss_8/audio/phase.wav differ diff --git a/mods/iron_coast_stage2_boss_8/audio/shot.wav b/mods/iron_coast_stage2_boss_8/audio/shot.wav new file mode 100644 index 00000000..ee8038dd Binary files /dev/null and b/mods/iron_coast_stage2_boss_8/audio/shot.wav differ diff --git a/mods/iron_coast_stage2_boss_8/audio/warning.wav b/mods/iron_coast_stage2_boss_8/audio/warning.wav new file mode 100644 index 00000000..f58caf24 Binary files /dev/null and b/mods/iron_coast_stage2_boss_8/audio/warning.wav differ diff --git a/mods/iron_coast_stage2_boss_8/content.json b/mods/iron_coast_stage2_boss_8/content.json new file mode 100644 index 00000000..ea7abd07 --- /dev/null +++ b/mods/iron_coast_stage2_boss_8/content.json @@ -0,0 +1,77 @@ +{ + "weapons": [ + { + "id": "iron_coast_stage2_boss_8:shell", + "name": "Leviathan cannon shell", + "damage": 4, + "speed": 3, + "cooldown": 84, + "behavior": "straight", + "target": "all", + "art": { + "png": "art/projectile-sd.png", + "hd_png": "art/projectile-hd.png", + "logical_width": 6, + "logical_height": 12 + } + } + ], + "enemies": [ + { + "id": "iron_coast_stage2_boss_8:unit", + "name": "Leviathan", + "health": 360, + "speed": 0, + "reward": 9000, + "ground": false, + "boss": true, + "cooldown": 10000, + "art": { + "png": "art/unit-sd.png", + "hd_png": "art/unit-hd.png", + "logical_width": 112, + "logical_height": 112, + "frames": 3 + }, + "script": "scripts/ai.rhai" + } + ], + "sounds": [ + { + "id": "iron_coast_stage2_boss_8:warning", + "name": "Leviathan warning", + "file": "audio/warning.wav", + "volume": 90, + "pan": 127, + "pitch": 128, + "priority": 2 + }, + { + "id": "iron_coast_stage2_boss_8:phase", + "name": "Leviathan phase", + "file": "audio/phase.wav", + "volume": 110, + "pan": 127, + "pitch": 128, + "priority": 3 + }, + { + "id": "iron_coast_stage2_boss_8:shot", + "name": "Leviathan shot", + "file": "audio/shot.wav", + "volume": 110, + "pan": 127, + "pitch": 128, + "priority": 2 + }, + { + "id": "iron_coast_stage2_boss_8:death", + "name": "Leviathan death", + "file": "audio/death.wav", + "volume": 110, + "pan": 127, + "pitch": 128, + "priority": 3 + } + ] +} diff --git a/mods/iron_coast_stage2_boss_8/mod.toml b/mods/iron_coast_stage2_boss_8/mod.toml new file mode 100644 index 00000000..f755775c --- /dev/null +++ b/mods/iron_coast_stage2_boss_8/mod.toml @@ -0,0 +1,7 @@ +id = "iron_coast_stage2_boss_8" +name = "Iron Coast II: Leviathan Boss" +version = "1.0.0" +api_version = 1 +description = "Distinct persistent Leviathan carrier with telegraphed phase attacks, SD/HD artwork and original synthesized PCM sounds." +content = "content.json" +scripts = ["scripts/ai.rhai"] diff --git a/mods/iron_coast_stage2_boss_8/scripts/ai.rhai b/mods/iron_coast_stage2_boss_8/scripts/ai.rhai new file mode 100644 index 00000000..187c0422 --- /dev/null +++ b/mods/iron_coast_stage2_boss_8/scripts/ai.rhai @@ -0,0 +1,91 @@ +// Per-entity cursors prevent simultaneous carriers sharing phase/volley state. +fn alive(event) { + for unit in event.entities { if unit.entity == event.entity && unit.health > 0 { return true; } } + false +} +fn on_spawn(event,state,random) { + // A new spawn is a fresh lifecycle even when killed before dispatch. + if state.contains("last_death") && state.last_death == event.entity { state.remove("last_death"); } + if !alive(event) { return #{commands:[],state:state}; } + if !state.contains("units") { state.units = #{}; } + // Prune cursors from aborted/restarted worlds; retain simultaneous live carriers. + let live = #{}; + for unit in event.entities { if unit.definition == "iron_coast_stage2_boss_8:unit" { live[unit.entity.to_string()] = true; } } + for old in state.units.keys() { if !live.contains(old) { state.units.remove(old); } } + let spawn_health = 1; + for unit in event.entities { if unit.entity == event.entity { spawn_health = unit.health; } } + state.units[event.entity.to_string()] = #{age:0,volley:0,direction:1,phase:0,max_health:spawn_health}; + #{commands:[#{op:"velocity",entity:event.entity,vx:0,vy:2},#{op:"animation",entity:event.entity,frame:0}],state:state} +} +fn on_tick(event,state,random) { + if event.health <= 0 || !alive(event) { return #{commands:[],state:state}; } + let key = event.entity.to_string(); + if !state.contains("units") { state.units = #{}; } + let cursor = if state.units.contains(key) { state.units[key] } else { #{age:0,volley:0,direction:1,phase:0,max_health:event.health} }; + if event.y < 4 { + state.units[key] = cursor; + return #{commands:[#{op:"velocity",entity:event.entity,vx:0,vy:2}],state:state}; + } + let phase = if event.health * 3 <= cursor.max_health { 2 } else if event.health * 3 <= cursor.max_health * 2 { 1 } else { 0 }; + let commands = [#{op:"move",entity:event.entity,x:event.x,y:4}]; + if event.x >= 116 { cursor.direction = -1; } + if event.x <= 60 { cursor.direction = 1; } + commands.push(#{op:"velocity",entity:event.entity,vx:cursor.direction,vy:0}); + if phase != cursor.phase { + cursor.phase = phase; + cursor.age = 0; + commands.push(#{op:"animation",entity:event.entity,frame:phase}); + commands.push(#{op:"objective",key:"iron_coast_stage2_boss_8:phase",value:phase+1}); + commands.push(#{op:"play_sound",sound:"iron_coast_stage2_boss_8:phase"}); + } + cursor.age += 1; + let period = if phase == 0 { 96 } else if phase == 1 { 84 } else { 72 }; + let warning = 18; + if cursor.age % period == period-warning { + commands.push(#{op:"play_sound",sound:"iron_coast_stage2_boss_8:warning"}); + commands.push(#{op:"objective",key:"iron_coast_stage2_boss_8:safe_lane",value:cursor.volley % 3 + 1}); + // Blue charge arcs indicate the attacking pods, not an explosion. + let safe = cursor.volley % 3; + for lane in 0..3 { + if lane != safe { + commands.push(#{op:"arc",x:event.x+12+lane*32,y:4+112-14,to_x:event.x+28+lane*32,to_y:4+112-14,ticks:8,anchor:event.entity,to_anchor:event.entity}); + } + } + } + if cursor.age % period == 0 { + let safe = cursor.volley % 3; + if phase == 0 { + // Wide outward fan leaves the central column entirely open. + commands.push(#{op:"projectile",weapon:"iron_coast_stage2_boss_8:shell",x:event.x+16,y:4+112-12,vx:-2,vy:3,hostile:true}); + commands.push(#{op:"projectile",weapon:"iron_coast_stage2_boss_8:shell",x:event.x+32,y:4+112-12,vx:-1,vy:3,hostile:true}); + commands.push(#{op:"projectile",weapon:"iron_coast_stage2_boss_8:shell",x:event.x+76,y:4+112-12,vx:1,vy:3,hostile:true}); + commands.push(#{op:"projectile",weapon:"iron_coast_stage2_boss_8:shell",x:event.x+92,y:4+112-12,vx:2,vy:3,hostile:true}); + } else { + // Every later volley leaves one full32px deck lane open; the warning names + // it eighteen ticks early. Phase3 adds only outward flank shots. + for lane in 0..3 { + if lane != safe { + for i in 0..2 { commands.push(#{op:"projectile",weapon:"iron_coast_stage2_boss_8:shell",x:event.x+12+lane*32+i*10,y:4+112-12,vx:0,vy:3,hostile:true}); } + } + } + if phase == 2 { + commands.push(#{op:"projectile",weapon:"iron_coast_stage2_boss_8:shell",x:event.x+8,y:4+112-12,vx:-2,vy:3,hostile:true}); + commands.push(#{op:"projectile",weapon:"iron_coast_stage2_boss_8:shell",x:event.x+100,y:4+112-12,vx:2,vy:3,hostile:true}); + } + } + commands.push(#{op:"play_sound",sound:"iron_coast_stage2_boss_8:shot"}); + cursor.volley += 1; + } + state.units[key] = cursor; + #{commands:commands,state:state} +} +fn on_hit(event,state,random) { #{commands:[],state:state} } +fn on_death(event,state,random) { + if state.contains("last_death") && state.last_death == event.entity { return #{commands:[],state:state}; } + state.last_death = event.entity; + if state.contains("units") { state.units.remove(event.entity.to_string()); } + let count = if event.objectives.contains("iron_coast_stage2_boss_8:defeated") { event.objectives["iron_coast_stage2_boss_8:defeated"]+1 } else { 1 }; + #{commands:[#{op:"objective",key:"iron_coast_stage2_boss_8:defeated",value:count}, + #{op:"effect",x:event.x+28,y:event.y+112/2},#{op:"effect",x:event.x+84,y:event.y+112/2}, + #{op:"play_sound",sound:"iron_coast_stage2_boss_8:death"}],state:state} +} diff --git a/mods/iron_coast_stage2_boss_8/validation-summary.json b/mods/iron_coast_stage2_boss_8/validation-summary.json new file mode 100644 index 00000000..816fa195 --- /dev/null +++ b/mods/iron_coast_stage2_boss_8/validation-summary.json @@ -0,0 +1,194 @@ +{ + "status": "Author production acceptance passed; independent campaign/SD-HD Host review handled separately", + "package": "iron_coast_stage2_boss_8", + "version": "1.0.0", + "api_version": 1, + "actual_original_catalog": true, + "starter_fire_only": true, + "normal_movement_limit_pixels_per_tick": 4, + "near_shot_sidesteps": { + "hostile_y": [ + 136, + 188 + ], + "horizontal_distance_from_player_center": 24 + }, + "runs": [ + { + "boss_only": true, + "classic_ids": [], + "credits": 19000, + "difficulty": 0, + "digest": "82a8828e680e89c203740ba3b807925ad84c36e674569db5d3d80e55e98c3696", + "initial_credits": 10000, + "initial_shield": 75, + "inventory_preserved": true, + "inventory_slots": 2, + "maximum_live_enemies": 1, + "mission": 8, + "native_movement_ids": [], + "objectives": { + "iron_coast_stage2_boss_8:defeated": 1, + "iron_coast_stage2_boss_8:phase": 3, + "iron_coast_stage2_boss_8:safe_lane": 1 + }, + "outcome": "Playing", + "phase_frames": [ + 0, + 1, + 2 + ], + "rewards_once": true, + "shield": 75, + "sound_ids": [ + "iron_coast_stage2_boss_8:death", + "iron_coast_stage2_boss_8:phase", + "iron_coast_stage2_boss_8:warning" + ], + "tick": 186 + }, + { + "boss_only": true, + "classic_ids": [], + "credits": 19000, + "difficulty": 1, + "digest": "d2fb5d93ca6b5fd0459181e16accc15f2d9c36cf72f485d5466c1d2ec8439291", + "initial_credits": 10000, + "initial_shield": 75, + "inventory_preserved": true, + "inventory_slots": 2, + "maximum_live_enemies": 1, + "mission": 8, + "native_movement_ids": [], + "objectives": { + "iron_coast_stage2_boss_8:defeated": 1, + "iron_coast_stage2_boss_8:phase": 3, + "iron_coast_stage2_boss_8:safe_lane": 1 + }, + "outcome": "Playing", + "phase_frames": [ + 0, + 1, + 2 + ], + "rewards_once": true, + "shield": 75, + "sound_ids": [ + "iron_coast_stage2_boss_8:death", + "iron_coast_stage2_boss_8:phase", + "iron_coast_stage2_boss_8:warning" + ], + "tick": 186 + }, + { + "boss_only": true, + "classic_ids": [], + "credits": 19000, + "difficulty": 2, + "digest": "fedb0de99190f972a895d86902cdd87dcfef31ae2e5c247765a70aa73a0d72c3", + "initial_credits": 10000, + "initial_shield": 75, + "inventory_preserved": true, + "inventory_slots": 2, + "maximum_live_enemies": 1, + "mission": 8, + "native_movement_ids": [], + "objectives": { + "iron_coast_stage2_boss_8:defeated": 1, + "iron_coast_stage2_boss_8:phase": 3, + "iron_coast_stage2_boss_8:safe_lane": 2 + }, + "outcome": "Playing", + "phase_frames": [ + 0, + 1, + 2 + ], + "rewards_once": true, + "shield": 75, + "sound_ids": [ + "iron_coast_stage2_boss_8:death", + "iron_coast_stage2_boss_8:phase", + "iron_coast_stage2_boss_8:shot", + "iron_coast_stage2_boss_8:warning" + ], + "tick": 366 + }, + { + "boss_only": true, + "classic_ids": [], + "credits": 19000, + "difficulty": 3, + "digest": "0648e781f17a72f6e5144a5c816d7abd2b8fd09106145697451c62f26ff6eb05", + "initial_credits": 10000, + "initial_shield": 75, + "inventory_preserved": true, + "inventory_slots": 2, + "maximum_live_enemies": 1, + "mission": 8, + "native_movement_ids": [], + "objectives": { + "iron_coast_stage2_boss_8:defeated": 1, + "iron_coast_stage2_boss_8:phase": 3, + "iron_coast_stage2_boss_8:safe_lane": 2 + }, + "outcome": "Playing", + "phase_frames": [ + 0, + 1, + 2 + ], + "rewards_once": true, + "shield": 75, + "sound_ids": [ + "iron_coast_stage2_boss_8:death", + "iron_coast_stage2_boss_8:phase", + "iron_coast_stage2_boss_8:shot", + "iron_coast_stage2_boss_8:warning" + ], + "tick": 366 + } + ], + "actual_production_mixer": [ + { + "actual_mixer_peak": 6016, + "actual_mixer_rms": 689.7685176927112, + "muted_exact_zero": true, + "sound": "iron_coast_stage2_boss_8:death" + }, + { + "actual_mixer_peak": 6016, + "actual_mixer_rms": 1565.0945326081744, + "muted_exact_zero": true, + "sound": "iron_coast_stage2_boss_8:phase" + }, + { + "actual_mixer_peak": 5888, + "actual_mixer_rms": 318.4385906261991, + "muted_exact_zero": true, + "sound": "iron_coast_stage2_boss_8:shot" + }, + { + "actual_mixer_peak": 4864, + "actual_mixer_rms": 955.2234502984105, + "muted_exact_zero": true, + "sound": "iron_coast_stage2_boss_8:warning" + } + ], + "actual_mixer_cues_unclipped": true, + "actual_mute_exact_zero": true, + "per_entity_phase_isolation": true, + "actual_world_repeated_spawn_step_lethal_with_retained_state": true, + "death_and_rewards_once": true, + "PNG_source_and_output_dimensions_checked": true, + "external_proof_hashes": { + "validation-results.json": "d063d101d9e1d5cf1cb94240caba3ddef04b5183def5b6625ebe32d92951b28d", + "boss-validation-results.json": "ef20464533b00c35f63c1add0d3149dc9da341ec580f3221e389a62230143e0a", + "actual-audio-proof.json": "293e8f37a5e0ae776d6b0369207dc80f2e38b52c0c903de412bba9b4fbfc60d4", + "actual-mixer-all-cues.wav": "af00e983a61e1c26e1504a818fa524b31528fa8f44211cc6969bbc0f6e430124", + "asset-validation.json": "7a30c3aaf365a8ac16c97c1b519d93ca39f1723c96b1fac5f93fa88f7757a1f7", + "boss-art-contact.png": "444de75e4c171ddac84e2ae6f3f206e749e1fdc3a59d406aa4c66f7678519aa7", + "terrain-briefing-contact.png": "254895a2296d6972f9fa4132e21d95979b149be960600507633f44847398eb3b" + }, + "reference_visibility_limits": "Art contact sheets are author visual inspection. Sound proof uses actual mixer without a liveSDL occurrence claim. Root/independent Host screenshots bind final gameplay presentation separately." +} diff --git a/mods/iron_coast_stage2_campaign/README.md b/mods/iron_coast_stage2_campaign/README.md new file mode 100644 index 00000000..8f9f8f11 --- /dev/null +++ b/mods/iron_coast_stage2_campaign/README.md @@ -0,0 +1,21 @@ +# Iron Coast II: Black Tide + +Enable **Iron Coast II — Black Tide** in the game's Mods screen. Dependency +selection brings in all eight missions, their individual bosses, the shared +coastal enemies, the three-track soundtrack and two optional shop weapons. +Apply the selection at the main menu, choose this campaign in the hangar and +start Nightbreak Inlet. Normal pilot saves retain the campaign and package pins. + +The individual mission, boss, enemy and weapon mods can also be enabled +separately. Removing a required mod shows the dependent packages before the +selection changes. Existing Stage 1 and original campaigns remain available. + +The aggregate adds its own campaign; it does not override existing definitions +or grant equipment. Railburst Cannon and Depth Charge are normal optional +purchases. Fire with Ctrl, drop owned bombs with Space and cycle selectable +weapons with Alt or Shift. The shop explains each weapon's targeting and role. + +This package's new briefing was created using built-in imagegen. Its saved +prompt, unchanged generated master and provenance are in `art/`. Re-export +the palette SD and 4× HD canvases with `python3 build_assets.py` (Pillow). +Gameplay, music and generated sound effects live in the individual dependencies. diff --git a/mods/iron_coast_stage2_campaign/art/briefing-master.png b/mods/iron_coast_stage2_campaign/art/briefing-master.png new file mode 100644 index 00000000..61c04ca6 Binary files /dev/null and b/mods/iron_coast_stage2_campaign/art/briefing-master.png differ diff --git a/mods/iron_coast_stage2_campaign/art/briefing_hd.png b/mods/iron_coast_stage2_campaign/art/briefing_hd.png new file mode 100644 index 00000000..31f3691b Binary files /dev/null and b/mods/iron_coast_stage2_campaign/art/briefing_hd.png differ diff --git a/mods/iron_coast_stage2_campaign/art/briefing_sd.png b/mods/iron_coast_stage2_campaign/art/briefing_sd.png new file mode 100644 index 00000000..20a2654a Binary files /dev/null and b/mods/iron_coast_stage2_campaign/art/briefing_sd.png differ diff --git a/mods/iron_coast_stage2_campaign/art/prompt.txt b/mods/iron_coast_stage2_campaign/art/prompt.txt new file mode 100644 index 00000000..d6025f26 --- /dev/null +++ b/mods/iron_coast_stage2_campaign/art/prompt.txt @@ -0,0 +1,6 @@ +Use case: stylized-concept. +Asset type: full-canvas 16:10 campaign briefing artwork for Iron Coast II: Black Tide, a faithful top-down Raptor-style military shoot-em-up expansion. +Input image: existing Iron Coast harbor artwork is a STYLE REFERENCE only, not an edit target. Match its industrial steel panels, muted warm rust, cold deep-blue sea, orthographic detail and readable game-art materials. Create a genuinely new composition. +Primary request: a thrilling nighttime offshore command-carrier assault in a wide 16:10 composition, entirely orthographic top-down. A massive futuristic but grounded steel command carrier anchors the center-right, with broad armored flight deck, warm warning lights, several distinct turret platforms, stern engine vents and military green machinery. Smaller escort craft and rusted angular offshore refinery platforms frame the left and lower edges. Black-blue ocean channels and restrained white wake streaks separate all silhouettes. Suggest an ominous coastal campaign with cold moonlit steel, warm amber lamps and an ember-orange glow in distant industrial infrastructure. Keep surfaces crisp and recognizable at 320x200, with painted remaster quality and detailed 1280x800 readability. All subjects viewed from directly overhead, no horizon or tilted cinematic perspective. +Composition: landscape 16:10, full opaque canvas; larger carrier structure occupies about half the picture, generous dark sea around it. Balanced readable shapes, no repetitive square tile grid, no artificial HUD, no UI buttons, no text, letters, numbers, logos or watermark. No player ship, projectile trails, explosions or active enemy sprites baked into this briefing. No photorealistic humans, fantasy monsters or neon-purple science-fiction accents. +Output: one complete opaque PNG, maximum available landscape resolution. Preserve content around every edge for a slight aspect-ratio crop to the exact game canvas. SD and HD exports retain the same complete composition. diff --git a/mods/iron_coast_stage2_campaign/art/provenance.json b/mods/iron_coast_stage2_campaign/art/provenance.json new file mode 100644 index 00000000..71a22560 --- /dev/null +++ b/mods/iron_coast_stage2_campaign/art/provenance.json @@ -0,0 +1,21 @@ +{ + "generator": "built-in imagegen", + "generated_date": "2026-10-11", + "reference": "Iron Coast Stage 1 briefing used as style reference only", + "original_artwork": true, + "logical_canvas": [ + 320, + 200 + ], + "hd_canvas": [ + 1280, + 800 + ], + "processing": "Preserved opaque master; centered aspect fit and Lanczos export; SD noncycling VGA palette without dithering", + "sha256": { + "prompt.txt": "cc9f341ba0a974c0933fa8d3bf89fdfa66dedd31c29bd2112a1bf52fc1ce37ca", + "briefing-master.png": "01a3ab723d4732a763a3899d727624f2883c43d19a88cfd04e4fdcade223657b", + "briefing_hd.png": "37e6cf64833777bbca81a61c6ad2098cdaca27a0702a32299149b1119fb0da01", + "briefing_sd.png": "8f5e3ffbd5427605e6b0c4aeb386b00e3120a8c1be8ec5eacf779a9d8d0741e9" + } +} diff --git a/mods/iron_coast_stage2_campaign/build_assets.py b/mods/iron_coast_stage2_campaign/build_assets.py new file mode 100644 index 00000000..ce9c3f48 --- /dev/null +++ b/mods/iron_coast_stage2_campaign/build_assets.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 +"""Export the preserved imagegen briefing master to the shared SD/HD canvas.""" +import argparse +import hashlib +import json +from pathlib import Path +from PIL import Image, ImageOps + +ROOT = Path(__file__).resolve().parent + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--palette", type=Path, default=ROOT.parents[1] / "data/misc/PALETTE_DAT") + args = parser.parse_args() + raw = args.palette.read_bytes() + if len(raw) != 768: + raise ValueError("Expected original VGA palette") + colors = [(min(v, 63) << 2) | (min(v, 63) >> 4) for v in raw] + # Ordinary PNG artwork excludes the engine's cycling and effect indices. + palette = Image.new("P", (1, 1)) + palette.putpalette(colors[:720] + colors[:3] * 16) + art = ROOT / "art" + master = Image.open(art / "briefing-master.png").convert("RGBA") + if master.getchannel("A").getextrema() != (255, 255): + raise ValueError("Briefing must be opaque") + hd = ImageOps.fit(master, (1280, 800), method=Image.Resampling.LANCZOS) + sd = hd.resize((320, 200), Image.Resampling.LANCZOS).convert("RGB").quantize( + palette=palette, dither=Image.Dither.NONE).convert("RGBA") + hd.save(art / "briefing_hd.png") + sd.save(art / "briefing_sd.png") + files = {p.name: hashlib.sha256(p.read_bytes()).hexdigest() for p in + [art / "prompt.txt", art / "briefing-master.png", art / "briefing_hd.png", art / "briefing_sd.png"]} + provenance = { + "generator": "built-in imagegen", "generated_date": "2026-10-11", + "reference": "Iron Coast Stage 1 briefing used as style reference only", + "original_artwork": True, "logical_canvas": [320, 200], "hd_canvas": [1280, 800], + "processing": "Preserved opaque master; centered aspect fit and Lanczos export; SD noncycling VGA palette without dithering", + "sha256": files + } + (art / "provenance.json").write_text(json.dumps(provenance, indent=2) + "\n") + +if __name__ == "__main__": + main() diff --git a/mods/iron_coast_stage2_campaign/content.json b/mods/iron_coast_stage2_campaign/content.json new file mode 100644 index 00000000..85c3f315 --- /dev/null +++ b/mods/iron_coast_stage2_campaign/content.json @@ -0,0 +1,25 @@ +{ + "campaigns": [ + { + "id": "iron_coast_stage2_campaign:campaign", + "name": "Iron Coast II: Black Tide", + "art": { + "png": "art/briefing_sd.png", + "hd_png": "art/briefing_hd.png", + "logical_width": 320, + "logical_height": 200, + "frames": 1 + }, + "missions": [ + "iron_coast_stage2_mission_1:mission_01", + "iron_coast_stage2_mission_2:mission_02", + "iron_coast_stage2_mission_3:mission_03", + "iron_coast_stage2_mission_4:mission_04", + "iron_coast_stage2_mission_5:mission_05", + "iron_coast_stage2_mission_6:mission_06", + "iron_coast_stage2_mission_7:mission_07", + "iron_coast_stage2_mission_8:mission_08" + ] + } + ] +} diff --git a/mods/iron_coast_stage2_campaign/mod.toml b/mods/iron_coast_stage2_campaign/mod.toml new file mode 100644 index 00000000..e7b9a9de --- /dev/null +++ b/mods/iron_coast_stage2_campaign/mod.toml @@ -0,0 +1,18 @@ +id = "iron_coast_stage2_campaign" +name = "Iron Coast II — Black Tide" +version = "1.0.0" +api_version = 1 +description = "Eight linked sorties from Nightbreak Inlet to the Black Tide command citadel, with eight distinct bosses, classic Raptor waves, new coastal enemies, two optional weapons and an original three-track soundtrack." +content = "content.json" + +[dependencies] +iron_coast_stage2_mission_1 = "^1.0" +iron_coast_stage2_mission_2 = "^1.0" +iron_coast_stage2_mission_3 = "^1.0" +iron_coast_stage2_mission_4 = "^1.0" +iron_coast_stage2_mission_5 = "^1.0" +iron_coast_stage2_mission_6 = "^1.0" +iron_coast_stage2_mission_7 = "^1.0" +iron_coast_stage2_mission_8 = "^1.0" +iron_coast_railburst = "^1.0" +iron_coast_depth_charge = "^1.0" diff --git a/mods/iron_coast_stage2_interceptor/ART_PROVENANCE.md b/mods/iron_coast_stage2_interceptor/ART_PROVENANCE.md new file mode 100644 index 00000000..9db5dddb --- /dev/null +++ b/mods/iron_coast_stage2_interceptor/ART_PROVENANCE.md @@ -0,0 +1,15 @@ +# Needlewing artwork and audio provenance + +The two `art/*-generated-v1.png` files are unchanged outputs of the built-in image generator. Their exact built-in paths, output hints, generation job/lease IDs, original bytes SHA-256 and saved prompt paths are recorded in `provenance-unit-v1.json` and `provenance-projectile-v1.json`. They were generated as transparent new enemy/artwork designs; the originals were style references, not replacement sprite authority. No decoded original reference image is distributed inside this mod. + +The authentic catalog style references were viewed before generation: the enemy reference is asset `102f8`, and the projectile reference is `101d6`. Their decoded reference SHA-256 values are retained in the provenance records. Original gray metal, compact top-down silhouette, restrained highlights and readable small logical canvases informed these new designs. The exact palette used for local renderer review is recorded in the external validation handoff. + +`prepare_art.rs` is the complete reproducible preparation recipe. It crops only completely transparent outer margins (every input pixel with alpha at least one remains within the recorded crop), preserves the occupied aspect ratio, fits and centers the artwork inside the declared logical canvas with padding, and creates an 8× HD canvas using premultiplied-alpha Lanczos3. SD uses the same floor-nearest sample positions as the renderer at logical size, retaining bright projectile cores and matching the SD/HD silhouette placement at 1×. The production PNG loader performs its normal alpha threshold and original-palette conversion; this package does not change that policy. Native details necessarily simplify at SD and the smallest indexed HD sizes. + +`art-qa.json` records every raw/SD/HD hash, dimensions, crop, occupied fit, offsets, logical origin `[0,0]`, single-frame count and alpha-threshold bounds. No opaque edge touches the sprite canvas. HD and SD canvases have exactly the same aspect and logical placement. Generated masters remain untouched; only derived artwork is prepared. + +To reproduce preparation, compile `prepare_art.rs` against the project's locked `image`, `serde_json` and `sha2` crates, then pass this mod folder to the resulting executable. The checked local compiler arguments are retained in the external development validation record. This helper writes only derived PNGs and `art-qa.json` in the supplied mod. + +`generate_audio.py` creates original effects with seeded chirps and filtered noise using the Python standard library. It uses no original recordings, external audio service or nondeterministic noise source. Run `python3 generate_audio.py` from this mod folder to reproduce the three WAVs and their recipe. All are mono 22050 Hz 16-bit PCM, with short attack/release envelopes and normalized peaks below clipping. Exact seeds, lengths, peak/RMS and SHA-256 values are in `audio-recipe.json`. + +Local visual review covers the unchanged raw outputs, both prepared modes and all indexed renderer outputs at scales 1–4. These diagnostic galleries do not claim live whole-mission rendering. SoundBank/Mixer tests confirm that all effects decode, queue and produce nonzero unclipped output; they do not measure a user's speakers. diff --git a/mods/iron_coast_stage2_interceptor/README.md b/mods/iron_coast_stage2_interceptor/README.md new file mode 100644 index 00000000..0f677e28 --- /dev/null +++ b/mods/iron_coast_stage2_interceptor/README.md @@ -0,0 +1,34 @@ +# Iron Coast II: Needlewing + +An independent enemy package for API version 1. Enable **Iron Coast II: Needlewing** in the game's Mods menu. Enabling a mission that requires it also enables this package through the dependency manager. Enabling this enemy alone registers its content; a mission or another mod must spawn it. There are no dependencies or overrides. + +## Behavior + +- Enemy ID: `iron_coast_stage2_interceptor:unit`; air target, logical canvas 24×24, health 18, reward 100 credits. +- Fast flanker. Its integer route curves through eight lateral phases, with short straight pauses and a downward speed of one or two logical pixels per tick. +- Three aimed 2-damage projectiles at speed 3, four ticks apart. The next burst starts after 70 engine ticks (about 3 seconds). There is no warning chirp for this quick, low-damage enemy. +- `:gun` is a scripted firing controller; `:projectile` is the distinct hostile projectile definition. These weapons are enemy content, unavailable in the shop; no player equipment or credits are granted. +- `:shot`, `:warning` and `:death` are synthesized local WAV cues. Needlewing's warning is supplied for authors but is not played by its ordinary AI. + +The original forward guns can hit these enemies. Air-only weapons cannot hit ground enemies, and ground-only weapons cannot hit the Needlewing. Collision dimensions are identical in SD and HD; artwork has transparent padding and one aligned frame per sprite. Normal units leave the playfield if not killed. A mission may hold a required target inside the screen while retaining its lateral movement. + +## Mission integration + +Spawn `iron_coast_stage2_interceptor:unit` through normal mission definitions or the documented `spawn` command. Actual deaths increment the objective `iron_coast_stage2_interceptor:defeated` once. Escapes and despawns do not increment it. The engine awards the configured reward and creates normal death feedback; this script adds its local death cue. Objective keys and content IDs are namespaced so all three shared enemy packages coexist. + +Firing is rejected for dead or invisible units and after they pass the player. Bursts are finite; scripts never spawn enemies, grant equipment, deal direct damage, or complete a mission. Per-entity movement clocks and burst state are serializable and use only supplied deterministic RNG. Up to 128 live units receive custom AI, with periodic pruning and a bounded 128-entry death guard. Excess units retain basic engine movement and do not gain extra attacks. The diagnostics counters saturate at one billion. Missions should use much smaller readable waves. + +No new controls are introduced. Fire and weapon selection remain the normal game controls. All prices are inapplicable because the package adds enemies, not purchasable items. + +## Assets and validation + +Both artwork modes, unchanged generated masters, prompts, derivation recipe and all sound recipes are included. See [artwork provenance](ART_PROVENANCE.md), [art checks](art-qa.json), [audio recipe](audio-recipe.json) and [validation record](validation/acceptance.json). Decoded original style references and local review screenshots are deliberately kept outside this package. + +From the RustRaptor folder: + +```sh +cargo test --locked --no-default-features --test stage2_enemies +cargo run --locked --no-default-features -- --data data --mods mods --validate-mods iron_coast_stage2_interceptor +``` + +Tests exercise actual World callbacks, finite volleys and telegraphs, ground/air filtering, damage behavior, escapes, real death rewards and counters, reused entity IDs, bounded state, full save/RNG continuation and independent/combined activation. Shipped PNG geometry and all nine effects are also checked through the real SoundBank/Mixer. Local catalog validation and indexed SD/HD scale 1–4 galleries are recorded separately. These controlled checks do not establish full campaign balance or a live SDL scene; the mission packages have their own route tests. diff --git a/mods/iron_coast_stage2_interceptor/art-qa.json b/mods/iron_coast_stage2_interceptor/art-qa.json new file mode 100644 index 00000000..09a35d91 --- /dev/null +++ b/mods/iron_coast_stage2_interceptor/art-qa.json @@ -0,0 +1,105 @@ +{ + "all_occupied_input_alpha_retained_in_crop": true, + "frames": [ + { + "crop_all_alpha_ge_1": [ + 49, + 17, + 1228, + 1222 + ], + "frames": 1, + "hd_alpha128_bounds": [ + 49, + 33, + 139, + 160 + ], + "hd_canvas": [ + 192, + 192 + ], + "hd_sha256": "807f76b69212afa067c1e8b174bcc6684210770c6f489b2586256579a356ad44", + "kind": "unit", + "logical_canvas": [ + 24, + 24 + ], + "logical_origin": [ + 0, + 0 + ], + "occupied_fit": [ + 157, + 160 + ], + "offset_hd": [ + 17, + 16 + ], + "raw_dimensions": [ + 1254, + 1254 + ], + "raw_sha256": "63dbe918a54b0eb63244f43c457a6b5159810d748b3c196c54e6740fcf09d38f", + "sd_alpha128_bounds": [ + 7, + 5, + 18, + 19 + ], + "sd_sha256": "1ba81cb20ca88df1bde669ea349e4d5b1a5f038fc350c5b6bc3bc8c5a8f4f10f" + }, + { + "crop_all_alpha_ge_1": [ + 528, + 286, + 983, + 1053 + ], + "frames": 1, + "hd_alpha128_bounds": [ + 18, + 14, + 30, + 44 + ], + "hd_canvas": [ + 64, + 64 + ], + "hd_sha256": "06d43691f1f9bef015dce3abac58cca332c5b324cbbf4593d47dda3b8d0caff2", + "kind": "projectile", + "logical_canvas": [ + 8, + 8 + ], + "logical_origin": [ + 0, + 0 + ], + "occupied_fit": [ + 28, + 48 + ], + "offset_hd": [ + 18, + 8 + ], + "raw_dimensions": [ + 1254, + 1254 + ], + "raw_sha256": "3fa7d9897a3bce5d409ae468db7d6cb097b2793ca0e4efb416507baf66984a69", + "sd_alpha128_bounds": [ + 3, + 2, + 4, + 6 + ], + "sd_sha256": "a52c0e0843dc6a5aab78255f5a1c01de9bcae495270381db13a57aa1183d1d3a" + } + ], + "method": "prepare_art.rs: unchanged genuine alpha master, crop only transparent margin, aspect-preserving centered fit, premultiplied-alpha Lanczos3 HD8x and renderer-aligned floor-nearest SD; original images are style references only", + "source_unchanged": true +} \ No newline at end of file diff --git a/mods/iron_coast_stage2_interceptor/art/projectile-generated-v1.png b/mods/iron_coast_stage2_interceptor/art/projectile-generated-v1.png new file mode 100644 index 00000000..71fbe8bd Binary files /dev/null and b/mods/iron_coast_stage2_interceptor/art/projectile-generated-v1.png differ diff --git a/mods/iron_coast_stage2_interceptor/art/projectile-hd.png b/mods/iron_coast_stage2_interceptor/art/projectile-hd.png new file mode 100644 index 00000000..29f365c1 Binary files /dev/null and b/mods/iron_coast_stage2_interceptor/art/projectile-hd.png differ diff --git a/mods/iron_coast_stage2_interceptor/art/projectile-sd.png b/mods/iron_coast_stage2_interceptor/art/projectile-sd.png new file mode 100644 index 00000000..9dc258ea Binary files /dev/null and b/mods/iron_coast_stage2_interceptor/art/projectile-sd.png differ diff --git a/mods/iron_coast_stage2_interceptor/art/unit-generated-v1.png b/mods/iron_coast_stage2_interceptor/art/unit-generated-v1.png new file mode 100644 index 00000000..ab8f4062 Binary files /dev/null and b/mods/iron_coast_stage2_interceptor/art/unit-generated-v1.png differ diff --git a/mods/iron_coast_stage2_interceptor/art/unit-hd.png b/mods/iron_coast_stage2_interceptor/art/unit-hd.png new file mode 100644 index 00000000..eba74c9e Binary files /dev/null and b/mods/iron_coast_stage2_interceptor/art/unit-hd.png differ diff --git a/mods/iron_coast_stage2_interceptor/art/unit-sd.png b/mods/iron_coast_stage2_interceptor/art/unit-sd.png new file mode 100644 index 00000000..3ad02e19 Binary files /dev/null and b/mods/iron_coast_stage2_interceptor/art/unit-sd.png differ diff --git a/mods/iron_coast_stage2_interceptor/audio-recipe.json b/mods/iron_coast_stage2_interceptor/audio-recipe.json new file mode 100644 index 00000000..2ddc87f0 --- /dev/null +++ b/mods/iron_coast_stage2_interceptor/audio-recipe.json @@ -0,0 +1,38 @@ +{ + "generator": "generate_audio.py standard Python seeded chirp/filtered noise; no original recordings", + "files": [ + { + "file": "audio/shot.wav", + "seed": 8100, + "duration_seconds": 0.09501133786848072, + "samples": 2095, + "format": "mono PCM16 little endian", + "sample_rate": 22050, + "peak": 20316, + "rms": 0.11567749432475564, + "sha256": "137a4999185422b4deecbb9be39cfe527d122fe4b7e5a8ceae92c536ebba8cca" + }, + { + "file": "audio/warning.wav", + "seed": 8101, + "duration_seconds": 0.12, + "samples": 2646, + "format": "mono PCM16 little endian", + "sample_rate": 22050, + "peak": 13107, + "rms": 0.17848923628054095, + "sha256": "3703d9b61d5a29d554edd60d34cee1fa08a6be4fb977672340a85e7216aa7b2b" + }, + { + "file": "audio/death.wav", + "seed": 8102, + "duration_seconds": 0.46, + "samples": 10143, + "format": "mono PCM16 little endian", + "sample_rate": 22050, + "peak": 24248, + "rms": 0.09599223209118642, + "sha256": "a71baa3260753133d4690add919f0ff31dfc2e5baf81876f655ad6c6b171f232" + } + ] +} diff --git a/mods/iron_coast_stage2_interceptor/audio/death.wav b/mods/iron_coast_stage2_interceptor/audio/death.wav new file mode 100644 index 00000000..870515ae Binary files /dev/null and b/mods/iron_coast_stage2_interceptor/audio/death.wav differ diff --git a/mods/iron_coast_stage2_interceptor/audio/shot.wav b/mods/iron_coast_stage2_interceptor/audio/shot.wav new file mode 100644 index 00000000..0f63a1b6 Binary files /dev/null and b/mods/iron_coast_stage2_interceptor/audio/shot.wav differ diff --git a/mods/iron_coast_stage2_interceptor/audio/warning.wav b/mods/iron_coast_stage2_interceptor/audio/warning.wav new file mode 100644 index 00000000..33624bc0 Binary files /dev/null and b/mods/iron_coast_stage2_interceptor/audio/warning.wav differ diff --git a/mods/iron_coast_stage2_interceptor/content.json b/mods/iron_coast_stage2_interceptor/content.json new file mode 100644 index 00000000..bad1d6b7 --- /dev/null +++ b/mods/iron_coast_stage2_interceptor/content.json @@ -0,0 +1,74 @@ +{ + "weapons": [ + { + "id": "iron_coast_stage2_interceptor:gun", + "name": "Needlewing firing controller", + "damage": 1, + "speed": 0, + "cooldown": 69, + "behavior": "scripted", + "target": "all", + "script": "scripts/gun.rhai" + }, + { + "id": "iron_coast_stage2_interceptor:projectile", + "name": "Needlewing shell", + "damage": 2, + "speed": 3, + "cooldown": 69, + "behavior": "straight", + "target": "all", + "art": { + "png": "art/projectile-sd.png", + "hd_png": "art/projectile-hd.png", + "logical_width": 8, + "logical_height": 8, + "frames": 1 + } + } + ], + "enemies": [ + { + "id": "iron_coast_stage2_interceptor:unit", + "name": "Needlewing", + "health": 18, + "speed": 1, + "reward": 100, + "ground": false, + "boss": false, + "cooldown": 69, + "weapon": "iron_coast_stage2_interceptor:gun", + "art": { + "png": "art/unit-sd.png", + "hd_png": "art/unit-hd.png", + "logical_width": 24, + "logical_height": 24, + "frames": 1 + }, + "script": "scripts/ai.rhai" + } + ], + "sounds": [ + { + "id": "iron_coast_stage2_interceptor:shot", + "name": "Needlewing shot", + "file": "audio/shot.wav", + "volume": 72, + "priority": 2 + }, + { + "id": "iron_coast_stage2_interceptor:warning", + "name": "Needlewing warning", + "file": "audio/warning.wav", + "volume": 62, + "priority": 2 + }, + { + "id": "iron_coast_stage2_interceptor:death", + "name": "Needlewing death", + "file": "audio/death.wav", + "volume": 96, + "priority": 3 + } + ] +} diff --git a/mods/iron_coast_stage2_interceptor/contract.json b/mods/iron_coast_stage2_interceptor/contract.json new file mode 100644 index 00000000..bee9ea4a --- /dev/null +++ b/mods/iron_coast_stage2_interceptor/contract.json @@ -0,0 +1,20 @@ +{ + "id": "iron_coast_stage2_interceptor", + "name": "Needlewing", + "logical_size": [ + 24, + 24 + ], + "ground": false, + "health": 18, + "reward": 100, + "gun_cooldown": 69, + "actual_engine_firing_period": 70, + "projectile_damage": 2, + "projectile_speed": 3, + "burst": 3, + "warning_ticks": 0, + "objective": "iron_coast_stage2_interceptor:defeated", + "maximum_live_script_units": 128, + "maximum_retained_death_guards": 128 +} diff --git a/mods/iron_coast_stage2_interceptor/generate_audio.py b/mods/iron_coast_stage2_interceptor/generate_audio.py new file mode 100644 index 00000000..21dd6bd0 --- /dev/null +++ b/mods/iron_coast_stage2_interceptor/generate_audio.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 +"""Reproduce authored mono PCM effects using seeded chirps and filtered noise.""" +from pathlib import Path +import random,math,struct,wave,json,hashlib +root=Path(__file__).resolve().parent +role=root.name.split('_')[-1];index=['interceptor','siege','skimmer'].index(role) +rate=22050;files=[] +for name,duration in [('shot',[.095,.19,.14][index]),('warning',[.12,.26,.19][index]),('death',[.46,.72,.56][index])]: + seed=8100+index*100+['shot','warning','death'].index(name);rng=random.Random(seed);count=round(rate*duration);values=[];phase=0.0;low=0.0 + for i in range(count): + t=i/rate;u=i/max(count-1,1);noise=rng.uniform(-1,1);low=.9*low+.1*noise + if name=='shot': + start=[1600,440,1000][index];end=[460,90,280][index];phase+=2*math.pi*(end+(start-end)*(1-u)**2)/rate + value=[.64,.45,.57][index]*math.sin(phase)+[.10,.34,.18][index]*noise+.14*math.sin(1.93*phase);env=math.exp(-[5.8,6.5,5.3][index]*u) + elif name=='warning': + phase+=2*math.pi*([670,310,540][index]+[390,240,420][index]*u)/rate;value=.7*math.sin(phase)+.1*math.sin(2*phase);env=math.sin(math.pi*u)**1.4*(.65+.35*math.sin(2*math.pi*[13,9,16][index]*t)) + else: + phase+=2*math.pi*([130,85,110][index]*(1-u)+24)/rate;value=.55*low+.27*noise+.24*math.sin(phase);env=math.exp(-[5.5,4.7,5.1][index]*u) + env*=min(1,t/.003)*min(1,(count-1-i)/(rate*.006));values.append(value*max(env,0)) + peak=max(abs(v)for v in values);amp=.4 if name=='warning'else(.62 if name=='shot'else.74);samples=[round(v/peak*amp*32767)for v in values];path=root/'audio'/f'{name}.wav' + with wave.open(str(path),'wb')as out:out.setnchannels(1);out.setsampwidth(2);out.setframerate(rate);out.writeframes(struct.pack('<'+'h'*count,*samples)) + files.append({'file':str(path.relative_to(root)),'seed':seed,'duration_seconds':count/rate,'samples':count,'format':'mono PCM16 little endian','sample_rate':rate,'peak':max(abs(v)for v in samples),'rms':math.sqrt(sum(v*v for v in samples)/count)/32767,'sha256':hashlib.sha256(path.read_bytes()).hexdigest()}) +(root/'audio-recipe.json').write_text(json.dumps({'generator':'generate_audio.py standard Python seeded chirp/filtered noise; no original recordings','files':files},indent=2)+'\n') +print(root.name,'3 valid PCM WAV cues reproduced') diff --git a/mods/iron_coast_stage2_interceptor/mod.toml b/mods/iron_coast_stage2_interceptor/mod.toml new file mode 100644 index 00000000..8117462f --- /dev/null +++ b/mods/iron_coast_stage2_interceptor/mod.toml @@ -0,0 +1,7 @@ +id = "iron_coast_stage2_interceptor" +name = "Iron Coast II: Needlewing" +version = "1.0.0" +api_version = 1 +description = "Independent Stage 2 interceptor: Needlewing. Scripted movement, readable volleys, SD/HD sprites and synthesized sounds." +content = "content.json" +scripts = ["scripts/ai.rhai", "scripts/gun.rhai"] diff --git a/mods/iron_coast_stage2_interceptor/prepare_art.rs b/mods/iron_coast_stage2_interceptor/prepare_art.rs new file mode 100644 index 00000000..e68cc49c --- /dev/null +++ b/mods/iron_coast_stage2_interceptor/prepare_art.rs @@ -0,0 +1,127 @@ +//! Derive aligned SD/HD canvases from unchanged built-in generated PNG masters. +//! The PNG master is never modified. Only wholly transparent margins are trimmed; +//! every occupied input alpha pixel remains inside the recorded source crop. +use image::{ + imageops::{self, FilterType}, + Rgba, RgbaImage, +}; +use serde_json::json; +use sha2::{Digest, Sha256}; +use std::{fs, path::Path}; +fn sha(p: &Path) -> String { + format!("{:x}", Sha256::digest(fs::read(p).unwrap())) +} +fn bounds(im: &RgbaImage, threshold: u8) -> (u32, u32, u32, u32) { + let (mut x0, mut y0, mut x1, mut y1) = (im.width(), im.height(), 0, 0); + for (x, y, p) in im.enumerate_pixels() { + if p[3] >= threshold { + x0 = x0.min(x); + y0 = y0.min(y); + x1 = x1.max(x + 1); + y1 = y1.max(y + 1); + } + } + assert!(x1 > x0 && y1 > y0, "empty sprite"); + (x0, y0, x1, y1) +} +fn filtered(im: &RgbaImage, w: u32, h: u32, filter: FilterType) -> RgbaImage { + // Resample premultiplied alpha to keep opaque dark interior recesses while + // preventing invisible RGB from becoming a dark fringe at the sprite edge. + let mut premul = im.clone(); + for p in premul.pixels_mut() { + for c in 0..3 { + p[c] = ((p[c] as u32 * p[3] as u32 + 127) / 255) as u8; + } + } + let mut out = imageops::resize(&premul, w, h, filter); + for p in out.pixels_mut() { + if p[3] == 0 { + *p = Rgba([0, 0, 0, 0]); + } else { + for c in 0..3 { + p[c] = ((p[c] as u32 * 255 + p[3] as u32 / 2) / p[3] as u32).min(255) as u8; + } + } + } + out +} +fn main() { + let arg = std::env::args().nth(1).expect("pass the mod directory"); + let root = Path::new(&arg); + let contract: serde_json::Value = + serde_json::from_slice(&fs::read(root.join("contract.json")).unwrap()).unwrap(); + let mut reports = Vec::new(); + for kind in ["unit", "projectile"] { + let (lw, lh) = if kind == "unit" { + ( + contract["logical_size"][0].as_u64().unwrap() as u32, + contract["logical_size"][1].as_u64().unwrap() as u32, + ) + } else { + (8, 8) + }; + let source_path = root.join(format!("art/{kind}-generated-v1.png")); + let original_sha = sha(&source_path); + let raw = image::open(&source_path).unwrap().into_rgba8(); + assert!( + raw.pixels().any(|p| p[3] == 0), + "generated source needs genuine transparent background" + ); + assert!( + raw.pixels().any(|p| p[3] == 255), + "generated source needs occupied opaque artwork" + ); + let (x0, y0, x1, y1) = bounds(&raw, 1); + let occupied = imageops::crop_imm(&raw, x0, y0, x1 - x0, y1 - y0).to_image(); + let scale = 8; + let pad = if kind == "unit" { 2 } else { 1 }; + let (limit_w, limit_h) = ((lw - pad * 2) * scale, (lh - pad * 2) * scale); + let (ow, oh) = occupied.dimensions(); + let (w, h) = if limit_w as u64 * oh as u64 <= limit_h as u64 * ow as u64 { + ( + limit_w, + ((oh as u64 * limit_w as u64 + ow as u64 / 2) / ow as u64) as u32, + ) + } else { + ( + ((ow as u64 * limit_h as u64 + oh as u64 / 2) / oh as u64) as u32, + limit_h, + ) + }; + let fitted = filtered(&occupied, w, h, FilterType::Lanczos3); + let mut hd = RgbaImage::new(lw * scale, lh * scale); + let offset = ((hd.width() - w) / 2, (hd.height() - h) / 2); + imageops::overlay(&mut hd, &fitted, offset.0 as i64, offset.1 as i64); + // Match the renderer's indexed HD-to-logical sample positions exactly. + // This retains the bright projectile core and aligns both modes at 1x. + let mut sd = RgbaImage::new(lw, lh); + for y in 0..lh { + for x in 0..lw { + sd.put_pixel(x, y, *hd.get_pixel(x * scale, y * scale)); + } + } + let sdb = bounds(&sd, 128); + let hdb = bounds(&hd, 128); + assert!( + sdb.0 >= 1 && sdb.1 >= 1 && sdb.2 < lw && sdb.3 < lh, + "SD clipped {kind}" + ); + assert!( + hdb.0 >= 1 && hdb.1 >= 1 && hdb.2 < hd.width() && hdb.3 < hd.height(), + "HD clipped {kind}" + ); + let sdpath = root.join(format!("art/{kind}-sd.png")); + let hdpath = root.join(format!("art/{kind}-hd.png")); + sd.save(&sdpath).unwrap(); + hd.save(&hdpath).unwrap(); + assert_eq!(sha(&source_path), original_sha); + reports.push(json!({"kind":kind,"raw_sha256":original_sha,"raw_dimensions":[raw.width(),raw.height()],"crop_all_alpha_ge_1":[x0,y0,x1,y1],"logical_canvas":[lw,lh],"hd_canvas":[hd.width(),hd.height()],"occupied_fit":[w,h],"offset_hd":[offset.0,offset.1],"sd_alpha128_bounds":[sdb.0,sdb.1,sdb.2,sdb.3],"hd_alpha128_bounds":[hdb.0,hdb.1,hdb.2,hdb.3],"logical_origin":[0,0],"frames":1,"sd_sha256":sha(&sdpath),"hd_sha256":sha(&hdpath)})); + } + let report = json!({"method":"prepare_art.rs: unchanged genuine alpha master, crop only transparent margin, aspect-preserving centered fit, premultiplied-alpha Lanczos3 HD8x and renderer-aligned floor-nearest SD; original images are style references only","source_unchanged":true,"all_occupied_input_alpha_retained_in_crop":true,"frames":reports}); + fs::write( + root.join("art-qa.json"), + serde_json::to_vec_pretty(&report).unwrap(), + ) + .unwrap(); + println!("Prepared aligned SD/HD art: {}", root.display()); +} diff --git a/mods/iron_coast_stage2_interceptor/prompts/projectile-v1.txt b/mods/iron_coast_stage2_interceptor/prompts/projectile-v1.txt new file mode 100644 index 00000000..7363bf22 --- /dev/null +++ b/mods/iron_coast_stage2_interceptor/prompts/projectile-v1.txt @@ -0,0 +1,5 @@ +Use case: stylized-concept +Asset type: one transparent original-palette Raptor-style hostile projectile sprite. +Input image1: authentic original8x8 Raptor bullet, palette/readability reference only. +Subject: one tiny amber kinetic needle shell pointing DOWN, bright warm central tip and short dark copper casing, clean tapered vertical silhouette. A new projectile for Needlewing, readable in an8x8logical game canvas. +Style: crisp overhead arcade game sprite detail, warm/muted metal accents matching classic Raptor, isolated single projectile. One centered frame on real transparent square canvas with at least15% transparent safe margins. Whole visible. DOWN orientation. Opaque dark interior; genuine alpha outside. No background, labels, smoke, muzzle explosion, fireworks, trail beyond sprite, giant bloom, contact sheet or extra projectiles. diff --git a/mods/iron_coast_stage2_interceptor/prompts/unit-v1.txt b/mods/iron_coast_stage2_interceptor/prompts/unit-v1.txt new file mode 100644 index 00000000..5f315768 --- /dev/null +++ b/mods/iron_coast_stage2_interceptor/prompts/unit-v1.txt @@ -0,0 +1,6 @@ +Use case: stylized-concept +Asset type: one transparent top-down sprite for the new Raptor-style enemy mod Needlewing. +Input image1: authentic original Raptor sprite, STYLE AND CAMERA REFERENCE ONLY; create the requested new enemy, not a duplicate. +Subject: A slim steel-grey swept-wing interceptor with a long pointed nose facing DOWN, narrow cyan cockpit and two compact dark rear engines. Its unmistakable angular needle silhouette is slimmer than the reference and reads cleanly at24x24. No glow, engine plume or smoke. +Style: faithful classic Raptor military arcade shooter remastered into crisp richly hand-painted HD sprite detail: small bevels, muted original palette, clear original-scale silhouette, upper-left metallic lighting, strictly orthographic overhead. +Canvas: one fully isolated sprite on REAL alpha-transparent background, centered with at least10% completely transparent safe space on every side; no text, watermark, backdrop, contact sheet or other sprites. Whole object visible. Logical canvas 24x24, source orientation down-screen. Native occupied black/dark recesses remain opaque; only space outside object transparent. One frame only. Aim for a square source canvas; do not imply extra content or effects outside the craft. Clean silhouette and clean alpha. Avoid photographic camera perspective, oblique views, neon saturation, large glows, generic modern vector icon style. diff --git a/mods/iron_coast_stage2_interceptor/provenance-projectile-v1.json b/mods/iron_coast_stage2_interceptor/provenance-projectile-v1.json new file mode 100644 index 00000000..7fa28db7 --- /dev/null +++ b/mods/iron_coast_stage2_interceptor/provenance-projectile-v1.json @@ -0,0 +1,15 @@ +{ + "output_hint": "Generated images are saved to /home/quintine/.codex/generated_images/01a129a5-9f83-7611-a949-ec6a80b026d4 as /home/quintine/.codex/generated_images/01a129a5-9f83-7611-a949-ec6a80b026d4/exec-29d65f5a-2c01-4f24-9672-4ec8650466e8.png by default.\nIf you need to use a generated image at another path, copy it and leave the original in place unless the user explicitly asks you to delete it.\nThe generated image is already displayed to the user. There is no need to render it in the final response as a Markdown image or file link.", + "lease": "5967e4d1-ea4f-46b8-a876-f1275a0a9c1b", + "job": "stage2-needlewing-projectile-v1", + "builtin_path": "/home/quintine/.codex/generated_images/01a129a5-9f83-7611-a949-ec6a80b026d4/exec-29d65f5a-2c01-4f24-9672-4ec8650466e8.png", + "raw_sha256": "3fa7d9897a3bce5d409ae468db7d6cb097b2793ca0e4efb416507baf66984a69", + "mode": "built-in imagegen", + "raw_unchanged": true, + "prompt": "prompts/projectile-v1.txt", + "original_style_reference_asset": "101d6", + "original_reference_copies_shipped": false, + "external_style_reference_png_sha256": "090d5cd708457f92c04253328ac47413f2cc53b6f83546df92c816d3debbcbcc", + "original_style_reference_payload_sha256": "73dfa9a1f1313b1b9bbd71c3f3e2086ffb0440d5a298d98cbb4de407a9faaf2b", + "original_palette_payload_sha256": "1cf6adb926d1dee1888b3e3d33b51a7049b3e5eb5f90a3067ef71c8970547204" +} diff --git a/mods/iron_coast_stage2_interceptor/provenance-unit-v1.json b/mods/iron_coast_stage2_interceptor/provenance-unit-v1.json new file mode 100644 index 00000000..39270ff1 --- /dev/null +++ b/mods/iron_coast_stage2_interceptor/provenance-unit-v1.json @@ -0,0 +1,16 @@ +{ + "output_hint": "Generated images are saved to /home/quintine/.codex/generated_images/01a129a5-9f83-7611-a949-ec6a80b026d4 as /home/quintine/.codex/generated_images/01a129a5-9f83-7611-a949-ec6a80b026d4/exec-04a2c21c-b9fe-4793-aa71-d0b115af5c49.png by default.\nIf you need to use a generated image at another path, copy it and leave the original in place unless the user explicitly asks you to delete it.\nThe generated image is already displayed to the user. There is no need to render it in the final response as a Markdown image or file link.", + "lease": "76e3ea1c-4c47-490e-b7c1-63aacb5a62d8", + "job": "stage2-needlewing-unit-v1", + "builtin_path": "/home/quintine/.codex/generated_images/01a129a5-9f83-7611-a949-ec6a80b026d4/exec-04a2c21c-b9fe-4793-aa71-d0b115af5c49.png", + "raw_sha256": "63dbe918a54b0eb63244f43c457a6b5159810d748b3c196c54e6740fcf09d38f", + "mode": "built-in imagegen", + "raw_unchanged": true, + "prompt": "prompts/unit-v1.txt", + "reference_asset": "102f8", + "original_style_reference_asset": "102f8", + "original_reference_copies_shipped": false, + "external_style_reference_png_sha256": "3b075b95941b123c9fed4127b555d8f5a96c339aa6f614e04ba2973b7061c07b", + "original_style_reference_payload_sha256": "ada9598e7844d77c0fb8d782b74128772d94d901dc873b4fa23b2c1c009a951b", + "original_palette_payload_sha256": "1cf6adb926d1dee1888b3e3d33b51a7049b3e5eb5f90a3067ef71c8970547204" +} diff --git a/mods/iron_coast_stage2_interceptor/scripts/ai.rhai b/mods/iron_coast_stage2_interceptor/scripts/ai.rhai new file mode 100644 index 00000000..7a75a53e --- /dev/null +++ b/mods/iron_coast_stage2_interceptor/scripts/ai.rhai @@ -0,0 +1,125 @@ +// Integer-only per-entity clocks. No spawns, equipment grants or direct damage. +// The engine owns collision, one kill reward, projectile retirement and explosions. +fn alive(event) { + for unit in event.entities { + if unit.entity == event.entity && unit.health > 0 { return true; } + } + false +} +// Firing events use muzzle coordinates; visibility must use the real canvas. +fn ready_to_fire(event) { + for unit in event.entities { + if unit.entity == event.entity { + return unit.health > 0 && unit.x >= 0 && unit.x + unit.width <= 320 && unit.y >= 0 && unit.y + unit.height <= 180 && unit.y + unit.height < event.player.y - 8; + } + } + false +} +fn fresh(random) { #{clock:0, sign: if random[0] % 2 == 0 {1} else {-1}, remaining:0, wait:0, aim_x:0, aim_y:3} } +fn ready(state) { + if !state.contains("units") { state.units = #{}; } + if !state.contains("dead") { state.dead = #{}; } + if !state.contains("dead_order") { state.dead_order = []; } + state +} +fn tidy(event, state) { + state = ready(state); + let retained = #{}; + for unit in event.entities { + let key = unit.entity.to_string(); + if unit.definition == "iron_coast_stage2_interceptor:unit" && unit.health > 0 && state.units.contains(key) && retained.len() < 128 { + retained[key] = state.units[key]; + } + } + state.units = retained; + state +} +fn counter(state, key) { + if !state.contains(key) {return 1;} + if state[key] >= 1000000000 {return 1000000000;} + state[key] + 1 +} +fn clamp_speed(value) { if value < -3 {-3} else if value > 3 {3} else {value} } +fn aimed(event) { + let dx = event.player.x + 16 - event.x; + let dy = event.player.y + 16 - event.y; + let ax = if dx < 0 {-dx} else {dx}; + let ay = if dy < 0 {-dy} else {dy}; + let norm = if ax > ay {ax} else {ay}; + if norm == 0 {return [0,3];} + let vy = dy * 3 / norm; + [clamp_speed(dx * 3 / norm), if vy < 1 {1} else {vy}] +} +fn on_spawn(event, state, random) { + state = tidy(event,state); + let key = event.entity.to_string(); + // Entity IDs restart with each mission. Clear the old lifecycle guard even + // when a spawn was already killed before queued callbacks are dispatched. + state.dead.remove(key); + let keep = []; + for old in state.dead_order { if old != key {keep.push(old);} } + state.dead_order = keep; + if !alive(event) {return #{commands:[],state:state};} + if state.units.len() >= 128 {return #{commands:[],state:state};} + let unit = fresh(random); + state.units[key] = unit; + #{commands:[#{op:"velocity",entity:event.entity,vx:unit.sign,vy:1}],state:state} +} +fn on_fire(event, state, random) { + state = ready(state); + if !ready_to_fire(event) || event.x < 0 || event.x >= 320 || event.y < 24 || event.y > 180 || event.y >= event.player.y - 8 { + return #{commands:[],state:state}; + } + let key = event.entity.to_string(); + if !state.units.contains(key) {return #{commands:[],state:state};} + let unit = state.units[key]; + let aim = aimed(event); + unit.remaining = 3; unit.wait = 0; + unit.aim_x = aim[0]; unit.aim_y = aim[1]; + state.units[key] = unit; + #{commands:[],state:state} +} +fn on_tick(event, state, random) { + state = ready(state); + // Stagger periodic pruning to keep dense waves within the shared script budget. + if (event.tick + event.entity) % 32 == 0 { state = tidy(event,state); } + if event.health <= 0 || !alive(event) {return #{commands:[],state:state};} + let key = event.entity.to_string(); + if !state.units.contains(key) {return #{commands:[],state:state};} + let unit = state.units[key]; + unit.clock = (unit.clock + 1) % 96; + let phase = unit.clock / 12; + let route = [2,1,0,-1,-2,-1,0,1]; + let sideways = route[phase] * unit.sign; + let down = if unit.clock % 48 < 12 {2} else {1}; + if event.x <= 8 {sideways = 1;} + if event.x >= 320 - 24 - 8 {sideways = -1;} + let commands = [#{op:"velocity",entity:event.entity,vx:sideways,vy:down}]; + // Never fire from an invisible/dead unit, or backwards at a player it passed. + if event.x < 0 || event.x + 24 > 320 || event.y < 0 || event.y + 24 > 180 || event.y + 24 >= event.player.y - 8 { + unit.remaining = 0; + } + if unit.wait > 0 {unit.wait -= 1;} + if unit.remaining > 0 && unit.wait == 0 { + commands.push(#{op:"projectile",weapon:"iron_coast_stage2_interceptor:projectile",x:event.x+8,y:event.y+22,vx:unit.aim_x,vy:unit.aim_y,hostile:true}); + unit.remaining -= 1;unit.wait=4; + commands.push(#{op:"play_sound",sound:"iron_coast_stage2_interceptor:shot"}); + state.shots = counter(state,"shots"); + } + state.units[key] = unit; + #{commands:commands,state:state} +} +fn on_hit(event, state, random) { + state.hits = counter(state,"hits"); + #{commands:[],state:state} +} +fn on_death(event, state, random) { + state = tidy(event,state); + let key = event.entity.to_string(); + if alive(event) || state.dead.contains(key) {return #{commands:[],state:state};} + if state.dead_order.len() >= 128 {let oldest=state.dead_order.remove(0);state.dead.remove(oldest);} + state.dead[key] = true; state.dead_order.push(key); state.units.remove(key); + state.destroyed = counter(state,"destroyed"); + let defeated = if event.objectives.contains("iron_coast_stage2_interceptor:defeated") {event.objectives["iron_coast_stage2_interceptor:defeated"] + 1} else {1}; + #{commands:[#{op:"objective",key:"iron_coast_stage2_interceptor:defeated",value:defeated},#{op:"play_sound",sound:"iron_coast_stage2_interceptor:death"}],state:state} +} diff --git a/mods/iron_coast_stage2_interceptor/scripts/gun.rhai b/mods/iron_coast_stage2_interceptor/scripts/gun.rhai new file mode 100644 index 00000000..a5f05834 --- /dev/null +++ b/mods/iron_coast_stage2_interceptor/scripts/gun.rhai @@ -0,0 +1,3 @@ +// The engine supplies the firing cooldown. This wrapper deliberately emits +// no default projectile: the enemy AI schedules its own bounded burst. +fn on_fire(event, state, random) { #{commands: [], state: state} } diff --git a/mods/iron_coast_stage2_interceptor/validation/acceptance.json b/mods/iron_coast_stage2_interceptor/validation/acceptance.json new file mode 100644 index 00000000..37764d0b --- /dev/null +++ b/mods/iron_coast_stage2_interceptor/validation/acceptance.json @@ -0,0 +1,49 @@ +{ + "api_version": 1, + "owned_package": "iron_coast_stage2_interceptor", + "portable_actual_world_tests": { + "command": "cargo test --locked --no-default-features --test stage2_enemies -- --nocapture", + "passed": 9, + "failed": 0, + "test_log_sha256": "1ceb868b5dcb07efd054f529a5356069c1837dd45f27f536886124782256d862", + "coverage": [ + "independent and Stage1 coexistence activation", + "exact engine cooldown/finite burst/warning ticks", + "distinct bounded movement and escape without reward", + "actual ground/air collision filtering and damaged crawler shell loss", + "actual death rewards/objectives once and reused IDs after queued early kills", + "full serialized World plus Rhai state and RNG deterministic continuation", + "260 deaths per package with bounded128 history/live state", + "shipped PNG dimensions/padding/unchanged source SHA and all9SoundBank/Mixer nonzero unclipped effects", + "no invisible/passed-unit warning/projectile from muzzle-coordinate event" + ] + }, + "shipped_assets": { + "SD_HD_PNGs": 4, + "unchanged_generated_masters": 2, + "WAV_effects": 3, + "alpha_and_alignment": "checked; equal logical canvas/aspect;one frame;origin0,0;opaque content leaves padding" + }, + "local_visual_review": { + "actual_palette_outputs": 16, + "modes": [ + "SD", + "HD" + ], + "scales": [ + 1, + 2, + 3, + 4 + ], + "reserved_animated_palette_indices": 0, + "scope": "Actual art_sprite_variant plus identical desktop scaling branch, full diagnostic gallery visually inspected; not a live SDL Host scene. Fine HD details simplify in SD. Full raw masters inspected earlier; unedited generator bytes and exact hashes retained." + }, + "real_catalog_validation": "Included assets and scripts passed real-catalog activation; final whole-folder pins and CLI reruns are recorded outside package in .reference/stage2-enemies/final-handoff.json to avoid recursive content hashes.", + "limits": [ + "No whole-campaign balance or live SDL scene claim by this package owner; mission owners and independent reviewer validate integration.", + "Ordinary targets may escape; required mission targets must be held by mission logic.", + "Custom AI state is capped128 per package; dense enemy spawning remains a mission-author balance responsibility.", + "No platform source or launcher changes." + ] +} diff --git a/mods/iron_coast_stage2_mission_1/README.md b/mods/iron_coast_stage2_mission_1/README.md new file mode 100644 index 00000000..dedf41e3 --- /dev/null +++ b/mods/iron_coast_stage2_mission_1/README.md @@ -0,0 +1,50 @@ +# Iron Coast II — Mission 1: Nightbreak Inlet + +An independently playable Black Tide sortie with native Raptor aircraft paths, +new patrols and its own boss. Enable **Nightbreak Inlet** in **Mods**; installed compatible +required enemy/boss/music dependencies are selected automatically. Select +`iron_coast_stage2_mission_1:mission_01` in the hangar. Installing the optional full Black Tide +campaign places this sortie in its eight-mission progression. + +Destroy 3 actual `siege` units and then the `iron_coast_stage2_boss_1:unit` boss. Required +convoys are held inside the reachable playfield after entry; leaving or despawning +never counts as destruction. The boss arrives at tick 1900. A duration +timeout cannot grant victory. Completion awards 24,000 credits once, in addition +to actual enemy rewards. Replaying resets this sortie's kill counters and phases. + +Hold **Ctrl/Fire** to use owned weapons; **Alt/Shift** cycles selected weapons; +**Space** retains bombs. Starter forward guns can target all mandatory enemies; +optional purchased gear improves firepower. The mission grants no equipment or +shield/credit cheats, and works with a full 20-slot inventory. + +New terrain is generated from original Raptor material/palette references, with a +320×512 logical map and a reflected scroll cycle repeated through 4,096 rows. +This preserves terrain beneath delayed boss fights. All mandatory targets appear +on every difficulty; higher difficulties add patrol reinforcements. The briefing crops the same +master. Both SD and 4× HD terrain and generated WAV mission cues are tracked. +`build_assets.py` reproduces all derived art/audio from the untouched raw master. +See [generation provenance](generation-provenance.json) and +[asset recipe/report](asset-report.json). Original reference images and working +review captures stay outside the package. + +```sh +python3 mods/iron_coast_stage2_mission_1/build_assets.py +CARGO_TARGET_DIR="$PWD/target" cargo run --locked --release --manifest-path mods/iron_coast_stage2_boss_1/validation/Cargo.toml +``` + +The CLI requires all dependency IDs explicitly; the in-game manager resolves them. +Final real-catalog gameplay, audio, native path and save/RNG observations are +recorded in `acceptance-report.json`. Local single-sortie campaign definition +uses no overrides, so the optional aggregate campaign controls progression. + +Author acceptance passed seven complete cases: difficulties 0–3 with starter +guns, default 100-shield, a full 20-slot inventory, and owned optional new gear. +The registered 75-shield pilot completes at tick 2222 with 69 shield and +a 41,010-credit gain using ordinary Fire and a mouse movement cap of +four logical pixels per tick. Serialized script state/RNG continuation, replay +reset, reward-once and actual native path motion checks passed. A separate +health-buffer fixture verifies reachable targets and terrain after 5,000 ticks; +it is not a balance result. The purchased-gear fixture funds shop purchases +before gameplay, rather than claiming a new pilot can afford both weapons. + +Asset recipes use Python 3 with Pillow. The game uses the shipped PNG and WAV files. diff --git a/mods/iron_coast_stage2_mission_1/acceptance-report.json b/mods/iron_coast_stage2_mission_1/acceptance-report.json new file mode 100644 index 00000000..4f5dfe89 --- /dev/null +++ b/mods/iron_coast_stage2_mission_1/acceptance-report.json @@ -0,0 +1,400 @@ +{ + "utc": "2026-10-11T08:51:02.199238+00:00", + "status": "author_checked_review_ready", + "real_catalog": true, + "engine_source_hashes_at_report": { + "src/assets.rs": "4cdf11a229f6ca4c6183fb545dba43e9a2323f839f7a095292045aa13a773ddc", + "src/content.rs": "7f35df7100c450ba4bb30a0fdc90101c115b5ae42a7aac57829441c5b7761647", + "src/modding.rs": "f37d67004392f5726121e58a995900cd7062016e3f060ea131b0df38995e2912", + "src/simulation.rs": "0ec9f6da11ab82c1461868a7b147e4cdb14689fa7373bd0c24067d9014e9583a", + "src/render.rs": "d4abdccbc3c1ee840ef8548bcff43080521937ef9f9f5ed69e810f417ef1e842", + "src/sound.rs": "aff6779b85f9f4f4bc30a15ad75ec6fdd61d42895639700f4842870636e73c4b", + "src/persistence.rs": "9a4adf1e33d3504db3d4d3e6091316cc7116fb35c89b2de8fbd4640d368aa0e2", + "Cargo.lock": "aac0a22725250ab35828223f8d129e4d2a4e6113cf81463e59600da3a59ffdea" + }, + "catalog_file_hashes": { + "data/INDEX": "4ce78e5e638b6603114dd233ceaa41f386c0963ba4aa02ecf88ce0215b096681", + "data/misc/PALETTE_DAT": "1cf6adb926d1dee1888b3e3d33b51a7049b3e5eb5f90a3067ef71c8970547204", + "data/misc/GENMIDI_OP2": "fdc93c076bf44207299e61ec1bbcfafca421454bfa99dd14fa4e5dcada1547b9" + }, + "compiled_validation_binary_sha256": "98f43eef5943061a18a465e95e8089189be793b9f8cbac275b8ebe982953567b", + "full_external_result_sha256": "63f97c1f8cab57452ee9235124551178fe2593c5e40f4a5ecd6e2aa9bf0cd19e", + "cli": { + "selected_packages": 10, + "overrides": 0, + "log_sha256": "c9401f44dc4fa438f75ccc00223e95f79cfa8bffcd1c8db5c106963f7b474822" + }, + "visual_limits": "Author inspected native indexed SD1/HD4 Canvas/PNG-loader diagnostics, exact new source masters and SD/HD final art. Terrain in owned captures uses a simplified row sampler. Live SDL/Host captures and independent eight-stage progression are root-owned; no live device or whole-map rendering claim.", + "package": "iron_coast_stage2_mission_1", + "content_sha256": "704c47ade42d414346c327386e258eb19cc1acdc4d82ed23df733801d6fa790c", + "scripts": { + "scripts/mission.rhai": "d3d35ac92e5fc821a84c2aa2c5c7ba2dd4f82a2e1f626211d7bbb314f3ef2af7" + }, + "asset_report_sha256": "750d0bacfbe02ead4c723233e343b5078a4412ed26df1f9458b25ebaaf3b9d13", + "raw_identity_checks": [ + { + "package": "iron_coast_stage2_mission_1", + "role": "unit_or_terrain", + "raw": "mods/iron_coast_stage2_mission_1/art/terrain-generated-v1.png", + "raw_sha256": "b505fda73b613d34c5646ecb3f081aeec6d48d67c5386549376bc29633849aa6", + "builtin_byte_identical": true, + "raw_dimensions": [ + 992, + 1586 + ], + "raw_alpha": "RGB", + "reported_success": true + } + ], + "mission_acceptance": { + "enabled_packages": [ + "iron_coast_stage2_music", + "iron_coast_stage2_interceptor", + "iron_coast_stage2_siege", + "iron_coast_stage2_boss_1", + "iron_coast_stage2_mission_1" + ], + "late_fight_fixture": { + "boss_remains": true, + "playing_beyond_declared_duration": true, + "reachable_required_units": 3, + "scope": "Persistence-only difficulty3 fixture restoring shield10000 before each step to suppress pilot death; ordinary balance runs above have no health/damage cheats.", + "scroll": 5000, + "terrain_covered": true, + "terrain_rows": 4096, + "tick": 5000 + }, + "missing_one_required_death_blocks_victory": true, + "mission": "iron_coast_stage2_mission_1:mission_01", + "required_deaths": 3, + "runs": [ + { + "captures": [ + 500, + 1600, + 2000 + ], + "credit_gain": 41010, + "credits": 51010, + "cues": [ + "iron_coast_stage2_boss_1:death", + "iron_coast_stage2_boss_1:shot", + "iron_coast_stage2_boss_1:warning", + "iron_coast_stage2_interceptor:death", + "iron_coast_stage2_interceptor:shot", + "iron_coast_stage2_mission_1:approach", + "iron_coast_stage2_mission_1:boss_alarm", + "iron_coast_stage2_mission_1:objective", + "iron_coast_stage2_mission_1:victory", + "iron_coast_stage2_siege:death", + "iron_coast_stage2_siege:shot", + "iron_coast_stage2_siege:warning" + ], + "difficulty": 2, + "digest": "ec1f4ac443bb793035f68641412c7080abaf0a8938e89792f0fffe6d8b903008", + "full20_inventory": false, + "initial_credits": 10000, + "initial_shield": 75, + "native_classes_moving": [ + "base:enemy_0_20", + "base:enemy_0_23", + "base:enemy_0_56" + ], + "objectives": { + "iron_coast_stage2_boss_1:defeated": 1, + "iron_coast_stage2_interceptor:defeated": 7, + "iron_coast_stage2_mission_1:complete": 1, + "iron_coast_stage2_mission_1:debrief": 1, + "iron_coast_stage2_mission_1:phase": 3, + "iron_coast_stage2_siege:defeated": 3 + }, + "purchased_new_gear": false, + "replay_reset": true, + "reward_once": true, + "serialized_state_rng_round_trip_identical": true, + "shield": 69, + "tick": 2222 + }, + { + "captures": [], + "credit_gain": 41010, + "credits": 41010, + "cues": [ + "iron_coast_stage2_boss_1:death", + "iron_coast_stage2_boss_1:shot", + "iron_coast_stage2_boss_1:warning", + "iron_coast_stage2_interceptor:death", + "iron_coast_stage2_interceptor:shot", + "iron_coast_stage2_mission_1:approach", + "iron_coast_stage2_mission_1:boss_alarm", + "iron_coast_stage2_mission_1:objective", + "iron_coast_stage2_mission_1:victory", + "iron_coast_stage2_siege:death", + "iron_coast_stage2_siege:shot", + "iron_coast_stage2_siege:warning" + ], + "difficulty": 2, + "digest": "f403c999e4e9a5830cbce1cbf2c3bba1d509639f0cf018ce4213827ba30c782d", + "full20_inventory": false, + "initial_credits": 0, + "initial_shield": 100, + "native_classes_moving": [ + "base:enemy_0_20", + "base:enemy_0_23", + "base:enemy_0_56" + ], + "objectives": { + "iron_coast_stage2_boss_1:defeated": 1, + "iron_coast_stage2_interceptor:defeated": 7, + "iron_coast_stage2_mission_1:complete": 1, + "iron_coast_stage2_mission_1:debrief": 1, + "iron_coast_stage2_mission_1:phase": 3, + "iron_coast_stage2_siege:defeated": 3 + }, + "purchased_new_gear": false, + "replay_reset": true, + "reward_once": true, + "serialized_state_rng_round_trip_identical": true, + "shield": 94, + "tick": 2222 + }, + { + "captures": [], + "credit_gain": 41060, + "credits": 51060, + "cues": [ + "iron_coast_stage2_boss_1:death", + "iron_coast_stage2_boss_1:shot", + "iron_coast_stage2_boss_1:warning", + "iron_coast_stage2_interceptor:death", + "iron_coast_stage2_mission_1:approach", + "iron_coast_stage2_mission_1:boss_alarm", + "iron_coast_stage2_mission_1:objective", + "iron_coast_stage2_mission_1:victory", + "iron_coast_stage2_siege:death", + "iron_coast_stage2_siege:shot", + "iron_coast_stage2_siege:warning" + ], + "difficulty": 2, + "digest": "ebe455bdae69846bcebbc667e59a81bec6b99c6d5aced6fc9d928529d1c519ef", + "full20_inventory": true, + "initial_credits": 10000, + "initial_shield": 75, + "native_classes_moving": [ + "base:enemy_0_20", + "base:enemy_0_23", + "base:enemy_0_56" + ], + "objectives": { + "iron_coast_stage2_boss_1:defeated": 1, + "iron_coast_stage2_interceptor:defeated": 8, + "iron_coast_stage2_mission_1:complete": 1, + "iron_coast_stage2_mission_1:debrief": 1, + "iron_coast_stage2_mission_1:phase": 3, + "iron_coast_stage2_siege:defeated": 3 + }, + "purchased_new_gear": false, + "replay_reset": true, + "reward_once": true, + "serialized_state_rng_round_trip_identical": true, + "shield": 63, + "tick": 2058 + }, + { + "captures": [], + "credit_gain": 41060, + "credits": 51060, + "cues": [ + "iron_coast_railburst:fire", + "iron_coast_railburst:impact", + "iron_coast_stage2_boss_1:death", + "iron_coast_stage2_boss_1:warning", + "iron_coast_stage2_interceptor:death", + "iron_coast_stage2_interceptor:shot", + "iron_coast_stage2_mission_1:approach", + "iron_coast_stage2_mission_1:boss_alarm", + "iron_coast_stage2_mission_1:objective", + "iron_coast_stage2_mission_1:victory", + "iron_coast_stage2_siege:death" + ], + "difficulty": 2, + "digest": "dfce13c44c4821caa2612c239a2a41312c2f23f2b8e310c645d9b38ad6ea5852", + "full20_inventory": false, + "initial_credits": 10000, + "initial_shield": 75, + "native_classes_moving": [ + "base:enemy_0_20", + "base:enemy_0_23", + "base:enemy_0_56" + ], + "objectives": { + "iron_coast_stage2_boss_1:defeated": 1, + "iron_coast_stage2_interceptor:defeated": 8, + "iron_coast_stage2_mission_1:complete": 1, + "iron_coast_stage2_mission_1:debrief": 1, + "iron_coast_stage2_mission_1:phase": 3, + "iron_coast_stage2_siege:defeated": 3 + }, + "purchased_new_gear": true, + "replay_reset": true, + "reward_once": true, + "serialized_state_rng_round_trip_identical": true, + "shield": 57, + "tick": 2008 + }, + { + "captures": [], + "credit_gain": 38610, + "credits": 48610, + "cues": [ + "iron_coast_stage2_boss_1:death", + "iron_coast_stage2_boss_1:shot", + "iron_coast_stage2_boss_1:warning", + "iron_coast_stage2_interceptor:death", + "iron_coast_stage2_interceptor:shot", + "iron_coast_stage2_mission_1:approach", + "iron_coast_stage2_mission_1:boss_alarm", + "iron_coast_stage2_mission_1:objective", + "iron_coast_stage2_mission_1:victory", + "iron_coast_stage2_siege:death", + "iron_coast_stage2_siege:shot", + "iron_coast_stage2_siege:warning" + ], + "difficulty": 0, + "digest": "c3456a349cabd2db8264acd1fda92215e82449e16a5170213fd815568b46e4b8", + "full20_inventory": false, + "initial_credits": 10000, + "initial_shield": 75, + "native_classes_moving": [ + "base:enemy_0_20", + "base:enemy_0_23", + "base:enemy_0_56" + ], + "objectives": { + "iron_coast_stage2_boss_1:defeated": 1, + "iron_coast_stage2_interceptor:defeated": 3, + "iron_coast_stage2_mission_1:complete": 1, + "iron_coast_stage2_mission_1:debrief": 1, + "iron_coast_stage2_mission_1:phase": 3, + "iron_coast_stage2_siege:defeated": 3 + }, + "purchased_new_gear": false, + "replay_reset": true, + "reward_once": true, + "serialized_state_rng_round_trip_identical": true, + "shield": 75, + "tick": 2062 + }, + { + "captures": [], + "credit_gain": 40360, + "credits": 50360, + "cues": [ + "iron_coast_stage2_boss_1:death", + "iron_coast_stage2_boss_1:shot", + "iron_coast_stage2_boss_1:warning", + "iron_coast_stage2_interceptor:death", + "iron_coast_stage2_interceptor:shot", + "iron_coast_stage2_mission_1:approach", + "iron_coast_stage2_mission_1:boss_alarm", + "iron_coast_stage2_mission_1:objective", + "iron_coast_stage2_mission_1:victory", + "iron_coast_stage2_siege:death", + "iron_coast_stage2_siege:shot", + "iron_coast_stage2_siege:warning" + ], + "difficulty": 1, + "digest": "0bc4f6db0fa88616fe6a6c224521768f9d6195f6526829016455c2a0ed632cfd", + "full20_inventory": false, + "initial_credits": 10000, + "initial_shield": 75, + "native_classes_moving": [ + "base:enemy_0_20", + "base:enemy_0_23", + "base:enemy_0_56" + ], + "objectives": { + "iron_coast_stage2_boss_1:defeated": 1, + "iron_coast_stage2_interceptor:defeated": 4, + "iron_coast_stage2_mission_1:complete": 1, + "iron_coast_stage2_mission_1:debrief": 1, + "iron_coast_stage2_mission_1:phase": 3, + "iron_coast_stage2_siege:defeated": 3 + }, + "purchased_new_gear": false, + "replay_reset": true, + "reward_once": true, + "serialized_state_rng_round_trip_identical": true, + "shield": 73, + "tick": 2062 + }, + { + "captures": [], + "credit_gain": 41010, + "credits": 51010, + "cues": [ + "iron_coast_stage2_boss_1:death", + "iron_coast_stage2_boss_1:shot", + "iron_coast_stage2_boss_1:warning", + "iron_coast_stage2_interceptor:death", + "iron_coast_stage2_interceptor:shot", + "iron_coast_stage2_mission_1:approach", + "iron_coast_stage2_mission_1:boss_alarm", + "iron_coast_stage2_mission_1:objective", + "iron_coast_stage2_mission_1:victory", + "iron_coast_stage2_siege:death", + "iron_coast_stage2_siege:shot", + "iron_coast_stage2_siege:warning" + ], + "difficulty": 3, + "digest": "aff9e08453c3a507c4b81d15d7de218eb0774a0a0bd65794c97f92fdb880fa7a", + "full20_inventory": false, + "initial_credits": 10000, + "initial_shield": 75, + "native_classes_moving": [ + "base:enemy_0_20", + "base:enemy_0_23", + "base:enemy_0_56" + ], + "objectives": { + "iron_coast_stage2_boss_1:defeated": 1, + "iron_coast_stage2_interceptor:defeated": 7, + "iron_coast_stage2_mission_1:complete": 1, + "iron_coast_stage2_mission_1:debrief": 1, + "iron_coast_stage2_mission_1:phase": 3, + "iron_coast_stage2_siege:defeated": 3 + }, + "purchased_new_gear": false, + "replay_reset": true, + "reward_once": true, + "serialized_state_rng_round_trip_identical": true, + "shield": 69, + "tick": 2222 + } + ] + }, + "normal_control_strategy": "Held Fire; mouseposition moves\u22644 logicalpx/tick, y160, aim at required living convoy centers then boss then ordinary visible enemies. No damage/shield/credit cheats or loans.", + "purchased_gear_fixture_scope": "The controlled shop preflight funds the 1,210,000-credit cost of owning both optional weapons before the sortie. It checks actual Pilot.buy/selection and gear preservation, and leaves10,000 credits for gameplay. It does not claim a newly registered pilot can afford both weapons.", + "sound_mixer_checks": [ + { + "fx_mute_zero": true, + "mixed_peak": 2176, + "sound": "iron_coast_stage2_mission_1:approach" + }, + { + "fx_mute_zero": true, + "mixed_peak": 2176, + "sound": "iron_coast_stage2_mission_1:boss_alarm" + }, + { + "fx_mute_zero": true, + "mixed_peak": 2176, + "sound": "iron_coast_stage2_mission_1:objective" + }, + { + "fx_mute_zero": true, + "mixed_peak": 2560, + "sound": "iron_coast_stage2_mission_1:victory" + } + ] +} diff --git a/mods/iron_coast_stage2_mission_1/art/briefing-hd.png b/mods/iron_coast_stage2_mission_1/art/briefing-hd.png new file mode 100644 index 00000000..147a7a08 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/briefing-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/briefing-sd.png b/mods/iron_coast_stage2_mission_1/art/briefing-sd.png new file mode 100644 index 00000000..c1d6218b Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/briefing-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/terrain-generated-v1.png b/mods/iron_coast_stage2_mission_1/art/terrain-generated-v1.png new file mode 100644 index 00000000..7c5d61dc Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/terrain-generated-v1.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/terrain-preview-hd.png b/mods/iron_coast_stage2_mission_1/art/terrain-preview-hd.png new file mode 100644 index 00000000..0665a354 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/terrain-preview-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/terrain-preview-sd.png b/mods/iron_coast_stage2_mission_1/art/terrain-preview-sd.png new file mode 100644 index 00000000..4ec095a3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/terrain-preview-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_000-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_000-hd.png new file mode 100644 index 00000000..111c3140 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_000-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_000-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_000-sd.png new file mode 100644 index 00000000..d7bd938b Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_000-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_001-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_001-hd.png new file mode 100644 index 00000000..f3e8d101 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_001-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_001-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_001-sd.png new file mode 100644 index 00000000..700dbc15 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_001-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_002-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_002-hd.png new file mode 100644 index 00000000..32e04b03 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_002-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_002-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_002-sd.png new file mode 100644 index 00000000..5457838d Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_002-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_003-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_003-hd.png new file mode 100644 index 00000000..88dea746 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_003-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_003-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_003-sd.png new file mode 100644 index 00000000..36322458 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_003-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_004-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_004-hd.png new file mode 100644 index 00000000..111d8ac1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_004-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_004-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_004-sd.png new file mode 100644 index 00000000..3ad04f76 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_004-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_005-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_005-hd.png new file mode 100644 index 00000000..246bffa4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_005-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_005-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_005-sd.png new file mode 100644 index 00000000..dc0fa978 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_005-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_006-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_006-hd.png new file mode 100644 index 00000000..5dd02017 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_006-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_006-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_006-sd.png new file mode 100644 index 00000000..1009a8a8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_006-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_007-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_007-hd.png new file mode 100644 index 00000000..02d6616d Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_007-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_007-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_007-sd.png new file mode 100644 index 00000000..0b41e18b Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_007-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_008-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_008-hd.png new file mode 100644 index 00000000..17cfe7f1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_008-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_008-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_008-sd.png new file mode 100644 index 00000000..32470e6d Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_008-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_009-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_009-hd.png new file mode 100644 index 00000000..b305cad6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_009-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_009-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_009-sd.png new file mode 100644 index 00000000..7fa56b25 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_009-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_010-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_010-hd.png new file mode 100644 index 00000000..2f07fa56 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_010-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_010-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_010-sd.png new file mode 100644 index 00000000..0d4fd8a0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_010-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_011-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_011-hd.png new file mode 100644 index 00000000..d46f5cb4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_011-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_011-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_011-sd.png new file mode 100644 index 00000000..071fe3e0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_011-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_012-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_012-hd.png new file mode 100644 index 00000000..ac779973 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_012-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_012-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_012-sd.png new file mode 100644 index 00000000..48cc3e30 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_012-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_013-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_013-hd.png new file mode 100644 index 00000000..23a6c83d Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_013-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_013-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_013-sd.png new file mode 100644 index 00000000..1c76afac Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_013-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_014-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_014-hd.png new file mode 100644 index 00000000..9c22f7d0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_014-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_014-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_014-sd.png new file mode 100644 index 00000000..6f9c4b17 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_014-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_015-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_015-hd.png new file mode 100644 index 00000000..7c1fa3e0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_015-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_015-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_015-sd.png new file mode 100644 index 00000000..d3e60852 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_015-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_016-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_016-hd.png new file mode 100644 index 00000000..477abc91 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_016-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_016-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_016-sd.png new file mode 100644 index 00000000..bd11546d Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_016-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_017-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_017-hd.png new file mode 100644 index 00000000..1b07783e Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_017-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_017-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_017-sd.png new file mode 100644 index 00000000..227fef7b Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_017-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_018-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_018-hd.png new file mode 100644 index 00000000..0271bb74 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_018-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_018-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_018-sd.png new file mode 100644 index 00000000..498b61fd Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_018-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_019-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_019-hd.png new file mode 100644 index 00000000..8994063f Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_019-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_019-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_019-sd.png new file mode 100644 index 00000000..674852d6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_019-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_020-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_020-hd.png new file mode 100644 index 00000000..4f29f7bc Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_020-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_020-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_020-sd.png new file mode 100644 index 00000000..379e046f Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_020-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_021-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_021-hd.png new file mode 100644 index 00000000..3b8a977d Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_021-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_021-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_021-sd.png new file mode 100644 index 00000000..d7030394 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_021-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_022-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_022-hd.png new file mode 100644 index 00000000..7d216758 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_022-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_022-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_022-sd.png new file mode 100644 index 00000000..9076b68c Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_022-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_023-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_023-hd.png new file mode 100644 index 00000000..4bd0fec5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_023-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_023-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_023-sd.png new file mode 100644 index 00000000..6686cdac Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_023-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_024-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_024-hd.png new file mode 100644 index 00000000..7094a7d1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_024-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_024-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_024-sd.png new file mode 100644 index 00000000..ffc955ce Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_024-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_025-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_025-hd.png new file mode 100644 index 00000000..b59dbbcb Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_025-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_025-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_025-sd.png new file mode 100644 index 00000000..f61c1e11 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_025-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_026-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_026-hd.png new file mode 100644 index 00000000..c9bbc99e Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_026-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_026-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_026-sd.png new file mode 100644 index 00000000..4cf1eb11 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_026-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_027-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_027-hd.png new file mode 100644 index 00000000..5f4efc3b Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_027-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_027-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_027-sd.png new file mode 100644 index 00000000..33a18758 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_027-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_028-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_028-hd.png new file mode 100644 index 00000000..bf160ade Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_028-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_028-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_028-sd.png new file mode 100644 index 00000000..3daf285b Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_028-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_029-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_029-hd.png new file mode 100644 index 00000000..b5ead7f6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_029-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_029-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_029-sd.png new file mode 100644 index 00000000..ccdba246 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_029-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_030-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_030-hd.png new file mode 100644 index 00000000..6b477a42 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_030-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_030-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_030-sd.png new file mode 100644 index 00000000..0c8e5efe Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_030-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_031-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_031-hd.png new file mode 100644 index 00000000..b57565fc Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_031-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_031-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_031-sd.png new file mode 100644 index 00000000..c57a5388 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_031-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_032-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_032-hd.png new file mode 100644 index 00000000..cc690daa Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_032-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_032-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_032-sd.png new file mode 100644 index 00000000..1a1dabe9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_032-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_033-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_033-hd.png new file mode 100644 index 00000000..324043ab Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_033-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_033-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_033-sd.png new file mode 100644 index 00000000..ff748eaa Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_033-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_034-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_034-hd.png new file mode 100644 index 00000000..c69eb0cc Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_034-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_034-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_034-sd.png new file mode 100644 index 00000000..867cd16c Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_034-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_035-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_035-hd.png new file mode 100644 index 00000000..e785d104 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_035-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_035-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_035-sd.png new file mode 100644 index 00000000..ca940ff9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_035-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_036-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_036-hd.png new file mode 100644 index 00000000..a55a75ef Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_036-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_036-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_036-sd.png new file mode 100644 index 00000000..0803f8dc Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_036-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_037-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_037-hd.png new file mode 100644 index 00000000..d3183dbb Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_037-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_037-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_037-sd.png new file mode 100644 index 00000000..04e52364 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_037-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_038-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_038-hd.png new file mode 100644 index 00000000..bd9823d8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_038-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_038-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_038-sd.png new file mode 100644 index 00000000..f5fccbf2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_038-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_039-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_039-hd.png new file mode 100644 index 00000000..9d2aec51 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_039-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_039-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_039-sd.png new file mode 100644 index 00000000..79a9f831 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_039-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_040-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_040-hd.png new file mode 100644 index 00000000..e1ac5927 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_040-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_040-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_040-sd.png new file mode 100644 index 00000000..9d337070 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_040-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_041-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_041-hd.png new file mode 100644 index 00000000..402aea91 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_041-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_041-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_041-sd.png new file mode 100644 index 00000000..2ebd3ced Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_041-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_042-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_042-hd.png new file mode 100644 index 00000000..8a929525 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_042-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_042-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_042-sd.png new file mode 100644 index 00000000..930c5219 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_042-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_043-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_043-hd.png new file mode 100644 index 00000000..781743a4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_043-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_043-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_043-sd.png new file mode 100644 index 00000000..9ce4b120 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_043-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_044-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_044-hd.png new file mode 100644 index 00000000..a93472c9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_044-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_044-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_044-sd.png new file mode 100644 index 00000000..8a1a31db Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_044-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_045-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_045-hd.png new file mode 100644 index 00000000..8104d6b7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_045-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_045-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_045-sd.png new file mode 100644 index 00000000..72606494 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_045-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_046-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_046-hd.png new file mode 100644 index 00000000..0e1bf4dc Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_046-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_046-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_046-sd.png new file mode 100644 index 00000000..c956889a Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_046-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_047-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_047-hd.png new file mode 100644 index 00000000..f389cd2e Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_047-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_047-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_047-sd.png new file mode 100644 index 00000000..4a6e1505 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_047-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_048-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_048-hd.png new file mode 100644 index 00000000..e964916a Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_048-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_048-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_048-sd.png new file mode 100644 index 00000000..a0ae87b7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_048-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_049-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_049-hd.png new file mode 100644 index 00000000..7be90d82 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_049-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_049-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_049-sd.png new file mode 100644 index 00000000..4edebb00 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_049-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_050-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_050-hd.png new file mode 100644 index 00000000..212b6930 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_050-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_050-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_050-sd.png new file mode 100644 index 00000000..2f620840 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_050-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_051-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_051-hd.png new file mode 100644 index 00000000..18644c68 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_051-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_051-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_051-sd.png new file mode 100644 index 00000000..2a063452 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_051-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_052-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_052-hd.png new file mode 100644 index 00000000..7f8b8569 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_052-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_052-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_052-sd.png new file mode 100644 index 00000000..6015df2b Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_052-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_053-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_053-hd.png new file mode 100644 index 00000000..d105ac9d Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_053-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_053-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_053-sd.png new file mode 100644 index 00000000..e37671df Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_053-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_054-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_054-hd.png new file mode 100644 index 00000000..c677def7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_054-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_054-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_054-sd.png new file mode 100644 index 00000000..dc7144c2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_054-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_055-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_055-hd.png new file mode 100644 index 00000000..af4632a7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_055-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_055-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_055-sd.png new file mode 100644 index 00000000..dab50d23 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_055-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_056-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_056-hd.png new file mode 100644 index 00000000..86f06dcf Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_056-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_056-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_056-sd.png new file mode 100644 index 00000000..ddef692e Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_056-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_057-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_057-hd.png new file mode 100644 index 00000000..c982bcb4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_057-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_057-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_057-sd.png new file mode 100644 index 00000000..0dfc3a77 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_057-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_058-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_058-hd.png new file mode 100644 index 00000000..dbded444 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_058-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_058-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_058-sd.png new file mode 100644 index 00000000..c5f11640 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_058-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_059-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_059-hd.png new file mode 100644 index 00000000..9096a0f8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_059-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_059-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_059-sd.png new file mode 100644 index 00000000..6dea4f93 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_059-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_060-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_060-hd.png new file mode 100644 index 00000000..742ed739 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_060-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_060-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_060-sd.png new file mode 100644 index 00000000..75130d71 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_060-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_061-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_061-hd.png new file mode 100644 index 00000000..56896e4c Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_061-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_061-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_061-sd.png new file mode 100644 index 00000000..0d2f6271 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_061-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_062-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_062-hd.png new file mode 100644 index 00000000..8eb18ae0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_062-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_062-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_062-sd.png new file mode 100644 index 00000000..970ec161 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_062-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_063-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_063-hd.png new file mode 100644 index 00000000..e94f90ca Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_063-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_063-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_063-sd.png new file mode 100644 index 00000000..dab91511 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_063-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_064-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_064-hd.png new file mode 100644 index 00000000..ed5e1161 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_064-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_064-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_064-sd.png new file mode 100644 index 00000000..61ba176b Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_064-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_065-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_065-hd.png new file mode 100644 index 00000000..99a59271 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_065-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_065-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_065-sd.png new file mode 100644 index 00000000..67cb6a51 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_065-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_066-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_066-hd.png new file mode 100644 index 00000000..cad864ba Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_066-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_066-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_066-sd.png new file mode 100644 index 00000000..da9cb95b Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_066-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_067-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_067-hd.png new file mode 100644 index 00000000..62054060 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_067-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_067-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_067-sd.png new file mode 100644 index 00000000..c5106853 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_067-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_068-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_068-hd.png new file mode 100644 index 00000000..4091c3b5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_068-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_068-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_068-sd.png new file mode 100644 index 00000000..49dbbc71 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_068-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_069-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_069-hd.png new file mode 100644 index 00000000..ba4f17eb Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_069-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_069-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_069-sd.png new file mode 100644 index 00000000..0c20d7d2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_069-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_070-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_070-hd.png new file mode 100644 index 00000000..da7c1a61 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_070-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_070-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_070-sd.png new file mode 100644 index 00000000..558717ca Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_070-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_071-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_071-hd.png new file mode 100644 index 00000000..e9ce987d Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_071-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_071-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_071-sd.png new file mode 100644 index 00000000..6242aab5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_071-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_072-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_072-hd.png new file mode 100644 index 00000000..44a61551 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_072-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_072-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_072-sd.png new file mode 100644 index 00000000..c2aab9e4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_072-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_073-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_073-hd.png new file mode 100644 index 00000000..2ef649ba Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_073-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_073-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_073-sd.png new file mode 100644 index 00000000..58d2ed0a Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_073-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_074-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_074-hd.png new file mode 100644 index 00000000..215be800 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_074-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_074-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_074-sd.png new file mode 100644 index 00000000..a5e0861a Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_074-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_075-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_075-hd.png new file mode 100644 index 00000000..05c6d3c4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_075-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_075-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_075-sd.png new file mode 100644 index 00000000..fbfd480a Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_075-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_076-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_076-hd.png new file mode 100644 index 00000000..e47f8ad5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_076-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_076-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_076-sd.png new file mode 100644 index 00000000..b7038e74 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_076-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_077-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_077-hd.png new file mode 100644 index 00000000..7f762ad3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_077-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_077-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_077-sd.png new file mode 100644 index 00000000..bfee3386 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_077-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_078-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_078-hd.png new file mode 100644 index 00000000..2d0dd7c7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_078-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_078-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_078-sd.png new file mode 100644 index 00000000..9978df7c Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_078-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_079-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_079-hd.png new file mode 100644 index 00000000..30c1bb9c Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_079-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_079-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_079-sd.png new file mode 100644 index 00000000..5a6bc634 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_079-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_080-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_080-hd.png new file mode 100644 index 00000000..809682e5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_080-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_080-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_080-sd.png new file mode 100644 index 00000000..df75800c Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_080-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_081-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_081-hd.png new file mode 100644 index 00000000..038c2926 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_081-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_081-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_081-sd.png new file mode 100644 index 00000000..05015c87 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_081-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_082-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_082-hd.png new file mode 100644 index 00000000..4bc2bcba Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_082-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_082-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_082-sd.png new file mode 100644 index 00000000..38593eb3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_082-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_083-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_083-hd.png new file mode 100644 index 00000000..983ef6d0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_083-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_083-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_083-sd.png new file mode 100644 index 00000000..b082e69a Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_083-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_084-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_084-hd.png new file mode 100644 index 00000000..15bb267b Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_084-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_084-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_084-sd.png new file mode 100644 index 00000000..a385060c Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_084-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_085-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_085-hd.png new file mode 100644 index 00000000..79bbacad Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_085-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_085-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_085-sd.png new file mode 100644 index 00000000..232caf64 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_085-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_086-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_086-hd.png new file mode 100644 index 00000000..39604436 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_086-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_086-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_086-sd.png new file mode 100644 index 00000000..12e5fbce Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_086-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_087-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_087-hd.png new file mode 100644 index 00000000..c97d4d68 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_087-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_087-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_087-sd.png new file mode 100644 index 00000000..bf260c78 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_087-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_088-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_088-hd.png new file mode 100644 index 00000000..6555fa5b Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_088-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_088-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_088-sd.png new file mode 100644 index 00000000..c9cdcad0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_088-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_089-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_089-hd.png new file mode 100644 index 00000000..1387dfcc Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_089-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_089-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_089-sd.png new file mode 100644 index 00000000..a4d7a8a5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_089-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_090-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_090-hd.png new file mode 100644 index 00000000..723fda09 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_090-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_090-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_090-sd.png new file mode 100644 index 00000000..c907236b Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_090-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_091-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_091-hd.png new file mode 100644 index 00000000..152b37bd Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_091-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_091-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_091-sd.png new file mode 100644 index 00000000..8dfafc5d Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_091-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_092-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_092-hd.png new file mode 100644 index 00000000..91d98bfd Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_092-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_092-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_092-sd.png new file mode 100644 index 00000000..012565c5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_092-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_093-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_093-hd.png new file mode 100644 index 00000000..9caeaf93 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_093-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_093-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_093-sd.png new file mode 100644 index 00000000..39d27374 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_093-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_094-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_094-hd.png new file mode 100644 index 00000000..c0154608 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_094-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_094-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_094-sd.png new file mode 100644 index 00000000..a57504bc Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_094-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_095-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_095-hd.png new file mode 100644 index 00000000..76bc6346 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_095-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_095-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_095-sd.png new file mode 100644 index 00000000..81204ec3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_095-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_096-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_096-hd.png new file mode 100644 index 00000000..fbeae569 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_096-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_096-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_096-sd.png new file mode 100644 index 00000000..a7dcf212 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_096-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_097-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_097-hd.png new file mode 100644 index 00000000..cbe61672 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_097-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_097-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_097-sd.png new file mode 100644 index 00000000..57edd171 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_097-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_098-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_098-hd.png new file mode 100644 index 00000000..d3650d74 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_098-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_098-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_098-sd.png new file mode 100644 index 00000000..b64c51d9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_098-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_099-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_099-hd.png new file mode 100644 index 00000000..a3ab2e0e Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_099-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_099-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_099-sd.png new file mode 100644 index 00000000..80c376a5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_099-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_100-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_100-hd.png new file mode 100644 index 00000000..088ad30a Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_100-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_100-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_100-sd.png new file mode 100644 index 00000000..f5e05674 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_100-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_101-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_101-hd.png new file mode 100644 index 00000000..9dd8a65b Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_101-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_101-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_101-sd.png new file mode 100644 index 00000000..46dc7f9b Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_101-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_102-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_102-hd.png new file mode 100644 index 00000000..491ece8a Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_102-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_102-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_102-sd.png new file mode 100644 index 00000000..f1cd053e Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_102-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_103-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_103-hd.png new file mode 100644 index 00000000..e91761d3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_103-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_103-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_103-sd.png new file mode 100644 index 00000000..8b8cd800 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_103-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_104-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_104-hd.png new file mode 100644 index 00000000..31f384f1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_104-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_104-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_104-sd.png new file mode 100644 index 00000000..b0b67022 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_104-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_105-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_105-hd.png new file mode 100644 index 00000000..a3e9fa19 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_105-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_105-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_105-sd.png new file mode 100644 index 00000000..9374d7f4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_105-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_106-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_106-hd.png new file mode 100644 index 00000000..d54dee1d Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_106-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_106-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_106-sd.png new file mode 100644 index 00000000..ac284fdf Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_106-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_107-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_107-hd.png new file mode 100644 index 00000000..dbc404ed Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_107-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_107-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_107-sd.png new file mode 100644 index 00000000..420622a9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_107-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_108-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_108-hd.png new file mode 100644 index 00000000..c0459164 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_108-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_108-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_108-sd.png new file mode 100644 index 00000000..2c20e7c8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_108-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_109-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_109-hd.png new file mode 100644 index 00000000..09822bf0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_109-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_109-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_109-sd.png new file mode 100644 index 00000000..53c6e83b Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_109-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_110-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_110-hd.png new file mode 100644 index 00000000..a304fa23 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_110-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_110-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_110-sd.png new file mode 100644 index 00000000..fda2f0a4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_110-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_111-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_111-hd.png new file mode 100644 index 00000000..e7edf504 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_111-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_111-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_111-sd.png new file mode 100644 index 00000000..ace6bf04 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_111-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_112-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_112-hd.png new file mode 100644 index 00000000..ca9fac09 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_112-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_112-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_112-sd.png new file mode 100644 index 00000000..da727d5e Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_112-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_113-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_113-hd.png new file mode 100644 index 00000000..94582fe0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_113-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_113-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_113-sd.png new file mode 100644 index 00000000..018fe573 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_113-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_114-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_114-hd.png new file mode 100644 index 00000000..cec111dc Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_114-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_114-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_114-sd.png new file mode 100644 index 00000000..f979e373 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_114-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_115-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_115-hd.png new file mode 100644 index 00000000..af7caee7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_115-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_115-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_115-sd.png new file mode 100644 index 00000000..95803566 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_115-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_116-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_116-hd.png new file mode 100644 index 00000000..ec30c10f Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_116-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_116-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_116-sd.png new file mode 100644 index 00000000..e1977ee2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_116-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_117-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_117-hd.png new file mode 100644 index 00000000..850cd283 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_117-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_117-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_117-sd.png new file mode 100644 index 00000000..d0dbf126 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_117-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_118-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_118-hd.png new file mode 100644 index 00000000..e0814eec Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_118-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_118-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_118-sd.png new file mode 100644 index 00000000..7f7df584 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_118-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_119-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_119-hd.png new file mode 100644 index 00000000..cfe7f254 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_119-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_119-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_119-sd.png new file mode 100644 index 00000000..46497ad0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_119-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_120-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_120-hd.png new file mode 100644 index 00000000..3fc02a1c Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_120-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_120-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_120-sd.png new file mode 100644 index 00000000..a591ae0e Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_120-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_121-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_121-hd.png new file mode 100644 index 00000000..3be52a09 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_121-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_121-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_121-sd.png new file mode 100644 index 00000000..918612d9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_121-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_122-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_122-hd.png new file mode 100644 index 00000000..16014ad7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_122-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_122-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_122-sd.png new file mode 100644 index 00000000..ad2b4dca Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_122-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_123-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_123-hd.png new file mode 100644 index 00000000..9bfca255 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_123-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_123-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_123-sd.png new file mode 100644 index 00000000..ff110d3a Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_123-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_124-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_124-hd.png new file mode 100644 index 00000000..45ee48f2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_124-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_124-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_124-sd.png new file mode 100644 index 00000000..be837044 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_124-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_125-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_125-hd.png new file mode 100644 index 00000000..0a7f7e88 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_125-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_125-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_125-sd.png new file mode 100644 index 00000000..0d65bbab Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_125-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_126-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_126-hd.png new file mode 100644 index 00000000..1097d07c Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_126-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_126-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_126-sd.png new file mode 100644 index 00000000..d3d96fed Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_126-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_127-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_127-hd.png new file mode 100644 index 00000000..e65e307d Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_127-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_127-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_127-sd.png new file mode 100644 index 00000000..83635670 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_127-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_128-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_128-hd.png new file mode 100644 index 00000000..ad2cf264 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_128-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_128-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_128-sd.png new file mode 100644 index 00000000..2eac38bc Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_128-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_129-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_129-hd.png new file mode 100644 index 00000000..47d42e2a Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_129-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_129-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_129-sd.png new file mode 100644 index 00000000..a86686de Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_129-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_130-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_130-hd.png new file mode 100644 index 00000000..ff029e04 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_130-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_130-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_130-sd.png new file mode 100644 index 00000000..5df335c8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_130-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_131-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_131-hd.png new file mode 100644 index 00000000..1b9b730c Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_131-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_131-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_131-sd.png new file mode 100644 index 00000000..55351998 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_131-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_132-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_132-hd.png new file mode 100644 index 00000000..89cb65b8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_132-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_132-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_132-sd.png new file mode 100644 index 00000000..5aeab3d6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_132-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_133-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_133-hd.png new file mode 100644 index 00000000..8dec3e63 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_133-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_133-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_133-sd.png new file mode 100644 index 00000000..e4996d64 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_133-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_134-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_134-hd.png new file mode 100644 index 00000000..2402d393 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_134-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_134-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_134-sd.png new file mode 100644 index 00000000..14eb993b Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_134-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_135-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_135-hd.png new file mode 100644 index 00000000..24d384aa Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_135-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_135-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_135-sd.png new file mode 100644 index 00000000..8ecaf97d Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_135-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_136-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_136-hd.png new file mode 100644 index 00000000..5196a448 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_136-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_136-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_136-sd.png new file mode 100644 index 00000000..cea6df1f Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_136-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_137-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_137-hd.png new file mode 100644 index 00000000..17cc594c Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_137-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_137-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_137-sd.png new file mode 100644 index 00000000..e62dbc69 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_137-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_138-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_138-hd.png new file mode 100644 index 00000000..5b3cd505 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_138-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_138-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_138-sd.png new file mode 100644 index 00000000..d0c0de96 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_138-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_139-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_139-hd.png new file mode 100644 index 00000000..72ea2801 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_139-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_139-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_139-sd.png new file mode 100644 index 00000000..45f8e507 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_139-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_140-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_140-hd.png new file mode 100644 index 00000000..f1cdaac0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_140-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_140-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_140-sd.png new file mode 100644 index 00000000..7b857d0f Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_140-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_141-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_141-hd.png new file mode 100644 index 00000000..6978c89f Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_141-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_141-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_141-sd.png new file mode 100644 index 00000000..686034b1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_141-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_142-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_142-hd.png new file mode 100644 index 00000000..061a4904 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_142-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_142-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_142-sd.png new file mode 100644 index 00000000..e03765e2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_142-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_143-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_143-hd.png new file mode 100644 index 00000000..24d4ef4f Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_143-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_143-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_143-sd.png new file mode 100644 index 00000000..40e59655 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_143-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_144-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_144-hd.png new file mode 100644 index 00000000..3ce25be0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_144-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_144-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_144-sd.png new file mode 100644 index 00000000..1d3f14ec Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_144-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_145-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_145-hd.png new file mode 100644 index 00000000..4022875b Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_145-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_145-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_145-sd.png new file mode 100644 index 00000000..84a0a131 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_145-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_146-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_146-hd.png new file mode 100644 index 00000000..a6437e16 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_146-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_146-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_146-sd.png new file mode 100644 index 00000000..7e12aa2e Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_146-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_147-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_147-hd.png new file mode 100644 index 00000000..2b29ba81 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_147-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_147-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_147-sd.png new file mode 100644 index 00000000..be65ddbe Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_147-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_148-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_148-hd.png new file mode 100644 index 00000000..721677e3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_148-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_148-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_148-sd.png new file mode 100644 index 00000000..db4581b9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_148-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_149-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_149-hd.png new file mode 100644 index 00000000..2fe28619 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_149-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_149-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_149-sd.png new file mode 100644 index 00000000..878debba Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_149-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_150-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_150-hd.png new file mode 100644 index 00000000..3a2b324b Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_150-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_150-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_150-sd.png new file mode 100644 index 00000000..f1f200aa Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_150-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_151-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_151-hd.png new file mode 100644 index 00000000..71411c23 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_151-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_151-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_151-sd.png new file mode 100644 index 00000000..80135f14 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_151-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_152-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_152-hd.png new file mode 100644 index 00000000..898ef64e Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_152-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_152-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_152-sd.png new file mode 100644 index 00000000..d9f7b8c7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_152-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_153-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_153-hd.png new file mode 100644 index 00000000..2f9f68fb Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_153-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_153-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_153-sd.png new file mode 100644 index 00000000..f8a809b3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_153-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_154-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_154-hd.png new file mode 100644 index 00000000..ee48e20e Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_154-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_154-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_154-sd.png new file mode 100644 index 00000000..73b5b36b Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_154-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_155-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_155-hd.png new file mode 100644 index 00000000..3fc0c7c0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_155-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_155-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_155-sd.png new file mode 100644 index 00000000..44fcc926 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_155-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_156-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_156-hd.png new file mode 100644 index 00000000..616832de Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_156-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_156-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_156-sd.png new file mode 100644 index 00000000..67d5c538 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_156-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_157-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_157-hd.png new file mode 100644 index 00000000..b6bca01b Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_157-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_157-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_157-sd.png new file mode 100644 index 00000000..bb12adf7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_157-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_158-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_158-hd.png new file mode 100644 index 00000000..19f3b776 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_158-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_158-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_158-sd.png new file mode 100644 index 00000000..9612eb9a Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_158-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_159-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_159-hd.png new file mode 100644 index 00000000..3bd904f7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_159-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_159-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_159-sd.png new file mode 100644 index 00000000..07d7e563 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_159-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_160-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_160-hd.png new file mode 100644 index 00000000..a6cdd255 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_160-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_160-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_160-sd.png new file mode 100644 index 00000000..c52993ad Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_160-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_161-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_161-hd.png new file mode 100644 index 00000000..aee99edd Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_161-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_161-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_161-sd.png new file mode 100644 index 00000000..538c98e0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_161-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_162-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_162-hd.png new file mode 100644 index 00000000..d2172988 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_162-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_162-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_162-sd.png new file mode 100644 index 00000000..101b64c9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_162-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_163-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_163-hd.png new file mode 100644 index 00000000..6642e560 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_163-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_163-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_163-sd.png new file mode 100644 index 00000000..cdfc36c1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_163-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_164-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_164-hd.png new file mode 100644 index 00000000..5a86637c Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_164-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_164-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_164-sd.png new file mode 100644 index 00000000..a296037e Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_164-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_165-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_165-hd.png new file mode 100644 index 00000000..f4bfc5e6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_165-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_165-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_165-sd.png new file mode 100644 index 00000000..fb6abd9a Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_165-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_166-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_166-hd.png new file mode 100644 index 00000000..712c3725 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_166-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_166-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_166-sd.png new file mode 100644 index 00000000..cab22bcd Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_166-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_167-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_167-hd.png new file mode 100644 index 00000000..1d4840f0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_167-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_167-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_167-sd.png new file mode 100644 index 00000000..46d1d26a Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_167-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_168-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_168-hd.png new file mode 100644 index 00000000..149095b2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_168-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_168-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_168-sd.png new file mode 100644 index 00000000..a4072f04 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_168-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_169-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_169-hd.png new file mode 100644 index 00000000..5a0c3da8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_169-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_169-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_169-sd.png new file mode 100644 index 00000000..ec8d6ec6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_169-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_170-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_170-hd.png new file mode 100644 index 00000000..d73a1467 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_170-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_170-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_170-sd.png new file mode 100644 index 00000000..d41fc760 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_170-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_171-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_171-hd.png new file mode 100644 index 00000000..98cd4ae1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_171-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_171-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_171-sd.png new file mode 100644 index 00000000..a85f711e Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_171-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_172-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_172-hd.png new file mode 100644 index 00000000..17d2d88d Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_172-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_172-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_172-sd.png new file mode 100644 index 00000000..90359c20 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_172-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_173-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_173-hd.png new file mode 100644 index 00000000..5b5ce13d Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_173-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_173-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_173-sd.png new file mode 100644 index 00000000..9fa878c4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_173-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_174-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_174-hd.png new file mode 100644 index 00000000..d7015210 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_174-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_174-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_174-sd.png new file mode 100644 index 00000000..5784e20c Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_174-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_175-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_175-hd.png new file mode 100644 index 00000000..7bddbe45 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_175-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_175-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_175-sd.png new file mode 100644 index 00000000..8ad785e3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_175-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_176-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_176-hd.png new file mode 100644 index 00000000..a700a355 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_176-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_176-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_176-sd.png new file mode 100644 index 00000000..9ac82e1f Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_176-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_177-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_177-hd.png new file mode 100644 index 00000000..2ea034a6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_177-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_177-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_177-sd.png new file mode 100644 index 00000000..e742256d Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_177-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_178-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_178-hd.png new file mode 100644 index 00000000..926af3c4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_178-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_178-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_178-sd.png new file mode 100644 index 00000000..5a6eeaaf Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_178-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_179-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_179-hd.png new file mode 100644 index 00000000..019e5fd8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_179-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_179-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_179-sd.png new file mode 100644 index 00000000..0ca73a11 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_179-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_180-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_180-hd.png new file mode 100644 index 00000000..2126a728 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_180-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_180-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_180-sd.png new file mode 100644 index 00000000..33224812 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_180-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_181-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_181-hd.png new file mode 100644 index 00000000..9d22ac7a Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_181-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_181-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_181-sd.png new file mode 100644 index 00000000..f0661b27 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_181-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_182-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_182-hd.png new file mode 100644 index 00000000..b02ddfb7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_182-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_182-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_182-sd.png new file mode 100644 index 00000000..6c85032a Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_182-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_183-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_183-hd.png new file mode 100644 index 00000000..89f658ce Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_183-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_183-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_183-sd.png new file mode 100644 index 00000000..76d541cf Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_183-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_184-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_184-hd.png new file mode 100644 index 00000000..ff53be00 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_184-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_184-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_184-sd.png new file mode 100644 index 00000000..faf8829f Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_184-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_185-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_185-hd.png new file mode 100644 index 00000000..6a65d480 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_185-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_185-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_185-sd.png new file mode 100644 index 00000000..ecd02397 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_185-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_186-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_186-hd.png new file mode 100644 index 00000000..0026f221 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_186-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_186-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_186-sd.png new file mode 100644 index 00000000..8a3fa904 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_186-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_187-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_187-hd.png new file mode 100644 index 00000000..aee7023f Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_187-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_187-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_187-sd.png new file mode 100644 index 00000000..53983421 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_187-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_188-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_188-hd.png new file mode 100644 index 00000000..a74a3036 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_188-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_188-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_188-sd.png new file mode 100644 index 00000000..98c0b652 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_188-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_189-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_189-hd.png new file mode 100644 index 00000000..45019a39 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_189-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_189-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_189-sd.png new file mode 100644 index 00000000..5a80e479 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_189-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_190-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_190-hd.png new file mode 100644 index 00000000..37da65cc Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_190-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_190-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_190-sd.png new file mode 100644 index 00000000..b609ec31 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_190-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_191-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_191-hd.png new file mode 100644 index 00000000..2d106ff2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_191-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_191-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_191-sd.png new file mode 100644 index 00000000..41a6ff58 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_191-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_192-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_192-hd.png new file mode 100644 index 00000000..eb43328e Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_192-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_192-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_192-sd.png new file mode 100644 index 00000000..492706b8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_192-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_193-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_193-hd.png new file mode 100644 index 00000000..d7e67873 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_193-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_193-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_193-sd.png new file mode 100644 index 00000000..f6ced9ec Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_193-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_194-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_194-hd.png new file mode 100644 index 00000000..bb9d3f70 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_194-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_194-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_194-sd.png new file mode 100644 index 00000000..3fb39acc Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_194-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_195-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_195-hd.png new file mode 100644 index 00000000..6c5d181b Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_195-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_195-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_195-sd.png new file mode 100644 index 00000000..8355e03a Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_195-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_196-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_196-hd.png new file mode 100644 index 00000000..84ddebdb Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_196-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_196-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_196-sd.png new file mode 100644 index 00000000..0ed6cb50 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_196-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_197-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_197-hd.png new file mode 100644 index 00000000..294b28a0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_197-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_197-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_197-sd.png new file mode 100644 index 00000000..42e2f3a3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_197-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_198-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_198-hd.png new file mode 100644 index 00000000..c521f5a5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_198-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_198-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_198-sd.png new file mode 100644 index 00000000..1808a0cf Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_198-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_199-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_199-hd.png new file mode 100644 index 00000000..51b1b6fa Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_199-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_199-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_199-sd.png new file mode 100644 index 00000000..6d7d11d2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_199-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_200-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_200-hd.png new file mode 100644 index 00000000..c59b094d Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_200-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_200-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_200-sd.png new file mode 100644 index 00000000..feacb12b Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_200-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_201-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_201-hd.png new file mode 100644 index 00000000..8874b168 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_201-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_201-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_201-sd.png new file mode 100644 index 00000000..fa01d59a Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_201-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_202-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_202-hd.png new file mode 100644 index 00000000..70684a79 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_202-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_202-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_202-sd.png new file mode 100644 index 00000000..23e3b359 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_202-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_203-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_203-hd.png new file mode 100644 index 00000000..17d6c557 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_203-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_203-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_203-sd.png new file mode 100644 index 00000000..61dc298c Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_203-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_204-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_204-hd.png new file mode 100644 index 00000000..e51e9bb3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_204-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_204-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_204-sd.png new file mode 100644 index 00000000..5b4546ae Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_204-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_205-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_205-hd.png new file mode 100644 index 00000000..7716b7c8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_205-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_205-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_205-sd.png new file mode 100644 index 00000000..42aa0792 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_205-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_206-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_206-hd.png new file mode 100644 index 00000000..fd3a46d0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_206-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_206-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_206-sd.png new file mode 100644 index 00000000..93e8d342 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_206-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_207-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_207-hd.png new file mode 100644 index 00000000..2470fdd5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_207-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_207-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_207-sd.png new file mode 100644 index 00000000..b4f140a1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_207-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_208-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_208-hd.png new file mode 100644 index 00000000..72676cf0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_208-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_208-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_208-sd.png new file mode 100644 index 00000000..2f4da655 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_208-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_209-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_209-hd.png new file mode 100644 index 00000000..ef5e22b2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_209-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_209-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_209-sd.png new file mode 100644 index 00000000..c4610cf3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_209-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_210-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_210-hd.png new file mode 100644 index 00000000..10050d38 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_210-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_210-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_210-sd.png new file mode 100644 index 00000000..7f1c9a45 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_210-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_211-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_211-hd.png new file mode 100644 index 00000000..73331257 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_211-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_211-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_211-sd.png new file mode 100644 index 00000000..4df9333b Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_211-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_212-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_212-hd.png new file mode 100644 index 00000000..69fbc29e Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_212-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_212-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_212-sd.png new file mode 100644 index 00000000..c87b6330 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_212-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_213-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_213-hd.png new file mode 100644 index 00000000..b381d3d7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_213-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_213-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_213-sd.png new file mode 100644 index 00000000..334d49d4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_213-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_214-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_214-hd.png new file mode 100644 index 00000000..ffe2a882 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_214-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_214-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_214-sd.png new file mode 100644 index 00000000..2236b3b8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_214-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_215-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_215-hd.png new file mode 100644 index 00000000..71f5eb0f Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_215-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_215-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_215-sd.png new file mode 100644 index 00000000..8a941bbf Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_215-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_216-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_216-hd.png new file mode 100644 index 00000000..097ec649 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_216-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_216-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_216-sd.png new file mode 100644 index 00000000..d9fe5c62 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_216-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_217-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_217-hd.png new file mode 100644 index 00000000..943c5804 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_217-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_217-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_217-sd.png new file mode 100644 index 00000000..87e11081 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_217-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_218-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_218-hd.png new file mode 100644 index 00000000..bcbf631a Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_218-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_218-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_218-sd.png new file mode 100644 index 00000000..bd1041a9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_218-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_219-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_219-hd.png new file mode 100644 index 00000000..c24eb097 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_219-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_219-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_219-sd.png new file mode 100644 index 00000000..444e2361 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_219-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_220-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_220-hd.png new file mode 100644 index 00000000..e9346deb Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_220-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_220-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_220-sd.png new file mode 100644 index 00000000..dc8a1f81 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_220-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_221-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_221-hd.png new file mode 100644 index 00000000..d4989517 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_221-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_221-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_221-sd.png new file mode 100644 index 00000000..97fc2d2b Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_221-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_222-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_222-hd.png new file mode 100644 index 00000000..e091ba5d Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_222-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_222-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_222-sd.png new file mode 100644 index 00000000..f51f106f Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_222-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_223-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_223-hd.png new file mode 100644 index 00000000..a584c1be Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_223-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_223-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_223-sd.png new file mode 100644 index 00000000..6d7f1d51 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_223-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_224-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_224-hd.png new file mode 100644 index 00000000..bf92aa40 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_224-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_224-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_224-sd.png new file mode 100644 index 00000000..6a46fa7f Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_224-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_225-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_225-hd.png new file mode 100644 index 00000000..516283f7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_225-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_225-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_225-sd.png new file mode 100644 index 00000000..03be1cf9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_225-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_226-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_226-hd.png new file mode 100644 index 00000000..a1276dcc Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_226-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_226-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_226-sd.png new file mode 100644 index 00000000..80e61237 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_226-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_227-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_227-hd.png new file mode 100644 index 00000000..e16ac0aa Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_227-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_227-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_227-sd.png new file mode 100644 index 00000000..31b551f8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_227-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_228-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_228-hd.png new file mode 100644 index 00000000..627a2f60 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_228-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_228-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_228-sd.png new file mode 100644 index 00000000..b6788c42 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_228-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_229-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_229-hd.png new file mode 100644 index 00000000..c24a0530 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_229-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_229-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_229-sd.png new file mode 100644 index 00000000..3aa92681 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_229-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_230-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_230-hd.png new file mode 100644 index 00000000..e2481c28 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_230-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_230-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_230-sd.png new file mode 100644 index 00000000..3cea1380 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_230-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_231-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_231-hd.png new file mode 100644 index 00000000..1aa799f7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_231-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_231-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_231-sd.png new file mode 100644 index 00000000..dc05e9e8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_231-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_232-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_232-hd.png new file mode 100644 index 00000000..dfb36ce3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_232-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_232-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_232-sd.png new file mode 100644 index 00000000..bcb9f1f5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_232-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_233-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_233-hd.png new file mode 100644 index 00000000..22b1622f Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_233-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_233-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_233-sd.png new file mode 100644 index 00000000..39aa1567 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_233-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_234-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_234-hd.png new file mode 100644 index 00000000..12935f48 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_234-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_234-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_234-sd.png new file mode 100644 index 00000000..941caec9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_234-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_235-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_235-hd.png new file mode 100644 index 00000000..600ce31b Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_235-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_235-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_235-sd.png new file mode 100644 index 00000000..8f0a7ab1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_235-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_236-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_236-hd.png new file mode 100644 index 00000000..367793b9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_236-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_236-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_236-sd.png new file mode 100644 index 00000000..a77193b8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_236-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_237-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_237-hd.png new file mode 100644 index 00000000..1a3ce435 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_237-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_237-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_237-sd.png new file mode 100644 index 00000000..141cfaca Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_237-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_238-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_238-hd.png new file mode 100644 index 00000000..fe113913 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_238-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_238-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_238-sd.png new file mode 100644 index 00000000..38752f1c Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_238-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_239-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_239-hd.png new file mode 100644 index 00000000..9f9e1c21 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_239-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_239-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_239-sd.png new file mode 100644 index 00000000..778341ab Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_239-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_240-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_240-hd.png new file mode 100644 index 00000000..71e3b7bd Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_240-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_240-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_240-sd.png new file mode 100644 index 00000000..9cd9dbfc Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_240-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_241-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_241-hd.png new file mode 100644 index 00000000..27d280ff Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_241-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_241-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_241-sd.png new file mode 100644 index 00000000..a7ddb166 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_241-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_242-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_242-hd.png new file mode 100644 index 00000000..99f682b6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_242-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_242-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_242-sd.png new file mode 100644 index 00000000..d7c086a3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_242-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_243-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_243-hd.png new file mode 100644 index 00000000..a0fe9310 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_243-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_243-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_243-sd.png new file mode 100644 index 00000000..e484318e Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_243-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_244-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_244-hd.png new file mode 100644 index 00000000..6e89935f Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_244-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_244-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_244-sd.png new file mode 100644 index 00000000..83e6b494 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_244-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_245-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_245-hd.png new file mode 100644 index 00000000..faba5fbc Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_245-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_245-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_245-sd.png new file mode 100644 index 00000000..8ea995ae Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_245-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_246-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_246-hd.png new file mode 100644 index 00000000..4f70ce2d Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_246-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_246-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_246-sd.png new file mode 100644 index 00000000..b59954a3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_246-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_247-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_247-hd.png new file mode 100644 index 00000000..79f9a770 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_247-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_247-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_247-sd.png new file mode 100644 index 00000000..615e2f6a Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_247-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_248-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_248-hd.png new file mode 100644 index 00000000..456aef98 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_248-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_248-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_248-sd.png new file mode 100644 index 00000000..03b3c328 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_248-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_249-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_249-hd.png new file mode 100644 index 00000000..48e09203 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_249-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_249-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_249-sd.png new file mode 100644 index 00000000..a80fd9b3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_249-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_250-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_250-hd.png new file mode 100644 index 00000000..85132617 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_250-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_250-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_250-sd.png new file mode 100644 index 00000000..78c1143e Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_250-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_251-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_251-hd.png new file mode 100644 index 00000000..cbc69bb7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_251-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_251-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_251-sd.png new file mode 100644 index 00000000..33dbe9ce Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_251-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_252-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_252-hd.png new file mode 100644 index 00000000..16d86df8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_252-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_252-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_252-sd.png new file mode 100644 index 00000000..4c7244be Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_252-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_253-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_253-hd.png new file mode 100644 index 00000000..73e66090 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_253-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_253-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_253-sd.png new file mode 100644 index 00000000..07042839 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_253-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_254-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_254-hd.png new file mode 100644 index 00000000..dac0715f Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_254-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_254-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_254-sd.png new file mode 100644 index 00000000..90f703a2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_254-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_255-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_255-hd.png new file mode 100644 index 00000000..d6ce56d2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_255-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_255-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_255-sd.png new file mode 100644 index 00000000..aa78655c Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_255-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_256-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_256-hd.png new file mode 100644 index 00000000..a6b40954 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_256-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_256-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_256-sd.png new file mode 100644 index 00000000..019f6bbd Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_256-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_257-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_257-hd.png new file mode 100644 index 00000000..219e395c Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_257-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_257-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_257-sd.png new file mode 100644 index 00000000..f171fefa Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_257-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_258-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_258-hd.png new file mode 100644 index 00000000..9df55a7d Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_258-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_258-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_258-sd.png new file mode 100644 index 00000000..be0ab398 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_258-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_259-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_259-hd.png new file mode 100644 index 00000000..caad3a94 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_259-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_259-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_259-sd.png new file mode 100644 index 00000000..1ea258b3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_259-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_260-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_260-hd.png new file mode 100644 index 00000000..7fc24e6c Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_260-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_260-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_260-sd.png new file mode 100644 index 00000000..b90f38e6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_260-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_261-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_261-hd.png new file mode 100644 index 00000000..ab29aba8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_261-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_261-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_261-sd.png new file mode 100644 index 00000000..4711d36d Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_261-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_262-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_262-hd.png new file mode 100644 index 00000000..18618d1a Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_262-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_262-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_262-sd.png new file mode 100644 index 00000000..0197be4b Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_262-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_263-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_263-hd.png new file mode 100644 index 00000000..aee1bc6d Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_263-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_263-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_263-sd.png new file mode 100644 index 00000000..cd2be7dc Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_263-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_264-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_264-hd.png new file mode 100644 index 00000000..ddbf3868 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_264-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_264-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_264-sd.png new file mode 100644 index 00000000..62c0fcdc Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_264-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_265-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_265-hd.png new file mode 100644 index 00000000..92917d7d Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_265-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_265-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_265-sd.png new file mode 100644 index 00000000..e8dd0bf1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_265-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_266-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_266-hd.png new file mode 100644 index 00000000..cf0d4a11 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_266-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_266-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_266-sd.png new file mode 100644 index 00000000..3fa02a70 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_266-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_267-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_267-hd.png new file mode 100644 index 00000000..81eba9ac Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_267-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_267-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_267-sd.png new file mode 100644 index 00000000..129ace23 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_267-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_268-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_268-hd.png new file mode 100644 index 00000000..06fcb269 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_268-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_268-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_268-sd.png new file mode 100644 index 00000000..456d22d3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_268-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_269-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_269-hd.png new file mode 100644 index 00000000..a58d1151 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_269-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_269-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_269-sd.png new file mode 100644 index 00000000..1fbc3eb7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_269-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_270-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_270-hd.png new file mode 100644 index 00000000..1804b60e Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_270-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_270-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_270-sd.png new file mode 100644 index 00000000..b8609a6e Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_270-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_271-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_271-hd.png new file mode 100644 index 00000000..063c8bc1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_271-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_271-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_271-sd.png new file mode 100644 index 00000000..6eec1274 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_271-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_272-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_272-hd.png new file mode 100644 index 00000000..0093af91 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_272-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_272-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_272-sd.png new file mode 100644 index 00000000..15ef8619 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_272-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_273-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_273-hd.png new file mode 100644 index 00000000..9ac780ba Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_273-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_273-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_273-sd.png new file mode 100644 index 00000000..b64d96c4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_273-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_274-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_274-hd.png new file mode 100644 index 00000000..84373c0e Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_274-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_274-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_274-sd.png new file mode 100644 index 00000000..9c5c413c Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_274-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_275-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_275-hd.png new file mode 100644 index 00000000..22095f41 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_275-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_275-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_275-sd.png new file mode 100644 index 00000000..3ef1387c Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_275-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_276-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_276-hd.png new file mode 100644 index 00000000..2bcf1cd9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_276-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_276-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_276-sd.png new file mode 100644 index 00000000..19be2d6d Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_276-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_277-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_277-hd.png new file mode 100644 index 00000000..b634d6ff Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_277-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_277-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_277-sd.png new file mode 100644 index 00000000..44832bec Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_277-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_278-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_278-hd.png new file mode 100644 index 00000000..b174af1e Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_278-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_278-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_278-sd.png new file mode 100644 index 00000000..f3114520 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_278-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_279-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_279-hd.png new file mode 100644 index 00000000..78fa57f2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_279-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_279-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_279-sd.png new file mode 100644 index 00000000..2d4c8e0d Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_279-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_280-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_280-hd.png new file mode 100644 index 00000000..69d06e89 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_280-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_280-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_280-sd.png new file mode 100644 index 00000000..59a496c6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_280-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_281-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_281-hd.png new file mode 100644 index 00000000..26563aea Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_281-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_281-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_281-sd.png new file mode 100644 index 00000000..4bfb0ac2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_281-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_282-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_282-hd.png new file mode 100644 index 00000000..0e908314 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_282-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_282-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_282-sd.png new file mode 100644 index 00000000..93b110e4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_282-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_283-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_283-hd.png new file mode 100644 index 00000000..6eb37182 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_283-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_283-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_283-sd.png new file mode 100644 index 00000000..2b059741 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_283-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_284-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_284-hd.png new file mode 100644 index 00000000..9f43f7df Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_284-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_284-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_284-sd.png new file mode 100644 index 00000000..d2d0cfe0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_284-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_285-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_285-hd.png new file mode 100644 index 00000000..c765e4ea Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_285-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_285-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_285-sd.png new file mode 100644 index 00000000..f85eaefb Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_285-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_286-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_286-hd.png new file mode 100644 index 00000000..42a40d5a Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_286-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_286-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_286-sd.png new file mode 100644 index 00000000..169cda55 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_286-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_287-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_287-hd.png new file mode 100644 index 00000000..21c8f2bd Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_287-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_287-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_287-sd.png new file mode 100644 index 00000000..68839d91 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_287-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_288-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_288-hd.png new file mode 100644 index 00000000..9f221e69 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_288-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_288-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_288-sd.png new file mode 100644 index 00000000..9d29b541 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_288-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_289-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_289-hd.png new file mode 100644 index 00000000..00ceeb1a Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_289-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_289-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_289-sd.png new file mode 100644 index 00000000..b39ca3d4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_289-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_290-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_290-hd.png new file mode 100644 index 00000000..e84ae8a3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_290-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_290-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_290-sd.png new file mode 100644 index 00000000..305d8a1b Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_290-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_291-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_291-hd.png new file mode 100644 index 00000000..9727e944 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_291-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_291-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_291-sd.png new file mode 100644 index 00000000..b46c7b24 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_291-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_292-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_292-hd.png new file mode 100644 index 00000000..1139b27d Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_292-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_292-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_292-sd.png new file mode 100644 index 00000000..6bc83cda Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_292-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_293-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_293-hd.png new file mode 100644 index 00000000..be00b813 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_293-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_293-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_293-sd.png new file mode 100644 index 00000000..230395c0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_293-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_294-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_294-hd.png new file mode 100644 index 00000000..6f682203 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_294-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_294-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_294-sd.png new file mode 100644 index 00000000..13fabf33 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_294-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_295-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_295-hd.png new file mode 100644 index 00000000..a097dbe4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_295-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_295-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_295-sd.png new file mode 100644 index 00000000..dcde4007 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_295-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_296-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_296-hd.png new file mode 100644 index 00000000..cbcaf2aa Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_296-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_296-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_296-sd.png new file mode 100644 index 00000000..a2b48a24 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_296-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_297-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_297-hd.png new file mode 100644 index 00000000..c58aff35 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_297-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_297-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_297-sd.png new file mode 100644 index 00000000..5dd8a091 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_297-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_298-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_298-hd.png new file mode 100644 index 00000000..15344d78 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_298-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_298-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_298-sd.png new file mode 100644 index 00000000..af09b7b6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_298-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_299-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_299-hd.png new file mode 100644 index 00000000..948a2de6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_299-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_299-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_299-sd.png new file mode 100644 index 00000000..03b6fa8a Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_299-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_300-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_300-hd.png new file mode 100644 index 00000000..597fa9b8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_300-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_300-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_300-sd.png new file mode 100644 index 00000000..c8dfceac Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_300-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_301-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_301-hd.png new file mode 100644 index 00000000..d4e9655c Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_301-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_301-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_301-sd.png new file mode 100644 index 00000000..defe6305 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_301-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_302-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_302-hd.png new file mode 100644 index 00000000..ac89ecb8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_302-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_302-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_302-sd.png new file mode 100644 index 00000000..afd4f881 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_302-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_303-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_303-hd.png new file mode 100644 index 00000000..44f9553e Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_303-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_303-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_303-sd.png new file mode 100644 index 00000000..1039cb20 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_303-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_304-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_304-hd.png new file mode 100644 index 00000000..9540b632 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_304-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_304-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_304-sd.png new file mode 100644 index 00000000..a89d5831 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_304-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_305-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_305-hd.png new file mode 100644 index 00000000..87616f33 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_305-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_305-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_305-sd.png new file mode 100644 index 00000000..b81d5b31 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_305-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_306-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_306-hd.png new file mode 100644 index 00000000..c477bf52 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_306-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_306-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_306-sd.png new file mode 100644 index 00000000..ca688609 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_306-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_307-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_307-hd.png new file mode 100644 index 00000000..7add1745 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_307-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_307-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_307-sd.png new file mode 100644 index 00000000..31685145 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_307-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_308-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_308-hd.png new file mode 100644 index 00000000..5946bfbe Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_308-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_308-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_308-sd.png new file mode 100644 index 00000000..b0e6c18a Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_308-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_309-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_309-hd.png new file mode 100644 index 00000000..b7083efe Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_309-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_309-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_309-sd.png new file mode 100644 index 00000000..b8e1a0c0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_309-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_310-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_310-hd.png new file mode 100644 index 00000000..2753bfd3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_310-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_310-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_310-sd.png new file mode 100644 index 00000000..e60aaf1d Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_310-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_311-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_311-hd.png new file mode 100644 index 00000000..8176374f Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_311-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_311-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_311-sd.png new file mode 100644 index 00000000..1f632caf Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_311-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_312-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_312-hd.png new file mode 100644 index 00000000..9b7305ae Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_312-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_312-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_312-sd.png new file mode 100644 index 00000000..579686ba Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_312-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_313-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_313-hd.png new file mode 100644 index 00000000..ee1593d3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_313-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_313-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_313-sd.png new file mode 100644 index 00000000..6af3c96a Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_313-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_314-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_314-hd.png new file mode 100644 index 00000000..a1266ff0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_314-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_314-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_314-sd.png new file mode 100644 index 00000000..710a50d5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_314-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_315-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_315-hd.png new file mode 100644 index 00000000..68464f84 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_315-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_315-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_315-sd.png new file mode 100644 index 00000000..5af09d38 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_315-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_316-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_316-hd.png new file mode 100644 index 00000000..e2a0dde4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_316-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_316-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_316-sd.png new file mode 100644 index 00000000..89751a81 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_316-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_317-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_317-hd.png new file mode 100644 index 00000000..74827e47 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_317-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_317-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_317-sd.png new file mode 100644 index 00000000..acba1323 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_317-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_318-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_318-hd.png new file mode 100644 index 00000000..9af2f82e Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_318-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_318-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_318-sd.png new file mode 100644 index 00000000..a17a99a8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_318-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_319-hd.png b/mods/iron_coast_stage2_mission_1/art/tile_319-hd.png new file mode 100644 index 00000000..8954d2dc Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_319-hd.png differ diff --git a/mods/iron_coast_stage2_mission_1/art/tile_319-sd.png b/mods/iron_coast_stage2_mission_1/art/tile_319-sd.png new file mode 100644 index 00000000..d21490b9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/art/tile_319-sd.png differ diff --git a/mods/iron_coast_stage2_mission_1/asset-report.json b/mods/iron_coast_stage2_mission_1/asset-report.json new file mode 100644 index 00000000..cda7b0df --- /dev/null +++ b/mods/iron_coast_stage2_mission_1/asset-report.json @@ -0,0 +1,5462 @@ +{ + "utc": "2026-10-11T08:18:04.043741+00:00", + "recipe": "build_assets.py", + "recipe_sha256": "b7ecc4ecb69d0e6a2fb9185ed80cc27a8129e7c494b04befecc881c954bc8012", + "palette_sha256": "1cf6adb926d1dee1888b3e3d33b51a7049b3e5eb5f90a3067ef71c8970547204", + "ordinary_palette_entries_only": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 216, + 217, + 218, + 219, + 220, + 221, + 222, + 223, + 224, + 225, + 226, + 227, + 228, + 229, + 230, + 231, + 232, + 233, + 234, + 235, + 236, + 237, + 238, + 239 + ], + "assets": [ + { + "source": "art/terrain-generated-v1.png", + "sha256": "b505fda73b613d34c5646ecb3f081aeec6d48d67c5386549376bc29633849aa6", + "logical_map": [ + 320, + 512 + ], + "hd_map": [ + 1280, + 2048 + ], + "reflected_cycle": true, + "tiles": 320, + "briefing": "same generated map cropped with 8:5 viewport, no separate generation", + "source_not_modified": true + } + ], + "audio": [ + { + "file": "audio/approach.wav", + "sha256": "83e5f10c1daed02853b03f2b8158c0d699cef86130ce1f1bf16433cfe9f747ad", + "samples": 13230, + "rate": 22050, + "duration": 0.6, + "peak": 8433, + "rms": 3076.36, + "seed": 8083 + }, + { + "file": "audio/objective.wav", + "sha256": "f6c53307bff448e4258da92c9555c927cd10070863a779ec07c96ded8b9d4f7a", + "samples": 7938, + "rate": 22050, + "duration": 0.36, + "peak": 8444, + "rms": 3076.41, + "seed": 8390 + }, + { + "file": "audio/boss_alarm.wav", + "sha256": "2d0fc1d0bdfa803ad256db4aa79ed25140393f01df3aff41b371e8178bac2dac", + "samples": 16537, + "rate": 22050, + "duration": 0.75, + "peak": 7394, + "rms": 2449.59, + "seed": 8377 + }, + { + "file": "audio/victory.wav", + "sha256": "f56f91ac92e5b3134441ee3a2b71005ad8af39cc87d5fa79edf0047eca4eceb3", + "samples": 20947, + "rate": 22050, + "duration": 0.95, + "peak": 8443, + "rms": 3077.07, + "seed": 8089 + } + ], + "final_art": [ + { + "file": "art/briefing-hd.png", + "sha256": "d020f7f5cc7f4bd983b32726cd0d028dd60ba6997db115d0b9a3145da4e78cb5", + "size": [ + 1280, + 800 + ] + }, + { + "file": "art/briefing-sd.png", + "sha256": "98ebd4eac60c52f5ac8288e071dc7154f5480dda0ae6ceeb4d33d48a5fef44c5", + "size": [ + 320, + 200 + ] + }, + { + "file": "art/terrain-preview-hd.png", + "sha256": "f27193d675d501a0f9a86eb20f1c452da0d687b168d1409398a89582dd70190c", + "size": [ + 1280, + 2048 + ] + }, + { + "file": "art/terrain-preview-sd.png", + "sha256": "83d7da3e5fb06d6ebf81dbd6e3be8716c66caf40e7b7e2a25942f0b1021330ef", + "size": [ + 320, + 512 + ] + }, + { + "file": "art/tile_000-hd.png", + "sha256": "a51c2d9f79630ea29c95f03395fe83bc6fd566c690a7b8d4646963c468a5e5e3", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_000-sd.png", + "sha256": "4452d47304935481b5f7207f7d8f5bf98f0869d88a3d1b1881b3ef6d6e586a78", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_001-hd.png", + "sha256": "3ef1da82517d4a7aa9d848e336ea0734b7dcbc983dcbcd86719f0f76a56f0e30", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_001-sd.png", + "sha256": "d4b04fb96fdcdfa5e8609ff0dfca23c8f8d24a65f6cae4c6e268f8c3f3e9b40d", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_002-hd.png", + "sha256": "fc1171254c212388654341161d61a370d0717552e11afa691d6f5866f788776f", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_002-sd.png", + "sha256": "618eb07896f9387ce5c3ad9e639c75dca5c8eacd39fb210eff46cfe102633d51", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_003-hd.png", + "sha256": "1c4d790582a4b5ecaee9b8df601b20c8da2df291d3a62838fe4cfefa9c7dda1c", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_003-sd.png", + "sha256": "d5bc84e5ffb90ecc522d0d4244018d702feb9d623ab200f7c7bb673af71326c6", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_004-hd.png", + "sha256": "bc5d7eb9930420f3659f68cfe9b74325451ef474a3e67a6cde5a01ab8d7c81d5", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_004-sd.png", + "sha256": "dc1863cfa40d1a3b814cdddd3da575f4627e1f3bfa3444da454622314f057362", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_005-hd.png", + "sha256": "937351dde991753ef351f22a48af01b1f5d2c5dd3a3e4d2475948f9f8ef49b14", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_005-sd.png", + "sha256": "bc8b66da829959dafea82a0103bcfa529b4804376a4578ccde89e0f64c4b2dfb", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_006-hd.png", + "sha256": "0d4301cfa25d2d8df292b79726f0305e126340165ae96da00b5c29a59bcd3372", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_006-sd.png", + "sha256": "5c9485622d9700f7c18a40589660c22d57dfbd1d69bcc3ed7ad9dfc4292d37f2", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_007-hd.png", + "sha256": "2cc4072f934028aa604b8e56c15bdf21a498ffe484d078ea1876491aee64b974", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_007-sd.png", + "sha256": "ebfa72e7da6125f586a9d9c7c072fa4347879f6d9df1fa2a85d1887fd2da10e4", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_008-hd.png", + "sha256": "219f1e8c7cfbd4edc8d11de69ec9364e93978dc2a2e6d65e5713b946ccffa487", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_008-sd.png", + "sha256": "47046114f9aa52cee1c728d1743c34ff83100fc55e80e2715d157f60590e3dec", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_009-hd.png", + "sha256": "d48eabb883761fd88f7bc4c40bb84a94875c338abfc8752ccffd1a7a638ca8df", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_009-sd.png", + "sha256": "9d209596e69d5018a1dc40b8b50b187f0f840aaa91a43fbefd542e6fb696ae98", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_010-hd.png", + "sha256": "b198f9511c0b3f66e10b6c35e729e30bbcdf16b3e7541fc5524f74fdc2dccfff", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_010-sd.png", + "sha256": "25b262332323396263ef11f8717d8ab1cbab85bb70ad36a7c67a30d622f3f5ce", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_011-hd.png", + "sha256": "673d67af0e92575673347df1ad50602eb19e51082c67c0a0ba432d0d9ec7ac8d", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_011-sd.png", + "sha256": "e32bdef6a9beca869b9b39da62b1a87298986848192aadae95a2f388044eceee", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_012-hd.png", + "sha256": "49dfe6bd2ed29fc35099e94404fcba77be223631762a51578b2b2333f663bde3", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_012-sd.png", + "sha256": "a766840140aa87bb3985ddd1a9ffc519da202d6db440d20e4bb1cbf5681dfdc2", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_013-hd.png", + "sha256": "02083b5b3ec9a188b0053e50534a19665003c2dd177a3b558477f64e199b15c5", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_013-sd.png", + "sha256": "2baf26d5d9a15de94905f7f821815fc3ce2744c7e5ec8aba979853ed2152288f", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_014-hd.png", + "sha256": "91320fa2a837f56ff41b5a286de1d86bb448de45e5e88c4c693b799d661963fb", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_014-sd.png", + "sha256": "172a5f09681996b38d491e76f16ab66f02b3edbb772948854cd75e27516f7322", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_015-hd.png", + "sha256": "f357e446ac7d438486774834d18544a0c61a3e2dad71d990ffd02a2af6812287", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_015-sd.png", + "sha256": "aaee3927077a61e69cdf912b779168e79c681f60edcc6bc69083a63b9117471d", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_016-hd.png", + "sha256": "6a812b5600b0aaa8ddd08baed63d927b03706d6e5d5bdd46f148c2d09ecb198c", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_016-sd.png", + "sha256": "51760752c5c92c60dd85ae6792f7cb1d532b31a9266bec697b246d0b42cf11f6", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_017-hd.png", + "sha256": "104e785f828e51bec60d2ae7837fd0441d2254ffa765583aa5b676918153f8c7", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_017-sd.png", + "sha256": "76746a371abe0200667c63d8e0dee0a0f124e42f8eb1ee770a6d7dc6fab82b57", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_018-hd.png", + "sha256": "61d60e531fe3381774c8354978220d68737ca35c5a28f00f001192108c7033e3", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_018-sd.png", + "sha256": "f07c1086b0978cf1c217994d7fd129fd282d684924a13fe2f9c232c2b816a04a", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_019-hd.png", + "sha256": "988ea18fba8b18adfd75ca90b91eb6300ac63ceafcc12dc74d3dfbf0e6d685c3", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_019-sd.png", + "sha256": "ea9308a08a0c8d37c82b22db85e6a376332227f51b21c2f9121e6480f363f4eb", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_020-hd.png", + "sha256": "9aa6f85601e76903bdd45e9705a9480985f4d5ba353d5549d72d9b76aaf9854e", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_020-sd.png", + "sha256": "16b39fc959eb28dcbec32d0930c105b0aada746bc9640a4d01f12694d9bfbb88", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_021-hd.png", + "sha256": "07c9ad39d2f596e8377eb0a0415cea07cc50ab8532759701d5fc0e2073d7551c", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_021-sd.png", + "sha256": "58be41106b54b5f80377022bbde3430bb15fcefbb6c65d09528639783d003332", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_022-hd.png", + "sha256": "1734b6dec124cf523184165ae476e421c3a036e5f27937b55fd70a1c1839bb3f", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_022-sd.png", + "sha256": "877b17b8c85698d015c29b3cde07c862ed0e61180eecc700a8dcac2b20ac96cb", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_023-hd.png", + "sha256": "abbf739e1dd4d3fdf184531da7f1be64e47008ece3bd5f998eb27cdeb14cf7b4", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_023-sd.png", + "sha256": "d84b373f6a3aa0e5d77736349541126850323d92cdac45b65298526064fa9da9", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_024-hd.png", + "sha256": "13d5380f2a021f92065a6a2dc72e255a1601785dfdd0f4b75a81b496517e1ffa", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_024-sd.png", + "sha256": "2a82010c92a3d1ee8dc4a678bf5275dc84fd49b890cd58eca4e0b91c54cdd12f", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_025-hd.png", + "sha256": "186f89096581a5317219bebad80215a83ce7052c0af0932612b7379cb296268e", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_025-sd.png", + "sha256": "29330ef7935ebba3243f84c39b761ea2e112a5e7e6718539fa744c780b38a562", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_026-hd.png", + "sha256": "06e0e6ebd1446705c4f5522d10c5c22984d731b491be6c054fb83189a39e735a", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_026-sd.png", + "sha256": "ceb79fd1c19c7fe9edf90115e25d8669a20f9d2d96f823894383f73d3bc1264c", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_027-hd.png", + "sha256": "35cf10c2c0d97fb263b162122bac5a7e14db82e7b7b80134b8939fa33a0072d2", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_027-sd.png", + "sha256": "3ce7dcee4321fe7e7533343478f4547dd0e75438e388f6887ec8b58f9071b7bc", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_028-hd.png", + "sha256": "79b7867e33febef22c7ee7dcd35c2715ad36d3d2b71a1afce3f6193b3e01def8", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_028-sd.png", + "sha256": "ae536e3f70e990ac8732dede9c424b100972bee4ce0e5fc9e285ead7080c5ee9", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_029-hd.png", + "sha256": "f816802433e9a4f628f0590251a801e24fad8e4f69172b7ad4054e907673b71e", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_029-sd.png", + "sha256": "433bd6227b50b9d5d59e6289f2c1eb47781ddd4d111599b1763b3c19cfd040d0", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_030-hd.png", + "sha256": "93b490b1fc01853756a900019a6b14dfef02cd2a2ecfc40796d41e54f09fc562", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_030-sd.png", + "sha256": "6fb87dab601632f5d6237defbc70d288e0d37927ad8c469757c5152683cf5ff3", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_031-hd.png", + "sha256": "5beaf3e132582bf48db33045330d4c5c8576789c70ddaed823815d7e52b273f3", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_031-sd.png", + "sha256": "5d15fcd5c2516ba73391d185592bcdb6295675d4da079ec433e362ecde6bfeae", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_032-hd.png", + "sha256": "3e5983aa8325cbeaca9f7979f774535d98ef1607880c8d6a1768841767cba14f", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_032-sd.png", + "sha256": "51165d5161f5065b991e247f76e107f4745cdabbc20d7862a5f1ca6bfe4931de", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_033-hd.png", + "sha256": "060184ee0162fc14f8e686ca777d1027d1328ffb9aa601144c541afa6a500d16", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_033-sd.png", + "sha256": "433c82b74ea3b74cbc1ee4fe7ae170dd799828b0cca0981640d00f09f7f59cec", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_034-hd.png", + "sha256": "7abe5b606b5f72b60fb583f1310a990437e91144413b856c32b410ac0d91dfb8", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_034-sd.png", + "sha256": "c8a5cf21c87260449b7c5efdfbf7177742dd9d5c40163f6dfac72f327e901a7a", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_035-hd.png", + "sha256": "22e4486bd2a37897f9a90963fbe8451e2f997f5f23cc0e19ef5f2fdc0815f031", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_035-sd.png", + "sha256": "44bb4cbd9d1f392759ec2e7298e20aad504b9ba65f69e4100cd364134c7f9011", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_036-hd.png", + "sha256": "cd024eea8e990db356b5744ea4b3ffcdc86dfe424f9c3aea76ad7e8b6ac53eb9", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_036-sd.png", + "sha256": "6b836c83e04c5988dce3933d697706543d2e09964ed8d1d2bd8db7ce8b4c5ce2", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_037-hd.png", + "sha256": "c669cf1e54462575a99c2e5ac4b77865ddd7b3496ffae5be62fc3e1ff0d88adb", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_037-sd.png", + "sha256": "669f116894082b841d1544485c9c942011de55228ce92a9bd0d5a1f3900f49d3", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_038-hd.png", + "sha256": "3c636a0b42836b6dccb20dfab3c49feef95418e9464c8f99510c82e90fb27174", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_038-sd.png", + "sha256": "3c8ee033dde59371649cb0a1fa71cec89871fbd0c95aa095b26c3007c5a43377", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_039-hd.png", + "sha256": "90f9bd4dff7fc60b32e43ff8d004605f548801a4c14cd007c88d0bf78f719b81", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_039-sd.png", + "sha256": "243786e476a54dc3b27706b583a9d31c24dc6b29ba56e120832896007d80aa95", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_040-hd.png", + "sha256": "1e4882d94da0341b4194db7811dcbc547d94a21c2c6ef52c1f333a9c0a9d437a", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_040-sd.png", + "sha256": "8a21b588ae91f74beb6f44150efe2f6f0da9c56559e558fcea9495ce744c460b", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_041-hd.png", + "sha256": "30dbaf4663ed7bf0adbf0f2136530cb000ced00a460020178ee5b767798ba762", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_041-sd.png", + "sha256": "82e0765e97c775b88efabc12e9d7545f56d78896ea03e9325204f5381ba1fc0b", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_042-hd.png", + "sha256": "cbc72407f1ca3fc7034de9478111c96875c3eab51fd1ec7b878ae51a93589a4f", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_042-sd.png", + "sha256": "15323a1ded23a0bcad7e25143d492e3bba8ddf3e9900add2e13de32662c8cdb9", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_043-hd.png", + "sha256": "765ce197dbf7338a3bfb83f36dd3dad1e2b2142ba7f9234a67c01c8e3b903135", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_043-sd.png", + "sha256": "ef54726dcef4094f5f209df9ff63860b62ae385e61204ae8e0248bcfc06d98c8", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_044-hd.png", + "sha256": "5162803fe8e5f99a2912c928576954bc8abd76c427539893eacfe59b18743cdc", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_044-sd.png", + "sha256": "108d6abd4b49264e20da6ba4aff8a7c336b42bb55a13212467d43e1122f0d8f5", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_045-hd.png", + "sha256": "428d9b44bcaef0be3f134a8833a071226f0b3a0e495369be78d49e308668da5d", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_045-sd.png", + "sha256": "6a47f502f79579f45e1f68213d322eed757ad7ec314dd36913dc42eeeb0fb36c", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_046-hd.png", + "sha256": "b2fbbf38b01fe48cbd949d34448461ca7007e2280756129268d693785907bbf4", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_046-sd.png", + "sha256": "d4e394e481db32f048f3f5a90e6aa332c7db79106c97e9bd96c7888c0aded98b", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_047-hd.png", + "sha256": "9a73cf39447f287bdc9dec7ebcd4261f8c3c224c4b90380d13d1d8d7760d71c0", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_047-sd.png", + "sha256": "399f1bf60e19a9d4b8d0530a5c4735e10833c05814b892a844608bf48603efdb", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_048-hd.png", + "sha256": "4b193879487342397a12cbb18d2408573070c11534521d837dfde4dec6b18249", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_048-sd.png", + "sha256": "8e6538c12cb54e7df7a76609a4e6a09b83b71825fd6811d4ef6ebe5ad956af23", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_049-hd.png", + "sha256": "14f2f1d5a258aea8f455a89af1ebc1121d0ea2a6c3fa195d91f86b354890aeeb", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_049-sd.png", + "sha256": "a4009c4b510792a67064fd6f1ecd3c6ccea18f8c696f04a9592852bc56d33b07", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_050-hd.png", + "sha256": "b3d879c01df2895969c4bc45d8e63faaf01c10aebaacfac49cd2d4f6be0a7aeb", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_050-sd.png", + "sha256": "2b22f2eb5918585e15c554bd0e0d01983a1ba890b56a707f6187c3fa1c267234", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_051-hd.png", + "sha256": "a88136ec80a2252258fea2288622aab5163e0d2d602fb0e03c386a4039b3d646", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_051-sd.png", + "sha256": "65f57e93905d261b7a8ee9f0fc69464adecd94fe7a6cfc3fc4ba00563059cc6f", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_052-hd.png", + "sha256": "92a451fa4bc0b797f51cfd83425b5b75c2566ae008c942514fe59f180f5a14d7", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_052-sd.png", + "sha256": "de06f594be95bc09cac9342c872ab3dc577810924af58772f9892c732dd6b60f", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_053-hd.png", + "sha256": "830681552d50cae9dfa1fa8483cfb0fddcf79a9706ae4942358ad3ab6987d542", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_053-sd.png", + "sha256": "d54ea44eda9c4ea624b873ab16b7e3144762cd12fbf3e6c7960c06beaccc7ecc", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_054-hd.png", + "sha256": "31734a0440e04e1040610a9eaa48f53bab722a6faafd74d1e67479b0bfddeeb5", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_054-sd.png", + "sha256": "1d762e481ced16c2f8ccf3602d413ec0e4704d1aaccb6b1a0ba78ffa2e0719d4", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_055-hd.png", + "sha256": "33f408d9833486058a8df3f8853ed7d2e92685e4dad622a52108575a756ac37b", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_055-sd.png", + "sha256": "8764afe292440fbb24fbae428315c0388aa2aef828c394aba94ddab31ef8523d", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_056-hd.png", + "sha256": "fe3563a619764252814cf924bb520ce7049b7699c35d5a81a9d145c47b819233", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_056-sd.png", + "sha256": "cf8940a0b75249f5753518f0481b4d26cdb34db75c763da5ebb82f6e621248b0", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_057-hd.png", + "sha256": "0c5f9d351a0cbce4855362044dd74fc4b86db6a9f0432b07587863565fae15e7", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_057-sd.png", + "sha256": "3b24469c9e1ab3ee041d8abaaee7380ab35c0f07f612e6f217112635332f3332", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_058-hd.png", + "sha256": "7bd0879246b6a398649df00c53938b3293e5edc8ed99e941a1e17a161e5fc366", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_058-sd.png", + "sha256": "a265340cb3f12a740c433b9d8bb37ddc2c7b35ba845a6dad352fb271fdef8b98", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_059-hd.png", + "sha256": "c691f78f245fbd8a504d9aad849d651c755cb33906a14f53f8f36e2ee3c07f65", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_059-sd.png", + "sha256": "15468209858361fe793202118c45c5d7eb0c5bfb4e0e857640b4d677c86c4da6", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_060-hd.png", + "sha256": "1612c5238f4de5843bffd7a028350d22198953e94c492ae39a59ec503ade93b8", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_060-sd.png", + "sha256": "ef7355e9186d6d6c470ec9edcd3d76bcda1a612988679bb798eda966341513c8", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_061-hd.png", + "sha256": "5935f380c03d21a1eb520e585cb4de70aea9dbe02e519e1ce7f1b15d1d972a92", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_061-sd.png", + "sha256": "fcccca7759c7943166ab97f2791f4310d9b45b8168c1dec4bcf2577c0559f026", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_062-hd.png", + "sha256": "8cb2ff0f8a28d88eeac0cbc28e5b805246971328c4bc9f9723226a5554c163ec", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_062-sd.png", + "sha256": "59c0f26f37c04f1b07defe6468e1c7236f8d4bf147932336fe5fdf476b306d06", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_063-hd.png", + "sha256": "ddbb1ea4b88ba09dde3991cfa7b9e94418a2100aca2db6112d53216c8c1edafd", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_063-sd.png", + "sha256": "03d0cd181fd346c1ed66b71cc4980e408e9225f65b7a25648d65481055599284", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_064-hd.png", + "sha256": "aeb28f2e9b5d9efb621a221082a7f4d5b1ba04cf0cab49385df12298bbb446ab", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_064-sd.png", + "sha256": "cd59882702aa8899ca39b9d51a3d62052d2e7983c9391aa9721063ab4a2422a0", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_065-hd.png", + "sha256": "0cfce122b3226aa3c4fb7b1ed101ffe72ded11fbdb7cbbe7212d13f96f9a8c58", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_065-sd.png", + "sha256": "01029692c1f0a624be69ec5292d4cf45409e4fdc7923e52a6d69cda4b0a30a1a", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_066-hd.png", + "sha256": "ba96c60440afde30b27810bc6ab53ce0c6546587d9bdcdf05e0abf064e484c46", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_066-sd.png", + "sha256": "58bfd3df2264c6b378fc4544651659def8091b4a75babd0546b9916559757dbf", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_067-hd.png", + "sha256": "44b6f116b22b9c0a9d1f58e55ec3e663e65d8fc4b503ddc1266b978f7b543a0c", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_067-sd.png", + "sha256": "243417fb95ebec493aac0000726172866c406aec64446c4072fbbcd0b68db82b", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_068-hd.png", + "sha256": "8be9dd288e64b27870b45d8b7510a03a0c86c96a8783e623279e449f17b36117", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_068-sd.png", + "sha256": "be722f794a910fe349e0ad38bb5df40c6de98667a90524bf4371f0d8777ce121", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_069-hd.png", + "sha256": "36208cf6283405ed0c3196db0aa4c8d138ab651e84ebbe310d64259006098179", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_069-sd.png", + "sha256": "cfefb8a274e69093456bfe7687614c9b0dd5c37d6fca1c9eb0a174a866c48ced", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_070-hd.png", + "sha256": "215750c0d15854074dbd57a4e161263fd55d39a449ed22f8ba111758f2a5bcdb", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_070-sd.png", + "sha256": "265adffb84ff5cc81759f7eb9b50dc2f8768cedd2437b4d1f6860c0f761f1af5", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_071-hd.png", + "sha256": "e42c20d4459e866f21a1f658fa1ed5ea9bc2dcba243295d33e34086d7cf7d1ce", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_071-sd.png", + "sha256": "faa80e07766f711b3de38c39fd05f926ce82445c0258cd0291a518f5cd8da3c9", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_072-hd.png", + "sha256": "94af5e53fb6a56659b46e15fea9a69f39953918d6eafc012cdaf39fdd5dd2243", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_072-sd.png", + "sha256": "da57c42c89b847442128fb552a6829b03e8be78706dc21773ae0215d87fc2f53", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_073-hd.png", + "sha256": "ed804dbcc108e6cae393f677172848c72a072a9cf4f2b64fa6f610d0526e8c79", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_073-sd.png", + "sha256": "84a69ff7cbff6beb02b6ba5286747be8e44db786cb6efe5d6a3754a5d67a8a89", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_074-hd.png", + "sha256": "934a3aeb71a2f068ec968d0d1331b3f11e06f2345b40a0e95c9d4f851f7deab7", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_074-sd.png", + "sha256": "3eadb031e73114e307addf0338b05a9a197a94e71cc508dfb79a1b178300be25", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_075-hd.png", + "sha256": "0e76887f14be6edad72bff2c310d523186608059483af3721468fb294c993000", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_075-sd.png", + "sha256": "a82f548c2d67e2b025df4d108cd122210e558289fd8b4e8a08efcaa5db584770", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_076-hd.png", + "sha256": "6ab011e388bb89434fbb652b45ab06a6faa366889aa5759191bf7af995304378", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_076-sd.png", + "sha256": "78bf5146c94e4baf7d93dc33236bc8c423a733d20ccbb8c4bd9c880c1e41059c", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_077-hd.png", + "sha256": "c70891d20e339a2259af9129888df2b74ea179e6d9cccfca03c312bc46891d4d", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_077-sd.png", + "sha256": "c23a91126c5cd4f44b9a1f9c85d285b2d216316247b1c69614c2b79ef4782ff3", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_078-hd.png", + "sha256": "a271440b400e5c3a213a3c55e31cf6685b1d1b856d544af5acd5598f2467039d", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_078-sd.png", + "sha256": "46cece8282a4408cca20665d1e0f22fcddcd12e581cba04ffe5cd7e5313d0d91", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_079-hd.png", + "sha256": "5b8614f75f861550a7fed03033ca118d87f0007a3837e81a61d40e356ef58737", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_079-sd.png", + "sha256": "bcf0c86c1c049e445cbc6c42b5b8911c2acb326cfb1ebb9f3b3b1b4435fffe7a", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_080-hd.png", + "sha256": "fe2007df13b8441e5f395988102a9bfcf2b61212faa34ccd75f80d55b6f72ac0", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_080-sd.png", + "sha256": "04fdc2d1e231acb546ad8e6c4db4b6fd71fc1b913cdbe84a4bff9ed9ec2622ed", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_081-hd.png", + "sha256": "7c28ad86d63ac63d7a6c3872102bbf0c7e59f5e827ee80bb421cdcf52832b4da", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_081-sd.png", + "sha256": "5439a703ab49f17744609efd6ae6c24b8dd406788faecec3eef1c4f3ba5f7e09", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_082-hd.png", + "sha256": "03f5c4735d88e343079c5641e9365d54d782b96d50fa1f63a53af79f14d6c2e9", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_082-sd.png", + "sha256": "89905c29f1fd1f9c0da0a1b2c8c0fa88c13bf06845d63c7fd5ae35615b1537ed", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_083-hd.png", + "sha256": "32675f6996e1d26e6646fa94e173295db25345909edec72a604207f142523cbf", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_083-sd.png", + "sha256": "d9cf16074f4c782f11f484033f84f677986e67b62e076fef87ea6d348361a9c4", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_084-hd.png", + "sha256": "8c02c5b874f234277528256cbf5b747ee4943b8663b9139775c183c5066926fa", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_084-sd.png", + "sha256": "25fd01bd8ac5a5cde1e668e1e633549c6afe84352cdeaa315d922cb425b35aec", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_085-hd.png", + "sha256": "704ac2e5581cd94e3b9f27e2294a9e4fa9f87bce8bed7a9bb2f629675bf043e6", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_085-sd.png", + "sha256": "74c3a357787a2fcc63ca9ef52cb529c205af28288c843ea198b26b7d507bb55a", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_086-hd.png", + "sha256": "82473936e2100b8d2e9c8a687490e6be88aeb31ba89fbefa730d8edd06fd9c1e", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_086-sd.png", + "sha256": "3314c1fd0b68830ab38379d939f29b9afd63cb4a0103b0897641dffe8b04bc2a", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_087-hd.png", + "sha256": "fc9b6b851fccb9694affdf6a30e744bc90e009e0dc2c7d14236475e2bb30aace", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_087-sd.png", + "sha256": "e211212220fb4b3b5a2f4e85af4ee50fd4d23f18edf0be089a1f3bcbf05242c4", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_088-hd.png", + "sha256": "24f9eeba213855ae48243332888c5fb1a906775793bb615246d655840180bb92", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_088-sd.png", + "sha256": "f4e912dc3299be1c2bfaaa74d006c9a502e8b39602c2d8d5842d4f11bc0400af", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_089-hd.png", + "sha256": "9f70c95fef7a3fd1a0665fa9aa48634ce3d401704d799d58cb3237d4fd9da1c8", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_089-sd.png", + "sha256": "970b36644ce85aeb0fd65c63cce61a46c6746a011d21264b3cdfaa408807b16e", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_090-hd.png", + "sha256": "9d1e8c47dd3a3ebbb163b604870ee0d273db379e9411b3536eb9bf96f88f9dd4", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_090-sd.png", + "sha256": "0b433c5b9c3c77851f001e20c6573f5f1d16630d5dd38a0fd13ff8481ee18f74", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_091-hd.png", + "sha256": "6534872a088fed9bad0082a737088abf5a33334bdbab3e53e7e28aebc91bce83", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_091-sd.png", + "sha256": "c35ada62869cef5454fe78423f48d1d0cc616dae20c31af3bdf2191b26ce9b87", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_092-hd.png", + "sha256": "d75cf278d2f8bf1d16b8d537693d0b14893f1d81f54895a0fc2efeeedba0c727", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_092-sd.png", + "sha256": "e6587d8acb652d96bd712c5147cc1c73086cb4347697cf35b14db34f1f137cec", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_093-hd.png", + "sha256": "5d78045001ba428f41a0af8b02e3db30e45c0c3b8016c68f86cf009a2a4b04ca", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_093-sd.png", + "sha256": "a2b985269eaad2858c20b3ab8d8cee9fe0cf74a5c226145928a6fcae7e5428bf", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_094-hd.png", + "sha256": "40af2177ee28f6e7fc22edd339835156156747d3ed00781e741b31b696e9defa", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_094-sd.png", + "sha256": "9510e1936c9552925925dc9eaa49cc468e63a15a40bf8672810ccb98f485d7cd", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_095-hd.png", + "sha256": "e644deb12fec105872aa1a35132384b80f26579e217b21d92c9f638c76cbf5be", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_095-sd.png", + "sha256": "de0c8ca1237c1d30e66c20ceafac411bcd643fecf6cbbf5a5de442aa371704bc", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_096-hd.png", + "sha256": "8d8c5c54d5df60a2d60210f671c579f432e5592f6fb46358588523dc3bba4a22", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_096-sd.png", + "sha256": "61f37d240cc5e79bdf84fa448fee1ba72e32490280c4dac29f97c3105f06c4e0", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_097-hd.png", + "sha256": "86ab8ab9225b850ee524386507bc2e3dd2426ceaabffa7826134242eb9a5d748", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_097-sd.png", + "sha256": "6f184012c7de40079209fa6557aa6c02a4af141e5608582b9a682c8c771d9000", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_098-hd.png", + "sha256": "75dba97c36f97185e39bc7a86ac08c3c36c87017f55eedb55288be9ee8ec6900", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_098-sd.png", + "sha256": "caf48bb51a64121841727cb4bcb2fad376c8c1208b9500e4d659f694463aac44", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_099-hd.png", + "sha256": "29ca344361c810edfdb261afbc5cf5290066263704b7270fe9be34df36f885d4", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_099-sd.png", + "sha256": "3a48ccc57ad173144746875d73e9df66f682b8bfe87731622cba67d91d19b309", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_100-hd.png", + "sha256": "a9da4c4eafde9f033518831ac72dcd47f012300c49f8d427c10658a5aa291a82", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_100-sd.png", + "sha256": "9e673e0c7ed516679edeb12787742d9a704440adec2535f3e0941988b070be57", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_101-hd.png", + "sha256": "31e095a44aec2c0039236713be3642ce3507e1fce377076660846a0df00d7ba6", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_101-sd.png", + "sha256": "77f3dc8117343a2f2144a3720dc97cf76e4c51642fdbd0ae1ef88f2eadd0f158", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_102-hd.png", + "sha256": "e9416852338d7641274242b7b12a7d8ff11ecb07ad92d9a858d7cd7f32537180", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_102-sd.png", + "sha256": "3e578599e164c27d494a072604efa2ff7d1cc9ac1e2590276ac65b86240579b8", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_103-hd.png", + "sha256": "215d97917df420795ee72d3992f62196877c781480d592a4a5b6088a14293651", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_103-sd.png", + "sha256": "c2b82b6e54bc47082709f857c73cec5cbe4351f9384c65d951bd4d708225b93b", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_104-hd.png", + "sha256": "06114b7de6f53819f2a46b81cfdce9c42159e55cd2c0a850574042a4ee5f1e81", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_104-sd.png", + "sha256": "ead5e099607e962271af76b3be5b087f26eadf07d4c16b01a00e31e38866866d", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_105-hd.png", + "sha256": "dca1c9abc2e94779720a9e3bc1dbe035dff90e2a946b5d105eba53a3851b0556", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_105-sd.png", + "sha256": "4b2a8f84ca44f9babc9081dfa9dae8b3f36f10f1d6c27113fd0a005d58d20b0c", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_106-hd.png", + "sha256": "de16132eef7134e71230c932023c7b3c3c455283af18edfe63eb33d007f84807", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_106-sd.png", + "sha256": "ecdbdfc65a2c0c2cb1f59eae7b37f774ed5cba9799dffbca107ff3e454d63e03", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_107-hd.png", + "sha256": "75143765d571157fbe14a45e33b1ff8ed922d46502f2ddd59026f6f34e31c24c", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_107-sd.png", + "sha256": "a9f4c38268618790d794a3817f01c7f7c68181e3547f8f113a22a38059288a99", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_108-hd.png", + "sha256": "9c5501866badef516aa4a535f034b978e843b97ff2cc6a83e8039916560b66f3", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_108-sd.png", + "sha256": "bdfb3d52c22a20733d0d2dd5d3e3b6c3e2a9f4dbd8df5aca6bf36957306d56f3", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_109-hd.png", + "sha256": "0a8ca9fc5ea603775223b49eb23b12b821bd02131428f6628d53546f22db4245", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_109-sd.png", + "sha256": "7a1855a4a8ff74c8968986d0c204c92ae428c924204e9c3c40f41678f06fd521", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_110-hd.png", + "sha256": "ca929db9f00e55e70e579f80c3bf6d571c49d9426ed584727bfc5eda2d602ecc", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_110-sd.png", + "sha256": "eb47d01b1bb3daaf8b56b2e319c1fff385eff5ef56c14dc085f9a0e6c2130a27", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_111-hd.png", + "sha256": "7dcd0826c14d04ed33adf397bff29f548051371dcf26eff0be364218bb2c3660", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_111-sd.png", + "sha256": "99ef79f912cb2d34761579e930af0b7c90f60ba003618a628136667e9481cc02", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_112-hd.png", + "sha256": "c649872920e57c7b6a05fb783a712e397d1f4c52292794986ed8a387a6942476", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_112-sd.png", + "sha256": "bffd883d3229a650c826c30029383727b432a87cfdaf24f4776e93b725f94d92", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_113-hd.png", + "sha256": "fb9874aafae116e78e0c6cabe181227ec6f373dd3f00b41cbc69d54680984737", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_113-sd.png", + "sha256": "71f1474a51d57f56f547468e3eef9817d8ef48f782ac3a086ed81703b261988e", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_114-hd.png", + "sha256": "a9b0e2941cc188f8f0bf36feef06ffce514b3e47cc4132a6a466d49a598966ca", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_114-sd.png", + "sha256": "9e8291ab7db98e8fe4577704ab822972ced0a0e9e720de8e375ca4bcae691426", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_115-hd.png", + "sha256": "50774c0422ce9e4be581ec9a9114ee2fdd048cf778fd57c236f35b749f91f750", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_115-sd.png", + "sha256": "c7f0edf733b3b9a02ddda33235f5d106626eef36f512d774511f0dee62215ac9", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_116-hd.png", + "sha256": "37b04478efe5fd5ec0386837cf321e0a72e7d050b5c80fc5c14ae00b7c8ef1f7", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_116-sd.png", + "sha256": "1eb0f9ba4dfa4842c99e1738cbeaedbf3af5af34a520ffb475ee4604807015d2", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_117-hd.png", + "sha256": "1ac7f07e997fa78b36b0347a9ac198f5b384b24aaf3ba97fc654c69b714de3b9", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_117-sd.png", + "sha256": "232e6f491fdc71f8da3e6f16ba71ceea8cf42cdbedfb3b1530b61df90db2c7f0", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_118-hd.png", + "sha256": "0dfd8958728dc9cd295b41e0b441dbeedc31fde52f63fa2e6f1ec184a7afc1b8", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_118-sd.png", + "sha256": "f3c77b860db39832f75fe8893d35a175db91ff360c28cf0039ac197314faaf51", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_119-hd.png", + "sha256": "633f310e6f045ffc5d26e05a266941b0f46f98a58960b3bf6fc72bf5d14af286", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_119-sd.png", + "sha256": "37aa56ab0739140d1b07c05bf5ac831cae0d198329edda1809a14581bd39f110", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_120-hd.png", + "sha256": "92bc919dfb558bc244ad5eeb72ed540606d459c9c7eceb2384f8aaf1799714a8", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_120-sd.png", + "sha256": "0e554d3dec0a38a4046427b60649208fb73c0815b34acb6eaa8c5e81df1f3f6b", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_121-hd.png", + "sha256": "7b675c21b72afc3fbe430c11cadab20e07802d6b41f9f674ab2c26272cf1fb76", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_121-sd.png", + "sha256": "c59de391a67518c764fcbb3d68ef4dcbb5e012d5cb5aebeb35d766feade0555b", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_122-hd.png", + "sha256": "f36a018121b2d9940c05f5b7422330dde4a18ddb4de36dbc8807e64aa17b7b5e", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_122-sd.png", + "sha256": "090f4c56e76bdb5336790a1554def0f71c6998d362e60a3cd204bc0aead4b3c1", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_123-hd.png", + "sha256": "32102c6e21256b12d7607756d45c1bf2fc34e887e1a77dd92d820bb7c60daac5", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_123-sd.png", + "sha256": "c8e118be23499e75670fdda98417f5706dc97a28f1447e0053c5c806bfdc4c96", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_124-hd.png", + "sha256": "84e66dd1869c5c54c6b9b23f18f4b61ef618b1516f5b2dbee7305042dff241e2", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_124-sd.png", + "sha256": "51889c977cc88af5e48484d9565cb5eaac79143eb0d3ffe00d950eabfb877f57", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_125-hd.png", + "sha256": "f5f7702b4ab531d152965e2a63ee4718a37fd03e74c79b91d036239ec1e69014", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_125-sd.png", + "sha256": "b2f19d85630bd49b4b495b32f300dc3af9e4caf546009038dae07c9b430fca3b", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_126-hd.png", + "sha256": "5a2ac4a767f33e30c3345e107b36a05f79a348bda132c787ace07c83f20f6614", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_126-sd.png", + "sha256": "c0d26c3a5b0608d4f0c2bc3f514bd4557901423691def27781986ba15916bdc5", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_127-hd.png", + "sha256": "b3875a78fa28bfb7c3efe973e13c7d06bcdb685a899e2eabaf09437490efcc47", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_127-sd.png", + "sha256": "397b08e1eb32ff7c595e688e0414e8c8722720bae1aa52db1f97c9d319856ff0", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_128-hd.png", + "sha256": "ad7053b7515755a825181ec6064db7f9b1219521faa76ba9cdc3cccf3e9edf3a", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_128-sd.png", + "sha256": "9223831c43bb58183ebaf22c0395bcbf65a4005fdbd94a6edaff57d924a122f5", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_129-hd.png", + "sha256": "82bd937bb92d069ad16da7eddebd557ef74361081bc41cbae3493eb9c4bcd461", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_129-sd.png", + "sha256": "3521758a2b3372619c57066b5c53aa819e0ea5eb5cdb8801c814aab6536222a0", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_130-hd.png", + "sha256": "53d60a26d4ed0fda4ca9c33ea9d41432bdb6c9fc8cd39c73f78d0eaaefa5ad5e", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_130-sd.png", + "sha256": "0ba414270c19b36ea29834b656c6cc643be5723d306fcc821ada4065d2a6e8be", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_131-hd.png", + "sha256": "7c77d904261911444e64e83f2165a19b97c4c257a9d79bb8559b47b3abf1e9cd", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_131-sd.png", + "sha256": "030e0d4fccac1778b75ed1edd258620ae6412a1c572c4e4cd7e6d84fe945c4e1", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_132-hd.png", + "sha256": "f239dc5911d3ffa1a5fd47c5370c28f82732258833a125dbc2bf64b6c8a29078", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_132-sd.png", + "sha256": "a3cb0cb9d9adfe2c809716ece70f52dafbc4fe11feb3f2c6500af0e01d3f2e85", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_133-hd.png", + "sha256": "6a7e3440525c6f8eb45c22dd89306d1a1ae5deb3b51b90616f5cd13a9b2858fe", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_133-sd.png", + "sha256": "136cab87f36508bea53bd94b43588dc77a76331695f70b60bd712c19ea82f5a7", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_134-hd.png", + "sha256": "fdfaa55a3ec6dbe7fad1a9af42f5b8e47fa9594a9661be537476543f600469b4", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_134-sd.png", + "sha256": "e753f4f7671bd4003125143797e044e5e12baba09c63a76185b2e1b12bfdd578", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_135-hd.png", + "sha256": "ad301f6759317de359d3915a6009417f75adbd49cecb33c065ad98e512ca3abc", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_135-sd.png", + "sha256": "f4acfdd3ae1fe9459154eebc68647b57635c169b4f1cdafa97d774058db53d1f", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_136-hd.png", + "sha256": "1178f2ccf30443d75f89177a5b5a5f4420c632c85097c2d47911e028ec6a29fb", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_136-sd.png", + "sha256": "a36f900197493eb57cc149717d65711841457cc70d1d15d6b1ef34c98e32f3a6", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_137-hd.png", + "sha256": "43e49db093d963de743fc782138b11d9a2c4fe65a7e9139867785e4c7f09fa38", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_137-sd.png", + "sha256": "05c54893f9542974617fd7c289e3a97e2dca9f17928da95b1dc27f5e882ad3c2", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_138-hd.png", + "sha256": "b14e8cc9324c6bb4a7c72e19c66a19901135bbc427c1e2d3468e09ad4be4d83b", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_138-sd.png", + "sha256": "2c8c1c819c3833e9f4a521559a6751f9e87500e7d2591fa07be650e2f477201b", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_139-hd.png", + "sha256": "1ab2eef1a6e6bd5f4311a1b7071b4b8c90ae77dac83727fd553cea6dd06cec3c", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_139-sd.png", + "sha256": "e56c75db9a48fc23c84e9b8e2e665f28e8ed0b9f2a034c7568eab4f3ea30f2a5", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_140-hd.png", + "sha256": "0082c7c60970acaf19decf0cb93ce2b14c9f95d03745d277d509b63cdd8519ce", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_140-sd.png", + "sha256": "d06d3de0726c8d4e5a745c29a85bf0fcebd8507e7deebbe9b0df05989558c68a", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_141-hd.png", + "sha256": "c67db8d233f69010b9df94376f6d7830c6a0073a5fe88677256bd890e37a921a", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_141-sd.png", + "sha256": "b4583b200ee9ddd46734933a818f0df0454f16f3a5728cc5a4780f3340f6c6f4", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_142-hd.png", + "sha256": "c3584fe5b437bb9e47cfb4c34279cade64a233e7d5b7778c73d5fa12d01ed923", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_142-sd.png", + "sha256": "d54bd93696fa4dad3e11ec5aacf337e216025c3dab359639ac297a5ad68eb828", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_143-hd.png", + "sha256": "e6fc61facd518db3a765736e5a8c7699118bad1aab2382f6d4837b407c782b3c", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_143-sd.png", + "sha256": "c71f5a9a01cd589c937c448d50bec6786b5de1ea7cf26adc9e9deea6b7b5bf48", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_144-hd.png", + "sha256": "5ae7b96c8a9ce6a4743977fcc388904eff62cd82e11813f72970496ee57dd8a7", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_144-sd.png", + "sha256": "efd606918a57674b617ff10bc05b1303aa39ecf563cad33f2bade128775597f4", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_145-hd.png", + "sha256": "3e1fed42107cc01a05b6561d08318f83a3ba6cc260d2b3b44bbf272a6eeca198", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_145-sd.png", + "sha256": "35b09dc2f12c8cddb4cc53b90ff1216f8b6c9a480414d92502d20de68ee3ba0c", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_146-hd.png", + "sha256": "1b2ec352aab2a3a695fad56cdb55edf61d2830e3c732882c6311d861ecffa922", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_146-sd.png", + "sha256": "58b9fd91edddcf2f3e68ef383d19c63faff410b7fd90987c4da827c19fd1740c", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_147-hd.png", + "sha256": "ab7bfe12b574199f041418998baafc9d817f6fc3d1f796e7956297f5575976db", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_147-sd.png", + "sha256": "9f99e90016601b15dcb572e32471a629f319f20b99a6d96a277a44313a83088a", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_148-hd.png", + "sha256": "15a6e0f119f60f703cc693675903c0060d60c3caaa6fb039a0265268bb33b7f0", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_148-sd.png", + "sha256": "45e3bab4a9f6688fbe89fbda472eaee94a315e4c2780aa3365d998732e7cf6d0", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_149-hd.png", + "sha256": "662c32decd783af614d929a4378e8d4ff0600863b4c62dd9ef3a4c07a1636a93", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_149-sd.png", + "sha256": "581e2480bb62dbb1d5872bbef80e9d3f386b17df02b1899cf4eccc8ca3084fa3", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_150-hd.png", + "sha256": "5ed92e6972b83a2b3f330226f20a56c391d0933f3de7189fd2befd80c5413528", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_150-sd.png", + "sha256": "8b374bc28f630912570379b99e8fb228888851e2b55dd0810712282357fb3697", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_151-hd.png", + "sha256": "26bdec3b7f2c43d3b430863459459cac145e53dc7f8954585ecc01239f01dcbc", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_151-sd.png", + "sha256": "992b9896df4f82158a834199c21b23632abbbfb3a2a6daf1da15ad68d59068bc", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_152-hd.png", + "sha256": "ff64e9d766edfbcca3213df913b5c8048650ee6e759a84282fa51390b7914b26", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_152-sd.png", + "sha256": "771a65d54e105f8a40c79684404741aaf63581a54577b58cdbbbaad03a14d87b", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_153-hd.png", + "sha256": "9ac0655ba95b324eb2426a329cd4cc383182f6c25ebf91641958247998ee721d", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_153-sd.png", + "sha256": "4183765cf7b9f0c2cc33ea1fdf194899faa52715e4c51d1c806b6a12e31ce237", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_154-hd.png", + "sha256": "a73fbc543f40fa29a9e3497552c34e3db67c0180d0ece7513aae6d7a9d886f19", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_154-sd.png", + "sha256": "9dcf3cc41e0ae4c94edbe72ab18a5a2cd3aaf1c03081e119381b39af3d66edb6", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_155-hd.png", + "sha256": "74ba56c0a4f96c10c74669a6f1ab068b2a90ff01b5681ab66577de7dc3f205f9", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_155-sd.png", + "sha256": "9af282fe54df4b59d28631cc0a780274664b832df74df3e687d3e338ca66ce85", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_156-hd.png", + "sha256": "9f39be292cee61265aced5d82be3040ab6e0679b329d62c7656a471e79a03ebc", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_156-sd.png", + "sha256": "b27227bbacf7447bbd44d54ce16103a64c0ce85c07c219087de2caa2d31797a2", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_157-hd.png", + "sha256": "d493c99e0d4b327dea5fdbf48ade11da9db60f26fbfe0f54ef26783f4d2ed14d", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_157-sd.png", + "sha256": "f9bc4d03762ee3fe932cfbe312f4b5f7909c0834fed767a647393dcd2f17daee", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_158-hd.png", + "sha256": "546a8b61afcc6ac52ddab7f24c7a8ee78ea11b0aca5340726129e24dfbedaa26", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_158-sd.png", + "sha256": "959fc27489e84b435ddc9a4fb4c37ef417f8e15e7a963edf6a7a76dc348d360c", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_159-hd.png", + "sha256": "8bc9c9ee93a071a97b78b74e790269769afc88c7b676a82ee9e0a3995b9d9e12", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_159-sd.png", + "sha256": "11a7e6c93b78247045d76a56a173b85bc9851860b459db89f4763bcc68c7c8ee", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_160-hd.png", + "sha256": "05f26be3db7bb16c58bed383b923db44230201b34c90e6e353d2963dcabb8e5f", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_160-sd.png", + "sha256": "bc93241ba441c619110514cb08ff5466f977cfbc0e54bd5ac2576593019a562b", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_161-hd.png", + "sha256": "890b7c7bfbe019b70f6e3e1ddcfb1e11dc0cadee8d4c8aa2fc8e81a50dd9a030", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_161-sd.png", + "sha256": "5eb0dfd7bc0144f26dd889d9ffbb8b6bfb999582e8b21d585d7e4a4bacbdb506", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_162-hd.png", + "sha256": "b609525bf3c2274f86aca8d071a46aa52df470a19c1e435bdf4ee48fe33029b1", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_162-sd.png", + "sha256": "24a0d652d41214e464d535c47ec63e987519dda7a4b90def9c53c2c161149030", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_163-hd.png", + "sha256": "b6937d4369d0097340389c42e2f2941d3af5f353990bb0d5758a54edd0aff322", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_163-sd.png", + "sha256": "2b7b4ed18a4a3124327069443e107426eff3759ed8ab05e13cc7acd85ef5fc78", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_164-hd.png", + "sha256": "fc3ef8d872d6094f2f57722696a8918c00ff2052acdd634b74f1321dd039fe34", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_164-sd.png", + "sha256": "262268ab15a2768bf5fef6b01505a9df9a1f736867f0f1a69f24534c0fc0af9c", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_165-hd.png", + "sha256": "7558394ef7a4795df6d4f8461fec4c023736c884041740c64faa4cec26131342", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_165-sd.png", + "sha256": "d08413705a1c00282a4795c6e55e3af50403c7ad9e3650bd0afc45fa63814a0f", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_166-hd.png", + "sha256": "83e6f952fc2202e5891ca3c6afd4d32949ca389b0780059afbd61a45e76a4d2e", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_166-sd.png", + "sha256": "67f96f45338671e3265a0783577fb09645189e19cdfe9d50ecaa9f0436ba508b", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_167-hd.png", + "sha256": "480065a41d9d7490ccd833d205bf533c4b698eae9ad2e634fdc739bd2411b78a", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_167-sd.png", + "sha256": "e6f08b02b677323ea5b6bd73e47c7108f1f4cc60c9330187d248e872225cc6ef", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_168-hd.png", + "sha256": "e9e16d47ee0194b7cc42912373e17608d77921aa90500f2cfe7bdff4d77c65ac", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_168-sd.png", + "sha256": "62394ec7436e77e68c8d75f345b256f39f929b666914b5608b893baa283a1ad0", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_169-hd.png", + "sha256": "b1881edf54eb2dcea60d0cc8b7450d4e280ffafa83ed8c8ba53802954f9c5fe6", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_169-sd.png", + "sha256": "c71f0c3b991781f67e59ccaecbf8e0e240e764659b0b066925d9adeb7bb1623b", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_170-hd.png", + "sha256": "d01f9b3b280037c4f851ba787ad605ac9c744a98c1a70ee155375b2827ed119c", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_170-sd.png", + "sha256": "f32e22a6b6a703882ddab4476e00b760bfbd8c9d6b1c0b3c774b66204250547d", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_171-hd.png", + "sha256": "ae0d9ad0159518f00b5f97ebdc31a49385ce3fe0b0039f3efe8d63e1fad43f87", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_171-sd.png", + "sha256": "4dd6e452bdf979b55beb1014ea28d1343ac301c5e67fbd6b73eadbf84e659aba", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_172-hd.png", + "sha256": "4770fc67e44e6123be38f53f5a93441756cd7c6782a8981df393e6f72f2398e1", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_172-sd.png", + "sha256": "8f9f090bfc37e3809cfb97a55d158aa3a35f7c6f73318c2e0f7a1032b1048fc7", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_173-hd.png", + "sha256": "19c7ca5312fc58b5bd4ec795027dc2f5578ebc68d40e8a35914d5daaab7788c2", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_173-sd.png", + "sha256": "eaf96e8ffe53cb9615fb3c6b0e6fc57775f7e01cab78ff62fa36865946d5e7bf", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_174-hd.png", + "sha256": "3c4006b55ab152810b44670fd2caafbbadbe8452e45fa1bb8da2f5af7f316cb1", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_174-sd.png", + "sha256": "3f1f8b4b1d8d231f8625e6eec118d1c903deb63422606a035427b44a42c816ca", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_175-hd.png", + "sha256": "acaa2c2fc15f98d16422914b836a2460c0bec3e0218f6789c9944de20024686b", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_175-sd.png", + "sha256": "f3d296b1c791d67b8739ca4c194773ce7169180b69d23da4ffd1153d40527a44", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_176-hd.png", + "sha256": "3496568457b4cf160ab932b6b2b1c7fbd62843385f5589cccb8a104cce8a7a42", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_176-sd.png", + "sha256": "f378c29fecde507663b1c86fea84f69eea5cd206756cc0514fd990caf5567b29", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_177-hd.png", + "sha256": "117ff29b9f026509c7c6b08c535cbbca0f6d34eb07717715ae4953fec1ef45d5", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_177-sd.png", + "sha256": "bb9b3533b6fbb8140357c5b69ab050894db093d40e1bdbdc5289427fbf28cc30", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_178-hd.png", + "sha256": "eea01abcc0b179489d3ce9f0d592059abeb1076f193c1acbe51823a224eb4a71", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_178-sd.png", + "sha256": "65cca8169b81f9b4fefbbced7cc6147eb89a956a2b0c0c71fd7ccc9778651e1c", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_179-hd.png", + "sha256": "9262ec338f4405c29c6c6242843f761463dab940531813adf25246a5ad58805f", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_179-sd.png", + "sha256": "a435f9690d3f016193ff8cb05d8ca3ba1f37c8fd990e9a1886e91f84fb9ed1d8", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_180-hd.png", + "sha256": "82c4c67f03dcf63bd27f5e38a00d4a1812f6d311f1e6fe3307cd3fe3feb3e15a", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_180-sd.png", + "sha256": "a1c1bca907f2a509aed3230d8b349789d0329b1f3739e4874dc2e22398907d9b", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_181-hd.png", + "sha256": "8e8fc46df341ba4d97638af606ce88065f84ad23979519ddc23fae28cbe963ad", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_181-sd.png", + "sha256": "494103f9ad26ae8f517e83b01f3d38c43786fcd9c843c620cddd8b83c2b7a49c", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_182-hd.png", + "sha256": "db85552f1f6d3ae423ad08bd0ad0464db02ec8f0166b9407eea3a2ebad4fa02f", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_182-sd.png", + "sha256": "949317f705a5c4d68522f231ea5d3fbfbd6335ee1ed04d67f15f45e5e1a777f3", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_183-hd.png", + "sha256": "709af67a76720116ff22aeeff88b5eca8d350d2afeebd689e2007578e5bfa56a", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_183-sd.png", + "sha256": "cbbb05da68331703b80059a43981028053dc662ab6000458b5c6aceb3d303f63", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_184-hd.png", + "sha256": "93cac6179c82a21090552398908f0c89bb5c67de39ba2312e89c7b203fb15443", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_184-sd.png", + "sha256": "bbc94987562d14b2aa8c422f2a4489c5503fb48873c8eb465626adef03999f03", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_185-hd.png", + "sha256": "7c20e4d8ae0be1fe502f8972c13b0b72d8282c6e5790f71c6c49b05ca6faf55c", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_185-sd.png", + "sha256": "af2ad4ffa0e347a9f7d530de5b6f2482780d2ca6710954790c3be4d87677548a", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_186-hd.png", + "sha256": "09dde1f86af941b265296b46a8633840bdea2bda0849cb671b68ae290a721a23", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_186-sd.png", + "sha256": "ce7b54d4ba3235cd6545e7c3f20ab1e102f5bf66e25895a36d96372edbca1d06", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_187-hd.png", + "sha256": "2deadd19aecadbec5c3dc9df718b2448f9c28fadd716b96ac90f073793c659de", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_187-sd.png", + "sha256": "a73ff11b07703a2128d013c607bab12b33ba7f0d43095b72d87f9b44d5fdf2a1", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_188-hd.png", + "sha256": "fe2f329d301ef02a4961b9febce438403a1d275b07ad4a197b541d1969909ac8", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_188-sd.png", + "sha256": "a41a969b30e9a0afc2ed076f4ce3e90159f76a0adb9f8b87428d37622d4f0053", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_189-hd.png", + "sha256": "f9bc7aed88d21b2d27c73db353338756e5cdaa967943d0cda9549029f11ba643", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_189-sd.png", + "sha256": "bb17ef9604052ebbe8e5a70ccf460c129e750f204db7fbb8feac399fa633d603", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_190-hd.png", + "sha256": "24491c2b05b8fd837d65e3b89c00aba04e01cced0e3843ef00272316d523b2d9", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_190-sd.png", + "sha256": "168f51dc2c64d2772b6a7783602564c29c5271efc7c519a05ae454a71075c472", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_191-hd.png", + "sha256": "54a37cba9fd8c5dfe8a8b54a7e1ea1a3580dc66b704d03c85e0db9edd75c060f", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_191-sd.png", + "sha256": "8d4c61d1af6ca726342a4c220e623346f16db99f0fae42b2ccaeba1d5e4e3df9", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_192-hd.png", + "sha256": "f35c1394fa5cab253542b8386cbb1b3cd66ec3e5271cd64e52319e590e98fe23", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_192-sd.png", + "sha256": "2975658cd39b7e2ff2f3d55e83dcf598879c4eadadf4ec657737651035173c1e", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_193-hd.png", + "sha256": "d53d2b483603592d0fc6bab108333fb39e32908759513e6427508df123553bb5", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_193-sd.png", + "sha256": "9018872030300e51d2d1d7c051201d357519ec73187468a694d277ae525ca04b", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_194-hd.png", + "sha256": "917cce2bd1257e2f7373c3966d60afd7ea8edf1e48d6af497a86bed1034a4e9e", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_194-sd.png", + "sha256": "177eb502932f9c32d9bd2df485a88fc9058e6635fa44bc42307b4c45a32a79e3", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_195-hd.png", + "sha256": "d99748e5249a917f433d339978978ece2ba112791d02a999c4ddd18cce3eaa6a", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_195-sd.png", + "sha256": "622b259645387bb9dd0fcc1c79de99ef6ab193371756b81ae60318d4c82c7024", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_196-hd.png", + "sha256": "d98c28799c8f3158898b22681bce7595786fa4a75402b0c272174c33c527b1aa", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_196-sd.png", + "sha256": "40fd9f70a5247ddc0c46c0682ec5557156016466e81b7ae803e92785a935992c", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_197-hd.png", + "sha256": "0dd68115c214be1defee98f7dc681791a7506a1a2f89119afb1d5dc43c08819c", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_197-sd.png", + "sha256": "de7731319c34ea9afe0b0b0a419de96f601917de966bdc17b8b833566fbb78b0", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_198-hd.png", + "sha256": "ae30e901c57ea5f67af119389393bfa50bb8e0249ef12af6d7f9f7179e9b1ae3", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_198-sd.png", + "sha256": "9b5c4c979503e23d83c8625cbf20e1c1f4d671c3edf3941b59f9698bff59b929", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_199-hd.png", + "sha256": "18a6815f507179e54a9bc42a8e7c710b1e47ec226b43741f2ffc5136f67432d7", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_199-sd.png", + "sha256": "184722cb7f686c838aa21e87262b3fdd4d2fbcc656241aa50ca0965424c65576", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_200-hd.png", + "sha256": "38608ea22a612975d498f7a4d50a05a690f0f156f153d9c4b7a6bba65e233b6e", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_200-sd.png", + "sha256": "6d3ecf931b0f28a7767fa204e471edaaea028579f8c0fbda5e83351486691c4b", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_201-hd.png", + "sha256": "2a9f0ba9084633a41192c132993e33facec62e2dc192230aed34975ba3576d7d", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_201-sd.png", + "sha256": "432ed74991895154e3720c2d78757d757c12079d805b17a533d84e1a048711b6", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_202-hd.png", + "sha256": "b4500fc8265d3a826032779bc4d829b298f125856dd4d239440f0f03d555376a", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_202-sd.png", + "sha256": "5530e257dd78610e36080bb7301cf5067f2fa0be625b5a2e5cb42d41ae8f1743", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_203-hd.png", + "sha256": "22dcda75ec6236bab03620386ec4909f70ede9943fb33ec09a1e7e83c174711f", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_203-sd.png", + "sha256": "cebb22163157245f6da42a5c61178afb68c6ac017b661e14c5fff21a8db00ef2", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_204-hd.png", + "sha256": "bbbaf63da31375540fc79bc1eca786c2444a5699410db5f2a9b9391699d1c1a6", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_204-sd.png", + "sha256": "f7d2f802a1a85243a20d430cdd430f9fca1bf6351c2a293a62ef59a85f544979", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_205-hd.png", + "sha256": "983d94963b3c2dee4e49262b580f7bd26b8780f53b2b2d35a227b2f544ec7424", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_205-sd.png", + "sha256": "e977f666c10c4dcaa3e08ea7d9e826ba8e6da13b1ae7006a78e7fc667609cfe7", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_206-hd.png", + "sha256": "76ff91ac5dce1f44143f54e686d210918113e6e8be3548e711c6a437c60a0480", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_206-sd.png", + "sha256": "283f254a814a92ed1377027732bc77db86a3f918e250ddb0f8c40ef6646fe5aa", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_207-hd.png", + "sha256": "5e14def60734e9d9fe3e6b1c2f0ca6717892b47fe96cfb7d2ed524a6974f9d38", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_207-sd.png", + "sha256": "6f68bb8876a08a8654887b76c04b22aec0bd65e1c184e941f8c56f84c81b58b4", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_208-hd.png", + "sha256": "78f494c196926bb61d23a036d6259edf82fb9e32c1589d52fabbb1792d90c2c8", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_208-sd.png", + "sha256": "a403c4405448c893ec5ee29f71ee3272071d442f957a5a364664783d6c41743d", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_209-hd.png", + "sha256": "ba1a458aac23e004847a3f280beb53810f0bab3da3e4d55266806c1509f48545", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_209-sd.png", + "sha256": "64934e8a326e1e01441d71560f61b1f2a53207c41469dc9cc583dd9a686f2ac2", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_210-hd.png", + "sha256": "4b8a68affbffc7f429fc8ecced6055c95355fd3e0231d79695a139b7e293e93d", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_210-sd.png", + "sha256": "0bc89b40513acc4ae46f3bec5db3f7fe54101071a414fa123c4ee5cb81474054", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_211-hd.png", + "sha256": "50dc01000909203fb30bfd81b3be71dbb88b0db90daa24c7ff568ad4751e5bf1", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_211-sd.png", + "sha256": "f8426c5ac035acd5c50e106a3ce921d30af1ff691e83efa384270f5d34140872", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_212-hd.png", + "sha256": "f4923781c09a523b7263744515203734bb5972b042821e395f52be4ff7821fed", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_212-sd.png", + "sha256": "cb85d66a0398de5c3936359033685fbc4c071ea0ade9b439fcdabda600c7c08b", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_213-hd.png", + "sha256": "1722ac7bfbb1ff0cdac764fe26a68248885fa583d59315ee2bc33957bc6bb0c6", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_213-sd.png", + "sha256": "f314cfab075dd87c47dc2e95fc7dfdc6c472a539978ed6b68915018aa6a74aaf", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_214-hd.png", + "sha256": "dffe2d01daaac2f17550b66a7447dd3636ae6d52d99c6306358ed7894a28338d", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_214-sd.png", + "sha256": "8a80bc6aee27ff6ae6fac3e18f966035265f3042b5d8f7735c18ecb7bc92c93d", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_215-hd.png", + "sha256": "95289c11debf7ff60d51538a2497e050fd61cd9571de38cc18c6bd69e4feef4f", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_215-sd.png", + "sha256": "b2b04d5dcf1a2d85225ed8b39a303b18ff7e473a41ac6ea348341d020c00a78e", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_216-hd.png", + "sha256": "70da8f98f3aa5151ccda17f647c4409be79dec95f017e9e41d9d4f843970eb74", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_216-sd.png", + "sha256": "a25f716cedc381a81b43de1133bf9fddb9c1febf40c812306cb3e58e7edc6f38", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_217-hd.png", + "sha256": "e2dc4dca158679dc79715becba2916890a366364a1e525a3588ddfcd5f4083b9", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_217-sd.png", + "sha256": "2147fcf3d977ea45b15e3b1c9a3d1b1bdf70b18076b3a39b4ade694485ebc36c", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_218-hd.png", + "sha256": "466a9cc827484180625a785e0a4fa175cf9bdf5f2ac12f0a9a0eceb519b7032d", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_218-sd.png", + "sha256": "de838292700fb8e8a465aef223f02550d47bb60e44ab0754a13d23a58a8ac27a", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_219-hd.png", + "sha256": "d6ce1f373541dd89783c2a95fc8d6518f17b61189fb336fdd887fef92e516be9", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_219-sd.png", + "sha256": "eeb443df46fb98153847d374c03a96441594ceccb226063750575166b514c976", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_220-hd.png", + "sha256": "bd270857b44967af9d76128383d1efd20c99a4c5179c23413feb36dbf8917601", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_220-sd.png", + "sha256": "2c4c8bbf26a4a79aa92fa4032eb86c3be0f777b82a5b66510f1fd1e278810b38", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_221-hd.png", + "sha256": "4065b4559eae124d1a82da135b442e2844550bcbcc6204ff944110c99dbb6a02", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_221-sd.png", + "sha256": "fd1e7d57fa4ff55d785bc2db24bdb0f7a5830aabd668d8db317674d792f2e5e0", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_222-hd.png", + "sha256": "10055eedec973daf9966bac0bbf643266b3760bc8ec0da08b384e2744b8f7e2c", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_222-sd.png", + "sha256": "a552ecaa0957d616286fe249a8dcc2fdd87f3437b3300f09101239abb16ca170", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_223-hd.png", + "sha256": "d301a426b71c4095c245a8dadb16350640c71985d576a70cf846b263aac40631", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_223-sd.png", + "sha256": "e8581a373981ba69565cf07d870f91b209acc130c8dbc62ceb98c0ff8b7b6f03", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_224-hd.png", + "sha256": "32eac2bf1887173689bf49e7c49406c0d64f42c4e669ae9cda516e5dbc286c1e", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_224-sd.png", + "sha256": "a7f8717a436a1bc998a5783e60a996af416e3643687e2d90c8931b2cdfc0e820", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_225-hd.png", + "sha256": "2f2fdebe02bbb0f00201c0d15d9ddad7ff0403f92b42ee23287a6c586486e5d7", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_225-sd.png", + "sha256": "340564b6ec69eb6832c27e844b2e41862a0af5d534104ae5bfd08d526984d663", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_226-hd.png", + "sha256": "57533bb7314c2229946c74cd8d451f1fff43e8335ed770f0ccd4b8940de31c55", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_226-sd.png", + "sha256": "2ae3cc4cfaed0ffbf7f4861c57fad52e2f3cd24457bea38aaf282c60e713223b", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_227-hd.png", + "sha256": "928900f487967d37a485d6f96565de066f4b2b863039e28f183ec88cd1692757", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_227-sd.png", + "sha256": "3ff1d37112fe76a82c375759bc002cc7394824bc51f2716beb21cb76ff80447a", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_228-hd.png", + "sha256": "226ad0cc0402bc0640bd3f6370c99e9728913e56407e7bc18f898d4b061dd950", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_228-sd.png", + "sha256": "fdfba1b7b9e48964efad788ea6f76aaef4712b731354c75e0e96cbb33ad32934", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_229-hd.png", + "sha256": "1cbb34123004e12d66ce7fd372af67cd12969d4449b6bc040457b8df8cea0866", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_229-sd.png", + "sha256": "e2296fc03101da80be175ee33cf63b7d666dfc0c6c5c26f1ef6320c58d0e26a4", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_230-hd.png", + "sha256": "0a0c988648cfba38306ad3c3975bae9f27ae2dc24ae96bbbecef246f453172a6", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_230-sd.png", + "sha256": "83ff8cb2e7919c6c2e564307a53bb097e0a3d7c79387d2de08238861e8351ae8", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_231-hd.png", + "sha256": "8a206d47942550e13a554faf315c483a51889c2afc25a561a4d2c0ee7084592d", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_231-sd.png", + "sha256": "589bc5ca1d43d865ad469ff2e780debd3ee9852af5b1063d96eb787c902bbbc2", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_232-hd.png", + "sha256": "d2cf4702cec72f4a979c94afdb4674065fd8594f53d4e095b7a4c3e603889e0b", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_232-sd.png", + "sha256": "1f592106588cbc0a15f89cf3824bd351710b3fbe70658c550830ee707eb3cf75", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_233-hd.png", + "sha256": "fa27b80321488d50adfeea28281422b9925587d6e101253cf206da0fce8ede63", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_233-sd.png", + "sha256": "8d1d97e16d10cd1227feb852825b22f0a0a7456bad257b6102f51c86c8dc6071", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_234-hd.png", + "sha256": "2f5506a6594bcab59b5a490d2af21b0ea3a0fb4486e8571d47e80ac40d8987c8", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_234-sd.png", + "sha256": "4e33c3132b8a46e9c2c9b66e8fa95795a2d26958617ec13a1f4447200a5f0328", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_235-hd.png", + "sha256": "849b1d41da8c2c3992f56ffab7130788a6dc85b5a35acdd20c7007512629b89c", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_235-sd.png", + "sha256": "21d9a6c4dbe4324dc90aae46971f953d2020092733329439ae4b84ebb8315684", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_236-hd.png", + "sha256": "f0287572b585de54cfe8486fc0ee2092fa2cf1feb8a84980b3bbfe80c175f468", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_236-sd.png", + "sha256": "0d0bc4babafb53405c4e80e5a2ef98becbfc81b79644fdeac358cd0e0274d6c2", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_237-hd.png", + "sha256": "c338f5d3452e441916f7ad9b2bf03806a7373dccf02f09e1bb77e9441586c794", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_237-sd.png", + "sha256": "a01b4fb1b225530f6584bdf9e2e87723eb3d3725074117023a0186822f6289a4", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_238-hd.png", + "sha256": "c6b0d2e2c0b62e20787e2710809e1f7a58393b5e5d21fc4d4648b76d390b7210", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_238-sd.png", + "sha256": "3326640d6023230a273d01ecc8e616b1834fd05e118018e25701e47b054885e4", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_239-hd.png", + "sha256": "7f308f2c80dfc0de2db060a79cc4629fb6899ba739d65413a8f7de10e2b2de2e", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_239-sd.png", + "sha256": "2c6f0fd40cc41c2617a68732cc408e1ef51ec1ba83443dd490a687c7d977eba5", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_240-hd.png", + "sha256": "ab0e65393b499dfa8b106f33c77ab714a5326a68cecb5c65119a42d225a9fb78", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_240-sd.png", + "sha256": "9fe1e38bf9890a75418a0afdf6fc24d988e3db90e48d07e3457af4be51a801c0", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_241-hd.png", + "sha256": "f7a583e54beb23a42e7f488de2efbcd4500132bced7a5f4019607951000d8fa2", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_241-sd.png", + "sha256": "f5da87e80a25e63741cc8493bd26f762a7ef7de02f56a9a77270d6efce7e02b6", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_242-hd.png", + "sha256": "c65a5d731da7ae1d9e1d64d2b57d47ee2badd53bc470df316d4e96669d7b8171", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_242-sd.png", + "sha256": "410309505b06fd6c8261e8ebcca3e6ff8c7c06173a4aa874282ffc987c9bde48", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_243-hd.png", + "sha256": "f36c4d503ae287d0ad92546d30d24b49b2519298694b6a3228f042f1e5dd30e2", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_243-sd.png", + "sha256": "a99d126f712ebe0cbfe40179fb2ce5edb244067f34cbb794a7ed4ab1afe0eee1", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_244-hd.png", + "sha256": "e75d8560e9bbed7986ae7e50fbe53f4c40d859dbd130790d709144cf199e2a9c", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_244-sd.png", + "sha256": "21c166359e68cfae1f6e599fa2f28e0fd450280022022678e8fbaa1558797db8", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_245-hd.png", + "sha256": "2313354c2db3bde0f10d589c3593ec6d60cf6a2848d9e5a08adbcea7df49949e", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_245-sd.png", + "sha256": "f8ce18a4e301d71faa30390f616e2e1e426fe03832355a6680bedce52f8ea8d3", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_246-hd.png", + "sha256": "395f75b06da3308cd170613cf1da42f42da00f1b7664cca0144e295600dcad94", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_246-sd.png", + "sha256": "db0ee2d09c963fc59d190571c8c187ef63077f155ece373545b0d28b05bb7bfe", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_247-hd.png", + "sha256": "e1028538a9fa0a012615545d2fe05db8513584c359f6c2aac92c2eacde6a33cd", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_247-sd.png", + "sha256": "bf111536106d2fd102f8be12f66c7a8296f987eab0a8f82302b9a0646124c794", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_248-hd.png", + "sha256": "bfcc8820c4864761f68d4a5b588c075cdb401ea247695945847d36d47620c7f3", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_248-sd.png", + "sha256": "c6e6f6e40a641cc4b4817ba466d2915ee38dfd1198ef101809c5a4853033c72b", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_249-hd.png", + "sha256": "52cfa54bf898a330c04899264799c915db5df2ce528e312d37423a9365e34d5f", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_249-sd.png", + "sha256": "0ed2d74664e7809343aaf6a153d50d70001da5c5bc3b0256721c1b390f3840c1", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_250-hd.png", + "sha256": "cb3784fd714707e4b7e631408cb2fa87553902dfd2d9c9d42ea623cfe9a40c9d", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_250-sd.png", + "sha256": "799b550d08a269d3b03445fced4b0d8e274520ac0993ed82502e0ad9255c3cb3", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_251-hd.png", + "sha256": "bacf5f981af310204fff45869f6c5e23fd1ebf481426bb670a49c0f1bf863c0b", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_251-sd.png", + "sha256": "5a7a5077cefcd74562866e1ded420e3edf63d5cea3d1ebc09f3c2590bd2da581", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_252-hd.png", + "sha256": "c6460daee30f42208823ca6c298779f81e4e3292bfeee1dfd35430f9430a35e7", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_252-sd.png", + "sha256": "0fe1eb8386962af7e0794ba410466253b674914b0d25f345fc112024c82d18f2", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_253-hd.png", + "sha256": "d544c43d1f19c5bb2d778224270689db5c82465eee70d21c6023d59785ce024c", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_253-sd.png", + "sha256": "8758ea2b171a59b36f2f6c8bffede38463ab114c34d86061f91e6b0463a88446", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_254-hd.png", + "sha256": "0885b220e3b62025b5b3618a81bac3e0502989ea7caf1f3bf7d22547e38cba3d", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_254-sd.png", + "sha256": "5c8c27b7d2104527571c33ddbd8e8703be1089246ec54e3954fff80e6969c437", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_255-hd.png", + "sha256": "be7573bdf2f42d00e418f89fca3764ef514cfb45cecc61f0126edb509409a67e", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_255-sd.png", + "sha256": "a0153f666fdcbb7f559e0244e60b67380eff4ff5230f63cb544b0fa9e74e4d38", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_256-hd.png", + "sha256": "347c54fd14b6bb19dd1db9c61b06ad9bf8b11f8afdc5bd277e11a0e73b02cddf", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_256-sd.png", + "sha256": "b7986509bdb1be80be5738f1c0ca83ae4f93fb23b6d4ea195c049a894dc4b703", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_257-hd.png", + "sha256": "6305ae7f3878cf043c24446c87ffa9c7e30f238caa7d1ae22ef89d09bf0993f7", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_257-sd.png", + "sha256": "7116f40a2dc832b375e3794091188a99f71e3b34e65069251de3e9f456105641", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_258-hd.png", + "sha256": "1151de459f801e19e25764a393c4d6244b48e89f2302989822196723885329ae", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_258-sd.png", + "sha256": "72a4501233ad8459c5e4395f06b7988a61f0baabbc804b7ab9e55978803cc7d9", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_259-hd.png", + "sha256": "fc5e1e55e8ac9e2db53443993c8d12f819b682175725815f662af1bfabdf63f2", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_259-sd.png", + "sha256": "60393a7d295c8005bd5a85161c9ed0f57d095ab0f78dc393911b94b5bb30c2b7", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_260-hd.png", + "sha256": "682a97285388aeacface6ba91165612c2406419e54f37e318e5f419c4644f601", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_260-sd.png", + "sha256": "a53361547fd8bef80858d49b5d353e6f0a75b93c956aaf792df104d9fb3bd3d7", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_261-hd.png", + "sha256": "2d80eb3cba2e51f33ab1510fcd055fd7aab1cda54d618c506a63391648a421df", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_261-sd.png", + "sha256": "f141bb50653bcc61e29d7104619305b9c24f15f740a47a583c1b00fe6d2a882b", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_262-hd.png", + "sha256": "38fa66a362d005329169a5382a51fac687dcd6177e770c9e555653f15deac740", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_262-sd.png", + "sha256": "760516eee3a558e0b9dc4d82e210f81a7b4645cfacaf7e8394cdc2c745fc3238", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_263-hd.png", + "sha256": "ea27549a62b9f743fae9b1b243590f714794b0e97a1c307fec614c232da4c9f5", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_263-sd.png", + "sha256": "479a8c5c21fa3f7270d00896ccad59dc3df5e71045632fa548b6820eb7531efb", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_264-hd.png", + "sha256": "57914efa3ccc90ba3e1a39def08adc2dfd817a631d2bac2a0425ef198028b9c4", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_264-sd.png", + "sha256": "adeb4479ffaa1b334890ae0f621915217c05702469ab809d959db82cd0f7fcd3", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_265-hd.png", + "sha256": "f0267a9d6d6652aca9fce9602b270c55f584ed85e68aa68f927d2b18208e7225", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_265-sd.png", + "sha256": "7dfb2b6bc2876859eee4a5825be15e142c176157efb34c23827f40f4a0c8f809", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_266-hd.png", + "sha256": "13b251a267d1bb2093714b331a0acd3d7b2aa3c6bea5ab0e95f32f290016474c", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_266-sd.png", + "sha256": "67693103bb6bdcf732fbb73829b93b03db2c1e5588e765bbb32c8e1351afd8e9", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_267-hd.png", + "sha256": "b5a98fdfdc7eb44056e4b4f0a2130737e16c6f4477ab2c7efb42fe190935ecaf", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_267-sd.png", + "sha256": "6fb978bc99e929049959d38f09fdd7d56c849be0031286f26ef1c55fffd8618f", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_268-hd.png", + "sha256": "27aacf8db4759f43dbcddc9622f1de49ec380b41e5056bf88fc78b88d7efe53d", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_268-sd.png", + "sha256": "124021538678e103b6c3b18b728fdf9158593876f14be2170e11d5b8d00e2ec8", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_269-hd.png", + "sha256": "045e7b8cf42dcbef69f0fcf1d86695d1164c4504ac7d83b12261e2d33f6f2812", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_269-sd.png", + "sha256": "53d69531ad4db3b2a7c7b98519abbcb05c6d186b9ced518fc88f9258ef988f3c", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_270-hd.png", + "sha256": "735b23662cd3aa70abe2f361b0442bbee31c61eab6b8e44ac942143f9713bb3f", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_270-sd.png", + "sha256": "f591707691619a307ec2247adee2b18e72819f61c915f6acf54aad62073a6d86", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_271-hd.png", + "sha256": "46293a69c62ae39238fe253341c545819881fe74923924f5ce1b6412ee39f4e5", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_271-sd.png", + "sha256": "fa9ba2950d211ccdfa804810f8afae0dd2bbda355594b1448223df2559a03188", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_272-hd.png", + "sha256": "573ef57e6ff52cf1e65f831249b247fd5b1a716e6b66af10b026f68fd92c38ab", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_272-sd.png", + "sha256": "fdfd758a2ebc1b9b0ce7f57290c219b241d38234b2d0364c537a5f1de5c4540a", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_273-hd.png", + "sha256": "9e559a42bc240a268ea1379d4f0db68e1907c43af97ee8963c99d04b97063392", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_273-sd.png", + "sha256": "50abf44bf74a6f33657b34ca1aebd1dad18d04b700779e5fcbcc5686eddb648e", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_274-hd.png", + "sha256": "0d9a543720b61325b802ef202cb3b0e8a9cc7dd4c05fa00eed6a991b644398c4", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_274-sd.png", + "sha256": "41e16ed20f73d6e972db0789a1192143fdc2c00ae44acc96dc005d2b56a43334", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_275-hd.png", + "sha256": "cb8e9750318738e9779c41e2e49cbeb90c63248d720db22190ef7590904791a3", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_275-sd.png", + "sha256": "26754f7a7f9702f25ce6259da8405b51198fb529e0910ee0f12c53c2fb62430b", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_276-hd.png", + "sha256": "f8ba9023b46537bb6560bf8bd71ee4b1544d7a5a2fac55024757740f60b66ace", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_276-sd.png", + "sha256": "67330bd3e55ab79253f84adc8da47f65714447b2b7619014331b43d939ef2353", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_277-hd.png", + "sha256": "adc7fe65ed2409de83d5b7292532943bf37b39a82489c5b7f3c60e90d97d9c27", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_277-sd.png", + "sha256": "037a17b1bdabeff50d07739b7b81c3d77726db75c2fdb602d85a6ac8e5b4eb85", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_278-hd.png", + "sha256": "d7241ce027a313774ce9c15d3069d86c47920011b67566ff55e2702e0216c0fe", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_278-sd.png", + "sha256": "faf57021d47ec7fc808242014b5037d25b342c4533dbf441e38a9ea9bc4d43a9", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_279-hd.png", + "sha256": "7cfa0de437768da2611b4b6aef7841f25f70eb436f23de284bae24671d8f63d0", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_279-sd.png", + "sha256": "83ff2e7cf932c1263f93e1e89f911cad749d516d4a9f53db1b8093653ab68e3a", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_280-hd.png", + "sha256": "7a0a3cb4ceec8eb84bb2c938f3790c353a35183ab30ca9e3fa627d9413c48179", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_280-sd.png", + "sha256": "1558eecf8c0ef641b783a3a3274b9f9c1126a03a46d67ad5823a827a87d1c087", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_281-hd.png", + "sha256": "073c2ef144a617cfd24e90e9174215c0f37c18f0a125aca52498009cbcf7fa24", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_281-sd.png", + "sha256": "8f83b95c8fc86e2c75da21b2e6bbee2ab31cecd1799c55ad6b3d81b71536c6f2", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_282-hd.png", + "sha256": "122e925be01ce5d3977dec4c6e26889b728a3c66cba1e3e3711560f5f7902d0a", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_282-sd.png", + "sha256": "38edc6611e2946da179b4084c4758c19ffcbe2f071afc91d63107892b09561ec", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_283-hd.png", + "sha256": "2791b3a23c704d509beb3167dab574b09fa2fa494a7382e4c0a6882f06367fa4", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_283-sd.png", + "sha256": "e8195f1013baab4b64ad919018507a01d9c6446ee855e39264631bd815171703", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_284-hd.png", + "sha256": "370c70547a8dcddc34a4279d3d914287461a708e6da6bd4ff223b7f5bb9dc1fb", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_284-sd.png", + "sha256": "253aff74dd5b4d354df91f0d45d74a8f975bfcc067f53ac52e8b5f72ad34865d", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_285-hd.png", + "sha256": "171f6d3699f865aa954ad92f06c2d912102bb679154d5365e80eef4f8d0fd795", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_285-sd.png", + "sha256": "adfa270abad99869d948cefc3e9bf5bce48be19b842633369dcae072b0c8ecac", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_286-hd.png", + "sha256": "bfca7194cff4687e1166ae4abeb663962d7aedbccc1e056e5d4a28a6c897699d", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_286-sd.png", + "sha256": "9b30b9cf6e76a9e8d728de0ac8c2829b88e9b523be06d7a553138d114d68353d", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_287-hd.png", + "sha256": "65a124b1d3542f094398298ba0433ae311ac7025f8477fa7c780371ab3ffca87", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_287-sd.png", + "sha256": "27352f77e2b5ab457e3ffb3237a07eff6b3765d6d658571dde4733e51df9b919", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_288-hd.png", + "sha256": "7cc7d3451e0980a6ba747fa81435689b08dfd2b9f063ed9c58faef3faab19dba", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_288-sd.png", + "sha256": "3188d60d90dde445845eec86bb909a15b7d4f496cb52802bcc98420ac3f7084c", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_289-hd.png", + "sha256": "49f7ac7385d44fc43580663570dee081d548e89f77b0461c47b9223cdc30c119", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_289-sd.png", + "sha256": "3b63b665a058d20eb96b710e1b20705aee1d97fbc101a540cf3b10b50245a0f1", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_290-hd.png", + "sha256": "18c162baf25db65ca7ce283a243886ad1f1b6ade74ad84c0cdaa3b0a9da19401", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_290-sd.png", + "sha256": "4c8b580430005236f67f6d4679c54836ffe04c6764d8b19662f9aaa2afbf5b2a", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_291-hd.png", + "sha256": "11a9cdb5f2d46502a28697215e7fbb5b8cac79b95aabfe6b015e030a28b6543c", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_291-sd.png", + "sha256": "452f4e3ad64b8bcd776385235ee55939e4c0b85b54430184f4cf73f83714cc8f", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_292-hd.png", + "sha256": "f91dae5b3ada9a3c3cd04543b93406e68c5c49c67e01027d9af0ed5b757a93b6", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_292-sd.png", + "sha256": "366d3c10a4b82bccea4b9212bb3d432339db867f7e19e696a9b6053832994cb8", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_293-hd.png", + "sha256": "56e7fa597e48a2247cd0180acfd73488bb5b1918eb24bf98e2cb1d5af77f1384", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_293-sd.png", + "sha256": "45ad2bbf0e503472d4096233aeab9808f2e7cf9af1afc9f76b13ad2a2b828bde", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_294-hd.png", + "sha256": "801e33d561fcdd6b0efb9f470a60c4e7ce7495e69c908ce0c548419ed8ec0db5", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_294-sd.png", + "sha256": "fc417ed692fd4fd6469e11e2ee27f7af0c5c28e23f9a897e8369171212419a2d", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_295-hd.png", + "sha256": "6acdfbb04338bbb48cf46c0581b85583e82947cbcd58b9f8420afdaed88815b4", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_295-sd.png", + "sha256": "bde7c7ddd2a13822e24e3281171a23597acde3121329c950e72a0eaf8de06344", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_296-hd.png", + "sha256": "e3095b8ee52c7ed8defd9b012ae41886bef5f589d14444842778b6c47890735b", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_296-sd.png", + "sha256": "dcc6a51c878412c41cce0b9c34afc56180d51fb20bd513d4facd7145d1b95ca9", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_297-hd.png", + "sha256": "a8be89f9169912bcb3432f31e5c4fbdbee5ff55fa933adaf2074a81cacea87e6", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_297-sd.png", + "sha256": "280e0d10782e0ea8d69f958292b2cfb39233ced54a45ca144f3beb8c0def35b4", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_298-hd.png", + "sha256": "ac8065f31c5775d60832d7bd9c9a0c3b40a0bcee83e14f849e350b064c2b7bd1", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_298-sd.png", + "sha256": "39d2af6e503b2d90bedd2d29cf4180c717b3ffd12f449e5c4d989fa812e1a80f", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_299-hd.png", + "sha256": "0ff0b10adc45cfab7ac19787caf2a8d4e2f29a8582c096a215caffb0dd09a11a", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_299-sd.png", + "sha256": "6e97f0e0f93f595e99d95d60698d31270610136faec2e5c4adfc16ad987bed9a", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_300-hd.png", + "sha256": "601a56d57daa7c3d3f73ac772c072048175b3caa93a1128c9ec692e72a92d663", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_300-sd.png", + "sha256": "605295adea28c706a4aacea05f93c82dd82d65b345840fa3de6ea4565847ba80", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_301-hd.png", + "sha256": "208a5b3505ac93eacf37ced434fdbba63e14af1ebc237ad918a4696fdd145e02", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_301-sd.png", + "sha256": "ee898005a7298863656eb8d5e70a53ae1f9a473d77c359cb14929171bc2c0bcb", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_302-hd.png", + "sha256": "4209cb28eff61635dcc04920801bb95bdf753256551ff11c5ad3b8ba4b21a286", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_302-sd.png", + "sha256": "5790a1f067341e6e9b53187cf99b9e4921bf5e3b352e18f054ed02b2fbf5a4e4", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_303-hd.png", + "sha256": "3a04058c62b398c061e821e95fba7f1cd91feaf5299caa3fa3fc69deff32905c", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_303-sd.png", + "sha256": "ad42f8f94faeaa23786543ca70fbcc7eb32cbeea5f7539f9d5325b4fcb907388", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_304-hd.png", + "sha256": "dfb4ccbe5e2306e20a919e31b6349910c6a20773da2dad9f734e8782b77c79a3", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_304-sd.png", + "sha256": "3a3a678c47e2a62d03a152d9fe6aa188447f2cd4fcc4064bf2b350d77b2071bb", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_305-hd.png", + "sha256": "a8f3e67099a5bf5f5ef98a08fb790aef716171a45ce897fea06bbdae2aa8419d", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_305-sd.png", + "sha256": "a3d2627775a763d854da82db3e680d2c53b4ccda0985c855dfdf9eb2f0015176", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_306-hd.png", + "sha256": "29c511fa36b15b7a2e0057c0b3f0127d009bd4958ee4b563dbb2d0744d40a27a", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_306-sd.png", + "sha256": "eb323542c8a0a59625fa2761c57e34b6801db5d5334f13db08c8a26e5ebe26fc", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_307-hd.png", + "sha256": "a6050941bddd4ce84a8849bfccc60cf0bd89805215100d90765cfa84fbcd4b48", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_307-sd.png", + "sha256": "7dcb9043ce18ee6261dbe4c89526c3018c69b006764667d30cac124925eeee34", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_308-hd.png", + "sha256": "335b03d562268b498be955f7c482aa2f3091fe1b8c6defcb48c76c2072ad4ba0", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_308-sd.png", + "sha256": "b1b3e24f7ad4ca6635baa0be0c31235a74663d6e84faaccd498d3ff8cfcf7709", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_309-hd.png", + "sha256": "d8b7bc700e876b9218ba397691866e7542a90de8a8b3d3de17d3ffc36e4d1f6a", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_309-sd.png", + "sha256": "044da794829f1c99864e18dc350dbf3e44110eabcb04bd4513c3d3c7f93da1c8", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_310-hd.png", + "sha256": "c34f212b6ff15d17c3f94f96c48c0556c0b12a77bf74785b42f79812afa6d7ae", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_310-sd.png", + "sha256": "be5287cc89a1d301e4d8406a9b322eb5f72b4186d04d9f6b268ba441910d92a1", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_311-hd.png", + "sha256": "22110566a0e40e4be019ffca0a95b3cf67290b7e5412fe200eaf65392c11c509", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_311-sd.png", + "sha256": "639b22cfe73e2105a8def4975f082000cf00c9c198db24ed88b0eba36f2b8441", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_312-hd.png", + "sha256": "af76fb67190d6090b200bb6fd58c9ccb81499636ca6b395d1a27b4f2ecc9f997", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_312-sd.png", + "sha256": "4b965877cd5dbf95c2fb43199c1a02829906359094e7fa91832636d23792e125", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_313-hd.png", + "sha256": "f94b49e5d366905b5186367a13151e15e490c5d831b8052034265ac52cc218e9", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_313-sd.png", + "sha256": "ef4be4fd89a650a8bacf2beae19c36c73b9cd266ae382f5082eca887c72c4520", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_314-hd.png", + "sha256": "c3cdae1cb9ce55c0d3cb28f3923a5de4dfe1dc5601766a91eba4cd2f33ec3f89", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_314-sd.png", + "sha256": "bdb8696b97e2e2d7a03a78281b5a73f867092b67cb70d3f1e91de53109cba27a", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_315-hd.png", + "sha256": "e5ce843af09f5f41ccc782dab36493e9dccf38106ee6c89139881e83ac9f91c7", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_315-sd.png", + "sha256": "190b2f145b644bd0cca65b51e9ce6724ce68a3ce6de6b59d53c43756ffc096a1", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_316-hd.png", + "sha256": "7557166df7054d4d0fd5378380d59e726a16aa047fe4a7a589505d8976a488a5", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_316-sd.png", + "sha256": "b32e3e2877960ff0700d8a39eefd2240fafbb07a4b12b4490842c956eb431a31", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_317-hd.png", + "sha256": "02cc88fd694a8a7fc4effb584a54f164a8f544b7cf21be78014e89ff7b5a884c", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_317-sd.png", + "sha256": "69bb6fe737ab492d447bb948832592c27d36c1d2d4e794f3aa0f8ab7922264ed", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_318-hd.png", + "sha256": "a95a3caa9d8a6a4a991f4e0cfadebcccb11ef33bd0bfbdca9a500dd41c9db3d4", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_318-sd.png", + "sha256": "5efb9ffb541d4dc3c7a157d58f8169ee6d02314738b2fdc815b96788fc7b689c", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_319-hd.png", + "sha256": "59f8f2923660ec890201118fe98b230012dd8c3b5dfff1d864089f00ec33749c", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_319-sd.png", + "sha256": "e19b272cdde35c2167e9d9c87866cab261c454139b8a9673b9ac6d7980673fe8", + "size": [ + 32, + 32 + ] + } + ] +} diff --git a/mods/iron_coast_stage2_mission_1/audio/approach.wav b/mods/iron_coast_stage2_mission_1/audio/approach.wav new file mode 100644 index 00000000..5422207b Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/audio/approach.wav differ diff --git a/mods/iron_coast_stage2_mission_1/audio/boss_alarm.wav b/mods/iron_coast_stage2_mission_1/audio/boss_alarm.wav new file mode 100644 index 00000000..4a8ea75e Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/audio/boss_alarm.wav differ diff --git a/mods/iron_coast_stage2_mission_1/audio/objective.wav b/mods/iron_coast_stage2_mission_1/audio/objective.wav new file mode 100644 index 00000000..a6aa661b Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/audio/objective.wav differ diff --git a/mods/iron_coast_stage2_mission_1/audio/victory.wav b/mods/iron_coast_stage2_mission_1/audio/victory.wav new file mode 100644 index 00000000..0c3f8fd4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_1/audio/victory.wav differ diff --git a/mods/iron_coast_stage2_mission_1/build_assets.py b/mods/iron_coast_stage2_mission_1/build_assets.py new file mode 100644 index 00000000..7f744100 --- /dev/null +++ b/mods/iron_coast_stage2_mission_1/build_assets.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python3 +"""Reproduce SD/HD canvases and PCM WAVs from untouched builtin generated PNGs. +No decoded original images are packaged. No painted/masked master edits occur. +""" +from pathlib import Path +import argparse,datetime,hashlib,json,math,random,struct,wave +from PIL import Image,ImageOps +ROOT=Path(__file__).resolve().parent +h=lambda p:hashlib.sha256(Path(p).read_bytes()).hexdigest() +def palette(path): + raw=path.read_bytes();assert len(raw)==768 + values=[(min(v,63)<<2)|(min(v,63)>>4) for v in raw] + values[720:]=[0]*48 + im=Image.new('P',(1,1));im.putpalette(values);return im + +def small(im,size,pal): + im=im.convert('RGBA').resize(size,Image.Resampling.LANCZOS) + alpha=im.getchannel('A').point(lambda a:255 if a>=128 else 0) + out=im.convert('RGB').quantize(palette=pal,dither=Image.Dither.NONE).convert('RGBA');out.putalpha(alpha);return out + +def canvases(source,name,size,pal): + src=Image.open(source).convert('RGBA');target=(size[0]*4,size[1]*4) + hd=Image.new('RGBA',target);fitted=ImageOps.contain(src,target,Image.Resampling.LANCZOS);hd.alpha_composite(fitted,((target[0]-fitted.width)//2,(target[1]-fitted.height)//2)) + hd.save(ROOT/'art'/f'{name}-hd.png');small(hd,size,pal).save(ROOT/'art'/f'{name}-sd.png') + return {'source':str(source.relative_to(ROOT)),'sha256':h(source),'logical_size':size,'hd_size':target,'alpha_below128_transparent':True,'original_master_not_modified':True} + +def synth(name,duration,base): + rate=22050;n=int(rate*duration);rng=random.Random(7043+sum(map(ord,name))+base);data=bytearray();peak=0;sumsq=0 + for i in range(n): + t=i/rate;u=i/n;env=min(1,u*30)*(1-u)**1.3 + if name=='shot':s=(math.sin(2*math.pi*(95*t-40*t*t))+rng.uniform(-1,1)*0.45)*math.exp(-u*3) + elif name=='death':s=rng.uniform(-1,1)*0.65+math.sin(2*math.pi*(70*t-18*t*t))*0.4 + elif name=='warning' or name=='boss_alarm':s=math.sin(2*math.pi*(base+70*math.sin(2*math.pi*t*5))*t)*0.8+0.12*math.sin(2*math.pi*base*.5*t) + else: + notes=[1,1.25,1.5,2] if name=='victory' else [1,1.5,1.25];freq=base*notes[min(len(notes)-1,int(u*len(notes)))];s=math.sin(2*math.pi*freq*t)+0.15*math.sin(2*math.pi*freq*2*t) + v=max(-32767,min(32767,int(s*env*8500)));peak=max(peak,abs(v));sumsq+=v*v;data+=struct.pack('0 && unit.y>=65 { + let x=unit.x;if x<24 {x=24;}if x>264 {x=264;} + commands.push(#{op:"move",entity:unit.entity,x:x,y:65}); + commands.push(#{op:"velocity",entity:unit.entity,vx:0,vy:0}); + } + } + let kills=if event.objectives.contains("iron_coast_stage2_siege:defeated") {event.objectives["iron_coast_stage2_siege:defeated"]} else {0}; + if kills>state.reported {state.reported=kills;commands.push(#{op:"play_sound",sound:"iron_coast_stage2_mission_1:objective"});} + if event.tick>=1900 && !state.boss_alarm {state.boss_alarm=true;commands.push(#{op:"objective",key:"iron_coast_stage2_mission_1:phase",value:2});commands.push(#{op:"play_sound",sound:"iron_coast_stage2_mission_1:boss_alarm"});} + let defeated=if event.objectives.contains("iron_coast_stage2_boss_1:defeated") {event.objectives["iron_coast_stage2_boss_1:defeated"]} else {0}; + if kills>=3 && defeated>=1 && !state.complete { + state.complete=true; + commands.push(#{op:"objective",key:"iron_coast_stage2_mission_1:phase",value:3});commands.push(#{op:"objective",key:"iron_coast_stage2_mission_1:complete",value:1});commands.push(#{op:"credits",amount:24000});commands.push(#{op:"play_sound",sound:"iron_coast_stage2_mission_1:victory"});commands.push(#{op:"complete"}); + } + #{commands:commands,state:state} +} +fn on_mission_end(event,state,random) { + #{commands:[#{op:"objective",key:"iron_coast_stage2_mission_1:debrief",value:if event.success {1} else {0}}],state:state} +} diff --git a/mods/iron_coast_stage2_mission_2/README.md b/mods/iron_coast_stage2_mission_2/README.md new file mode 100644 index 00000000..b3eb4a37 --- /dev/null +++ b/mods/iron_coast_stage2_mission_2/README.md @@ -0,0 +1,50 @@ +# Iron Coast II — Mission 2: Undertow Run + +An independently playable Black Tide sortie with native Raptor aircraft paths, +new patrols and its own boss. Enable **Undertow Run** in **Mods**; installed compatible +required enemy/boss/music dependencies are selected automatically. Select +`iron_coast_stage2_mission_2:mission_02` in the hangar. Installing the optional full Black Tide +campaign places this sortie in its eight-mission progression. + +Destroy 4 actual `skimmer` units and then the `iron_coast_stage2_boss_2:unit` boss. Required +convoys are held inside the reachable playfield after entry; leaving or despawning +never counts as destruction. The boss arrives at tick 2280. A duration +timeout cannot grant victory. Completion awards 32,000 credits once, in addition +to actual enemy rewards. Replaying resets this sortie's kill counters and phases. + +Hold **Ctrl/Fire** to use owned weapons; **Alt/Shift** cycles selected weapons; +**Space** retains bombs. Starter forward guns can target all mandatory enemies; +optional purchased gear improves firepower. The mission grants no equipment or +shield/credit cheats, and works with a full 20-slot inventory. + +New terrain is generated from original Raptor material/palette references, with a +320×512 logical map and a reflected scroll cycle repeated through 4,096 rows. +This preserves terrain beneath delayed boss fights. All mandatory targets appear +on every difficulty; higher difficulties add patrol reinforcements. The briefing crops the same +master. Both SD and 4× HD terrain and generated WAV mission cues are tracked. +`build_assets.py` reproduces all derived art/audio from the untouched raw master. +See [generation provenance](generation-provenance.json) and +[asset recipe/report](asset-report.json). Original reference images and working +review captures stay outside the package. + +```sh +python3 mods/iron_coast_stage2_mission_2/build_assets.py +CARGO_TARGET_DIR="$PWD/target" cargo run --locked --release --manifest-path mods/iron_coast_stage2_boss_1/validation/Cargo.toml +``` + +The CLI requires all dependency IDs explicitly; the in-game manager resolves them. +Final real-catalog gameplay, audio, native path and save/RNG observations are +recorded in `acceptance-report.json`. Local single-sortie campaign definition +uses no overrides, so the optional aggregate campaign controls progression. + +Author acceptance passed seven complete cases: difficulties 0–3 with starter +guns, default 100-shield, a full 20-slot inventory, and owned optional new gear. +The registered 75-shield pilot completes at tick 2681 with 61 shield and +a 52,260-credit gain using ordinary Fire and a mouse movement cap of +four logical pixels per tick. Serialized script state/RNG continuation, replay +reset, reward-once and actual native path motion checks passed. A separate +health-buffer fixture verifies reachable targets and terrain after 5,000 ticks; +it is not a balance result. The purchased-gear fixture funds shop purchases +before gameplay, rather than claiming a new pilot can afford both weapons. + +Asset recipes use Python 3 with Pillow. The game uses the shipped PNG and WAV files. diff --git a/mods/iron_coast_stage2_mission_2/acceptance-report.json b/mods/iron_coast_stage2_mission_2/acceptance-report.json new file mode 100644 index 00000000..e29ec04b --- /dev/null +++ b/mods/iron_coast_stage2_mission_2/acceptance-report.json @@ -0,0 +1,394 @@ +{ + "utc": "2026-10-11T08:51:02.199238+00:00", + "status": "author_checked_review_ready", + "real_catalog": true, + "engine_source_hashes_at_report": { + "src/assets.rs": "4cdf11a229f6ca4c6183fb545dba43e9a2323f839f7a095292045aa13a773ddc", + "src/content.rs": "7f35df7100c450ba4bb30a0fdc90101c115b5ae42a7aac57829441c5b7761647", + "src/modding.rs": "f37d67004392f5726121e58a995900cd7062016e3f060ea131b0df38995e2912", + "src/simulation.rs": "0ec9f6da11ab82c1461868a7b147e4cdb14689fa7373bd0c24067d9014e9583a", + "src/render.rs": "d4abdccbc3c1ee840ef8548bcff43080521937ef9f9f5ed69e810f417ef1e842", + "src/sound.rs": "aff6779b85f9f4f4bc30a15ad75ec6fdd61d42895639700f4842870636e73c4b", + "src/persistence.rs": "9a4adf1e33d3504db3d4d3e6091316cc7116fb35c89b2de8fbd4640d368aa0e2", + "Cargo.lock": "aac0a22725250ab35828223f8d129e4d2a4e6113cf81463e59600da3a59ffdea" + }, + "catalog_file_hashes": { + "data/INDEX": "4ce78e5e638b6603114dd233ceaa41f386c0963ba4aa02ecf88ce0215b096681", + "data/misc/PALETTE_DAT": "1cf6adb926d1dee1888b3e3d33b51a7049b3e5eb5f90a3067ef71c8970547204", + "data/misc/GENMIDI_OP2": "fdc93c076bf44207299e61ec1bbcfafca421454bfa99dd14fa4e5dcada1547b9" + }, + "compiled_validation_binary_sha256": "98f43eef5943061a18a465e95e8089189be793b9f8cbac275b8ebe982953567b", + "full_external_result_sha256": "63f97c1f8cab57452ee9235124551178fe2593c5e40f4a5ecd6e2aa9bf0cd19e", + "cli": { + "selected_packages": 10, + "overrides": 0, + "log_sha256": "c9401f44dc4fa438f75ccc00223e95f79cfa8bffcd1c8db5c106963f7b474822" + }, + "visual_limits": "Author inspected native indexed SD1/HD4 Canvas/PNG-loader diagnostics, exact new source masters and SD/HD final art. Terrain in owned captures uses a simplified row sampler. Live SDL/Host captures and independent eight-stage progression are root-owned; no live device or whole-map rendering claim.", + "package": "iron_coast_stage2_mission_2", + "content_sha256": "ae66b60e1d7da60951188af7f71844bb87072616c5ac36a4d852de0890ba8915", + "scripts": { + "scripts/mission.rhai": "4f7950e48a428e992cb01f8ca12f0a71d162b472088360fdcc1c33fe3f27d088" + }, + "asset_report_sha256": "f66b1c529efd7af95d5c9d1d526d61e28006b37946c1eef58434bf66ecc2a6d9", + "raw_identity_checks": [ + { + "package": "iron_coast_stage2_mission_2", + "role": "unit_or_terrain", + "raw": "mods/iron_coast_stage2_mission_2/art/terrain-generated-v1.png", + "raw_sha256": "6d032b57afd4f40229a007af00b6678e1a37d6b062abfd4ccf48e076d994d41a", + "builtin_byte_identical": true, + "raw_dimensions": [ + 992, + 1586 + ], + "raw_alpha": "RGB", + "reported_success": true + } + ], + "mission_acceptance": { + "enabled_packages": [ + "iron_coast_stage2_music", + "iron_coast_stage2_interceptor", + "iron_coast_stage2_skimmer", + "iron_coast_stage2_boss_2", + "iron_coast_stage2_mission_2" + ], + "late_fight_fixture": { + "boss_remains": true, + "playing_beyond_declared_duration": true, + "reachable_required_units": 4, + "scope": "Persistence-only difficulty3 fixture restoring shield10000 before each step to suppress pilot death; ordinary balance runs above have no health/damage cheats.", + "scroll": 5000, + "terrain_covered": true, + "terrain_rows": 4096, + "tick": 5000 + }, + "missing_one_required_death_blocks_victory": true, + "mission": "iron_coast_stage2_mission_2:mission_02", + "required_deaths": 4, + "runs": [ + { + "captures": [ + 500, + 1600, + 2000, + 2350, + 2500 + ], + "credit_gain": 52260, + "credits": 62260, + "cues": [ + "iron_coast_stage2_boss_2:death", + "iron_coast_stage2_boss_2:shot", + "iron_coast_stage2_boss_2:warning", + "iron_coast_stage2_interceptor:death", + "iron_coast_stage2_interceptor:shot", + "iron_coast_stage2_mission_2:approach", + "iron_coast_stage2_mission_2:boss_alarm", + "iron_coast_stage2_mission_2:objective", + "iron_coast_stage2_mission_2:victory", + "iron_coast_stage2_skimmer:death", + "iron_coast_stage2_skimmer:warning" + ], + "difficulty": 2, + "digest": "f8c878a6ecfbc3d3a56150162e4d71885f7db1ea9e6cb2016360a5696064a64b", + "full20_inventory": false, + "initial_credits": 10000, + "initial_shield": 75, + "native_classes_moving": [ + "base:enemy_0_20", + "base:enemy_0_23", + "base:enemy_0_56" + ], + "objectives": { + "iron_coast_stage2_boss_2:defeated": 1, + "iron_coast_stage2_interceptor:defeated": 7, + "iron_coast_stage2_mission_2:complete": 1, + "iron_coast_stage2_mission_2:debrief": 1, + "iron_coast_stage2_mission_2:phase": 3, + "iron_coast_stage2_skimmer:defeated": 4 + }, + "purchased_new_gear": false, + "replay_reset": true, + "reward_once": true, + "serialized_state_rng_round_trip_identical": true, + "shield": 61, + "tick": 2681 + }, + { + "captures": [], + "credit_gain": 52260, + "credits": 52260, + "cues": [ + "iron_coast_stage2_boss_2:death", + "iron_coast_stage2_boss_2:shot", + "iron_coast_stage2_boss_2:warning", + "iron_coast_stage2_interceptor:death", + "iron_coast_stage2_interceptor:shot", + "iron_coast_stage2_mission_2:approach", + "iron_coast_stage2_mission_2:boss_alarm", + "iron_coast_stage2_mission_2:objective", + "iron_coast_stage2_mission_2:victory", + "iron_coast_stage2_skimmer:death", + "iron_coast_stage2_skimmer:warning" + ], + "difficulty": 2, + "digest": "ed00cbc8d9fac2657f4b09bc693f02b12f95ef4438265e6246b9ef65327c5907", + "full20_inventory": false, + "initial_credits": 0, + "initial_shield": 100, + "native_classes_moving": [ + "base:enemy_0_20", + "base:enemy_0_23", + "base:enemy_0_56" + ], + "objectives": { + "iron_coast_stage2_boss_2:defeated": 1, + "iron_coast_stage2_interceptor:defeated": 7, + "iron_coast_stage2_mission_2:complete": 1, + "iron_coast_stage2_mission_2:debrief": 1, + "iron_coast_stage2_mission_2:phase": 3, + "iron_coast_stage2_skimmer:defeated": 4 + }, + "purchased_new_gear": false, + "replay_reset": true, + "reward_once": true, + "serialized_state_rng_round_trip_identical": true, + "shield": 86, + "tick": 2681 + }, + { + "captures": [], + "credit_gain": 52960, + "credits": 62960, + "cues": [ + "iron_coast_stage2_boss_2:death", + "iron_coast_stage2_boss_2:shot", + "iron_coast_stage2_boss_2:warning", + "iron_coast_stage2_interceptor:death", + "iron_coast_stage2_mission_2:approach", + "iron_coast_stage2_mission_2:boss_alarm", + "iron_coast_stage2_mission_2:objective", + "iron_coast_stage2_mission_2:victory", + "iron_coast_stage2_skimmer:death" + ], + "difficulty": 2, + "digest": "2ccfa180d79b3a658808daa291e5f4fe6878a2aca204af09101f275ef31133d5", + "full20_inventory": true, + "initial_credits": 10000, + "initial_shield": 75, + "native_classes_moving": [ + "base:enemy_0_20", + "base:enemy_0_23", + "base:enemy_0_56" + ], + "objectives": { + "iron_coast_stage2_boss_2:defeated": 1, + "iron_coast_stage2_interceptor:defeated": 8, + "iron_coast_stage2_mission_2:complete": 1, + "iron_coast_stage2_mission_2:debrief": 1, + "iron_coast_stage2_mission_2:phase": 3, + "iron_coast_stage2_skimmer:defeated": 4 + }, + "purchased_new_gear": false, + "replay_reset": true, + "reward_once": true, + "serialized_state_rng_round_trip_identical": true, + "shield": 67, + "tick": 2497 + }, + { + "captures": [], + "credit_gain": 52360, + "credits": 62360, + "cues": [ + "iron_coast_depth_charge:fire", + "iron_coast_depth_charge:impact", + "iron_coast_stage2_boss_2:death", + "iron_coast_stage2_boss_2:shot", + "iron_coast_stage2_boss_2:warning", + "iron_coast_stage2_interceptor:death", + "iron_coast_stage2_interceptor:shot", + "iron_coast_stage2_mission_2:approach", + "iron_coast_stage2_mission_2:boss_alarm", + "iron_coast_stage2_mission_2:objective", + "iron_coast_stage2_mission_2:victory", + "iron_coast_stage2_skimmer:death" + ], + "difficulty": 2, + "digest": "e4ce9155cdf895fb91986381918e2a026c193b396905937852c790d853341df9", + "full20_inventory": false, + "initial_credits": 10000, + "initial_shield": 75, + "native_classes_moving": [ + "base:enemy_0_20", + "base:enemy_0_23", + "base:enemy_0_56" + ], + "objectives": { + "iron_coast_stage2_boss_2:defeated": 1, + "iron_coast_stage2_interceptor:defeated": 8, + "iron_coast_stage2_mission_2:complete": 1, + "iron_coast_stage2_mission_2:debrief": 1, + "iron_coast_stage2_mission_2:phase": 3, + "iron_coast_stage2_skimmer:defeated": 4 + }, + "purchased_new_gear": true, + "replay_reset": true, + "reward_once": true, + "serialized_state_rng_round_trip_identical": true, + "shield": 61, + "tick": 2411 + }, + { + "captures": [], + "credit_gain": 49860, + "credits": 59860, + "cues": [ + "iron_coast_stage2_boss_2:death", + "iron_coast_stage2_boss_2:shot", + "iron_coast_stage2_boss_2:warning", + "iron_coast_stage2_interceptor:death", + "iron_coast_stage2_interceptor:shot", + "iron_coast_stage2_mission_2:approach", + "iron_coast_stage2_mission_2:boss_alarm", + "iron_coast_stage2_mission_2:objective", + "iron_coast_stage2_mission_2:victory", + "iron_coast_stage2_skimmer:death" + ], + "difficulty": 0, + "digest": "64bf7056e9435040d9ed9f4dec830520012b2eacb146aa248bdce07505ee4008", + "full20_inventory": false, + "initial_credits": 10000, + "initial_shield": 75, + "native_classes_moving": [ + "base:enemy_0_20", + "base:enemy_0_23", + "base:enemy_0_56" + ], + "objectives": { + "iron_coast_stage2_boss_2:defeated": 1, + "iron_coast_stage2_interceptor:defeated": 3, + "iron_coast_stage2_mission_2:complete": 1, + "iron_coast_stage2_mission_2:debrief": 1, + "iron_coast_stage2_mission_2:phase": 3, + "iron_coast_stage2_skimmer:defeated": 4 + }, + "purchased_new_gear": false, + "replay_reset": true, + "reward_once": true, + "serialized_state_rng_round_trip_identical": true, + "shield": 71, + "tick": 2481 + }, + { + "captures": [], + "credit_gain": 51710, + "credits": 61710, + "cues": [ + "iron_coast_stage2_boss_2:death", + "iron_coast_stage2_boss_2:shot", + "iron_coast_stage2_boss_2:warning", + "iron_coast_stage2_interceptor:death", + "iron_coast_stage2_interceptor:shot", + "iron_coast_stage2_mission_2:approach", + "iron_coast_stage2_mission_2:boss_alarm", + "iron_coast_stage2_mission_2:objective", + "iron_coast_stage2_mission_2:victory", + "iron_coast_stage2_skimmer:death" + ], + "difficulty": 1, + "digest": "ad1c91a7f38918e4d20bbf16aa0893fe56108333b91e1c9e4f47cd8f6419cd51", + "full20_inventory": false, + "initial_credits": 10000, + "initial_shield": 75, + "native_classes_moving": [ + "base:enemy_0_20", + "base:enemy_0_23", + "base:enemy_0_56" + ], + "objectives": { + "iron_coast_stage2_boss_2:defeated": 1, + "iron_coast_stage2_interceptor:defeated": 5, + "iron_coast_stage2_mission_2:complete": 1, + "iron_coast_stage2_mission_2:debrief": 1, + "iron_coast_stage2_mission_2:phase": 3, + "iron_coast_stage2_skimmer:defeated": 4 + }, + "purchased_new_gear": false, + "replay_reset": true, + "reward_once": true, + "serialized_state_rng_round_trip_identical": true, + "shield": 65, + "tick": 2481 + }, + { + "captures": [], + "credit_gain": 52260, + "credits": 62260, + "cues": [ + "iron_coast_stage2_boss_2:death", + "iron_coast_stage2_boss_2:shot", + "iron_coast_stage2_boss_2:warning", + "iron_coast_stage2_interceptor:death", + "iron_coast_stage2_interceptor:shot", + "iron_coast_stage2_mission_2:approach", + "iron_coast_stage2_mission_2:boss_alarm", + "iron_coast_stage2_mission_2:objective", + "iron_coast_stage2_mission_2:victory", + "iron_coast_stage2_skimmer:death", + "iron_coast_stage2_skimmer:warning" + ], + "difficulty": 3, + "digest": "e48078a8b8e49c101186aa4ad9bb6fcfcd767c10679e706340d68367879ba2bb", + "full20_inventory": false, + "initial_credits": 10000, + "initial_shield": 75, + "native_classes_moving": [ + "base:enemy_0_20", + "base:enemy_0_23", + "base:enemy_0_56" + ], + "objectives": { + "iron_coast_stage2_boss_2:defeated": 1, + "iron_coast_stage2_interceptor:defeated": 7, + "iron_coast_stage2_mission_2:complete": 1, + "iron_coast_stage2_mission_2:debrief": 1, + "iron_coast_stage2_mission_2:phase": 3, + "iron_coast_stage2_skimmer:defeated": 4 + }, + "purchased_new_gear": false, + "replay_reset": true, + "reward_once": true, + "serialized_state_rng_round_trip_identical": true, + "shield": 61, + "tick": 2681 + } + ] + }, + "normal_control_strategy": "Held Fire; mouseposition moves\u22644 logicalpx/tick, y160, aim at required living convoy centers then boss then ordinary visible enemies. No damage/shield/credit cheats or loans.", + "purchased_gear_fixture_scope": "The controlled shop preflight funds the 1,210,000-credit cost of owning both optional weapons before the sortie. It checks actual Pilot.buy/selection and gear preservation, and leaves10,000 credits for gameplay. It does not claim a newly registered pilot can afford both weapons.", + "sound_mixer_checks": [ + { + "fx_mute_zero": true, + "mixed_peak": 2176, + "sound": "iron_coast_stage2_mission_2:approach" + }, + { + "fx_mute_zero": true, + "mixed_peak": 2176, + "sound": "iron_coast_stage2_mission_2:boss_alarm" + }, + { + "fx_mute_zero": true, + "mixed_peak": 2176, + "sound": "iron_coast_stage2_mission_2:objective" + }, + { + "fx_mute_zero": true, + "mixed_peak": 2560, + "sound": "iron_coast_stage2_mission_2:victory" + } + ] +} diff --git a/mods/iron_coast_stage2_mission_2/art/briefing-hd.png b/mods/iron_coast_stage2_mission_2/art/briefing-hd.png new file mode 100644 index 00000000..712a767e Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/briefing-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/briefing-sd.png b/mods/iron_coast_stage2_mission_2/art/briefing-sd.png new file mode 100644 index 00000000..ac6f1df3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/briefing-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/terrain-generated-v1.png b/mods/iron_coast_stage2_mission_2/art/terrain-generated-v1.png new file mode 100644 index 00000000..d4470d97 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/terrain-generated-v1.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/terrain-preview-hd.png b/mods/iron_coast_stage2_mission_2/art/terrain-preview-hd.png new file mode 100644 index 00000000..24714868 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/terrain-preview-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/terrain-preview-sd.png b/mods/iron_coast_stage2_mission_2/art/terrain-preview-sd.png new file mode 100644 index 00000000..d75884bf Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/terrain-preview-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_000-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_000-hd.png new file mode 100644 index 00000000..fc602d32 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_000-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_000-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_000-sd.png new file mode 100644 index 00000000..c06f2248 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_000-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_001-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_001-hd.png new file mode 100644 index 00000000..cb286ae9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_001-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_001-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_001-sd.png new file mode 100644 index 00000000..4ba8ef92 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_001-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_002-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_002-hd.png new file mode 100644 index 00000000..753d564d Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_002-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_002-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_002-sd.png new file mode 100644 index 00000000..3475ba3b Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_002-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_003-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_003-hd.png new file mode 100644 index 00000000..81feedab Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_003-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_003-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_003-sd.png new file mode 100644 index 00000000..e06ccd71 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_003-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_004-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_004-hd.png new file mode 100644 index 00000000..537bb49f Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_004-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_004-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_004-sd.png new file mode 100644 index 00000000..ea4761d4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_004-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_005-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_005-hd.png new file mode 100644 index 00000000..cec76eb1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_005-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_005-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_005-sd.png new file mode 100644 index 00000000..72a337b9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_005-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_006-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_006-hd.png new file mode 100644 index 00000000..7bbb85e3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_006-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_006-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_006-sd.png new file mode 100644 index 00000000..776eeadf Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_006-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_007-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_007-hd.png new file mode 100644 index 00000000..16a109fd Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_007-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_007-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_007-sd.png new file mode 100644 index 00000000..1aed8420 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_007-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_008-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_008-hd.png new file mode 100644 index 00000000..b74480b9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_008-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_008-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_008-sd.png new file mode 100644 index 00000000..79350509 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_008-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_009-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_009-hd.png new file mode 100644 index 00000000..a6e25186 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_009-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_009-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_009-sd.png new file mode 100644 index 00000000..30b4f916 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_009-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_010-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_010-hd.png new file mode 100644 index 00000000..c3d282d8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_010-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_010-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_010-sd.png new file mode 100644 index 00000000..39da90f4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_010-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_011-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_011-hd.png new file mode 100644 index 00000000..0a00eb76 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_011-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_011-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_011-sd.png new file mode 100644 index 00000000..235d65d6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_011-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_012-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_012-hd.png new file mode 100644 index 00000000..7cbfa7c7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_012-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_012-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_012-sd.png new file mode 100644 index 00000000..c05c121a Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_012-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_013-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_013-hd.png new file mode 100644 index 00000000..c8d1e0e5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_013-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_013-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_013-sd.png new file mode 100644 index 00000000..19839085 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_013-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_014-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_014-hd.png new file mode 100644 index 00000000..b32cbcb0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_014-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_014-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_014-sd.png new file mode 100644 index 00000000..1e7bc806 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_014-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_015-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_015-hd.png new file mode 100644 index 00000000..892ce269 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_015-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_015-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_015-sd.png new file mode 100644 index 00000000..2b6c00a8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_015-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_016-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_016-hd.png new file mode 100644 index 00000000..2a21aa2f Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_016-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_016-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_016-sd.png new file mode 100644 index 00000000..9a4f05f7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_016-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_017-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_017-hd.png new file mode 100644 index 00000000..5752cc43 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_017-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_017-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_017-sd.png new file mode 100644 index 00000000..877745ff Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_017-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_018-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_018-hd.png new file mode 100644 index 00000000..3464684c Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_018-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_018-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_018-sd.png new file mode 100644 index 00000000..a2363c5b Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_018-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_019-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_019-hd.png new file mode 100644 index 00000000..5d45898e Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_019-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_019-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_019-sd.png new file mode 100644 index 00000000..058b417f Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_019-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_020-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_020-hd.png new file mode 100644 index 00000000..35bf2377 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_020-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_020-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_020-sd.png new file mode 100644 index 00000000..81abae0f Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_020-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_021-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_021-hd.png new file mode 100644 index 00000000..8957b413 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_021-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_021-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_021-sd.png new file mode 100644 index 00000000..efa9927f Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_021-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_022-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_022-hd.png new file mode 100644 index 00000000..b19677b9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_022-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_022-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_022-sd.png new file mode 100644 index 00000000..6d216bf4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_022-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_023-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_023-hd.png new file mode 100644 index 00000000..fdcd08c4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_023-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_023-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_023-sd.png new file mode 100644 index 00000000..9c529eb1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_023-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_024-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_024-hd.png new file mode 100644 index 00000000..117002f4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_024-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_024-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_024-sd.png new file mode 100644 index 00000000..f0504034 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_024-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_025-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_025-hd.png new file mode 100644 index 00000000..3b3bd299 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_025-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_025-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_025-sd.png new file mode 100644 index 00000000..d147eaf8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_025-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_026-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_026-hd.png new file mode 100644 index 00000000..f30f9dd0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_026-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_026-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_026-sd.png new file mode 100644 index 00000000..2d7be630 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_026-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_027-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_027-hd.png new file mode 100644 index 00000000..bd1e4000 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_027-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_027-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_027-sd.png new file mode 100644 index 00000000..7f3af955 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_027-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_028-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_028-hd.png new file mode 100644 index 00000000..b372f001 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_028-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_028-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_028-sd.png new file mode 100644 index 00000000..cb645469 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_028-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_029-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_029-hd.png new file mode 100644 index 00000000..b6c44a19 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_029-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_029-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_029-sd.png new file mode 100644 index 00000000..5fc0d069 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_029-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_030-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_030-hd.png new file mode 100644 index 00000000..17a89696 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_030-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_030-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_030-sd.png new file mode 100644 index 00000000..b4ce22c7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_030-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_031-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_031-hd.png new file mode 100644 index 00000000..3330d3b6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_031-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_031-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_031-sd.png new file mode 100644 index 00000000..e46e281a Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_031-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_032-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_032-hd.png new file mode 100644 index 00000000..f05421bc Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_032-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_032-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_032-sd.png new file mode 100644 index 00000000..ac6f52c8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_032-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_033-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_033-hd.png new file mode 100644 index 00000000..81e385bf Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_033-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_033-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_033-sd.png new file mode 100644 index 00000000..80fe740a Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_033-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_034-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_034-hd.png new file mode 100644 index 00000000..0ebd94d2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_034-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_034-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_034-sd.png new file mode 100644 index 00000000..60fc71c4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_034-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_035-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_035-hd.png new file mode 100644 index 00000000..7ad86925 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_035-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_035-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_035-sd.png new file mode 100644 index 00000000..638d7eff Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_035-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_036-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_036-hd.png new file mode 100644 index 00000000..0f2a2349 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_036-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_036-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_036-sd.png new file mode 100644 index 00000000..1eb70a77 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_036-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_037-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_037-hd.png new file mode 100644 index 00000000..8c0c9f4b Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_037-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_037-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_037-sd.png new file mode 100644 index 00000000..54a327f0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_037-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_038-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_038-hd.png new file mode 100644 index 00000000..90b74ccb Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_038-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_038-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_038-sd.png new file mode 100644 index 00000000..a0c854bf Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_038-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_039-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_039-hd.png new file mode 100644 index 00000000..3dd02b6a Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_039-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_039-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_039-sd.png new file mode 100644 index 00000000..bb2aa6d0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_039-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_040-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_040-hd.png new file mode 100644 index 00000000..66d4e346 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_040-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_040-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_040-sd.png new file mode 100644 index 00000000..857b7f1a Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_040-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_041-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_041-hd.png new file mode 100644 index 00000000..20259d26 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_041-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_041-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_041-sd.png new file mode 100644 index 00000000..852b88c3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_041-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_042-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_042-hd.png new file mode 100644 index 00000000..79b246b2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_042-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_042-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_042-sd.png new file mode 100644 index 00000000..fb0018df Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_042-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_043-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_043-hd.png new file mode 100644 index 00000000..fc599930 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_043-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_043-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_043-sd.png new file mode 100644 index 00000000..581da481 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_043-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_044-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_044-hd.png new file mode 100644 index 00000000..8c47f1df Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_044-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_044-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_044-sd.png new file mode 100644 index 00000000..5848798a Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_044-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_045-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_045-hd.png new file mode 100644 index 00000000..b27d088f Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_045-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_045-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_045-sd.png new file mode 100644 index 00000000..08db91a4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_045-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_046-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_046-hd.png new file mode 100644 index 00000000..d8c0e2d3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_046-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_046-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_046-sd.png new file mode 100644 index 00000000..a7486e52 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_046-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_047-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_047-hd.png new file mode 100644 index 00000000..756244c0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_047-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_047-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_047-sd.png new file mode 100644 index 00000000..96c9c200 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_047-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_048-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_048-hd.png new file mode 100644 index 00000000..5325d00c Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_048-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_048-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_048-sd.png new file mode 100644 index 00000000..87a010f7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_048-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_049-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_049-hd.png new file mode 100644 index 00000000..4fc20375 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_049-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_049-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_049-sd.png new file mode 100644 index 00000000..564286ad Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_049-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_050-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_050-hd.png new file mode 100644 index 00000000..adf5701c Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_050-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_050-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_050-sd.png new file mode 100644 index 00000000..e1ba83a0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_050-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_051-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_051-hd.png new file mode 100644 index 00000000..25b9069a Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_051-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_051-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_051-sd.png new file mode 100644 index 00000000..ca225423 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_051-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_052-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_052-hd.png new file mode 100644 index 00000000..81432ba1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_052-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_052-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_052-sd.png new file mode 100644 index 00000000..f4e73fbf Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_052-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_053-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_053-hd.png new file mode 100644 index 00000000..1ca57a69 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_053-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_053-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_053-sd.png new file mode 100644 index 00000000..c3439248 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_053-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_054-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_054-hd.png new file mode 100644 index 00000000..306d5ad2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_054-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_054-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_054-sd.png new file mode 100644 index 00000000..10a65ea2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_054-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_055-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_055-hd.png new file mode 100644 index 00000000..531d17a5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_055-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_055-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_055-sd.png new file mode 100644 index 00000000..3ce4229d Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_055-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_056-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_056-hd.png new file mode 100644 index 00000000..6dd74005 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_056-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_056-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_056-sd.png new file mode 100644 index 00000000..f706dcfd Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_056-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_057-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_057-hd.png new file mode 100644 index 00000000..34117358 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_057-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_057-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_057-sd.png new file mode 100644 index 00000000..9924d59e Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_057-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_058-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_058-hd.png new file mode 100644 index 00000000..7b6bf482 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_058-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_058-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_058-sd.png new file mode 100644 index 00000000..cf1ba322 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_058-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_059-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_059-hd.png new file mode 100644 index 00000000..2d030d56 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_059-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_059-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_059-sd.png new file mode 100644 index 00000000..3f71b779 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_059-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_060-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_060-hd.png new file mode 100644 index 00000000..0fb6b5de Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_060-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_060-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_060-sd.png new file mode 100644 index 00000000..280a84ad Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_060-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_061-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_061-hd.png new file mode 100644 index 00000000..b6747dad Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_061-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_061-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_061-sd.png new file mode 100644 index 00000000..00125086 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_061-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_062-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_062-hd.png new file mode 100644 index 00000000..e12436e1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_062-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_062-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_062-sd.png new file mode 100644 index 00000000..69744ba9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_062-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_063-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_063-hd.png new file mode 100644 index 00000000..cffb5cc3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_063-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_063-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_063-sd.png new file mode 100644 index 00000000..deec153b Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_063-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_064-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_064-hd.png new file mode 100644 index 00000000..32be4b3f Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_064-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_064-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_064-sd.png new file mode 100644 index 00000000..26d8f1ef Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_064-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_065-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_065-hd.png new file mode 100644 index 00000000..5b0ec97b Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_065-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_065-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_065-sd.png new file mode 100644 index 00000000..2920a3cf Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_065-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_066-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_066-hd.png new file mode 100644 index 00000000..eb678b6f Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_066-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_066-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_066-sd.png new file mode 100644 index 00000000..0c785508 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_066-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_067-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_067-hd.png new file mode 100644 index 00000000..a406b381 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_067-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_067-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_067-sd.png new file mode 100644 index 00000000..cebe2dd9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_067-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_068-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_068-hd.png new file mode 100644 index 00000000..46a2df1d Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_068-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_068-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_068-sd.png new file mode 100644 index 00000000..c407b3e0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_068-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_069-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_069-hd.png new file mode 100644 index 00000000..22e77f4f Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_069-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_069-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_069-sd.png new file mode 100644 index 00000000..af19be4e Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_069-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_070-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_070-hd.png new file mode 100644 index 00000000..02e1619d Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_070-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_070-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_070-sd.png new file mode 100644 index 00000000..1eb3303d Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_070-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_071-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_071-hd.png new file mode 100644 index 00000000..fd1ef7b9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_071-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_071-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_071-sd.png new file mode 100644 index 00000000..51709494 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_071-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_072-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_072-hd.png new file mode 100644 index 00000000..569a5d2b Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_072-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_072-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_072-sd.png new file mode 100644 index 00000000..d6af3d57 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_072-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_073-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_073-hd.png new file mode 100644 index 00000000..2fd4ef17 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_073-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_073-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_073-sd.png new file mode 100644 index 00000000..471b7e6c Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_073-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_074-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_074-hd.png new file mode 100644 index 00000000..25ca2fe0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_074-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_074-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_074-sd.png new file mode 100644 index 00000000..25f5fbdc Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_074-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_075-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_075-hd.png new file mode 100644 index 00000000..f65dbfec Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_075-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_075-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_075-sd.png new file mode 100644 index 00000000..1eed6ef7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_075-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_076-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_076-hd.png new file mode 100644 index 00000000..3393c910 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_076-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_076-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_076-sd.png new file mode 100644 index 00000000..2b0af7e6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_076-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_077-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_077-hd.png new file mode 100644 index 00000000..f0eb4d8d Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_077-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_077-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_077-sd.png new file mode 100644 index 00000000..96602e0c Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_077-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_078-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_078-hd.png new file mode 100644 index 00000000..76019fc5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_078-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_078-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_078-sd.png new file mode 100644 index 00000000..edf9f407 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_078-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_079-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_079-hd.png new file mode 100644 index 00000000..637445d6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_079-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_079-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_079-sd.png new file mode 100644 index 00000000..f8c1359f Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_079-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_080-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_080-hd.png new file mode 100644 index 00000000..5e1c363f Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_080-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_080-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_080-sd.png new file mode 100644 index 00000000..5565f373 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_080-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_081-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_081-hd.png new file mode 100644 index 00000000..664d523a Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_081-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_081-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_081-sd.png new file mode 100644 index 00000000..b2ba894a Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_081-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_082-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_082-hd.png new file mode 100644 index 00000000..66c080e1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_082-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_082-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_082-sd.png new file mode 100644 index 00000000..8529044b Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_082-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_083-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_083-hd.png new file mode 100644 index 00000000..1c7dd1b6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_083-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_083-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_083-sd.png new file mode 100644 index 00000000..0a935a74 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_083-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_084-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_084-hd.png new file mode 100644 index 00000000..d0ba8d63 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_084-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_084-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_084-sd.png new file mode 100644 index 00000000..0a0ac6c6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_084-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_085-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_085-hd.png new file mode 100644 index 00000000..55d3dc39 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_085-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_085-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_085-sd.png new file mode 100644 index 00000000..4f54457e Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_085-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_086-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_086-hd.png new file mode 100644 index 00000000..f1afab06 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_086-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_086-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_086-sd.png new file mode 100644 index 00000000..a5daa584 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_086-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_087-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_087-hd.png new file mode 100644 index 00000000..68cf3849 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_087-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_087-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_087-sd.png new file mode 100644 index 00000000..fe5f72aa Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_087-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_088-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_088-hd.png new file mode 100644 index 00000000..90014c7c Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_088-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_088-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_088-sd.png new file mode 100644 index 00000000..4b64a2d8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_088-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_089-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_089-hd.png new file mode 100644 index 00000000..9f1036a5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_089-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_089-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_089-sd.png new file mode 100644 index 00000000..87829fbd Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_089-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_090-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_090-hd.png new file mode 100644 index 00000000..329ec6ec Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_090-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_090-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_090-sd.png new file mode 100644 index 00000000..c9167e58 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_090-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_091-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_091-hd.png new file mode 100644 index 00000000..7499b045 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_091-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_091-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_091-sd.png new file mode 100644 index 00000000..861451fd Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_091-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_092-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_092-hd.png new file mode 100644 index 00000000..229a4646 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_092-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_092-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_092-sd.png new file mode 100644 index 00000000..20d2afe0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_092-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_093-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_093-hd.png new file mode 100644 index 00000000..7a74c370 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_093-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_093-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_093-sd.png new file mode 100644 index 00000000..a9af16c5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_093-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_094-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_094-hd.png new file mode 100644 index 00000000..2b8f5aca Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_094-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_094-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_094-sd.png new file mode 100644 index 00000000..62dcc28b Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_094-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_095-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_095-hd.png new file mode 100644 index 00000000..1450d6cf Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_095-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_095-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_095-sd.png new file mode 100644 index 00000000..8384691a Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_095-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_096-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_096-hd.png new file mode 100644 index 00000000..e0c056e1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_096-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_096-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_096-sd.png new file mode 100644 index 00000000..f5ef187c Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_096-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_097-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_097-hd.png new file mode 100644 index 00000000..35ef2530 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_097-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_097-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_097-sd.png new file mode 100644 index 00000000..79311612 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_097-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_098-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_098-hd.png new file mode 100644 index 00000000..0ede0625 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_098-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_098-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_098-sd.png new file mode 100644 index 00000000..740db2cd Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_098-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_099-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_099-hd.png new file mode 100644 index 00000000..fc7b653c Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_099-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_099-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_099-sd.png new file mode 100644 index 00000000..478f95ee Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_099-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_100-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_100-hd.png new file mode 100644 index 00000000..d7e92de0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_100-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_100-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_100-sd.png new file mode 100644 index 00000000..df735738 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_100-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_101-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_101-hd.png new file mode 100644 index 00000000..0ba77a35 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_101-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_101-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_101-sd.png new file mode 100644 index 00000000..f46c3b03 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_101-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_102-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_102-hd.png new file mode 100644 index 00000000..0bf83c1c Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_102-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_102-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_102-sd.png new file mode 100644 index 00000000..5e9f539e Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_102-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_103-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_103-hd.png new file mode 100644 index 00000000..68a06e17 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_103-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_103-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_103-sd.png new file mode 100644 index 00000000..5ac38608 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_103-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_104-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_104-hd.png new file mode 100644 index 00000000..9690b9e5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_104-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_104-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_104-sd.png new file mode 100644 index 00000000..0682d4d8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_104-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_105-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_105-hd.png new file mode 100644 index 00000000..fe97afdd Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_105-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_105-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_105-sd.png new file mode 100644 index 00000000..fd324cd3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_105-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_106-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_106-hd.png new file mode 100644 index 00000000..1df8d7f3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_106-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_106-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_106-sd.png new file mode 100644 index 00000000..a9d9c374 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_106-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_107-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_107-hd.png new file mode 100644 index 00000000..9422fb7f Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_107-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_107-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_107-sd.png new file mode 100644 index 00000000..9c0661d5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_107-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_108-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_108-hd.png new file mode 100644 index 00000000..4d7739f5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_108-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_108-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_108-sd.png new file mode 100644 index 00000000..d07d9da2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_108-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_109-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_109-hd.png new file mode 100644 index 00000000..f86434d2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_109-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_109-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_109-sd.png new file mode 100644 index 00000000..c514f529 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_109-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_110-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_110-hd.png new file mode 100644 index 00000000..25ae01ff Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_110-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_110-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_110-sd.png new file mode 100644 index 00000000..bb4c8d57 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_110-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_111-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_111-hd.png new file mode 100644 index 00000000..85efd842 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_111-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_111-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_111-sd.png new file mode 100644 index 00000000..e53a2f4c Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_111-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_112-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_112-hd.png new file mode 100644 index 00000000..6554aac7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_112-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_112-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_112-sd.png new file mode 100644 index 00000000..08bfada2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_112-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_113-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_113-hd.png new file mode 100644 index 00000000..1dfb2368 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_113-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_113-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_113-sd.png new file mode 100644 index 00000000..df757455 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_113-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_114-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_114-hd.png new file mode 100644 index 00000000..6dc1b5a4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_114-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_114-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_114-sd.png new file mode 100644 index 00000000..4cfacba7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_114-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_115-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_115-hd.png new file mode 100644 index 00000000..ae59b0ba Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_115-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_115-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_115-sd.png new file mode 100644 index 00000000..b946301a Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_115-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_116-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_116-hd.png new file mode 100644 index 00000000..899d03d9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_116-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_116-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_116-sd.png new file mode 100644 index 00000000..9e32f6b4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_116-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_117-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_117-hd.png new file mode 100644 index 00000000..3d4c09fe Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_117-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_117-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_117-sd.png new file mode 100644 index 00000000..0b4c33aa Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_117-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_118-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_118-hd.png new file mode 100644 index 00000000..46c9f244 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_118-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_118-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_118-sd.png new file mode 100644 index 00000000..0e37457d Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_118-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_119-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_119-hd.png new file mode 100644 index 00000000..cb1f9a0e Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_119-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_119-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_119-sd.png new file mode 100644 index 00000000..7b5c3fc8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_119-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_120-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_120-hd.png new file mode 100644 index 00000000..94233688 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_120-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_120-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_120-sd.png new file mode 100644 index 00000000..814fe5ad Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_120-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_121-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_121-hd.png new file mode 100644 index 00000000..20e15430 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_121-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_121-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_121-sd.png new file mode 100644 index 00000000..2a3f5b00 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_121-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_122-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_122-hd.png new file mode 100644 index 00000000..afb78d2a Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_122-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_122-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_122-sd.png new file mode 100644 index 00000000..f2beb5b5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_122-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_123-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_123-hd.png new file mode 100644 index 00000000..c5a8a2a4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_123-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_123-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_123-sd.png new file mode 100644 index 00000000..ceb61dae Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_123-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_124-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_124-hd.png new file mode 100644 index 00000000..e39586af Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_124-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_124-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_124-sd.png new file mode 100644 index 00000000..ec841cad Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_124-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_125-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_125-hd.png new file mode 100644 index 00000000..4890a399 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_125-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_125-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_125-sd.png new file mode 100644 index 00000000..5edf7f3e Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_125-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_126-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_126-hd.png new file mode 100644 index 00000000..32be9058 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_126-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_126-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_126-sd.png new file mode 100644 index 00000000..6e0c675b Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_126-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_127-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_127-hd.png new file mode 100644 index 00000000..eaeabe30 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_127-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_127-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_127-sd.png new file mode 100644 index 00000000..94cf7d9b Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_127-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_128-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_128-hd.png new file mode 100644 index 00000000..2f048b4b Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_128-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_128-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_128-sd.png new file mode 100644 index 00000000..43911a4d Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_128-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_129-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_129-hd.png new file mode 100644 index 00000000..b7c10270 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_129-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_129-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_129-sd.png new file mode 100644 index 00000000..9703df43 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_129-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_130-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_130-hd.png new file mode 100644 index 00000000..97d96651 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_130-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_130-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_130-sd.png new file mode 100644 index 00000000..b7bebc08 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_130-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_131-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_131-hd.png new file mode 100644 index 00000000..b98bfbb7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_131-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_131-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_131-sd.png new file mode 100644 index 00000000..dfd6754a Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_131-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_132-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_132-hd.png new file mode 100644 index 00000000..b695434f Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_132-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_132-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_132-sd.png new file mode 100644 index 00000000..9d591843 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_132-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_133-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_133-hd.png new file mode 100644 index 00000000..31b6fdb4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_133-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_133-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_133-sd.png new file mode 100644 index 00000000..a6300b10 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_133-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_134-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_134-hd.png new file mode 100644 index 00000000..977608be Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_134-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_134-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_134-sd.png new file mode 100644 index 00000000..efa62eb8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_134-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_135-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_135-hd.png new file mode 100644 index 00000000..d14fc13c Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_135-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_135-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_135-sd.png new file mode 100644 index 00000000..8728a317 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_135-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_136-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_136-hd.png new file mode 100644 index 00000000..b0827c14 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_136-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_136-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_136-sd.png new file mode 100644 index 00000000..49e85499 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_136-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_137-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_137-hd.png new file mode 100644 index 00000000..58a408ca Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_137-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_137-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_137-sd.png new file mode 100644 index 00000000..c1518a29 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_137-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_138-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_138-hd.png new file mode 100644 index 00000000..837fe5d4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_138-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_138-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_138-sd.png new file mode 100644 index 00000000..c39f0eb7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_138-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_139-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_139-hd.png new file mode 100644 index 00000000..fcbc09a7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_139-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_139-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_139-sd.png new file mode 100644 index 00000000..737b03a3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_139-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_140-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_140-hd.png new file mode 100644 index 00000000..0fcbee4a Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_140-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_140-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_140-sd.png new file mode 100644 index 00000000..6257c1d9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_140-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_141-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_141-hd.png new file mode 100644 index 00000000..fa71be4c Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_141-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_141-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_141-sd.png new file mode 100644 index 00000000..97dc4ab1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_141-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_142-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_142-hd.png new file mode 100644 index 00000000..7266f324 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_142-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_142-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_142-sd.png new file mode 100644 index 00000000..b2386419 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_142-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_143-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_143-hd.png new file mode 100644 index 00000000..19a82bdc Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_143-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_143-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_143-sd.png new file mode 100644 index 00000000..32be61ed Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_143-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_144-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_144-hd.png new file mode 100644 index 00000000..f4fa44f4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_144-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_144-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_144-sd.png new file mode 100644 index 00000000..dce62eae Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_144-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_145-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_145-hd.png new file mode 100644 index 00000000..0e1cc70f Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_145-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_145-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_145-sd.png new file mode 100644 index 00000000..830afd1c Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_145-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_146-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_146-hd.png new file mode 100644 index 00000000..a60c2985 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_146-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_146-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_146-sd.png new file mode 100644 index 00000000..ddff676e Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_146-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_147-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_147-hd.png new file mode 100644 index 00000000..25258690 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_147-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_147-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_147-sd.png new file mode 100644 index 00000000..6bcc0c4c Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_147-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_148-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_148-hd.png new file mode 100644 index 00000000..d27e741f Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_148-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_148-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_148-sd.png new file mode 100644 index 00000000..818aede6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_148-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_149-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_149-hd.png new file mode 100644 index 00000000..6a5a838f Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_149-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_149-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_149-sd.png new file mode 100644 index 00000000..e37efd77 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_149-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_150-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_150-hd.png new file mode 100644 index 00000000..c2a86cef Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_150-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_150-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_150-sd.png new file mode 100644 index 00000000..5637ef8c Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_150-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_151-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_151-hd.png new file mode 100644 index 00000000..3e1cb3ba Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_151-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_151-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_151-sd.png new file mode 100644 index 00000000..e6f602f8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_151-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_152-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_152-hd.png new file mode 100644 index 00000000..f77fa3d5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_152-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_152-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_152-sd.png new file mode 100644 index 00000000..1595a018 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_152-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_153-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_153-hd.png new file mode 100644 index 00000000..6680070d Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_153-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_153-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_153-sd.png new file mode 100644 index 00000000..b82fa365 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_153-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_154-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_154-hd.png new file mode 100644 index 00000000..92e9f28b Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_154-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_154-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_154-sd.png new file mode 100644 index 00000000..43eab465 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_154-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_155-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_155-hd.png new file mode 100644 index 00000000..3d88e777 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_155-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_155-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_155-sd.png new file mode 100644 index 00000000..b7716c38 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_155-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_156-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_156-hd.png new file mode 100644 index 00000000..e8d45c0d Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_156-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_156-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_156-sd.png new file mode 100644 index 00000000..4fd6424e Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_156-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_157-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_157-hd.png new file mode 100644 index 00000000..b113ad2b Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_157-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_157-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_157-sd.png new file mode 100644 index 00000000..a4277f7e Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_157-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_158-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_158-hd.png new file mode 100644 index 00000000..0a456805 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_158-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_158-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_158-sd.png new file mode 100644 index 00000000..3698e9ce Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_158-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_159-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_159-hd.png new file mode 100644 index 00000000..7a89c6b8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_159-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_159-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_159-sd.png new file mode 100644 index 00000000..f8397c7e Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_159-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_160-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_160-hd.png new file mode 100644 index 00000000..5f0ae8be Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_160-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_160-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_160-sd.png new file mode 100644 index 00000000..b5c70d87 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_160-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_161-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_161-hd.png new file mode 100644 index 00000000..9d22a531 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_161-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_161-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_161-sd.png new file mode 100644 index 00000000..b8507ba4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_161-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_162-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_162-hd.png new file mode 100644 index 00000000..1da6199d Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_162-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_162-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_162-sd.png new file mode 100644 index 00000000..9ad30ee9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_162-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_163-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_163-hd.png new file mode 100644 index 00000000..595a6b08 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_163-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_163-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_163-sd.png new file mode 100644 index 00000000..5326ac16 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_163-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_164-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_164-hd.png new file mode 100644 index 00000000..305ecdc8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_164-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_164-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_164-sd.png new file mode 100644 index 00000000..f163b03f Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_164-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_165-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_165-hd.png new file mode 100644 index 00000000..69ddf3f9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_165-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_165-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_165-sd.png new file mode 100644 index 00000000..a739c6e1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_165-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_166-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_166-hd.png new file mode 100644 index 00000000..2a781638 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_166-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_166-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_166-sd.png new file mode 100644 index 00000000..544c72dd Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_166-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_167-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_167-hd.png new file mode 100644 index 00000000..6c83c3ed Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_167-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_167-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_167-sd.png new file mode 100644 index 00000000..9d0dd245 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_167-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_168-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_168-hd.png new file mode 100644 index 00000000..1c7d657d Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_168-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_168-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_168-sd.png new file mode 100644 index 00000000..ebfa5951 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_168-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_169-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_169-hd.png new file mode 100644 index 00000000..aad36501 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_169-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_169-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_169-sd.png new file mode 100644 index 00000000..cd9d8526 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_169-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_170-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_170-hd.png new file mode 100644 index 00000000..7e0cfdec Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_170-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_170-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_170-sd.png new file mode 100644 index 00000000..919d460d Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_170-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_171-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_171-hd.png new file mode 100644 index 00000000..d975b631 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_171-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_171-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_171-sd.png new file mode 100644 index 00000000..9b6d2bc0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_171-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_172-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_172-hd.png new file mode 100644 index 00000000..0af4ad19 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_172-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_172-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_172-sd.png new file mode 100644 index 00000000..002bb24f Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_172-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_173-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_173-hd.png new file mode 100644 index 00000000..ba109d05 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_173-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_173-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_173-sd.png new file mode 100644 index 00000000..d35eecd7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_173-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_174-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_174-hd.png new file mode 100644 index 00000000..466364ea Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_174-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_174-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_174-sd.png new file mode 100644 index 00000000..fbe6eab2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_174-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_175-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_175-hd.png new file mode 100644 index 00000000..5be7ad35 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_175-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_175-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_175-sd.png new file mode 100644 index 00000000..ac05123d Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_175-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_176-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_176-hd.png new file mode 100644 index 00000000..bb4e76b0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_176-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_176-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_176-sd.png new file mode 100644 index 00000000..3336c405 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_176-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_177-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_177-hd.png new file mode 100644 index 00000000..180f7a51 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_177-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_177-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_177-sd.png new file mode 100644 index 00000000..cb9be3e9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_177-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_178-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_178-hd.png new file mode 100644 index 00000000..7a0f2ace Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_178-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_178-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_178-sd.png new file mode 100644 index 00000000..fbb50e94 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_178-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_179-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_179-hd.png new file mode 100644 index 00000000..13f3cf1a Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_179-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_179-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_179-sd.png new file mode 100644 index 00000000..085eb8c7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_179-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_180-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_180-hd.png new file mode 100644 index 00000000..460ae7c2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_180-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_180-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_180-sd.png new file mode 100644 index 00000000..e3464f9f Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_180-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_181-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_181-hd.png new file mode 100644 index 00000000..f2d24eb4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_181-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_181-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_181-sd.png new file mode 100644 index 00000000..9e9888f5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_181-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_182-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_182-hd.png new file mode 100644 index 00000000..599019c9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_182-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_182-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_182-sd.png new file mode 100644 index 00000000..87800675 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_182-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_183-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_183-hd.png new file mode 100644 index 00000000..e822f6e2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_183-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_183-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_183-sd.png new file mode 100644 index 00000000..62501766 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_183-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_184-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_184-hd.png new file mode 100644 index 00000000..5cbb3167 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_184-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_184-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_184-sd.png new file mode 100644 index 00000000..fdbb3465 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_184-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_185-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_185-hd.png new file mode 100644 index 00000000..0bd19677 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_185-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_185-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_185-sd.png new file mode 100644 index 00000000..bc1d00dc Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_185-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_186-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_186-hd.png new file mode 100644 index 00000000..5f8a1fef Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_186-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_186-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_186-sd.png new file mode 100644 index 00000000..7709b462 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_186-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_187-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_187-hd.png new file mode 100644 index 00000000..7facbecb Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_187-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_187-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_187-sd.png new file mode 100644 index 00000000..a1792210 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_187-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_188-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_188-hd.png new file mode 100644 index 00000000..acb124c0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_188-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_188-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_188-sd.png new file mode 100644 index 00000000..06ca0b48 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_188-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_189-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_189-hd.png new file mode 100644 index 00000000..d395951c Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_189-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_189-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_189-sd.png new file mode 100644 index 00000000..f72cd10b Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_189-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_190-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_190-hd.png new file mode 100644 index 00000000..b280be16 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_190-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_190-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_190-sd.png new file mode 100644 index 00000000..ca867d2e Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_190-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_191-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_191-hd.png new file mode 100644 index 00000000..0c73f069 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_191-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_191-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_191-sd.png new file mode 100644 index 00000000..80fd7607 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_191-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_192-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_192-hd.png new file mode 100644 index 00000000..39381bdb Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_192-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_192-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_192-sd.png new file mode 100644 index 00000000..c27e12fd Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_192-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_193-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_193-hd.png new file mode 100644 index 00000000..629e3af6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_193-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_193-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_193-sd.png new file mode 100644 index 00000000..71f30a2f Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_193-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_194-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_194-hd.png new file mode 100644 index 00000000..98d17c2e Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_194-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_194-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_194-sd.png new file mode 100644 index 00000000..7b291a6c Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_194-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_195-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_195-hd.png new file mode 100644 index 00000000..51c8bc01 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_195-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_195-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_195-sd.png new file mode 100644 index 00000000..bd71f408 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_195-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_196-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_196-hd.png new file mode 100644 index 00000000..f6eb96f5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_196-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_196-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_196-sd.png new file mode 100644 index 00000000..5e2e58d2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_196-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_197-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_197-hd.png new file mode 100644 index 00000000..f40a1c64 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_197-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_197-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_197-sd.png new file mode 100644 index 00000000..9e0456e6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_197-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_198-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_198-hd.png new file mode 100644 index 00000000..5be63b1d Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_198-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_198-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_198-sd.png new file mode 100644 index 00000000..9f036ca2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_198-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_199-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_199-hd.png new file mode 100644 index 00000000..535ec7b4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_199-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_199-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_199-sd.png new file mode 100644 index 00000000..68b06673 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_199-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_200-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_200-hd.png new file mode 100644 index 00000000..05840c07 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_200-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_200-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_200-sd.png new file mode 100644 index 00000000..67e46d1f Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_200-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_201-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_201-hd.png new file mode 100644 index 00000000..5513a83e Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_201-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_201-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_201-sd.png new file mode 100644 index 00000000..42895ce1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_201-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_202-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_202-hd.png new file mode 100644 index 00000000..6425b74d Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_202-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_202-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_202-sd.png new file mode 100644 index 00000000..acd7c4e1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_202-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_203-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_203-hd.png new file mode 100644 index 00000000..549d2167 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_203-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_203-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_203-sd.png new file mode 100644 index 00000000..5c611dd0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_203-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_204-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_204-hd.png new file mode 100644 index 00000000..f8bb18f5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_204-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_204-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_204-sd.png new file mode 100644 index 00000000..acbd15c6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_204-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_205-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_205-hd.png new file mode 100644 index 00000000..c61489bd Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_205-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_205-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_205-sd.png new file mode 100644 index 00000000..1197b6a9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_205-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_206-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_206-hd.png new file mode 100644 index 00000000..c41a16d2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_206-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_206-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_206-sd.png new file mode 100644 index 00000000..95656ecd Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_206-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_207-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_207-hd.png new file mode 100644 index 00000000..368c344d Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_207-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_207-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_207-sd.png new file mode 100644 index 00000000..f9023b9d Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_207-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_208-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_208-hd.png new file mode 100644 index 00000000..5431f8ef Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_208-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_208-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_208-sd.png new file mode 100644 index 00000000..96d55a1c Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_208-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_209-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_209-hd.png new file mode 100644 index 00000000..b4076025 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_209-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_209-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_209-sd.png new file mode 100644 index 00000000..6e5dbfd5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_209-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_210-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_210-hd.png new file mode 100644 index 00000000..2c1b4a6c Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_210-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_210-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_210-sd.png new file mode 100644 index 00000000..b02b54e1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_210-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_211-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_211-hd.png new file mode 100644 index 00000000..0dc431d5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_211-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_211-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_211-sd.png new file mode 100644 index 00000000..5a28b18f Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_211-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_212-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_212-hd.png new file mode 100644 index 00000000..003daf67 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_212-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_212-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_212-sd.png new file mode 100644 index 00000000..e4c23a36 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_212-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_213-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_213-hd.png new file mode 100644 index 00000000..0a82391f Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_213-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_213-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_213-sd.png new file mode 100644 index 00000000..7feb7750 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_213-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_214-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_214-hd.png new file mode 100644 index 00000000..5aedd044 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_214-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_214-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_214-sd.png new file mode 100644 index 00000000..17241005 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_214-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_215-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_215-hd.png new file mode 100644 index 00000000..c31b5d09 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_215-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_215-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_215-sd.png new file mode 100644 index 00000000..367a679b Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_215-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_216-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_216-hd.png new file mode 100644 index 00000000..70461a60 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_216-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_216-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_216-sd.png new file mode 100644 index 00000000..f9d51825 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_216-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_217-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_217-hd.png new file mode 100644 index 00000000..c0c6ad0e Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_217-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_217-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_217-sd.png new file mode 100644 index 00000000..7159ce33 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_217-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_218-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_218-hd.png new file mode 100644 index 00000000..a8d2660c Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_218-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_218-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_218-sd.png new file mode 100644 index 00000000..7af8e94a Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_218-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_219-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_219-hd.png new file mode 100644 index 00000000..bbecd6ce Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_219-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_219-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_219-sd.png new file mode 100644 index 00000000..30cc5ba5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_219-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_220-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_220-hd.png new file mode 100644 index 00000000..74af328c Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_220-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_220-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_220-sd.png new file mode 100644 index 00000000..f69049af Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_220-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_221-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_221-hd.png new file mode 100644 index 00000000..cbf5021d Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_221-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_221-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_221-sd.png new file mode 100644 index 00000000..cd7d0397 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_221-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_222-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_222-hd.png new file mode 100644 index 00000000..d53b887a Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_222-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_222-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_222-sd.png new file mode 100644 index 00000000..6b219f9b Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_222-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_223-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_223-hd.png new file mode 100644 index 00000000..bdab8e17 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_223-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_223-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_223-sd.png new file mode 100644 index 00000000..c08ad6b7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_223-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_224-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_224-hd.png new file mode 100644 index 00000000..58089a74 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_224-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_224-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_224-sd.png new file mode 100644 index 00000000..2f78fb5d Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_224-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_225-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_225-hd.png new file mode 100644 index 00000000..fb118d32 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_225-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_225-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_225-sd.png new file mode 100644 index 00000000..46a50446 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_225-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_226-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_226-hd.png new file mode 100644 index 00000000..f826298c Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_226-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_226-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_226-sd.png new file mode 100644 index 00000000..91779cfb Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_226-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_227-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_227-hd.png new file mode 100644 index 00000000..d7fe4dee Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_227-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_227-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_227-sd.png new file mode 100644 index 00000000..1d953503 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_227-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_228-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_228-hd.png new file mode 100644 index 00000000..fb251af2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_228-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_228-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_228-sd.png new file mode 100644 index 00000000..a2a2d10b Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_228-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_229-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_229-hd.png new file mode 100644 index 00000000..3d093787 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_229-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_229-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_229-sd.png new file mode 100644 index 00000000..1af50115 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_229-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_230-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_230-hd.png new file mode 100644 index 00000000..8e7408fc Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_230-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_230-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_230-sd.png new file mode 100644 index 00000000..50f1ce53 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_230-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_231-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_231-hd.png new file mode 100644 index 00000000..5b14ecaa Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_231-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_231-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_231-sd.png new file mode 100644 index 00000000..23bd57bb Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_231-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_232-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_232-hd.png new file mode 100644 index 00000000..117f91ba Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_232-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_232-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_232-sd.png new file mode 100644 index 00000000..cc9b3834 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_232-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_233-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_233-hd.png new file mode 100644 index 00000000..3c9c5100 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_233-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_233-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_233-sd.png new file mode 100644 index 00000000..e06aa3f3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_233-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_234-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_234-hd.png new file mode 100644 index 00000000..7ab5d851 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_234-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_234-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_234-sd.png new file mode 100644 index 00000000..5f113e57 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_234-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_235-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_235-hd.png new file mode 100644 index 00000000..28928eed Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_235-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_235-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_235-sd.png new file mode 100644 index 00000000..b82ca977 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_235-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_236-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_236-hd.png new file mode 100644 index 00000000..aa4531e9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_236-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_236-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_236-sd.png new file mode 100644 index 00000000..801fac66 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_236-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_237-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_237-hd.png new file mode 100644 index 00000000..16cec7f2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_237-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_237-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_237-sd.png new file mode 100644 index 00000000..330e04dd Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_237-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_238-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_238-hd.png new file mode 100644 index 00000000..b6a453eb Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_238-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_238-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_238-sd.png new file mode 100644 index 00000000..e9a69fed Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_238-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_239-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_239-hd.png new file mode 100644 index 00000000..4ba1a5b1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_239-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_239-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_239-sd.png new file mode 100644 index 00000000..064d4b1f Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_239-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_240-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_240-hd.png new file mode 100644 index 00000000..ef885f56 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_240-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_240-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_240-sd.png new file mode 100644 index 00000000..2a3b1da7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_240-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_241-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_241-hd.png new file mode 100644 index 00000000..95147b1b Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_241-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_241-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_241-sd.png new file mode 100644 index 00000000..15f9963e Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_241-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_242-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_242-hd.png new file mode 100644 index 00000000..2d01970d Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_242-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_242-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_242-sd.png new file mode 100644 index 00000000..3c86d233 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_242-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_243-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_243-hd.png new file mode 100644 index 00000000..f8aa4287 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_243-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_243-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_243-sd.png new file mode 100644 index 00000000..1f1c636f Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_243-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_244-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_244-hd.png new file mode 100644 index 00000000..85a6f0ed Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_244-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_244-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_244-sd.png new file mode 100644 index 00000000..75b37632 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_244-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_245-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_245-hd.png new file mode 100644 index 00000000..d7e80e4f Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_245-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_245-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_245-sd.png new file mode 100644 index 00000000..54c0ada7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_245-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_246-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_246-hd.png new file mode 100644 index 00000000..63290eae Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_246-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_246-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_246-sd.png new file mode 100644 index 00000000..a8cdb681 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_246-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_247-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_247-hd.png new file mode 100644 index 00000000..fbd10edb Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_247-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_247-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_247-sd.png new file mode 100644 index 00000000..b07907fa Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_247-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_248-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_248-hd.png new file mode 100644 index 00000000..fa9f9563 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_248-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_248-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_248-sd.png new file mode 100644 index 00000000..8f8e5f52 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_248-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_249-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_249-hd.png new file mode 100644 index 00000000..54b7f33b Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_249-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_249-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_249-sd.png new file mode 100644 index 00000000..0d4ec9fe Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_249-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_250-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_250-hd.png new file mode 100644 index 00000000..5264710c Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_250-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_250-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_250-sd.png new file mode 100644 index 00000000..d945cb0e Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_250-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_251-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_251-hd.png new file mode 100644 index 00000000..310ad21c Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_251-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_251-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_251-sd.png new file mode 100644 index 00000000..d068f1b3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_251-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_252-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_252-hd.png new file mode 100644 index 00000000..b444545a Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_252-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_252-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_252-sd.png new file mode 100644 index 00000000..f29e74e5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_252-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_253-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_253-hd.png new file mode 100644 index 00000000..9f061f56 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_253-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_253-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_253-sd.png new file mode 100644 index 00000000..363e3eb5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_253-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_254-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_254-hd.png new file mode 100644 index 00000000..2e6ddce7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_254-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_254-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_254-sd.png new file mode 100644 index 00000000..6eedbeb3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_254-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_255-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_255-hd.png new file mode 100644 index 00000000..81c66426 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_255-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_255-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_255-sd.png new file mode 100644 index 00000000..877cc0c5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_255-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_256-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_256-hd.png new file mode 100644 index 00000000..d95670b5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_256-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_256-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_256-sd.png new file mode 100644 index 00000000..8e8888e6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_256-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_257-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_257-hd.png new file mode 100644 index 00000000..b2a7a1ef Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_257-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_257-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_257-sd.png new file mode 100644 index 00000000..60f09cd0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_257-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_258-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_258-hd.png new file mode 100644 index 00000000..db205124 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_258-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_258-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_258-sd.png new file mode 100644 index 00000000..eef97348 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_258-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_259-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_259-hd.png new file mode 100644 index 00000000..3be936a0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_259-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_259-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_259-sd.png new file mode 100644 index 00000000..c36f2ca9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_259-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_260-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_260-hd.png new file mode 100644 index 00000000..7b749727 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_260-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_260-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_260-sd.png new file mode 100644 index 00000000..ce15fda6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_260-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_261-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_261-hd.png new file mode 100644 index 00000000..962a40b2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_261-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_261-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_261-sd.png new file mode 100644 index 00000000..a840ca90 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_261-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_262-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_262-hd.png new file mode 100644 index 00000000..b0b8a395 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_262-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_262-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_262-sd.png new file mode 100644 index 00000000..6aabc417 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_262-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_263-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_263-hd.png new file mode 100644 index 00000000..97ba0de9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_263-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_263-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_263-sd.png new file mode 100644 index 00000000..dc2508ea Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_263-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_264-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_264-hd.png new file mode 100644 index 00000000..5d9d5eca Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_264-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_264-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_264-sd.png new file mode 100644 index 00000000..30549c63 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_264-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_265-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_265-hd.png new file mode 100644 index 00000000..0ec7f156 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_265-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_265-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_265-sd.png new file mode 100644 index 00000000..5a4d6150 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_265-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_266-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_266-hd.png new file mode 100644 index 00000000..02b17e13 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_266-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_266-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_266-sd.png new file mode 100644 index 00000000..642df29a Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_266-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_267-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_267-hd.png new file mode 100644 index 00000000..50282523 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_267-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_267-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_267-sd.png new file mode 100644 index 00000000..1a39ee9e Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_267-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_268-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_268-hd.png new file mode 100644 index 00000000..fc574579 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_268-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_268-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_268-sd.png new file mode 100644 index 00000000..ec69a36e Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_268-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_269-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_269-hd.png new file mode 100644 index 00000000..e1b6053d Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_269-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_269-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_269-sd.png new file mode 100644 index 00000000..336d0fcc Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_269-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_270-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_270-hd.png new file mode 100644 index 00000000..c1c1d9d2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_270-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_270-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_270-sd.png new file mode 100644 index 00000000..73f396f7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_270-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_271-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_271-hd.png new file mode 100644 index 00000000..425f2864 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_271-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_271-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_271-sd.png new file mode 100644 index 00000000..50c2c68f Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_271-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_272-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_272-hd.png new file mode 100644 index 00000000..81b752bc Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_272-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_272-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_272-sd.png new file mode 100644 index 00000000..5cd25fc7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_272-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_273-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_273-hd.png new file mode 100644 index 00000000..4bc764f5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_273-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_273-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_273-sd.png new file mode 100644 index 00000000..8fd0a582 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_273-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_274-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_274-hd.png new file mode 100644 index 00000000..969e745e Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_274-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_274-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_274-sd.png new file mode 100644 index 00000000..cc592b0d Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_274-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_275-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_275-hd.png new file mode 100644 index 00000000..3b748ba7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_275-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_275-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_275-sd.png new file mode 100644 index 00000000..b812310c Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_275-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_276-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_276-hd.png new file mode 100644 index 00000000..7fc71c3b Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_276-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_276-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_276-sd.png new file mode 100644 index 00000000..858bebdc Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_276-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_277-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_277-hd.png new file mode 100644 index 00000000..73deea8f Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_277-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_277-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_277-sd.png new file mode 100644 index 00000000..9866568c Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_277-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_278-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_278-hd.png new file mode 100644 index 00000000..c8a04cd3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_278-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_278-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_278-sd.png new file mode 100644 index 00000000..36877d1d Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_278-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_279-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_279-hd.png new file mode 100644 index 00000000..9b329ee6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_279-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_279-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_279-sd.png new file mode 100644 index 00000000..7917a066 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_279-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_280-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_280-hd.png new file mode 100644 index 00000000..3af69d03 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_280-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_280-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_280-sd.png new file mode 100644 index 00000000..29f4d81c Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_280-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_281-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_281-hd.png new file mode 100644 index 00000000..b832cded Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_281-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_281-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_281-sd.png new file mode 100644 index 00000000..de54a147 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_281-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_282-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_282-hd.png new file mode 100644 index 00000000..369bf37b Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_282-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_282-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_282-sd.png new file mode 100644 index 00000000..93c39b1d Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_282-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_283-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_283-hd.png new file mode 100644 index 00000000..478c3d61 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_283-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_283-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_283-sd.png new file mode 100644 index 00000000..81cda7cf Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_283-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_284-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_284-hd.png new file mode 100644 index 00000000..e9c4b79d Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_284-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_284-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_284-sd.png new file mode 100644 index 00000000..73a1163f Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_284-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_285-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_285-hd.png new file mode 100644 index 00000000..275548e5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_285-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_285-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_285-sd.png new file mode 100644 index 00000000..277ee0ab Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_285-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_286-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_286-hd.png new file mode 100644 index 00000000..cd5cf95a Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_286-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_286-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_286-sd.png new file mode 100644 index 00000000..6d922b78 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_286-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_287-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_287-hd.png new file mode 100644 index 00000000..aa9e5442 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_287-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_287-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_287-sd.png new file mode 100644 index 00000000..da7b95ec Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_287-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_288-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_288-hd.png new file mode 100644 index 00000000..134d6823 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_288-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_288-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_288-sd.png new file mode 100644 index 00000000..8c28f161 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_288-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_289-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_289-hd.png new file mode 100644 index 00000000..7746935d Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_289-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_289-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_289-sd.png new file mode 100644 index 00000000..6ece0710 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_289-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_290-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_290-hd.png new file mode 100644 index 00000000..e40199e1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_290-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_290-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_290-sd.png new file mode 100644 index 00000000..2c5a4aa3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_290-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_291-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_291-hd.png new file mode 100644 index 00000000..d4856ddb Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_291-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_291-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_291-sd.png new file mode 100644 index 00000000..2c93884e Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_291-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_292-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_292-hd.png new file mode 100644 index 00000000..01ef7243 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_292-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_292-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_292-sd.png new file mode 100644 index 00000000..48c12b38 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_292-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_293-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_293-hd.png new file mode 100644 index 00000000..2eaf163f Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_293-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_293-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_293-sd.png new file mode 100644 index 00000000..409541ba Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_293-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_294-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_294-hd.png new file mode 100644 index 00000000..276319d0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_294-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_294-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_294-sd.png new file mode 100644 index 00000000..b95e6f31 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_294-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_295-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_295-hd.png new file mode 100644 index 00000000..15e6db16 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_295-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_295-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_295-sd.png new file mode 100644 index 00000000..8669dfa6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_295-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_296-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_296-hd.png new file mode 100644 index 00000000..c45b96d5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_296-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_296-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_296-sd.png new file mode 100644 index 00000000..1079e778 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_296-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_297-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_297-hd.png new file mode 100644 index 00000000..c7c302d1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_297-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_297-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_297-sd.png new file mode 100644 index 00000000..bbbfcbc3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_297-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_298-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_298-hd.png new file mode 100644 index 00000000..09d3efc8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_298-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_298-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_298-sd.png new file mode 100644 index 00000000..274235fc Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_298-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_299-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_299-hd.png new file mode 100644 index 00000000..4ee1f2a4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_299-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_299-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_299-sd.png new file mode 100644 index 00000000..352b9881 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_299-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_300-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_300-hd.png new file mode 100644 index 00000000..35fdea6b Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_300-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_300-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_300-sd.png new file mode 100644 index 00000000..6ca56492 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_300-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_301-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_301-hd.png new file mode 100644 index 00000000..855734b1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_301-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_301-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_301-sd.png new file mode 100644 index 00000000..845904dc Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_301-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_302-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_302-hd.png new file mode 100644 index 00000000..4ceb66a9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_302-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_302-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_302-sd.png new file mode 100644 index 00000000..067eea5e Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_302-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_303-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_303-hd.png new file mode 100644 index 00000000..a5f80ca6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_303-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_303-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_303-sd.png new file mode 100644 index 00000000..d46c7d56 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_303-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_304-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_304-hd.png new file mode 100644 index 00000000..a26debb2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_304-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_304-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_304-sd.png new file mode 100644 index 00000000..28dc1a07 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_304-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_305-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_305-hd.png new file mode 100644 index 00000000..1a0accba Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_305-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_305-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_305-sd.png new file mode 100644 index 00000000..32ce8e00 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_305-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_306-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_306-hd.png new file mode 100644 index 00000000..4fde6f7f Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_306-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_306-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_306-sd.png new file mode 100644 index 00000000..c037fb8a Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_306-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_307-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_307-hd.png new file mode 100644 index 00000000..9d7cd465 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_307-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_307-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_307-sd.png new file mode 100644 index 00000000..2ebb4365 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_307-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_308-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_308-hd.png new file mode 100644 index 00000000..2be77d1d Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_308-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_308-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_308-sd.png new file mode 100644 index 00000000..1d565b30 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_308-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_309-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_309-hd.png new file mode 100644 index 00000000..e3f31b6c Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_309-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_309-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_309-sd.png new file mode 100644 index 00000000..200a8d5a Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_309-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_310-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_310-hd.png new file mode 100644 index 00000000..04193f8b Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_310-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_310-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_310-sd.png new file mode 100644 index 00000000..18cdeb64 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_310-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_311-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_311-hd.png new file mode 100644 index 00000000..6dfaabf2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_311-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_311-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_311-sd.png new file mode 100644 index 00000000..7d1fb70c Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_311-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_312-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_312-hd.png new file mode 100644 index 00000000..e62b7d61 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_312-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_312-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_312-sd.png new file mode 100644 index 00000000..fd7fb1b5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_312-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_313-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_313-hd.png new file mode 100644 index 00000000..947dc09a Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_313-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_313-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_313-sd.png new file mode 100644 index 00000000..eb4b2fa9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_313-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_314-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_314-hd.png new file mode 100644 index 00000000..d4dfc730 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_314-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_314-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_314-sd.png new file mode 100644 index 00000000..8573bc86 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_314-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_315-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_315-hd.png new file mode 100644 index 00000000..3175d0b3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_315-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_315-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_315-sd.png new file mode 100644 index 00000000..7f0b5f36 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_315-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_316-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_316-hd.png new file mode 100644 index 00000000..3ddc294b Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_316-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_316-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_316-sd.png new file mode 100644 index 00000000..ad184dcc Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_316-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_317-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_317-hd.png new file mode 100644 index 00000000..560bf1d0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_317-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_317-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_317-sd.png new file mode 100644 index 00000000..610089b3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_317-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_318-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_318-hd.png new file mode 100644 index 00000000..4c9dd733 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_318-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_318-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_318-sd.png new file mode 100644 index 00000000..e1c2b9e3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_318-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_319-hd.png b/mods/iron_coast_stage2_mission_2/art/tile_319-hd.png new file mode 100644 index 00000000..9eb1218f Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_319-hd.png differ diff --git a/mods/iron_coast_stage2_mission_2/art/tile_319-sd.png b/mods/iron_coast_stage2_mission_2/art/tile_319-sd.png new file mode 100644 index 00000000..c075b93f Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/art/tile_319-sd.png differ diff --git a/mods/iron_coast_stage2_mission_2/asset-report.json b/mods/iron_coast_stage2_mission_2/asset-report.json new file mode 100644 index 00000000..b4f1481e --- /dev/null +++ b/mods/iron_coast_stage2_mission_2/asset-report.json @@ -0,0 +1,5462 @@ +{ + "utc": "2026-10-11T08:20:40.940364+00:00", + "recipe": "build_assets.py", + "recipe_sha256": "b7ecc4ecb69d0e6a2fb9185ed80cc27a8129e7c494b04befecc881c954bc8012", + "palette_sha256": "1cf6adb926d1dee1888b3e3d33b51a7049b3e5eb5f90a3067ef71c8970547204", + "ordinary_palette_entries_only": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 216, + 217, + 218, + 219, + 220, + 221, + 222, + 223, + 224, + 225, + 226, + 227, + 228, + 229, + 230, + 231, + 232, + 233, + 234, + 235, + 236, + 237, + 238, + 239 + ], + "assets": [ + { + "source": "art/terrain-generated-v1.png", + "sha256": "6d032b57afd4f40229a007af00b6678e1a37d6b062abfd4ccf48e076d994d41a", + "logical_map": [ + 320, + 512 + ], + "hd_map": [ + 1280, + 2048 + ], + "reflected_cycle": true, + "tiles": 320, + "briefing": "same generated map cropped with 8:5 viewport, no separate generation", + "source_not_modified": true + } + ], + "audio": [ + { + "file": "audio/approach.wav", + "sha256": "2d280db897ba42734a99f727b49dfec22ec3e61a8a6415c854a2315be1ba41af", + "samples": 13230, + "rate": 22050, + "duration": 0.6, + "peak": 8437, + "rms": 3076.0, + "seed": 8113 + }, + { + "file": "audio/objective.wav", + "sha256": "f6c53307bff448e4258da92c9555c927cd10070863a779ec07c96ded8b9d4f7a", + "samples": 7938, + "rate": 22050, + "duration": 0.36, + "peak": 8444, + "rms": 3076.41, + "seed": 8390 + }, + { + "file": "audio/boss_alarm.wav", + "sha256": "2d0fc1d0bdfa803ad256db4aa79ed25140393f01df3aff41b371e8178bac2dac", + "samples": 16537, + "rate": 22050, + "duration": 0.75, + "peak": 7394, + "rms": 2449.59, + "seed": 8377 + }, + { + "file": "audio/victory.wav", + "sha256": "f56f91ac92e5b3134441ee3a2b71005ad8af39cc87d5fa79edf0047eca4eceb3", + "samples": 20947, + "rate": 22050, + "duration": 0.95, + "peak": 8443, + "rms": 3077.07, + "seed": 8089 + } + ], + "final_art": [ + { + "file": "art/briefing-hd.png", + "sha256": "c4550e13d85bf6816996e024673673899a92106ed4da0923933cb68fccfac602", + "size": [ + 1280, + 800 + ] + }, + { + "file": "art/briefing-sd.png", + "sha256": "c18e516f97218cabc1a2fe8da193cb15b6279d52a84dc103950e906e122c1f0f", + "size": [ + 320, + 200 + ] + }, + { + "file": "art/terrain-preview-hd.png", + "sha256": "2f26844de51c94b4da63bffcbc1757d57f9b7955cbe93eea7cabe5161ecacf9d", + "size": [ + 1280, + 2048 + ] + }, + { + "file": "art/terrain-preview-sd.png", + "sha256": "bbdc62d102a39028cf89dfb89c8279eb71cb412c5a4817e6ff8a36616711b3b9", + "size": [ + 320, + 512 + ] + }, + { + "file": "art/tile_000-hd.png", + "sha256": "b4c7420f50d2d11d949d46d832d53964a58060cbf38aa5c183e2d548c0766ff1", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_000-sd.png", + "sha256": "988670d6325c1156b3d5a26c73990abf7545e74f89255cacb8e46a808ceda3e8", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_001-hd.png", + "sha256": "f087636a82aedb48a07508c4b80a7b168c03aeed344cbca1813839e71d973806", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_001-sd.png", + "sha256": "409a2313e4b6e66e77338b4576c07c4ca94fb27a7ea88596cac26d8a6230edb8", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_002-hd.png", + "sha256": "f525f47bafec9406293b14ea50ae70655a78542bb309a88174e6d5403b4245ec", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_002-sd.png", + "sha256": "10593ea51b682be4d812eae151bb935ba69270e3f101be40bfef24d8573343d8", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_003-hd.png", + "sha256": "b0350e29516e712b0da15927bfb11b972732429dbb5de10ed41ebefd61d8110b", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_003-sd.png", + "sha256": "30b10775dfc48a5c19e8c821751de8936a1c2e472e54cee3245d39f74bd7ccba", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_004-hd.png", + "sha256": "80431883ef9a71409014a29f92b388def34551fc688b0835370c5fb45ed19c83", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_004-sd.png", + "sha256": "2957eea2c50e37f58dcfc858cc9c4c6620edb0ae93744ab5fcc97c3fafde1f9a", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_005-hd.png", + "sha256": "bfa800a95980811aee3eb2c47800602ee8c1d2c8d46d83c34b8f2ec3838f1c0c", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_005-sd.png", + "sha256": "1fd11ca2c64b8400ddb6695a5bfcb8a90c6ed69f94df3027cf57e04206ebefbc", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_006-hd.png", + "sha256": "8395aa8184780e0572d6330ca773bc9c1f27f8c8f11e44012cc37110768c478b", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_006-sd.png", + "sha256": "32770d40e0f47e497329f04380273ef7bcd5b645f0da2d2e29d88f2592c67a6b", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_007-hd.png", + "sha256": "9c95fcc03bbaeda03e59339eb90fe8229dc89b152809d697b62f43cc27c12641", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_007-sd.png", + "sha256": "fa3658fb35f5738ab0effa15c15d26bd7e9a92d8554d2bcdbcde88325e23fc1e", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_008-hd.png", + "sha256": "79bd2157544f1ec6d08fe496d1859c59f7100043d0260bc3235d2ed10aa5a87a", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_008-sd.png", + "sha256": "f48ad52879c96970dd297b313ea3907462e9110c865941c24e82f1c7dcb79cc7", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_009-hd.png", + "sha256": "7ef415bbf5384c465a3d62ba4a03a991b8147520420341d3afd4f32a2cf3fc08", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_009-sd.png", + "sha256": "e6195ef84f9fd1f6aad9f06cb7b9832bb3ef606541cb4266983ae15135515b7a", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_010-hd.png", + "sha256": "0d3b03da600d63be51ea72a0b404a21c42094e071f218c663b86eeca22ff490f", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_010-sd.png", + "sha256": "ba7d35417aa548930e1338e1648287f07895444e428a4decd2e0df9c9753e86c", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_011-hd.png", + "sha256": "04387b5a570455780fcc54ec20266593f247c9ed026aae368b04064a22794005", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_011-sd.png", + "sha256": "4329749e9ca42c78dee3495df84261a5dd43b248b50e74cb2bfd9b099b99d7ad", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_012-hd.png", + "sha256": "0975f3b6369441cc05e33866002faa8947c001025d87fb880789dc69b54d5d33", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_012-sd.png", + "sha256": "ac38fa8ab0e72da4e07fccfa6b8fd587ed526000bb44a84b7e9a61aa3249061b", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_013-hd.png", + "sha256": "a85d7b277c54f89a890015a34e221f05ba68aa709612a1b493f008cf2c0b3af1", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_013-sd.png", + "sha256": "fb5c7458a7db303f6a79dbff1e2369dc7be04a4ab418bea1548a273d993f63ef", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_014-hd.png", + "sha256": "635bf4199f05c68e9e557646313182b264d8bb9be51c6aaa55416d1a99acfe14", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_014-sd.png", + "sha256": "deae29f0273d4efb0fa0aa69d93a85b113dbb1137d3049ba1ff375998f5f5cb0", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_015-hd.png", + "sha256": "2a751938c535e0fce01ed9558aea2bc8ad1685c9ab88bde1a78a52c2ccb636f9", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_015-sd.png", + "sha256": "d4e86c8ba63006119b745113df626fae67ada309c37573cc3bc6747d6cc1a93a", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_016-hd.png", + "sha256": "ddc7e34a944eaab6f87b8696af22d05b23838b8fc3f60d173a7a20c087c3394e", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_016-sd.png", + "sha256": "e64329b5b5e0db3a8d8267ee7488a6a3ea31b25b11ac55f80866aae3cd5d2267", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_017-hd.png", + "sha256": "1382569c7e479e50930b1e38e4d64f5781bedfc6d24b0c488d63bf07ad463540", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_017-sd.png", + "sha256": "c55d7b6e8ba24cbe97ff29661cb52a6daf214be522231413e124db67eeb33359", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_018-hd.png", + "sha256": "d5ec89f763b2e418a35b57354c032b9f3b965ae45c7d9a665662c3cadeb4b8af", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_018-sd.png", + "sha256": "3d7a6b4ec380d6f0ec8a8401ef015c4583cc9c0f8112e317c84081306f74f4e1", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_019-hd.png", + "sha256": "de15912b7baca0c8c340c2e4a640543341eea12eff87a1fabf1fda99103e18a4", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_019-sd.png", + "sha256": "8c3c7052224ca55f03918733a1c0a9cd6127a31468485da0dde09b1b01734e44", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_020-hd.png", + "sha256": "a475406623335e039ee12eaf8a737fc05f78ac16ab86d72da1a424a2d08952a5", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_020-sd.png", + "sha256": "3fa3d830966a9011473fb9984a71d09b1deac7001017304794e35e14ce699caf", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_021-hd.png", + "sha256": "f757f89c6eb9b8dbd5477bb2e949ea84ec6d1202e98da3301419528f284a7155", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_021-sd.png", + "sha256": "de57467a5d781b93da0fdece3d11f7d080e35e874bfd6ed02d115f591124cb68", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_022-hd.png", + "sha256": "83bdf2454fe4a0100d44cbac2d9bf66b23574fd5013375e4a35f185940931ed9", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_022-sd.png", + "sha256": "e431b220a12e86033e0ea5b7aae21c74d211d4649ea9dcb46e6f71a05c2b6d89", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_023-hd.png", + "sha256": "983b0159b0ca0dd6526b53146048e889fdace75b1526b791123fe8c3097eb8c7", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_023-sd.png", + "sha256": "b5231170b075961184d1e6da866b58ef40bbc4546673b1d7421e25c94f08eef3", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_024-hd.png", + "sha256": "ae73f77dc8125f9f2fbdfc0ff0915cc962c23ec46b7f153b34f87272f3952a3d", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_024-sd.png", + "sha256": "f37ed61a774a3666b3ddc1b92a2bbce8df8f30df7a7c1a66e5535bc8d258c720", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_025-hd.png", + "sha256": "6fbcce54cf995113593a0440b53cf1bd985c3aaf22ec727273c1887763e47287", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_025-sd.png", + "sha256": "8e620440429dee1b80c368768f9fa60280b757d7583f9673c97f8d441bbba8c7", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_026-hd.png", + "sha256": "4ad7df4a0c56a2c850e3f2c4dec22ccd0540875bcff643ca92dc834f0927854d", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_026-sd.png", + "sha256": "c90d08137c095a2c4f8c5534ec95569bb5d091c12b12195bb67a72886d146df1", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_027-hd.png", + "sha256": "8d852fdd454876e113457c7bef430c474c03f8e8b878640f2d04ad782969494a", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_027-sd.png", + "sha256": "161d2bb47013455ebcb9d23e699ce44000d0a9908202860b81e1fa02443f5e9e", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_028-hd.png", + "sha256": "263d51b03d4632c222fcb49d921519d8344744073b67495810384004d5010feb", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_028-sd.png", + "sha256": "a31fa0fd2b7b47b479296f725a3d5eed55073756171211a7b83aa077577a3278", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_029-hd.png", + "sha256": "c24d4bbd15316fc06c4b3115c564b09ccc8f14f2fd2a33a52f795072811b1b1e", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_029-sd.png", + "sha256": "74d0406363ea1f2320dba01052312c72d0803bf65b9664cf44f549d0fdf0e64d", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_030-hd.png", + "sha256": "517945a7be936b1e08bdbea4161c7029e4c5618c128812c386910fe217d801db", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_030-sd.png", + "sha256": "57a6616dc1a8f21cd1b5feb06e71cbebca704706bc1b8bfbb44ded653804444d", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_031-hd.png", + "sha256": "af780accef96a85487920584dae8b3997f5e412646000fc47df5b9d3c2e915a8", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_031-sd.png", + "sha256": "7624ae6cc14b49465f068ff96fdd3a5264b4371278c77ccf495befd1e870d96d", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_032-hd.png", + "sha256": "2858aaa35d9e9a694b7494abf4835801fb97df16569f1d2f0d7ed46c6d75be45", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_032-sd.png", + "sha256": "df2b05dcd6be6310ff66f816a5ca5ca5eb25593bcb66f517941c05120cb26aec", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_033-hd.png", + "sha256": "e75962f53c813508e2f19e1961f6fc717d1ba6fd64e289579e17fb778b15ff63", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_033-sd.png", + "sha256": "51d908fad64fac2c0834094ec2ded53e0d6ee9b2300050bd508fcabcccfdd45b", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_034-hd.png", + "sha256": "2d1243ac568cf1f3fd269e534b92544a8d7e3a165093450d47c4f3dfe25b8ce1", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_034-sd.png", + "sha256": "f5295ca2a045fd0a56b5b28224eb7befe1c5f523080177b9b223ebc4e14e505d", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_035-hd.png", + "sha256": "8e9c49aec7f60d2e50722e3d1ce04aa0cfec2ab901364335e419525e8489a6dc", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_035-sd.png", + "sha256": "a07f4d38977943d6687f375fd0ad349deb772b7727784454620ab447dc50af32", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_036-hd.png", + "sha256": "461613e6c7b859b31ae707ec9f7a575d7386b9872b2d3d9c0fb32035ad81ceed", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_036-sd.png", + "sha256": "643f263b4042e8a68a59696cf7d8ad6d598a358f4ca3b94a85343cc1f646c2d5", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_037-hd.png", + "sha256": "562302ccc65e9a242455cd36a4c457ee4b1dfb7932ddb535957785d8711e8473", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_037-sd.png", + "sha256": "80ed773e30fce1b23522842df9bb9932471de5d269bfcdbc01994bdb9d2ef8a5", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_038-hd.png", + "sha256": "7418cafee5e2af7079d1171cc6a2a240f957d246b86cab7be6eb385f629ecdf5", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_038-sd.png", + "sha256": "cc81402fa4f7aa549a3ca79bbed326d021a5c8ccb36f406f19613cea74c2eacc", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_039-hd.png", + "sha256": "5726c0d4802a593a1d255dfceba4b0f402a6a3457e727ca5c49dd93fbe584a51", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_039-sd.png", + "sha256": "c7cad1937f465beea638d0a2d8f267ae2ad64bb6ccf04cbb541a489389d69472", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_040-hd.png", + "sha256": "610db26942590b655f4198cc104409851d593abbaae1fad10e330c390943bbc6", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_040-sd.png", + "sha256": "5ea7f40d11d44774e21f08df2edfb0d5375f92d5cf4884af932867fb175abfcc", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_041-hd.png", + "sha256": "24c9bbfef1adfd566c5dce4aea5cf0ea8a7a6e2a1b433a68af0d1fc22a2ce258", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_041-sd.png", + "sha256": "f0a5d8cce9943be920c16b8a895d0822810d791a3fa14461b31b481c03e10517", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_042-hd.png", + "sha256": "571e2c4afc4d2237a92fc3f8ef70cf2d7cf7d4c73b68e1c93c32f4ac7d76d132", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_042-sd.png", + "sha256": "36c3fcb086857e51b653b868fd296e5821d624857c566489d4821036b74ad877", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_043-hd.png", + "sha256": "69d5967a82a60a2c27af533bb799ab2bac138a04610b38ed34afa474c89171df", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_043-sd.png", + "sha256": "5c199e9b134e8f31628a812bcb5adeca373b359947bf9d5c5e1cd703421c5c8d", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_044-hd.png", + "sha256": "74a886ab0a499620b9eafebfb47871394fd370b857df5635f43f2c2e6cfc2cd2", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_044-sd.png", + "sha256": "7a5c8229f93c6ad59f701a5869450fe15cf8a99dd60205004a98262601387706", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_045-hd.png", + "sha256": "2c443e3c0770b830c97c450a6a411bcf112c8b3bf710640ddfa89b28b5fde000", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_045-sd.png", + "sha256": "418e39bc14fe955a9c985ac23312ef1486491f87948a04ad8c85415e29c0f49f", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_046-hd.png", + "sha256": "ce7d0c276921c9eba7758f27918ee51622faa48020d2a0764cb42e5a2b0943dc", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_046-sd.png", + "sha256": "a2f4d74088b12e51a99b30a941f3af6ebd1e7720674e62d46fe387640cb0e8b7", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_047-hd.png", + "sha256": "74972b44bd89d9c3b0060f334d5d0aa12c1c6638292a9d65e81d6486b6b9d749", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_047-sd.png", + "sha256": "ca36d11ceb5ddd39ada87e1569007470fa69a41509c89c7aa5ca0f80ee028369", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_048-hd.png", + "sha256": "3c1950c9fc3672ac6df715068eabc4f94a0beb1e61dce6f3a0d4fc4d1c6a58d0", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_048-sd.png", + "sha256": "5a217d6bc27e4d64aa3754d6d79a387b0ce918b52a6b144dca2751bf540219f2", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_049-hd.png", + "sha256": "dd50b63bf7fdd1e26747fa7acef0cbcb7fc24319e9adb93a806ee50b6ab3b0e0", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_049-sd.png", + "sha256": "624d1091b458df06afbacf52a92524c5680c78d480b37d0c77b603081176452f", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_050-hd.png", + "sha256": "c12f100789b732359a80e336560ee2964eee77b902db3ed08a6b5e8f95c706dc", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_050-sd.png", + "sha256": "ad269196bfe33fe3b9c71e284abaf7831a2ffc704f79eeeacf13c274e7970625", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_051-hd.png", + "sha256": "158e834ed0c3b47aa9f0f20c7af36773b922559b4190fc14840edc9a15f4cf10", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_051-sd.png", + "sha256": "02c8b4f01e8530183deb2d87be7fdf1df8b01efbee16af84fdc070f5a805054a", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_052-hd.png", + "sha256": "27c766a0241466ef621763ed73e52327ea1edb0ea40b0ab79655a0a0fc46082f", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_052-sd.png", + "sha256": "eb20a4c4290f969728f4c50023bcc1998959b85f16d21f5439c81d9bf4186652", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_053-hd.png", + "sha256": "95813fb19483d14501ccf72fb8aff33bf2e970b7ef45f2eaa7925969b600cb18", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_053-sd.png", + "sha256": "da5501d52a9a933e70f6b67df887c0d333e7289ba725c6c4e1f37e699a55e935", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_054-hd.png", + "sha256": "73fb898825c05bb882e443967a3ec52888656ab37fa7f341cf4149edf976ffeb", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_054-sd.png", + "sha256": "ffd600e75ebf48a5e09ebfc4b969f083ae324d09f1d83527c06fd3e01e28ff06", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_055-hd.png", + "sha256": "90ee8c4ed5dbaf542488ac7b83804140ed939f69956dbd142f8e074ddd81b500", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_055-sd.png", + "sha256": "b840058efadb547b9f9138c4c2d52bce77915457304378c47341deb7b33c7c2b", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_056-hd.png", + "sha256": "2b0dc976537c695e12cccf7e58bac513ede335e399a2f267149ed33d46825749", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_056-sd.png", + "sha256": "7a537f4794cd9ff81870a5bab1dfe2a6340539de6b5f91f379237bc734c55d31", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_057-hd.png", + "sha256": "1433f2c47f081dc61b75207b3d5b7ab6a9ec1d977d00113a1bba2fc1c642c422", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_057-sd.png", + "sha256": "60389abc2d339794a73fd66b7f9ca5822b8382bdbbe1c0c6eeb14e3dea71090a", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_058-hd.png", + "sha256": "0f3983dd915e9d36c15cd47d505a7baa53a5723a244d4b8f02a3c12aa463cd69", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_058-sd.png", + "sha256": "277e4b4ee339188b0d3273f16100aadf64315ec092bc3f77f26c547e58de0c7a", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_059-hd.png", + "sha256": "a58104efeeb3b53063b29f78f1ec26fa6639cb4a9ed1130d404e3e066ef1e120", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_059-sd.png", + "sha256": "4eae381fe6abffdf4397e454845a41d2bcba3764c7a82d5da250cb00554e617e", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_060-hd.png", + "sha256": "58d7f43fa715d9c39632a0abe299f12ae49e4c584b9fa2b6fc3fd45a146ee431", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_060-sd.png", + "sha256": "39ba3f5c617a86d92a14793395c5d5560a15e86902f314bc33e6aaa73e598013", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_061-hd.png", + "sha256": "efaf318a83c78006f811b3aba575ccfa1c672f67d300d397d6ea8f3932a931b2", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_061-sd.png", + "sha256": "56d3caef77aba6d83c1115bc7a14af6ba4620ff5d743e3727ef8d986f8dc7bb8", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_062-hd.png", + "sha256": "e360c2ff1aa82131dc0dbfa30da18c8af6dc5c2044d125caa96262998d8070c1", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_062-sd.png", + "sha256": "d06e9f481378ce1a5c98f09084f069ece1ac02878fe0fddff5d4110f04a3b72f", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_063-hd.png", + "sha256": "60dd2ee13d2b1d62b532cb1437eac3c80636509710a311c12f1df126831ea703", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_063-sd.png", + "sha256": "045836f154b91eb7368884698b87f18478b0691cabcdee7226fbd64b442763cc", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_064-hd.png", + "sha256": "526a2e39e6d7b56ae730664e1fac662f3f5921e658fa363627c54754ffa2b4e7", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_064-sd.png", + "sha256": "0d3a701a25520f793535ed692f95c76c194d8c98d89cd5200b45c17e304b09e5", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_065-hd.png", + "sha256": "e1e9b4fb17a84b68fb5570efde98e54223f3749ea3cbe45e767311afd44e6f00", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_065-sd.png", + "sha256": "a37e356a9baed1114b5e54297f2e2386e137fa96b84699b715b0801a118040b8", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_066-hd.png", + "sha256": "2709b26d2ed55283ee9a7461dd7edcea89d7f2922630ab2b4103a37984b3d52f", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_066-sd.png", + "sha256": "81fd390e08f4019816d2e28332c6db123785354ac8c8bfa643e508a282533bd0", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_067-hd.png", + "sha256": "2ec3496743a63e404ab224d0258f794cf88006ae3dab76441ee243e588323eb7", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_067-sd.png", + "sha256": "672f0222ddc3bb80c3b3ba483047106b4c1b3fb2ea7b15c686255b6c50e4b67f", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_068-hd.png", + "sha256": "058f53e712df65b702ec9b7e43c8e6f866ca421280257f040b97a11c4a89919c", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_068-sd.png", + "sha256": "fc3fb45144a67dbde73bafe58a005986d0ed36c0e677b37899068d7a7df0d1cf", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_069-hd.png", + "sha256": "a724d3cebf095c988bf1fe108836272b23aa307e956ad659fd6e85b7571a880b", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_069-sd.png", + "sha256": "f0d6e492fd66333a0796962ba834fcdf6b914ed1050bc0495b62f1a9e4b5288f", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_070-hd.png", + "sha256": "a3d116f4fb6f70ae679316b9bd44097fad9d3a542c4887c5bce0b68a20b625f9", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_070-sd.png", + "sha256": "c61483d092ca818387f58f714c8d5506c046a54bd4919292932c8d13866998b6", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_071-hd.png", + "sha256": "3d79b1c971a8ed5fa63cef01e981e94450beb896c03c68e76903128fcd26a01f", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_071-sd.png", + "sha256": "7d61a2e0b4884fa37cb623677a8f925e154d8fd0edbf60517c069417ece189b8", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_072-hd.png", + "sha256": "11aa1119f9b8a6b575d9b4b76a333d6d466dbbd06bd2b5f237d4d21628d18d10", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_072-sd.png", + "sha256": "f9fd8d930eabceac9fedda20650dcc29eb97fa55304ef15743c4c0fa1de6b958", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_073-hd.png", + "sha256": "f88fac815773575de38f4bbe779d43f9c602463eb4208c14e0b65a91b6d4253c", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_073-sd.png", + "sha256": "b7eac05408813ddd6bee32f854b40e022d57ef3fd3ee3a5f851a857b30c76077", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_074-hd.png", + "sha256": "4dee87aee276ad6c1eb73732539b455d05153152f9dc050454543e3bdc8703a5", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_074-sd.png", + "sha256": "7ec02ab548f982ee1148ab1ff82bde10ed647f83b0be70ca45e21847f8e6209c", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_075-hd.png", + "sha256": "2554c2515f6e517939049525676a562981ccc7589d85b9b0a10d131b621731fa", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_075-sd.png", + "sha256": "e84c8476b4c8d15743aca73adc43e3a19aaa0f33af5ca94633cf2985a7d9d8e7", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_076-hd.png", + "sha256": "82f53c00d590d12585010a42b53b276afe006d7c20625d61ec05deac184432e2", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_076-sd.png", + "sha256": "bdc5c33cf913313f130553e7bfc54f55ea28f11a90550957472f80696b01f427", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_077-hd.png", + "sha256": "b40a06ec9a8b5de991f9c3d268e95b5d03ae81d65db3546e8bb42713b1c86da9", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_077-sd.png", + "sha256": "218adb82ec93794acf5defe765568e374fa0b9200feda300aa46fb7e095607de", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_078-hd.png", + "sha256": "02c979610d095c206f80170ae29aff36434f45eec57ffe37aedf3c255cd6466a", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_078-sd.png", + "sha256": "7f55fe4338cb20a82b14c1eaa45bb4356f66bdc9ea3eb3562e9896d854e9a858", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_079-hd.png", + "sha256": "a42865671b443c6bc3053ccd976ac24226942c92458e3b3b0a1c6bca41e7c531", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_079-sd.png", + "sha256": "fb7fa0dac7771c9d0d8ec9265854748375ecb3a6ab06fb32054ce02884853b63", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_080-hd.png", + "sha256": "e50bd4e5f7e073536205dfa3bb625924c7bbc7b2192602c04c08fa824b307ca0", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_080-sd.png", + "sha256": "54056f2b645594829b4bbee7d95393a3fa5aeeadbcb88956c1d59b431cd7eafe", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_081-hd.png", + "sha256": "0475c637b6df8ac76c9949f3a2d8590a8689aaf64148b23091a46d0bd433f6ed", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_081-sd.png", + "sha256": "f22a6acebf52f40fb25d636aa59eff3a0af257bb30d754e5d0cc8112cd8e1890", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_082-hd.png", + "sha256": "95e2ad5c7447a97a742e74153ce81006436baac35ac7821180060c6adb411591", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_082-sd.png", + "sha256": "21d1eebed83e9de51fe46f2bac67a651a272912912f8812494aed665704b9272", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_083-hd.png", + "sha256": "25bdb75b7583580e1225228ba1ee9e4dc720fcc8e3c4b391eb49f287c8cd9e23", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_083-sd.png", + "sha256": "927d2621f097aa83cb9e4c25c7d1b8709c9b6d02146395df58e6507db4de66e8", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_084-hd.png", + "sha256": "23e7064aaa222222cf666f853bb01a5f7ed2c683b0c395107532ecca003705ff", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_084-sd.png", + "sha256": "e609610635548b5a8663b4ca5b69a54800d49c6558f4d9300c9de49170f577a9", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_085-hd.png", + "sha256": "23064910794703c71d5b0cdd563cba87b15b0b532909df051fa8ecbed9775ce8", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_085-sd.png", + "sha256": "e526879861e093f528cf5d1cbbcdf08b93d528b6b054fb2aca7187faf6fdf5cc", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_086-hd.png", + "sha256": "4a6e1273b7ad2206d73c8456eaf81cd9566450972049a1d7c6a77b10c806e53c", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_086-sd.png", + "sha256": "ea0c2a0a2f94952e4062e7843eefae5ffbdf08dcd07c7280ff1ff47e80e2a1a7", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_087-hd.png", + "sha256": "b0b72a5332faece579a216b599bddb2a009ad0931b937d1722cba31b64e9e07c", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_087-sd.png", + "sha256": "947decd95a8f4f0c0c7a79677fa4848fd23e6f58b3344d6db5efba81a5907342", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_088-hd.png", + "sha256": "473c2048a2692073d82a13ba3a5b317b85bc0e53e5a7c2147a11106867d7b678", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_088-sd.png", + "sha256": "0add71520a2cea2719feff85008a7c3a10f1e2f1cf49c28f38450cdaef69944a", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_089-hd.png", + "sha256": "3c80355f396e81dfc4e1a62d1758f4b54afc070e75efdcb180ba07dc7437e822", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_089-sd.png", + "sha256": "921e336de8f62acd10b981825070756c5f91402dfed5538bd84e97775d3b08c9", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_090-hd.png", + "sha256": "6b29edf06ccb5a408bc764700c3bd8d17336d19c4a9cd6c2154d45efd2f03b44", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_090-sd.png", + "sha256": "d147d0fad61a4b6835e4e187b20c4e8a6b7e451cf622a572b721ecc2fba08340", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_091-hd.png", + "sha256": "d920049ce570d8972967fd2d82e6b473768730534935e24cc420478a0ed9b8c4", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_091-sd.png", + "sha256": "46c1ba5b652211e2aa581883bf1ed9710c65beab0144b2a40e76af12fb0f063a", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_092-hd.png", + "sha256": "5681c50dc37f72620c6d6a7e2d47c8f38ee893d1d5ab835e86ed61b1d9d1e143", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_092-sd.png", + "sha256": "3c416b891ce5df26bf45fb5eb6de79cbc778f4b2161f3a0d9717f44bcd6bb308", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_093-hd.png", + "sha256": "9ba01bf3e6c29d9c6e4a243f82283834e11c5b2c9811431ceaf90de29462fd3e", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_093-sd.png", + "sha256": "69750fbfd69ef8f95c03de466cf61d5012cfa019051ac4829caab20e9fe67f8e", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_094-hd.png", + "sha256": "4407ae6769d41f1ed843efac4835a3a48c3e1c745bc3a3699b5e63a4386f9aae", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_094-sd.png", + "sha256": "1378590f415e17afb2911621a1181c66e0f9d99f5cd8374eeab0564c25c7ad84", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_095-hd.png", + "sha256": "b666407b4ebbe91cd8503ab2a9eec11c17aa81826a29e6931016aae4088678f4", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_095-sd.png", + "sha256": "0c18efce6740cadf643e27edc3aa5fef00290f307c3a0de676e4c42feebfbfb2", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_096-hd.png", + "sha256": "b6fe77eabca57f6b87b129a6d19528b3eb8ff1f79b4c232dea6ed605311459df", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_096-sd.png", + "sha256": "0f07c9a380ead38f5b3b9062bed54d08bc848e1a144552ad085efb49f44e7018", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_097-hd.png", + "sha256": "d28cd99bdf93c66623c4dc513e0d19c8b77fae4da89d9f75c933ef646e927224", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_097-sd.png", + "sha256": "e7da1becf93da0e85eaf25ed05160afdf1dda4d2b5224bcba6f4d8ea114c41e1", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_098-hd.png", + "sha256": "7b4de32f10a6d04ccfc558357fbf2aa6ac8b6d3963275044654697883fa11455", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_098-sd.png", + "sha256": "81ff7eb575b3fca184979fc1b05c3315ce59fe24fe99ef4014241369a2dbd360", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_099-hd.png", + "sha256": "28a6ebf8fec10d918c59dc236ec9396f9552775215998dedc06a79006a9a561e", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_099-sd.png", + "sha256": "4bb8e8691c4a6ea03da2f9ba5d915b888127b0b0c45aa25466492df7de7c82b4", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_100-hd.png", + "sha256": "c0a19b6d9dba7a23a0a6d5aaba387e0ecd356b21f46189254b96b91e12ffe444", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_100-sd.png", + "sha256": "fdc025de602afa6235ad54c846c0fb3f65386690d6242aac3367717286b3bb28", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_101-hd.png", + "sha256": "c6fcea5aabcb092ccd882d570f479eff907ddd8e6bb82419e3545f313f794d5c", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_101-sd.png", + "sha256": "3c6a7c80831b99a01981e35161e0b1fcfe6a1caa1123bd7f9807c75ea278e038", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_102-hd.png", + "sha256": "4af6b4b9e9740581e32661a3db09c9ecc2dd58ae5363b52fbcf3f8af9e17766a", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_102-sd.png", + "sha256": "bed424aed0d6f28302cec291023bddc4d58e3c7a6d54fa84da264ab9c82426b8", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_103-hd.png", + "sha256": "098eb31f91a3b8ef60b7152dfa652f68b06fd99125122e9d67fff3f998008e76", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_103-sd.png", + "sha256": "e02a2bf98511137f22462b10e1606c012288abe0a2048d0bf1ebfb8936725275", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_104-hd.png", + "sha256": "3356c3717de6ee682c055d4e0a0fea372a873c9ae9b9018599292c0e608fe8a5", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_104-sd.png", + "sha256": "f25c928e0881018f7cd87d8f32bb58fc5d7949a731a5ea3bdc8c1b485211a20d", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_105-hd.png", + "sha256": "b476eb5e7a92418a28bc709a6cf0041733ff7d283d1331b548d9e5d9fb97a93e", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_105-sd.png", + "sha256": "527ef17913f5499d0a62a14da239183705c4879262e1a463ed54c5a142e490a7", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_106-hd.png", + "sha256": "a50856fb395101e57e8cfc25f19e1c565974c79f7f0ffc7c2e8bb456e3d1f1ea", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_106-sd.png", + "sha256": "b2b4f1aa44af56ea1cf8f1f40a4a002d3f43aad2f6b6cf574f1410f03382061d", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_107-hd.png", + "sha256": "ba3af5f38222093c2ecac238873e4ddecafbdcb86aacdcb243cf7b694dda2cbf", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_107-sd.png", + "sha256": "220960860c5f405bdf01e7a7b53acba7ab8876fc696b07a941ab0723491427f0", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_108-hd.png", + "sha256": "b7d406d43cdd4affc25d7181d3f5262c8f3003d61f7f2232dade82dc2d4dfeb5", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_108-sd.png", + "sha256": "4160a9f4258b6333b3cc6607ba0999da774cb32dbf248ebbd8ee04ed81288fce", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_109-hd.png", + "sha256": "66989d1ffbe7ad313741994a9f453b33c4fbbd77ebd033b0e8bfe70ae6aaf11d", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_109-sd.png", + "sha256": "28cd4c4399c90958f5e1aa5f2cf7fe4a311dfd48c762ee70390c24c81c04469f", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_110-hd.png", + "sha256": "c85055c3e469f109f0a9029e1587fd91d2f805ecc01c3406df252cb94d54d0ae", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_110-sd.png", + "sha256": "a84bc909dbbed8e2f3e51ddf77dcc3bda7e0aa67d1f48ff5e1f42453157acc06", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_111-hd.png", + "sha256": "80e334c5e9c66e16aebd212b1e273353f55de0342bbe37d8660c253278625a1c", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_111-sd.png", + "sha256": "ed5d0db41785f9784e8e19b73ecf5d39fabcca656b08409fb65fed2b877bdae4", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_112-hd.png", + "sha256": "7285f353669ff8960ce114303affcd684d20bf6c5c67589744c41ddda9f90ff9", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_112-sd.png", + "sha256": "ad17a86cc73c7ca9816e527987410e5fcefd2bac00cbc168aa3ecf4b82b9904e", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_113-hd.png", + "sha256": "fbc5c9759c454e889590d7dd30ea9aea804aae5b47f7eabd7cd0fd9a439baa4c", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_113-sd.png", + "sha256": "54c853e9545a783322dae47a97ce6f5d05bf260c54f2b9738ae963a881b5beb5", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_114-hd.png", + "sha256": "e3f712512be7df1714b6bcf93d29583e314cda051ed5f4fee796767824829a29", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_114-sd.png", + "sha256": "fa55751b625963eff03ed662a2f4b7c7f21e9de20725cfc7ded11283011755a2", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_115-hd.png", + "sha256": "1566d8db21fcf3931e38e87cf9570157a055bddf8c71a4a4bb78d3145e7a580a", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_115-sd.png", + "sha256": "08207773ab7916ea50aa38dc116a9ade40926b5c0f6254ef5c8eeb7cd12f78e8", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_116-hd.png", + "sha256": "98f0a4b12392d66e3bb23eae36b7b0a391c91dba3117c701943926bf4253d8f3", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_116-sd.png", + "sha256": "b12d703b7c8b765fdd301025dfcc370365b063bd17a8144e4e8ee816bf4ce4ba", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_117-hd.png", + "sha256": "c34660c539b5f4786228ba8deedce8ad6b6f97af7432613b0820b7e42f5dc4ea", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_117-sd.png", + "sha256": "e14d6f77fed1aaeae5b4002f6682b6f23a1dd3730ea845b8552fa2541043ae77", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_118-hd.png", + "sha256": "8289e93f786331c5850a4f954399800d4dc9b7badd89314b812029e56651d645", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_118-sd.png", + "sha256": "6e84b6dc323c82b832c40bcbbbfad2ea240ca9aaf1d5c8285b1ca9114f9ac9ff", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_119-hd.png", + "sha256": "2b895480bc5b7a2f24454b66ed3d1cb9d8dc4e889d55607364684c0c5dd8cfb6", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_119-sd.png", + "sha256": "230a159faaf2648fd93bd5b66549aa23f493932303f91b56848f9b0a546edd2d", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_120-hd.png", + "sha256": "b2e11a35946332563631038c66214470ff39a7bbb311ef614686c7b90cf0c506", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_120-sd.png", + "sha256": "5b0b838b634525dbc04e40ee2b5c417521c59033e787500975083803edf9e8d5", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_121-hd.png", + "sha256": "dd333a23f31cadf4bd7f02a45e6f7c8326eed5170c679c70f82734d2fa7087f3", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_121-sd.png", + "sha256": "79eca4bf3955d37848bb84198ee947928bfcd775244150ad38a3de4c112ec52c", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_122-hd.png", + "sha256": "86c9c324cb88bb6398820575d16dc4cd3409ae250df648bc154ddf65c63d3c35", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_122-sd.png", + "sha256": "adee09ee93999ab71be3a65c1a275dd56524e95eda7fd5ee22919b004a6389bd", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_123-hd.png", + "sha256": "179cfa7b2d454be1b7150f3e1c799ba469528a417b3b839756a5387546e24b30", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_123-sd.png", + "sha256": "bda509b1aa33d290149360237f23de4adba0c4a103de0df82d02358fc0bb417f", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_124-hd.png", + "sha256": "d9ec7943fa170803275a8a52b646958249a433261ac4188d5fc6e27435b15442", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_124-sd.png", + "sha256": "280f3cc0e5d1e2e4fb6b3ac8cba81ed2f809f5b203b6d5750b22db07d79a4a76", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_125-hd.png", + "sha256": "9ef1065bca0c7f5b8024e8eab5fefc216b828d20c57dab09edf96b428393fb4f", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_125-sd.png", + "sha256": "bf28e0b01228a63354e2660f34aca3a4d31c7d182c9d4dde23639da54308179c", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_126-hd.png", + "sha256": "093e7cb5827dcfb3b3a2d8d7ae1bfb54bd8c3fcd18a903e9a7ffef931aa3ffae", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_126-sd.png", + "sha256": "1278b77dbcd166a1d1bd811693b13fd6382f6e449e27c2729d199d67d1158def", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_127-hd.png", + "sha256": "5dea0649b489f496485d0c5866a4373373ead157fd9568fcef58009c1dc699be", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_127-sd.png", + "sha256": "850f65992bd361386830f3ef04be8363abc6bde749c18f27030dec2fadc78489", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_128-hd.png", + "sha256": "2453224f2d732fed4bf5f5f9b5cb4a0e4c8590e2f3f1d6711dc4f178498e5282", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_128-sd.png", + "sha256": "9c9381d2ca7232c65654d4e17c7108ce55bf86861a980777da43b52cc1041916", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_129-hd.png", + "sha256": "ebd4df0c18a3d42ba8d1f632901026fb8c58e84a531fe9d9f6fc1016c5a2bd4f", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_129-sd.png", + "sha256": "686570b76ba2dc2c947836b7f30e4391681edeaea1dbe0807c2bb66a182fb41b", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_130-hd.png", + "sha256": "bb560eb0afc0ce61e777b8eb21f5bbaf7e0799ac8cd97320dc215e6d629077a3", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_130-sd.png", + "sha256": "83b873750f1211d8cb521f574844e6bf3e236a311dad0210ecffea1390f1c987", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_131-hd.png", + "sha256": "415225e51481cef5ee34f06c2248bbec12e8b004664ee6523301fa3f3c631163", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_131-sd.png", + "sha256": "ca39d1a4ea6b270e7c21cdd255e87c46929ce671567f58af2b6c4d9361f9e85c", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_132-hd.png", + "sha256": "8e75279c84c888793b7faa1822958079cca8c528109ed9b3f0065b6650a2a378", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_132-sd.png", + "sha256": "01eeada49769b89c87d4c923baa7f77bd55e60b5662dac4c271da42f92db9dfb", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_133-hd.png", + "sha256": "191225e20e768d4f543398f19a1c4ac26a42b098beda1b392387ee6e0e1810f4", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_133-sd.png", + "sha256": "e4c7896f57b3baa3f3092598a1b5de5944b193e2161cf5663fcee67e062a90eb", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_134-hd.png", + "sha256": "5c1ddd9bf920d9002e597294b5cce923d0bd00ca83562c2d8c11b076ffe8c0b0", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_134-sd.png", + "sha256": "8b3a5f06fdd35a4bd7c7f71f84f26ca4cb93fd54ef9b13b12d081ecbc5d0df18", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_135-hd.png", + "sha256": "f54d53dbc429a7211e770410e40a7146dc477042fccd256a166fd352f1ff901f", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_135-sd.png", + "sha256": "9c1c381f8893e5515f836dcf8942d87a72c64e4a0b6f51f164251b1195876e2c", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_136-hd.png", + "sha256": "f722d78e26e223c15b7d3983163cf46db5281200dffaf715ba1fc07045f9f63e", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_136-sd.png", + "sha256": "2beb0ccc40cc04ca35f814a295ebfc12ef3d5a83b6980d260998da91f01eabad", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_137-hd.png", + "sha256": "53567b9dac2431dc212976a5894ace33dab42f7fe6eda7f6eec120136279d70d", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_137-sd.png", + "sha256": "f19b2b3e79b2823a62f59ad48bebb12ba22f232174268af9c436d0d7a7a4afc9", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_138-hd.png", + "sha256": "130c9f9ba3275ff092c9981c510afc7dda3dbcb740dde5d27346a12ed9d5f74b", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_138-sd.png", + "sha256": "8aaf9993eb6210dda643b1e450a94d9ad906ac16f1eccfd2713419ec5d2d596d", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_139-hd.png", + "sha256": "8802462973de233067c3002f02e31195d8426cbaa6976c2ce204742ef7b95045", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_139-sd.png", + "sha256": "8d68114edc9a6ae8bb246d3891f013b159fa69b1c496b6422eabaa1e74d658ec", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_140-hd.png", + "sha256": "b3469bdebf2cba97d8b96a00058537af0e04e8f18ab3885aab660f0cd831cff2", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_140-sd.png", + "sha256": "70dfb560e480b5cdde0c4eb5c5a869f4fd4630dc790edd189f7fd367d5d97fb3", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_141-hd.png", + "sha256": "3f960f865abb1233e442b322a3e57971cdf2a7978917ca35b795663075e9ad5b", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_141-sd.png", + "sha256": "cbfcec902a2060bf362cd0ee7504edee634158b4a355120d33668e42df1f1e8b", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_142-hd.png", + "sha256": "94f9fa006f19785eb0f24fec0060e2ecfbc45399c20610ffafc50d1554add027", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_142-sd.png", + "sha256": "1feac10e6544c55246b5b53d8ff3fc13eb27b5e7df2abd13e9086fc38bb25b84", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_143-hd.png", + "sha256": "4d9c2fa9432befe36d3ec997910813f9f780541b7bce01e6fd56b35bd6c233d8", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_143-sd.png", + "sha256": "fcee145ff3c4615ab2116a663128bac74a9c218f204ba7c3164381b2d2d979fa", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_144-hd.png", + "sha256": "942613eef24f2bb7679338c0fa257ee5152671f5835afcf8e712521de86b154c", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_144-sd.png", + "sha256": "ca4bc86e4a5fdbef92fec5ef9959fa1704efffb2e1a9023f533b66be194d80fb", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_145-hd.png", + "sha256": "d52a117945d99a3ee52885b075269fb6462eb198f14028682f0a99e53cd39186", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_145-sd.png", + "sha256": "d02ca68ad6ad26f4f84fefbeec1f0fe8b458062773af1d8ff562e9849aaf49a7", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_146-hd.png", + "sha256": "0ece022f6fc951547a85bcb19cee918d81ef62a6d7fb34ff31af7ddbeea2b6e3", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_146-sd.png", + "sha256": "ad5235b52f2a7921a42895f1d4d40ce439d82597d6ef971daf5168af273e18ad", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_147-hd.png", + "sha256": "798570a775997206e017c031ddf2ab13698fa7ca5cae276cfc7afa33e6003119", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_147-sd.png", + "sha256": "b5e13cffda8735c9fca342fc053fd26190327762cd6b3ab7d8411d7d29d40bf4", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_148-hd.png", + "sha256": "f2c740d0cf43a2f9a0898b228985054e31f553758e30e3e3639934a828865bae", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_148-sd.png", + "sha256": "07d4d0c735fa7e200aa652f088c35f18f89fe2cf5024a01d6c27e5962e7033b5", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_149-hd.png", + "sha256": "bbd050ff006dc1a63763ffbacf454347335f0e0a719886649ed7ba05fd275a54", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_149-sd.png", + "sha256": "f82ea6007faa9ae0fd17fe96ba7b09ebea8b9e0a24a96b0037acfe2850bae3da", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_150-hd.png", + "sha256": "2967a21c648641e3c9239f1c245d0e33e228c9d7bcff86129508404ba6fdbecc", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_150-sd.png", + "sha256": "66b41ad55f0cefdb72251d9d12a3c624adf3f1605a897559ea938abc0efcb88a", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_151-hd.png", + "sha256": "aaa1b5fbd99a6891299090b1ea3d5a6e2418fbd6824f579e276ddb22aa89e3c4", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_151-sd.png", + "sha256": "966f245b531b68958d2ae1d8d67369df2e79ed1a1c9f584a592a9097b169bce8", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_152-hd.png", + "sha256": "c47200f9d0814aba873f0b8d99432e5b437a5489a7528373f594776edf710e4a", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_152-sd.png", + "sha256": "cb47b713d05829f74652474da32f910974ec4310060155e8c043bff14ca49f9d", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_153-hd.png", + "sha256": "7e7efe3e57c76f757da385fa1814ca28567db71f8ead32eeb50db562101b3190", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_153-sd.png", + "sha256": "259d0dbac7be1a846eee280fa1a8b7316e82a998e2164785bc59df91b9c9d439", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_154-hd.png", + "sha256": "b8744af8de642a8e00165095cd81fce75ffa5faa92d3560a17f6a50917be007a", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_154-sd.png", + "sha256": "d00f04acc4aa49687781970b0e7fd97754b6cd63e697bba24fab2403313b1667", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_155-hd.png", + "sha256": "eac4df38b210e03f1b9bb040808a9467dec2ac75c75385776f56f870ff746b5c", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_155-sd.png", + "sha256": "00fa0e9d25c4134f7cab81a6de6ca6439f790b978df07d543f6a142da8ab7957", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_156-hd.png", + "sha256": "8ed3e7af120e33603f9a3e0b9dc9384477bba140be55f2214627dc2048c5ec2a", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_156-sd.png", + "sha256": "51f9780d0aa419b9fd12c8f0886187fed2d69885b6c2d05b73db3602702d0ab3", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_157-hd.png", + "sha256": "c9aa4bdb525d3d8450fa4441710cbeaf79b3385a9ff7a03bc252a291e9df0e55", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_157-sd.png", + "sha256": "e3a3e7d874897f2f9b339809016d8fb5d4d4830c69e74715f99b858b7cfe7f40", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_158-hd.png", + "sha256": "db306eb7d971fd82107e8967821e1d6f721478f8544149951a13191e6d37f054", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_158-sd.png", + "sha256": "2c841c53464b06411dd33515bc01e19eb9500d34c7efdff031344a2752335bf6", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_159-hd.png", + "sha256": "a5f7f9d27a856817861c0de0290df06b46214c648ee18712be28deca2cd82aaf", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_159-sd.png", + "sha256": "dcb3afddca6e62ccf967d353a5b414e9cd8399c1378746f90651cad85de44072", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_160-hd.png", + "sha256": "54386775bd83af74f12256057c25f036f6eb3247958dd931e0067fb9dc43f0d7", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_160-sd.png", + "sha256": "8721f93b3c9ddf1a9f2184ed5611013cb34f716aea28de8c1d40bcb6cd6f8b07", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_161-hd.png", + "sha256": "442b703a841c5d80752910baa975614086db7e3e54bc73d0e0d499fba834f236", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_161-sd.png", + "sha256": "28ce08dbf58f93f0a7ea439f2dfd58fe9e56c1c998be4fb7b8a5ecc0bf43a058", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_162-hd.png", + "sha256": "657c3197a18406f53ed35dbec843861f9d83d274b010c8b32e360bbaecaaf594", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_162-sd.png", + "sha256": "8736cc1150a8db80b48a5b0e93484ee2195d149cedb257adbf7ad7a145f2f081", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_163-hd.png", + "sha256": "25ac7cdb2809aacd5691b6b03bb24162c4723ba1de32ac4de464c1bb2dd78c96", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_163-sd.png", + "sha256": "f4b94efd3d3beb16bcc62111c0dbc6edd629d066c42da8870ad39429d646dbb7", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_164-hd.png", + "sha256": "916b356c54bd585b2f281e6b628836f4e7a7e7882c92baf81f4daa4c4a289e9e", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_164-sd.png", + "sha256": "2f2613536dc5188d12b496decfde6db38a4bc83c0c5fbf19a2648469188709ec", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_165-hd.png", + "sha256": "cd0ccd75bbde887810cfe3d6b919a88abdc4023034473e9dbd08c946d88f69da", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_165-sd.png", + "sha256": "648aae741ed0da4afdabb5a4dfbe861d4ab052213f2c7b019ce317d51b3ccc94", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_166-hd.png", + "sha256": "8369b946c377f17e50f4e7682ae6564a0404722b24dda597577f01303d157ed0", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_166-sd.png", + "sha256": "1fffd89ba77e17eb44224c9e19b7348ecc99eb548569606fd6be57927b336037", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_167-hd.png", + "sha256": "61630d9d045f4ece1b017c263cae80ffe3d29e7c1ca780284ce0019de1c43418", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_167-sd.png", + "sha256": "e9025174059c77379eec43b509d8e5b74db09c9a22231a48557f9bc05d6cb4d9", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_168-hd.png", + "sha256": "61c2d21b0f3403145a6c7adfaa1b3071660e3f3182533835a873c1f67cc42251", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_168-sd.png", + "sha256": "fb32968f818affeb1f2c80851e148999cfebb9889634c3bf06108ed6bf64a2a7", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_169-hd.png", + "sha256": "0ac836dd00d1098a44fc5646145dc6c8a29c0254cf28ccfeec4f7b66e96c0c7b", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_169-sd.png", + "sha256": "556a7bf4e77a7fba70de3864826581456b0aa56fa8d801919577947ba12c8738", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_170-hd.png", + "sha256": "e7c7cbf6b09cf4f73c8df36af2dac7882e514b7f24869b93aa71fb82ea831509", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_170-sd.png", + "sha256": "79a2a02e6c032fe0cacfcbc7e4011e0d9f9c2b548f90608bdfeec902b7ea9f02", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_171-hd.png", + "sha256": "cd8d10ed4b1deb4da2e5f80ed97a33fe11bf4cc9f0427eb09fe64302dc63ed63", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_171-sd.png", + "sha256": "f7818c2f704b0659813fa183ea2c1872051bac67e6db5a3a6d6ac4192c7ce722", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_172-hd.png", + "sha256": "ffe2daacee260cd93cd906ec6d763ba93fc0f3c58a3c412d7106d170ab6acd26", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_172-sd.png", + "sha256": "0b3985285bf0c985a56fcfe27529869adcff691c7b9390dffb6aa12e8372a9ec", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_173-hd.png", + "sha256": "383616407285e07a77c1530fa3cdb2f5ce4f3f951d1e802b7b6c786dd86bd912", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_173-sd.png", + "sha256": "807363c5638798b57c1ba69723b332375be115d13837aa8a4afc84f0a5b9b7b4", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_174-hd.png", + "sha256": "f3955e80f9b719296d46ec4092a01bfefeb34aaf4241c3db9455c7334d5f0b0e", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_174-sd.png", + "sha256": "f7da5691d638a663b09d5af1dfd404600a80cf6e3c854f98b2c762f9ad1e25cf", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_175-hd.png", + "sha256": "54a83c3e8338792f57b19d27228e2949ae13174c216331f939a71c58f1211ac4", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_175-sd.png", + "sha256": "63b1b9164777341c2e2f49a26b9401a65defa1166f62b1cac5a4395ea4f3dbe1", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_176-hd.png", + "sha256": "5ef3e327e64c0c3306965fa0f4fe3073ecff3be3dcb371af33164e8da7a4aa75", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_176-sd.png", + "sha256": "89631cf4fbda531f9beab71f2e7bd7ed6ac25e2a6bf553fcf32bd00a7cf62ecd", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_177-hd.png", + "sha256": "2a1eed5f13896cb473fa2d9f17c8cdd09c1c11b82dfa5d4a1a461b95370b6531", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_177-sd.png", + "sha256": "57273282bc24d15b4bccc94120ec2cf9c987dd2e57b6329f4f50ac128fbbc6cb", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_178-hd.png", + "sha256": "fef5008a3268a010d2be333ffb630fd86b93d8e7f35fb7329ec7528ca2ea1296", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_178-sd.png", + "sha256": "0b88f9c99a47e2840c2963164d66914dddbf9fe3412335ecd4cc40d335a78215", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_179-hd.png", + "sha256": "fc1fa646f22086dfa13facdffea0eedbc23ff0ea38b811f2ddceef3bdd6bc61d", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_179-sd.png", + "sha256": "46c04e333352ae8f4fd4b6192d967da775cb630ecdbc6a1216019a00686ac60e", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_180-hd.png", + "sha256": "3f2a17553b102b97fd8d9b29781f8df5055320fc254ae61093f6f974752d6ce3", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_180-sd.png", + "sha256": "318c4f23fcbaf3ea6a9ea3e12a3a06271f74dc11ae9f1d39901906731690fd91", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_181-hd.png", + "sha256": "375ed64e405f7c8dfc0ff9654af31f13971dd5654ae81379d6ff21b93d71a897", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_181-sd.png", + "sha256": "460acdb44f96350a9239d7be88a0774f46e569b3ba4e6ff9eabf63efbaa9f59a", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_182-hd.png", + "sha256": "a813c63c6a1fbb15b150b19d8f2e28a2774d14154145e39f0569e450e02e8593", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_182-sd.png", + "sha256": "0521bc82c80c89e199542030033dd77c21e9387088fdb35a9d59a2d917f726ab", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_183-hd.png", + "sha256": "3bf11f8a4917211cfbf27612d54fe9a02e5b799cd2548d60b71f6dea1e0d6553", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_183-sd.png", + "sha256": "cf20cf8f33a280db542c391ec88ac6948e068a3a6fc5cc17bfafeae207141f20", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_184-hd.png", + "sha256": "851643626384964c764c4e566123f301c0c5ef1cf130a9d940384ac0fd300ed7", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_184-sd.png", + "sha256": "8030551c570aff69e19f6171bc4f1c18d0b5a89d0fe61728057d67e9357d1681", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_185-hd.png", + "sha256": "bfbe54a0f1f15173d277089adb5aeda4f46bf5215af36dadb311d7d6e18be195", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_185-sd.png", + "sha256": "41bb4801e389e502afbda7fb53bbfc435cd0e61293badac183bb96abfd85313b", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_186-hd.png", + "sha256": "5333a19dbfabb1f855b15c17d92d79b3127810651f5dbf80c67f4d0aabafffa5", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_186-sd.png", + "sha256": "8d438264a830ce7acfa3e3a3e08e5355e8d0661bdf2cbf236be8737aa3d54720", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_187-hd.png", + "sha256": "a52877abf00109050151fb35f9d3fe9a7896b3ba87abc0781f89e11e15e53509", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_187-sd.png", + "sha256": "8844552fffe077f90aaf730f74bf12f0b3092e6945e15a924b4929ac2c37e61a", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_188-hd.png", + "sha256": "67fac7380b601b9154f79092f475a0ecf4d8802419e056805da0ed7ccef085a3", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_188-sd.png", + "sha256": "ee668dc2afc67601bc05a1ad431801630bd038d2a371fb3b03d6f20de5ef5f0b", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_189-hd.png", + "sha256": "1d97653fb7055a3cfab943757d25e78ec20c1c689535496498eca1fa1e3bb37b", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_189-sd.png", + "sha256": "44ec7dd0c017c334226eba5b8ff59197b60ab834df58d7f5b45cccfe6946a760", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_190-hd.png", + "sha256": "9b13354b2b20ae2d5b24f1ed4047cd6740125a6feef0b8bd88e6b4385be9ec03", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_190-sd.png", + "sha256": "1a0c3c169fc6f0cfef995fd7dd80b651d3f3d54b513ee632f53989077c25b911", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_191-hd.png", + "sha256": "e26bb6db96d004bc1e13a333e3eef058d0c406026f1afa69506b143ae04b4f5c", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_191-sd.png", + "sha256": "2bf7fdae4fd0cb8d7e97ad3cd6cb1038571f6058b65620971115d2fd2b75fbbc", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_192-hd.png", + "sha256": "e813dbc5f348f7c406621514403f7bc35e4a88d2b0431677f36faa461d507377", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_192-sd.png", + "sha256": "ce675d3132395edc3b688116471263daf68d5044e8cf7a761745536577b63707", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_193-hd.png", + "sha256": "928de66a4af75c69b450960c6de9f589620794471f0642aaf1ac3a49a8c6fa16", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_193-sd.png", + "sha256": "f6033c4bf8fc393110d1b28a2ed18ab8ee5a8b00502672330ac623a364c906ec", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_194-hd.png", + "sha256": "f5d3cd5827139eff3a1cbcf527352c9368c519b7c0086679e65b59cb4c8121ae", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_194-sd.png", + "sha256": "a584e9eca77661079c4c274beb685c90c4c15a3dccf2a7a50944fc051d135a8b", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_195-hd.png", + "sha256": "42f15d14f6e8571d9ebf92934d790214cfee3a386f9f3da09730224754599840", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_195-sd.png", + "sha256": "24b86896c2ff860dca8a2595f8198229c03c20205858e8c48d6802fde655d7b8", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_196-hd.png", + "sha256": "8030246562465b5a53856b07ebabacb3f59314aed66f659ef19b1a5e40fcd54e", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_196-sd.png", + "sha256": "6ea85ff8ec641478b34867f60c3c1d16dab3824a54fcf2a93105610d0191047b", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_197-hd.png", + "sha256": "0c39e9dc8b4806d6c23b26d1ae608a2301d944f2f2a793764939016f7fe30363", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_197-sd.png", + "sha256": "72ac0c1039ac64da7563a3f330b9681c7de7b97f635d371df07bf0577a6a4442", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_198-hd.png", + "sha256": "c300f935696c088dad5ebaa5f3f7f7ee47e9536986e692a473bffe6f8dd70396", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_198-sd.png", + "sha256": "5375245da9bce2afec1fc599531e775a126cc56b5c9a5af105f42c77e9a0b56c", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_199-hd.png", + "sha256": "fc2afcabeadafaf159bb0d417923a3874056d042dfb6905e63085bee73dde35b", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_199-sd.png", + "sha256": "aa55d5065ebde5492d558709ab31f08c720405176a7c8956884aba5810f30736", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_200-hd.png", + "sha256": "0607bcb4460838633bd0c29191cacf48c5d02fdfe8782efac2558fa3c519058c", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_200-sd.png", + "sha256": "88d38e6ec4b4d28d91b4432d79104348d1be06cff71c66fd443cc71d12bf298a", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_201-hd.png", + "sha256": "f001b4bda81095c20fbfe8f200c3791091df88046ae8062136d0e387d0137c30", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_201-sd.png", + "sha256": "3b49ee6242f597a39733909e920d33b4195cde09c4fd9a7b28e53cfaa33e36a0", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_202-hd.png", + "sha256": "41a191f2b377147b382a6588c728c05328d95bb41c6ac110a4e8045357e47fd7", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_202-sd.png", + "sha256": "a7254b01c49b88f234e203560e89335e97b9878fcfb27ad0fc5bf4e20e5aedf1", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_203-hd.png", + "sha256": "055d152b7c4a0b7e8c33d090ae2c65ee7e0a107307f4498f7feeabc00958b9dd", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_203-sd.png", + "sha256": "21568c47fde1a773587580b4147a194396baf40a38495bb55af59e64bd0a6089", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_204-hd.png", + "sha256": "970227a650c84cd3a4669f570c40b43e2cf197349471ca69b40c77e1c798a632", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_204-sd.png", + "sha256": "cbcdd5b68ca4ff83678188b42a30ac7d0e04a50984a815f07214c0a92bda258e", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_205-hd.png", + "sha256": "c3ed3761c215b8e60ac1c505c2c98f72c418e6111f3f34672ba5bc24b413eda6", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_205-sd.png", + "sha256": "f5fd52cd30ae4c2b388f363b54b8528b097c8b9e45c828eed5750ba5c00bf465", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_206-hd.png", + "sha256": "477981ca24782ef12b730d93e05d4a9d1a9e1d56208cf2b1bc76459b352c652a", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_206-sd.png", + "sha256": "d1aafdc494e837cf8d8d04abe611dec852d4a2f530f89dcb1c3cc9c7c9e488eb", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_207-hd.png", + "sha256": "9bf955295d4ff35b6f24f0e6a05e09f93bd22be0ed66a9de29fd189070967466", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_207-sd.png", + "sha256": "1b2c6affb075e982a3e92af741da59810582b5791c3fc33f86680593d9c77ea3", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_208-hd.png", + "sha256": "a45f1b137bfb3c2e229a9bdbbc3fb930478643a387ef9a7e80d988ebb75f3b63", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_208-sd.png", + "sha256": "04f5ad6d2dbcb777aea954b18dc1d19c765f7ee098288fbed17085e7ef94488e", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_209-hd.png", + "sha256": "a11a8cfeed72f2b9efee41d72145536028d03f45352d4eee67a8b2e8827f124f", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_209-sd.png", + "sha256": "071b17349ad556965f40bfa25f780c13911816859f3b026b9c3545b4126d34a9", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_210-hd.png", + "sha256": "0ed0334304caf9aecd927c0295751694c1da6e8ce2e1aaa4ab39299aa4ac2f0d", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_210-sd.png", + "sha256": "d78df8b06021376f2cb335000c6a84fd2404b64de3b796b4fd8d2e5a0975caa7", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_211-hd.png", + "sha256": "fcc467957850e0ac44e07758945d5d78ad2ffe40057d916432ad2eac12aa5d86", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_211-sd.png", + "sha256": "6121c7aa1c15a3b6db7bf341cb3bd82deba0dadec1dd23e59a0958f2512861cf", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_212-hd.png", + "sha256": "1e9b388b88a2cd8980ab26b47d8cabc7b4b8fcfea63416d876744b3ad6a9b80d", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_212-sd.png", + "sha256": "f72bf5a8aa4137e55ace56be8f2d5cbb027cbc89c78e8975044eb64355a1a71b", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_213-hd.png", + "sha256": "ffea5344a833b06cffe538155b3805c96a8373dbff29696aff5374f5b087c96f", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_213-sd.png", + "sha256": "2d07585dab45a2089980661ff691d55dc8ea8e7e18c45cc6e73671f7dd43c368", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_214-hd.png", + "sha256": "20ef65e3967f0beffadcd4ef282261e973f331cf18960387cd5371aa1de28fc6", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_214-sd.png", + "sha256": "f52467b2304fe3f5b892c37477842f73f73e9fca6224c33b7f5649b3794337e0", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_215-hd.png", + "sha256": "88275b198b286889255885fa894b4005bebb77dcdeeac392d86d5889917cabe5", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_215-sd.png", + "sha256": "07bcf34fa8551a2fd3c08db8482d0b3564157457ad7e3beb9701633e7b0801cc", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_216-hd.png", + "sha256": "2e28c142ed1cc269166a74c207df747aca02a59606098d828fb3209c03eac884", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_216-sd.png", + "sha256": "8366398b1dbc65d0780e2790a6183b12c2f30d9764fdafb9b8dd06e6da53c86c", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_217-hd.png", + "sha256": "d13ba5fcfd10dd0dd9352862ca2bde75f153bb9a7f3055c8f503ee6321286f87", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_217-sd.png", + "sha256": "b292bd250f02d7c7fdea6e7cb952bc5f23ab7f8278c29608f8b3ce9c35b9de41", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_218-hd.png", + "sha256": "7d57e80a896743b6c2f2de581080ed35f5e02f48119bf447d98644645aed38d3", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_218-sd.png", + "sha256": "0d2737551ea211b2eca8f3bf7d263f919e6e7097d705409a6b6e6476593884ec", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_219-hd.png", + "sha256": "85b9b596ad2b716d94090c6c2de16da9e991508de0be724b811c7993c094e397", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_219-sd.png", + "sha256": "1bf38b8796d5f2824610ad43455afe1fa6df464c5c08e1d82ad81903fc2d7738", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_220-hd.png", + "sha256": "81641fb3103e2746598a48622b3721bbaeb9afded16750b881e2eb9aa1b21447", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_220-sd.png", + "sha256": "31dcab7053c90cea6dc96459a08eb16b1e7e584ee15adb7b1a0d6bdb37b7e33e", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_221-hd.png", + "sha256": "349a5677b0f87d76b323b971bb352881c24a32c70367d66609ad8e571d13cd37", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_221-sd.png", + "sha256": "ea7e7615d368b6237f264e6b5ad91147e1e766f0f30e3c9d06a930ce68a7a106", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_222-hd.png", + "sha256": "d8ef8e667c375ab397a60bbf00c51fb7e4742152631490e0a4d07403b429e672", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_222-sd.png", + "sha256": "8cb68bc08e3b1cefedb451faa3c88a98fc53ea51a0433d7093af493b78325637", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_223-hd.png", + "sha256": "eaade61379f6f59638f9ef512be26e91c5640dd9e0868a20ae66945949e23dbe", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_223-sd.png", + "sha256": "9aefae801fb5d0d41c49f7a67aa9986a458a60a8f5d0d9c41b39d2f2180dde0d", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_224-hd.png", + "sha256": "85c404719576b6dcbb4785a69970fd847479ec74cc8692ccb1817510669c9498", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_224-sd.png", + "sha256": "58dcfb1100d3f277ca00c6d9a6009ee1a60841471421b72561e67e7882bd0b4f", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_225-hd.png", + "sha256": "b38b67e02da41efb47e2200faa92bb344746e885a648f90664c20c5f15cf36ae", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_225-sd.png", + "sha256": "f4460fb18f7f12907cfd337ba4b281dfb09e88598edcb93f06737f94fd6a7188", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_226-hd.png", + "sha256": "3033e70d0df6afccf28362b8170694f410ad7e800fb096242f88285302a4342f", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_226-sd.png", + "sha256": "f09a38298a3825bdfb32ee60f25fef96f312c28d6ddd92c2c41ad259d6130869", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_227-hd.png", + "sha256": "1d34952e6157197dca307bc95ad200cd4bf0ff2ef9319b22cf2d29f7f5bb27e2", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_227-sd.png", + "sha256": "5a1d90d632efec8f5db219ab79ded6c35103655629628bf3fb1d1a578e93a87b", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_228-hd.png", + "sha256": "0c4651fcc439ff4499e29a4d58d2cae3da0f1550963d576cfad8a3eb5071a982", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_228-sd.png", + "sha256": "2dcd3c14a73d15518e5e02667b81ad9511caa1b69c12f5b02f2643230207459c", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_229-hd.png", + "sha256": "f8330ac3c2ee5ba1fb218c2576f7d6a4218dd122830b01233733ae1bb6f3c570", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_229-sd.png", + "sha256": "38a05c40565eb6bb58620fde92d55a2f21992a280fcaae6e4305051dd9cd445f", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_230-hd.png", + "sha256": "0380e72ee03baec7d98e8a44ff93fa695113ae5f8e1b582cde8857f786beb8ec", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_230-sd.png", + "sha256": "870c77c967bd33ac43fb819f470589189f74f7e74de9e67d5ef8b00990d4f523", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_231-hd.png", + "sha256": "91ea18a6f0efcb7fe8abe5643387394172c4e1de8b09525a595dd834fde664a1", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_231-sd.png", + "sha256": "eec7232ae608b400c7bc1dbff6e1abe852cfe28648d61837595a181abf2b3569", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_232-hd.png", + "sha256": "8b9d0378a4eda7c2844dc18392bb611d917676ace069990e252c83396c4a689d", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_232-sd.png", + "sha256": "c9303b24125d4390d694351db6584c7989c42a50deec901554d0e69a5c617cad", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_233-hd.png", + "sha256": "6f4562caba748bf93eb74ae8817f29b354ee9f606104acffd990ec714220a76a", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_233-sd.png", + "sha256": "e5e2619a2cf903032252edbae9af150d5aa2a490133a987339a04073430ede45", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_234-hd.png", + "sha256": "2aff113282a96c9a33e7fa65bc2590b9ae92a69cc234360fdc1f018c544d45dd", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_234-sd.png", + "sha256": "b805f0c636969288665ec828308383e2190687d0fb1aa03699a280fc0977fdd3", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_235-hd.png", + "sha256": "3731e808daca440a54013a4a2368bb4a36de29a34be8c0649dc5ed6620871860", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_235-sd.png", + "sha256": "a4acab6bb43e35f82af780d637f9e963fc8476cc8c4196b86768c8b7eab5fee5", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_236-hd.png", + "sha256": "b4b1c5d7c73d4e2ef72897258a863b6ee5f7a8d665be1117ab0c5f7ede87ccbc", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_236-sd.png", + "sha256": "78c6fdbf65bfcada7effd7f873c1656603b8f2d2ab9f7a461d4f017f57230220", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_237-hd.png", + "sha256": "e76d3b73115e2e941437c4ef237bf8fbe11f50bdcf59022cde2e3863ab950e03", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_237-sd.png", + "sha256": "bcf42f1e0b240e0b6751ff91f3718c2a107aa9b850346b6a9b5684798fb5fa39", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_238-hd.png", + "sha256": "6b32e26307f6673f5fec231b3e589595f8102f7cffa18662ad060300543f949f", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_238-sd.png", + "sha256": "202b9ee67da12180645501ecbb3c0e7af855df338ad779351db5132ed3386f81", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_239-hd.png", + "sha256": "ebb0c59114b3b9dff83c8a2bf719d80df5059acc37017e18462480f3731e267e", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_239-sd.png", + "sha256": "776b8d09acbd24373158680107d3a43f7974254dc17683f7f68f3da0a5cde8a5", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_240-hd.png", + "sha256": "c56c076c3cd25c962f3ab8ee9a503a563b66ac869956d7c9b13ad2a8bb035b20", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_240-sd.png", + "sha256": "5a17360a63973fe15a109d5a8390bf16629be4c2ff9604aa3bf6c83af585681a", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_241-hd.png", + "sha256": "b8e6918e268d6882432d0ae94e2278019d26138bab66b84d6e14bb71f3cfa04d", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_241-sd.png", + "sha256": "1c4b744e031309123697d29e2666a82c721ef65605a64b33843935ad343c381f", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_242-hd.png", + "sha256": "2f0a7c8dc791cbbab201708e7d6a53494faf659bf4585e6487a2de8f83d3a1e0", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_242-sd.png", + "sha256": "24c132720de6f9c15b93c8649177de44f6d8c1a564c94515f5cc3cf01308ca75", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_243-hd.png", + "sha256": "60b6f1db8f52734dfd44b54d90dbf4c14ba0219350570e651a25318cabf5ce1d", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_243-sd.png", + "sha256": "ee0539f56af170a801d2e7b968463d874e3d17eca85d1204beba5c2e0beb91d9", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_244-hd.png", + "sha256": "3b360bb9ebd8bdbd401b65496747427936f669efb6b1853c12d4affd427ed551", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_244-sd.png", + "sha256": "0d52e26d1b5df316de4837ea0e53185b6c230beb16570b7fcc653d2b7e34dbd7", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_245-hd.png", + "sha256": "987123418e910a55b86a1b1232429c932eee4e125affbccc28775c51da2495dc", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_245-sd.png", + "sha256": "22b4d5c22e8b795fef9d9994dece40b1b37b429816f1831d49394b4725e6bebb", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_246-hd.png", + "sha256": "f7f211318e3a5af99e12e11737520a6a81f78e33eaeddb3b4e84fc9881f897bb", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_246-sd.png", + "sha256": "555f50d5a9f3805eba1c69f27b10a965a9dcc5f0e93cbf09ad028a5d060aea93", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_247-hd.png", + "sha256": "82ef11e4fd7caabaedc3369eb88d25f777b02f934c22a76c113553e860f5ddc1", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_247-sd.png", + "sha256": "93bbbf90c117b07e0bc8b2d47e2d763b6135b076b6a673af2ba31e280afe9133", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_248-hd.png", + "sha256": "717ee956c3c1f25e018cf6e381358fbb2ff10f96996678d404855f0aeeb0f6cb", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_248-sd.png", + "sha256": "943353979251217380029fb19019d28354bcbb24d497c238b98fc36909d88152", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_249-hd.png", + "sha256": "6189c0f73b0b24a6dfeef7e2c3b8a0d49a9bc0675d9556efcbd31429f271b6d4", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_249-sd.png", + "sha256": "3d75cd2d9bf22a62e4fd40ff20d5945267f4edbdb5da771b113ec5e168ab212a", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_250-hd.png", + "sha256": "e833ba50f1f9a6d13bd71a5ebd77ecbd74c63b195a792f1376b51078849f48aa", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_250-sd.png", + "sha256": "2f358b8ef9ac388f2b33da4ae7c4253ea4f4a06ad236ac9a5867a6942e9bf568", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_251-hd.png", + "sha256": "d779de8f6ec91bf799738096920119c84b84405226cfeb0dbc5d5ebaa386ce88", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_251-sd.png", + "sha256": "1106a7b955a9dfd8ba93ce9342673af22f09aa9d4cd279223c676c18070e9a0f", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_252-hd.png", + "sha256": "b9f8a4b3ae5ce0ddad05bde8d130f2865f09a7f6506f4a7af4f6027ec70e8eb4", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_252-sd.png", + "sha256": "fff66d12aed60c72b1e42ca0ffd2a36b7bc3acb598b81ea0af65cc444f6c8dd3", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_253-hd.png", + "sha256": "caef80c8c3a17850f9334b1ab517a13f1802dedbaf46a45719cf9467052a3bcc", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_253-sd.png", + "sha256": "dff00da70e3dbb90ab8b6950ca624474e66f6aa3ab577077d000273c42c61ac7", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_254-hd.png", + "sha256": "7024be924e964a680d06e3a76c74d54d740374b39fd0c6eeb1f2d65cffaeeda0", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_254-sd.png", + "sha256": "1289c0d305408cc1cb132ce1ceaf989fdc0273a3caa12c6e0eba49d51680c5af", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_255-hd.png", + "sha256": "1a2a114354d186966c4291c64ff0492b6a66f613163ec2ea87a4fab75027dc90", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_255-sd.png", + "sha256": "dbcc4168aa7f01b0fd464d2158fabf6c6b00f7f5236b34863581d061aabf5b28", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_256-hd.png", + "sha256": "b8361bb8bcf42d722eb0b5aebc89d2e4b7ee136ba30c4fe2d690e084deb52cd2", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_256-sd.png", + "sha256": "f4f9f53fd22cd6d0fcddb199121b23600fb75e922d323b19dcb6fdc7e7c7dd68", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_257-hd.png", + "sha256": "8fd81ed339465267deb4fdd09ab6d3945e981d1d2995186c5d22fd348455e664", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_257-sd.png", + "sha256": "7fc9d039197186e0f94fe2460458cc6ac6e2bbd9ca5b4e872e520f6f57c57dda", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_258-hd.png", + "sha256": "93e1fc287f6db2906dd78dec7a8464ff2d8ecf7199f35a94631c88d3b57e11dc", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_258-sd.png", + "sha256": "83f5f66a5c6293926f3b7a8c7fbbf8fee23fa6ba2cf12d988419ad2ccf4dc80f", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_259-hd.png", + "sha256": "073624a5d68fa19157af1974830982d05d2b618236ac360bc1df7defb0a04457", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_259-sd.png", + "sha256": "12fe0c6aaa805bd8648a48aa173a768961bae83202f5e93c55126ec5d49f56cc", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_260-hd.png", + "sha256": "fdeb9004fe5edec02f21014750bb25e91ef6fc47d9ce92165e6273540e57ed3a", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_260-sd.png", + "sha256": "194daba7f26e47ccac72e29038aeec5d121de2819222fe4a7120a9c8a3f02717", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_261-hd.png", + "sha256": "8ab1cef57b0039f69a05745fed14f1168aa6483a90edabf19625f19ec06e0eb1", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_261-sd.png", + "sha256": "59773484f04136f474cf166835743ce330bd914417d6794b5ebf213b6d067c62", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_262-hd.png", + "sha256": "8875a4caf68ea210dc746d5d6cb64ae8d57ebd8d4bb228d5185c95974f1f7cf6", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_262-sd.png", + "sha256": "45b2083e7440870aababaa7ebfc008ca7b087abd5048b4722180d13aad6eecf5", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_263-hd.png", + "sha256": "63174539ddcad7a6c8c23f24c2e9b78ed043bfa5fbf9c6b7c6d8da78dd934545", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_263-sd.png", + "sha256": "5af549c8b1761d6f4468a130d0f22a1cb6bb67d9bc91c373676cf6583eb561c6", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_264-hd.png", + "sha256": "9b749d15f8ab9d38dd531bf8e642bef806714ad78ac5738f229b328230f5ac69", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_264-sd.png", + "sha256": "1684fd3fa6c571d148ba9309ec8156fe2ed5ed880e326b4b13e2e800efd80cef", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_265-hd.png", + "sha256": "4d264a5de985bf66d4e49de0effacf1ab8e8b7a10915e35c4131af3f1c938a46", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_265-sd.png", + "sha256": "0f0e3d526709c8d3c3b5577d1c78dcec8c639770dc1a293475597ad2871e6620", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_266-hd.png", + "sha256": "da4ece07800d5d46aa2a4087a973606b9089bea4c4b7977ba40704b2391986c9", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_266-sd.png", + "sha256": "d6687d293286b084039a0fe39820a2aa748e6e38874a04c0f79a9f9d422fd9d2", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_267-hd.png", + "sha256": "56930a82caf88464d4c1077e407704f51e5ba0c277eb40e9ad717f528b7d7bbd", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_267-sd.png", + "sha256": "3ad0b2db0b8fc9efd87c831fc2707bf4d3d7ed83af2f6384be466a0ad5036f0c", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_268-hd.png", + "sha256": "4f7dc9e15f3e6c9c577fa6436bf64165e175e605c094a2d9529450263221852f", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_268-sd.png", + "sha256": "9febf8ce5d4f77f9fe427cbbcb1f9f4494664832211d386917bc51afef0aa72a", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_269-hd.png", + "sha256": "28586333458b249b9d1136fcf6afd75aa5621d44cde9c8f9abbe6ddd5e87508a", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_269-sd.png", + "sha256": "b921a895b9658e355148400af6f9c1e6c2cdec4e0ef7e7f9adeab56abcd38a28", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_270-hd.png", + "sha256": "d41816ded39d651a484719014689e5361a427c75d7acdda64134439b4d6ccf14", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_270-sd.png", + "sha256": "4858f96ccc9af673069309418286f83ea5b54ed7f0243fc06ffdb584f6f69c40", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_271-hd.png", + "sha256": "ab4c8ab3fa5cfe9fdc0f168054f6de37485fe24617eb5c8eb89859b4be076359", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_271-sd.png", + "sha256": "98da7ee97cecd2092150fef2fd7dd8a056a036c66456d44ff424e04026a2776a", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_272-hd.png", + "sha256": "695861c1b983c52ab9a4a4109fd0ef1501cd3c59f891e6001ea10770c562375d", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_272-sd.png", + "sha256": "b6f101c2bf4552fb1ecdd5f72e1b8bd5dc0860155501b927ed71d798ad007786", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_273-hd.png", + "sha256": "c13dc696705805508b7fa9910498d54d3d54c31f7449c428f57fbcb46bab1594", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_273-sd.png", + "sha256": "a017556c51aa40470d822e476a8005fbedbbe7a197b4b03bd3cfc5560d589fac", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_274-hd.png", + "sha256": "9757b98533aeb8bf3499d66bca4a542490820c3c80f5dd797f5dc09abf07af4f", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_274-sd.png", + "sha256": "674c0f7b13df56d56e7b5722ba41dd7f84bccdc5a4f0b8704402e7c04365aa95", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_275-hd.png", + "sha256": "43bea1fd55b195880fe539a7601c4c55a03d4beaac599bfa7caafe0586e556e1", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_275-sd.png", + "sha256": "3ae12746c281d655d4a8f34c5757b6fbab346d3f0a6939b8554eb723b9f4d43b", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_276-hd.png", + "sha256": "e8fadd0cdf800da5c93db7bed84886f2f3b1c7a213811129de92c42082dd44bb", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_276-sd.png", + "sha256": "6d5a06e38a6d426d3113936b9c2ec3d17d23aad35da464b527ee2b43b2e8df70", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_277-hd.png", + "sha256": "77e2f7b805aa3b976c6ab7b7e973d88af17628f886e865d00191f9e434cd14b9", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_277-sd.png", + "sha256": "fa3783c06631783a0d1e00e4e6618b6d162e9190d407fddac53232ffaece60ad", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_278-hd.png", + "sha256": "6d60c800e3889f221b426a607b04539b652e2fa6380120ecb8bd61f1d4c6369f", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_278-sd.png", + "sha256": "28ffcb22bb284af93c3bb60a24462bc0299bd1604d8014705b9af72c0eada5d4", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_279-hd.png", + "sha256": "63a273e01b0f837dfa32189d319a8bd0278d642438539a9bc9581aa6c9c4a248", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_279-sd.png", + "sha256": "c648ee5bc2323356c4bd237814e0fab6bffd2c64bcd6f5812e3ccc2bd0dd5a68", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_280-hd.png", + "sha256": "e3e2ea6d7df157cd149fb598f28f7cfb984565bda36fa12ef2a6819a0930e1b2", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_280-sd.png", + "sha256": "ac5ae40294045621b35f12ea7a5b148b512c9f8a576048ac6e9cc77abd40aba6", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_281-hd.png", + "sha256": "a78589d58f40b82cae540e5a6eeafc7a085114bc7adebbd21dc7e884de77ae41", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_281-sd.png", + "sha256": "762191d94407068a823ce0f9083d83b24bc713e63d19b85b387079f416372971", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_282-hd.png", + "sha256": "830c572a39566a0b0e763108236531cd728cf1c0784cb082f8c2bfb700c9aad9", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_282-sd.png", + "sha256": "c5e514d83a991f7ad8b100e4b2ca5561c33589fcd70f94ea443aa248c9e7f590", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_283-hd.png", + "sha256": "130c80c921baaaa28611c82ce1113c0ef0b0a68eb45e9a2d74c2c6184a2c1f78", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_283-sd.png", + "sha256": "e6e5ffa56b31364fa10d9c6dac95756cf9f29dc80316f9d814436056207cfeed", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_284-hd.png", + "sha256": "cec47ef3ad5ad2359762e5da298f5d9572c3e7f31ea583d22223967b88d00131", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_284-sd.png", + "sha256": "1cf0603d0770d03244d360731192c508a21fa767272cefeaee150e938b204e2f", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_285-hd.png", + "sha256": "57a090c4317db1b2854715c5fa23eaec89cb286f32d6796b5356d0d423ffc8a4", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_285-sd.png", + "sha256": "0060e18f583cd3c42af4b4c3afcbad300407b8e977d692bd501a714e56868e49", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_286-hd.png", + "sha256": "14087feba3b6f8215f49a2859d0e508407f6d7a5c1e23b114d7e1339ceaa714b", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_286-sd.png", + "sha256": "c60bf56e7467cc1a807350d50aa4ae245451f66a130d8a216ef9c394b269271f", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_287-hd.png", + "sha256": "17c38b39cb0c81a5e8721684aa9d74cc4388b03ae1c9aafc78860abb96901b31", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_287-sd.png", + "sha256": "7a74397a7b5900c584fa9355f446c576f8524d0734cf51c454feaf88825d495c", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_288-hd.png", + "sha256": "1b6325c1cd048d16b3130bec9661f8680b79618b143b022de1b86c40e5d9edd6", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_288-sd.png", + "sha256": "5554569a5b5b68e09b27d395e5f88e3ddc933e767cb69f34bc84186347856dbc", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_289-hd.png", + "sha256": "93e9998e01514c9e6408ea278162723330180031601a3988c0333247d883877f", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_289-sd.png", + "sha256": "da4ae085a836b62613c98d3beba99bbdb5c07cc093f0bcf634ad1372738526c5", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_290-hd.png", + "sha256": "9e4ab30f0bf5f8dc0f3fce7bbf099623d2092daec4e2b83b74af38eee1055a29", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_290-sd.png", + "sha256": "490cc54c4459fd14649879dc3dbfca6dd432c5fc55a36db7db25b4e22114ea3a", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_291-hd.png", + "sha256": "1331bc33b1a2ee4fadbf502549eda26cbc94fea79a8948cb80887988dc7d978a", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_291-sd.png", + "sha256": "3539bc82753b84e9e467a2cf3cd7fd3d3812148a785e2ebfd572f177d71ee22f", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_292-hd.png", + "sha256": "46f41a2b0cbfe3cfa0a95f058858ee775a953d3725f11dc655e1d20f908183c4", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_292-sd.png", + "sha256": "fb0a3e7a57e8767e59ac577e5302eed14ca49ee4bfdf4c78534999775f26fd84", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_293-hd.png", + "sha256": "f82b7a936987bf0a0db9f33ab0129eefa5ca7557b883b0cf5c17884878398020", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_293-sd.png", + "sha256": "fd7caee61b2c193e4aa85cbccd146cdeb412e930047939e105fdd1e816ab9904", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_294-hd.png", + "sha256": "3ea901f6880f59a00469de5f1bae16f47ef0b9380a1ff3545a26d0034bcddd03", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_294-sd.png", + "sha256": "524769b703aa918d660784fed59abca913652425235615fadfe9a586cc2dd523", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_295-hd.png", + "sha256": "e9ff4e9d9a07fb90d31a9a5944d8ab9599c2a397eaee9e87551fed522fd6bb7a", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_295-sd.png", + "sha256": "63ffe31615ad6b4692b4d2cec5d09892eb0de3a23210b84bdfab53b70bd98054", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_296-hd.png", + "sha256": "b7e9ff8421e4fd8cce50ed921ca1d8e839cf0662dd54e6967abe2dcd28e58ac5", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_296-sd.png", + "sha256": "a21e0bd1b3acf8e113274142e7615273f21d2de07fff2c9c882b22871f70e33d", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_297-hd.png", + "sha256": "98496b4c3edc5d1a575be5540ed346e080157159f816e50c36cdc1e43043980f", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_297-sd.png", + "sha256": "de2b867e388534cec513e0017a2c3d2fb38c49204cefa85c123c5d1bf5e27f0a", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_298-hd.png", + "sha256": "90cc64c4c735c7ad6be1f5c4ddfe2eb953dc35923f3d0b21a9597aa58444f6b9", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_298-sd.png", + "sha256": "c91095d0b03a216a44e1a0399629eac91f18a4f19386ed59efd785d2607ab00d", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_299-hd.png", + "sha256": "4d09f36338ba330728cdb0013f96d117b004c065f97009d9954529fdbbba0fe4", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_299-sd.png", + "sha256": "04632fd843ced874786303fdbccf38c3777cd0523d7aad5d3e4df0d4da8ca1e1", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_300-hd.png", + "sha256": "ab5a9e9d0d2cd0d6871afcb5b79b1142d259fd5be6bb52d5c2c3c6baf0bb1a0b", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_300-sd.png", + "sha256": "d4404cba8d4f5308a6f94db152f3590ae4d387f73eea85365a02d4a962f7d1a8", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_301-hd.png", + "sha256": "ffa4e6b766ff44294f1a2a3a752c3a96f616f8c46d52debc72289b8ad6884572", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_301-sd.png", + "sha256": "2e1ff7eb2c3ab0eb58a63512ec8a86d69822498403ca937bf0dc0350c7152cfd", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_302-hd.png", + "sha256": "a2085565929c7278ad122e9245aa5a34ba872b80e556d71289bf8f2cf38491ec", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_302-sd.png", + "sha256": "5eb91f33497599de62457e7e3e186225df2b6c356f4ad8b82e40db0acf73419a", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_303-hd.png", + "sha256": "9a892d856c3a0ae93c48b404b0ff6f13fc7df3f858cd6140963911469d33ab7a", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_303-sd.png", + "sha256": "d656381f43f75eaa797a59c90fb5b96bbdf3ef3e9171eb55f05afead599eb410", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_304-hd.png", + "sha256": "2739e294801432872ecaf73dfa6893312a31e267c113731723b47c150cdc8e96", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_304-sd.png", + "sha256": "bb1d281e4f82b13b3c78a7eb92c26a79571aad0e0758f6fd330ddede0672365e", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_305-hd.png", + "sha256": "781724ec599ddbcc59c918eb3f3d5e966ea7a5b34987cfa5d75a69fd70504624", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_305-sd.png", + "sha256": "90044cfad1135bee32ad70c106b24c634c97a89b4107e86627065918b39310a7", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_306-hd.png", + "sha256": "118977fe2f785f56e31d23f6dea2e6a4d0c87d1fe999eeaaeae98c08d70dccbb", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_306-sd.png", + "sha256": "9a1fbc35757cca70b2e0fef68651393c11b9d7de7dfa9084b72f364ac97d1413", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_307-hd.png", + "sha256": "d41734f6ba5bd3cb2ced3dda961d24cf8c2bf90a4b129f409030ef873f4952d5", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_307-sd.png", + "sha256": "4d185dba39b999a5445ef90fdbd7978ddbf8e23555b611b8155491cc7b124099", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_308-hd.png", + "sha256": "b6f9a965bb573cd4372a04ee1bfd1bb76bdbb2c56bb0e7d1a6bc0f305c050b36", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_308-sd.png", + "sha256": "3c76ee964227173533f4ae0b2e22d5ec2cfed743efffda939792df2e80d05970", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_309-hd.png", + "sha256": "3f870dc8088f3adcd536d569a7cdcdaa89a4a885f41cdf40cdf04ea5b93ffe65", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_309-sd.png", + "sha256": "9099be616e6bf711b8ff4d44788ae19132b1c6d484863376b459c4c438e45385", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_310-hd.png", + "sha256": "01640890d009b62139ea5586b97b83f782f578b8da61f2ca57c001a6c2b041b1", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_310-sd.png", + "sha256": "d2592f22da3bf625ee3d80d7cfee98e5edf3d915b97d5c05c4dda8a68a94a8d9", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_311-hd.png", + "sha256": "caeb6107a6ec210a07812e4703eefe99d6e640378cb3c0d02ae78642b3816c9b", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_311-sd.png", + "sha256": "02db6fdfa9188d5fe771b2f8ee62f6ee4c5f24fe9395fbee323f237a39eaf744", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_312-hd.png", + "sha256": "2b77c7eb7270cb478361ac92d9d557f4d594a61a5d948881094c9a8b47f6ed99", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_312-sd.png", + "sha256": "7590bf5ce207c5f3248b4fb6d82ad61cfc654e235380ac3179b562c50c59be81", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_313-hd.png", + "sha256": "33aa101988138eb4f8660a318fcb9d7cc9077d728d49e904cbf99e0be3283877", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_313-sd.png", + "sha256": "08a7bb6741007284c8db926e4cf23ea069faa0963fec446fc377779473f9cddb", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_314-hd.png", + "sha256": "a445e0b6d1c9d72f8b4eca40789a31eb9add67ae677a9b5af4845cd32ab6f371", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_314-sd.png", + "sha256": "f019bb69bfabf4c6a24664f1079d92c4299bef215a76e5d787cebbddaaaa8838", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_315-hd.png", + "sha256": "a5efb10c3d00fd0536a5356a6150b948e96b94304b8cb6b534033d3b981f38d8", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_315-sd.png", + "sha256": "9bb45f9e4f7e5289e86b8ac4493e83beeaf3ebc2d0bc3d9e44b207aaf72760a6", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_316-hd.png", + "sha256": "0c8e4d722a0c23447d8733e18e7d6040e503e8b0f4d30e3aafe02bc3f5209b70", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_316-sd.png", + "sha256": "561ee5b719bcd6c339c1666c27da3656ad95560550479da770495eee0365e2a9", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_317-hd.png", + "sha256": "f14e823eec6d9b47943bfdaa21a066f4b0d584919c3894f2dc8ae33d6eda65b3", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_317-sd.png", + "sha256": "7f16ef7ccb70b973960684edb4d308be73fbf84a9f8dff6bbda8461345717c93", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_318-hd.png", + "sha256": "b4622796fff053467cff7a8a8ce030529c80fb72133a10e039ac0c27f29cee1c", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_318-sd.png", + "sha256": "75cca2cbf242c8f119d404c93317327f52ea7661970af0a367c41b3cfd168097", + "size": [ + 32, + 32 + ] + }, + { + "file": "art/tile_319-hd.png", + "sha256": "4453b1acd108882915fd3839567ff30f22c4a0bf6954a2e8c4989688ed8e1e5e", + "size": [ + 128, + 128 + ] + }, + { + "file": "art/tile_319-sd.png", + "sha256": "0e35d7eb842efc21e6fcd970ab6667e1c3732455e085f79e72348387c2b8570a", + "size": [ + 32, + 32 + ] + } + ] +} diff --git a/mods/iron_coast_stage2_mission_2/audio/approach.wav b/mods/iron_coast_stage2_mission_2/audio/approach.wav new file mode 100644 index 00000000..0191f56a Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/audio/approach.wav differ diff --git a/mods/iron_coast_stage2_mission_2/audio/boss_alarm.wav b/mods/iron_coast_stage2_mission_2/audio/boss_alarm.wav new file mode 100644 index 00000000..4a8ea75e Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/audio/boss_alarm.wav differ diff --git a/mods/iron_coast_stage2_mission_2/audio/objective.wav b/mods/iron_coast_stage2_mission_2/audio/objective.wav new file mode 100644 index 00000000..a6aa661b Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/audio/objective.wav differ diff --git a/mods/iron_coast_stage2_mission_2/audio/victory.wav b/mods/iron_coast_stage2_mission_2/audio/victory.wav new file mode 100644 index 00000000..0c3f8fd4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_2/audio/victory.wav differ diff --git a/mods/iron_coast_stage2_mission_2/build_assets.py b/mods/iron_coast_stage2_mission_2/build_assets.py new file mode 100644 index 00000000..7f744100 --- /dev/null +++ b/mods/iron_coast_stage2_mission_2/build_assets.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python3 +"""Reproduce SD/HD canvases and PCM WAVs from untouched builtin generated PNGs. +No decoded original images are packaged. No painted/masked master edits occur. +""" +from pathlib import Path +import argparse,datetime,hashlib,json,math,random,struct,wave +from PIL import Image,ImageOps +ROOT=Path(__file__).resolve().parent +h=lambda p:hashlib.sha256(Path(p).read_bytes()).hexdigest() +def palette(path): + raw=path.read_bytes();assert len(raw)==768 + values=[(min(v,63)<<2)|(min(v,63)>>4) for v in raw] + values[720:]=[0]*48 + im=Image.new('P',(1,1));im.putpalette(values);return im + +def small(im,size,pal): + im=im.convert('RGBA').resize(size,Image.Resampling.LANCZOS) + alpha=im.getchannel('A').point(lambda a:255 if a>=128 else 0) + out=im.convert('RGB').quantize(palette=pal,dither=Image.Dither.NONE).convert('RGBA');out.putalpha(alpha);return out + +def canvases(source,name,size,pal): + src=Image.open(source).convert('RGBA');target=(size[0]*4,size[1]*4) + hd=Image.new('RGBA',target);fitted=ImageOps.contain(src,target,Image.Resampling.LANCZOS);hd.alpha_composite(fitted,((target[0]-fitted.width)//2,(target[1]-fitted.height)//2)) + hd.save(ROOT/'art'/f'{name}-hd.png');small(hd,size,pal).save(ROOT/'art'/f'{name}-sd.png') + return {'source':str(source.relative_to(ROOT)),'sha256':h(source),'logical_size':size,'hd_size':target,'alpha_below128_transparent':True,'original_master_not_modified':True} + +def synth(name,duration,base): + rate=22050;n=int(rate*duration);rng=random.Random(7043+sum(map(ord,name))+base);data=bytearray();peak=0;sumsq=0 + for i in range(n): + t=i/rate;u=i/n;env=min(1,u*30)*(1-u)**1.3 + if name=='shot':s=(math.sin(2*math.pi*(95*t-40*t*t))+rng.uniform(-1,1)*0.45)*math.exp(-u*3) + elif name=='death':s=rng.uniform(-1,1)*0.65+math.sin(2*math.pi*(70*t-18*t*t))*0.4 + elif name=='warning' or name=='boss_alarm':s=math.sin(2*math.pi*(base+70*math.sin(2*math.pi*t*5))*t)*0.8+0.12*math.sin(2*math.pi*base*.5*t) + else: + notes=[1,1.25,1.5,2] if name=='victory' else [1,1.5,1.25];freq=base*notes[min(len(notes)-1,int(u*len(notes)))];s=math.sin(2*math.pi*freq*t)+0.15*math.sin(2*math.pi*freq*2*t) + v=max(-32767,min(32767,int(s*env*8500)));peak=max(peak,abs(v));sumsq+=v*v;data+=struct.pack('0 && unit.y>=85 { + let x=unit.x;if x<24 {x=24;}if x>264 {x=264;} + commands.push(#{op:"move",entity:unit.entity,x:x,y:85}); + commands.push(#{op:"velocity",entity:unit.entity,vx:0,vy:0}); + } + } + let kills=if event.objectives.contains("iron_coast_stage2_skimmer:defeated") {event.objectives["iron_coast_stage2_skimmer:defeated"]} else {0}; + if kills>state.reported {state.reported=kills;commands.push(#{op:"play_sound",sound:"iron_coast_stage2_mission_2:objective"});} + if event.tick>=2280 && !state.boss_alarm {state.boss_alarm=true;commands.push(#{op:"objective",key:"iron_coast_stage2_mission_2:phase",value:2});commands.push(#{op:"play_sound",sound:"iron_coast_stage2_mission_2:boss_alarm"});} + let defeated=if event.objectives.contains("iron_coast_stage2_boss_2:defeated") {event.objectives["iron_coast_stage2_boss_2:defeated"]} else {0}; + if kills>=4 && defeated>=1 && !state.complete { + state.complete=true; + commands.push(#{op:"objective",key:"iron_coast_stage2_mission_2:phase",value:3});commands.push(#{op:"objective",key:"iron_coast_stage2_mission_2:complete",value:1});commands.push(#{op:"credits",amount:32000});commands.push(#{op:"play_sound",sound:"iron_coast_stage2_mission_2:victory"});commands.push(#{op:"complete"}); + } + #{commands:commands,state:state} +} +fn on_mission_end(event,state,random) { + #{commands:[#{op:"objective",key:"iron_coast_stage2_mission_2:debrief",value:if event.success {1} else {0}}],state:state} +} diff --git a/mods/iron_coast_stage2_mission_3/README.md b/mods/iron_coast_stage2_mission_3/README.md new file mode 100644 index 00000000..cbb33601 --- /dev/null +++ b/mods/iron_coast_stage2_mission_3/README.md @@ -0,0 +1,13 @@ +# Iron Coast II — Mission 3: Stormglass Refinery + +Enable **Iron Coast II — Mission 3: Stormglass Refinery** in Mods at the main menu. Its own boss, shared interceptor, shared siege and Stage2 music are required; the dependency check selects them when installed. This single-mission campaign also works alongside the eight-mission Black Tide campaign pack. It has no explicit next mission, overrides, gear grant or equipment loan. + +Storm-season fuelworks combine fuel-battery objectives, classic divebombers and tanks, Needlewing interceptors, Bastion siege units and the Stormglass refinery crawler. Destroy all **four fuel batteries** and the boss. Required defenses stop at y60 and the boss patrols at y24 until destroyed; elapsed time and escaping ordinary enemies never count as kills or finish the mission. Cosmetic storm flashes cause no damage. + +Use ordinary game controls: Fire shoots equipped guns, Space drops owned bombs, Alt or Shift cycles selected weapons. Starter guns can destroy every required target. New campaign equipment is optional and can be purchased separately; this mission never modifies owned equipment or consumes inventory slots. Each objective grants 450 credits and restores12 shield. The boss pays 2400 credits, and a single completion bonus pays 14500. The boss enters at tick2100; expected complete sorties run roughly90–140seconds at70/3Hz. + +Each authored32×32 target has SD and8×HD art. The opaque industrial/river panorama is quantized as one joined image before splitting into288SD/HD terrain tiles; its forward/reflected32-row period repeats eight times across256rows, covering8192scroll pixels. The briefing is a wide crop from the same genuine terrain master. Originals, tracked prompts, exact builtin provenance, `asset-report.json`, `audio-recipe.json` and `build_assets.py` accompany the final assets. The recipe defaults to the bundled `RustRaptor/data/misc/PALETTE_DAT`; decoded original style references remain outside the package. Generated mono16-bit22050Hz WAVs use original seeded synthesis. + +From `RustRaptor/`, validate the complete dependency set with `target/release/raptor-rust --data data --mods mods --validate-mods iron_coast_stage2_mission_3,iron_coast_stage2_boss_3,iron_coast_stage2_interceptor,iron_coast_stage2_siege,iron_coast_stage2_music`. Run the package-local original-catalog probe with `cargo run --manifest-path mods/iron_coast_stage2_mission_3/validation/Cargo.toml --target-dir target/mod-validation --bin validate --release -- . 3`. It checks actual starter/full-inventory combat, genuine native movement, saved script-state/RNG continuation,4500-tick delayed objectives, replay reset, completion gating and every authored cue through the native PCM mixer. Local render evidence uses actual Rust asset conversion/indexed Canvas from World states; full desktop Host review is separate. + +Retired death guards are bounded to the most recent128 entity IDs, including deterministic migration of older checkpoints. Spawn resets a reused ID before any alive check; duplicate deaths for the current lifecycle emit no commands. The `retained-state` validation binary exercises1,205 actual-catalog/native lethal-collision lives, including1,200 distinct IDs, five reused-ID lives, JSON state/RNG restoration, a960-guard old checkpoint, duplicate callbacks, exact rewards and difficulty0–3. Run it from `RustRaptor/` with `cargo run --manifest-path mods/iron_coast_stage2_mission_3/validation/Cargo.toml --target-dir target/mod-validation --bin retained-state --release -- mods/iron_coast_stage2_mission_3`. The corresponding `validation/retained-state.json` records actual observations; package pins there identify the activation before generated proof files were finalized. The final external freeze ledger binds the complete resulting package. diff --git a/mods/iron_coast_stage2_mission_3/art/briefing-hd.png b/mods/iron_coast_stage2_mission_3/art/briefing-hd.png new file mode 100644 index 00000000..4e3e808e Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/briefing-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/briefing-sd.png b/mods/iron_coast_stage2_mission_3/art/briefing-sd.png new file mode 100644 index 00000000..0a08825c Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/briefing-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/target-hd.png b/mods/iron_coast_stage2_mission_3/art/target-hd.png new file mode 100644 index 00000000..4f54f613 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/target-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/target-sd.png b/mods/iron_coast_stage2_mission_3/art/target-sd.png new file mode 100644 index 00000000..bea1f040 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/target-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/target-source-v1.png b/mods/iron_coast_stage2_mission_3/art/target-source-v1.png new file mode 100644 index 00000000..0160e0a2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/target-source-v1.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/terrain-preview-hd.png b/mods/iron_coast_stage2_mission_3/art/terrain-preview-hd.png new file mode 100644 index 00000000..f86c0571 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/terrain-preview-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/terrain-preview-sd.png b/mods/iron_coast_stage2_mission_3/art/terrain-preview-sd.png new file mode 100644 index 00000000..ddcb4d44 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/terrain-preview-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/terrain-source-v1.png b/mods/iron_coast_stage2_mission_3/art/terrain-source-v1.png new file mode 100644 index 00000000..b52d5af2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/terrain-source-v1.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-000-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-000-hd.png new file mode 100644 index 00000000..058eae79 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-000-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-000-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-000-sd.png new file mode 100644 index 00000000..e5349609 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-000-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-001-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-001-hd.png new file mode 100644 index 00000000..51c20cc6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-001-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-001-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-001-sd.png new file mode 100644 index 00000000..21553c9c Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-001-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-002-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-002-hd.png new file mode 100644 index 00000000..596ffe61 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-002-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-002-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-002-sd.png new file mode 100644 index 00000000..80ad630f Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-002-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-003-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-003-hd.png new file mode 100644 index 00000000..b9f1adbb Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-003-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-003-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-003-sd.png new file mode 100644 index 00000000..b1d1b076 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-003-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-004-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-004-hd.png new file mode 100644 index 00000000..c65c0497 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-004-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-004-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-004-sd.png new file mode 100644 index 00000000..191f8c80 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-004-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-005-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-005-hd.png new file mode 100644 index 00000000..b2249fa9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-005-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-005-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-005-sd.png new file mode 100644 index 00000000..dad93c5a Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-005-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-006-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-006-hd.png new file mode 100644 index 00000000..93af3bdb Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-006-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-006-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-006-sd.png new file mode 100644 index 00000000..78f0ecaf Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-006-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-007-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-007-hd.png new file mode 100644 index 00000000..e11297f8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-007-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-007-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-007-sd.png new file mode 100644 index 00000000..27ac3cc3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-007-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-008-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-008-hd.png new file mode 100644 index 00000000..9ecb7b95 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-008-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-008-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-008-sd.png new file mode 100644 index 00000000..a1adeca2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-008-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-009-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-009-hd.png new file mode 100644 index 00000000..9c032e06 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-009-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-009-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-009-sd.png new file mode 100644 index 00000000..b1b33daa Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-009-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-010-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-010-hd.png new file mode 100644 index 00000000..31615cdb Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-010-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-010-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-010-sd.png new file mode 100644 index 00000000..86f8df9e Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-010-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-011-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-011-hd.png new file mode 100644 index 00000000..4fc257b6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-011-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-011-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-011-sd.png new file mode 100644 index 00000000..eaf96ae9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-011-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-012-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-012-hd.png new file mode 100644 index 00000000..f550536a Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-012-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-012-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-012-sd.png new file mode 100644 index 00000000..2a718ecc Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-012-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-013-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-013-hd.png new file mode 100644 index 00000000..0484e1d3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-013-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-013-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-013-sd.png new file mode 100644 index 00000000..ea5069f1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-013-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-014-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-014-hd.png new file mode 100644 index 00000000..8c4a5fe9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-014-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-014-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-014-sd.png new file mode 100644 index 00000000..65c2edf9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-014-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-015-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-015-hd.png new file mode 100644 index 00000000..2d0ff5fc Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-015-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-015-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-015-sd.png new file mode 100644 index 00000000..aded3ad3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-015-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-016-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-016-hd.png new file mode 100644 index 00000000..357817ea Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-016-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-016-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-016-sd.png new file mode 100644 index 00000000..3bcf8982 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-016-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-017-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-017-hd.png new file mode 100644 index 00000000..c51975d3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-017-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-017-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-017-sd.png new file mode 100644 index 00000000..9c91d6d1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-017-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-018-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-018-hd.png new file mode 100644 index 00000000..207df069 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-018-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-018-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-018-sd.png new file mode 100644 index 00000000..186d42ed Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-018-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-019-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-019-hd.png new file mode 100644 index 00000000..39a8e36e Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-019-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-019-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-019-sd.png new file mode 100644 index 00000000..ec2cd7e4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-019-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-020-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-020-hd.png new file mode 100644 index 00000000..f829012e Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-020-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-020-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-020-sd.png new file mode 100644 index 00000000..4a0d3538 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-020-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-021-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-021-hd.png new file mode 100644 index 00000000..26710421 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-021-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-021-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-021-sd.png new file mode 100644 index 00000000..7dc0c5a8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-021-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-022-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-022-hd.png new file mode 100644 index 00000000..b37154cb Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-022-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-022-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-022-sd.png new file mode 100644 index 00000000..49701d44 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-022-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-023-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-023-hd.png new file mode 100644 index 00000000..431ec07a Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-023-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-023-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-023-sd.png new file mode 100644 index 00000000..123350f3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-023-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-024-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-024-hd.png new file mode 100644 index 00000000..5eeb0a77 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-024-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-024-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-024-sd.png new file mode 100644 index 00000000..36ac8671 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-024-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-025-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-025-hd.png new file mode 100644 index 00000000..0e59e6a7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-025-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-025-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-025-sd.png new file mode 100644 index 00000000..a800a56f Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-025-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-026-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-026-hd.png new file mode 100644 index 00000000..e6f076b5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-026-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-026-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-026-sd.png new file mode 100644 index 00000000..555f9bbb Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-026-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-027-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-027-hd.png new file mode 100644 index 00000000..226c2523 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-027-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-027-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-027-sd.png new file mode 100644 index 00000000..69e2ffc9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-027-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-028-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-028-hd.png new file mode 100644 index 00000000..f991aefe Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-028-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-028-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-028-sd.png new file mode 100644 index 00000000..bbb53a89 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-028-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-029-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-029-hd.png new file mode 100644 index 00000000..e19c5e27 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-029-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-029-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-029-sd.png new file mode 100644 index 00000000..7581c9ce Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-029-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-030-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-030-hd.png new file mode 100644 index 00000000..73886588 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-030-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-030-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-030-sd.png new file mode 100644 index 00000000..4ce69e59 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-030-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-031-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-031-hd.png new file mode 100644 index 00000000..a237c543 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-031-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-031-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-031-sd.png new file mode 100644 index 00000000..41e8ff82 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-031-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-032-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-032-hd.png new file mode 100644 index 00000000..1014d32f Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-032-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-032-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-032-sd.png new file mode 100644 index 00000000..2dbc5d81 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-032-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-033-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-033-hd.png new file mode 100644 index 00000000..d81520ad Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-033-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-033-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-033-sd.png new file mode 100644 index 00000000..b538519b Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-033-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-034-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-034-hd.png new file mode 100644 index 00000000..7e1edb5d Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-034-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-034-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-034-sd.png new file mode 100644 index 00000000..a3c3118e Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-034-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-035-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-035-hd.png new file mode 100644 index 00000000..49e6a291 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-035-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-035-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-035-sd.png new file mode 100644 index 00000000..ffa25e95 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-035-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-036-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-036-hd.png new file mode 100644 index 00000000..fbc3f4aa Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-036-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-036-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-036-sd.png new file mode 100644 index 00000000..bf97db96 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-036-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-037-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-037-hd.png new file mode 100644 index 00000000..d1fcc4f1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-037-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-037-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-037-sd.png new file mode 100644 index 00000000..b4c8347a Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-037-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-038-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-038-hd.png new file mode 100644 index 00000000..f53f49e4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-038-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-038-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-038-sd.png new file mode 100644 index 00000000..c7ef9489 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-038-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-039-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-039-hd.png new file mode 100644 index 00000000..a4b5a0e5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-039-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-039-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-039-sd.png new file mode 100644 index 00000000..fbb7f399 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-039-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-040-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-040-hd.png new file mode 100644 index 00000000..b05b3b1a Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-040-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-040-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-040-sd.png new file mode 100644 index 00000000..a709e6b9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-040-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-041-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-041-hd.png new file mode 100644 index 00000000..b11f537a Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-041-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-041-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-041-sd.png new file mode 100644 index 00000000..96121e53 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-041-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-042-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-042-hd.png new file mode 100644 index 00000000..0ad4a957 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-042-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-042-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-042-sd.png new file mode 100644 index 00000000..b0da19ef Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-042-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-043-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-043-hd.png new file mode 100644 index 00000000..90836624 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-043-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-043-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-043-sd.png new file mode 100644 index 00000000..69d777c9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-043-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-044-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-044-hd.png new file mode 100644 index 00000000..01e518f9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-044-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-044-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-044-sd.png new file mode 100644 index 00000000..fd4680c8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-044-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-045-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-045-hd.png new file mode 100644 index 00000000..29ca7f74 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-045-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-045-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-045-sd.png new file mode 100644 index 00000000..fb96a058 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-045-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-046-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-046-hd.png new file mode 100644 index 00000000..c2582bdf Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-046-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-046-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-046-sd.png new file mode 100644 index 00000000..49d2d9b2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-046-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-047-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-047-hd.png new file mode 100644 index 00000000..9fb7f46e Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-047-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-047-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-047-sd.png new file mode 100644 index 00000000..162df383 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-047-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-048-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-048-hd.png new file mode 100644 index 00000000..06136747 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-048-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-048-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-048-sd.png new file mode 100644 index 00000000..d9585ff4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-048-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-049-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-049-hd.png new file mode 100644 index 00000000..9bd0f9e2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-049-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-049-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-049-sd.png new file mode 100644 index 00000000..1b2824b3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-049-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-050-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-050-hd.png new file mode 100644 index 00000000..85e42144 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-050-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-050-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-050-sd.png new file mode 100644 index 00000000..18fc92e3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-050-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-051-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-051-hd.png new file mode 100644 index 00000000..cf8182d7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-051-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-051-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-051-sd.png new file mode 100644 index 00000000..0cc9273e Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-051-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-052-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-052-hd.png new file mode 100644 index 00000000..700dcf01 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-052-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-052-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-052-sd.png new file mode 100644 index 00000000..1a27a188 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-052-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-053-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-053-hd.png new file mode 100644 index 00000000..8696c091 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-053-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-053-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-053-sd.png new file mode 100644 index 00000000..605e12ca Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-053-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-054-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-054-hd.png new file mode 100644 index 00000000..26287560 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-054-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-054-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-054-sd.png new file mode 100644 index 00000000..4c74f318 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-054-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-055-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-055-hd.png new file mode 100644 index 00000000..b475987e Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-055-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-055-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-055-sd.png new file mode 100644 index 00000000..97bc59cd Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-055-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-056-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-056-hd.png new file mode 100644 index 00000000..de4d5aaa Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-056-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-056-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-056-sd.png new file mode 100644 index 00000000..2bcb0c34 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-056-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-057-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-057-hd.png new file mode 100644 index 00000000..e87080bf Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-057-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-057-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-057-sd.png new file mode 100644 index 00000000..9f975491 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-057-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-058-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-058-hd.png new file mode 100644 index 00000000..396c6e91 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-058-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-058-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-058-sd.png new file mode 100644 index 00000000..e83b3963 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-058-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-059-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-059-hd.png new file mode 100644 index 00000000..33c4142c Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-059-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-059-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-059-sd.png new file mode 100644 index 00000000..a4e05045 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-059-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-060-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-060-hd.png new file mode 100644 index 00000000..856e362f Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-060-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-060-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-060-sd.png new file mode 100644 index 00000000..f2f26c3f Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-060-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-061-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-061-hd.png new file mode 100644 index 00000000..3d3babbb Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-061-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-061-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-061-sd.png new file mode 100644 index 00000000..fb84ab6f Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-061-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-062-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-062-hd.png new file mode 100644 index 00000000..0af6d617 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-062-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-062-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-062-sd.png new file mode 100644 index 00000000..cc0957c0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-062-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-063-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-063-hd.png new file mode 100644 index 00000000..7f384125 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-063-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-063-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-063-sd.png new file mode 100644 index 00000000..396aba93 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-063-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-064-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-064-hd.png new file mode 100644 index 00000000..8ec9483d Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-064-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-064-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-064-sd.png new file mode 100644 index 00000000..15c10c32 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-064-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-065-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-065-hd.png new file mode 100644 index 00000000..b60e9ca1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-065-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-065-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-065-sd.png new file mode 100644 index 00000000..515177ed Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-065-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-066-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-066-hd.png new file mode 100644 index 00000000..a065bbf5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-066-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-066-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-066-sd.png new file mode 100644 index 00000000..fef8a081 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-066-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-067-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-067-hd.png new file mode 100644 index 00000000..73e594d1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-067-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-067-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-067-sd.png new file mode 100644 index 00000000..d523a1c8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-067-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-068-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-068-hd.png new file mode 100644 index 00000000..6792def1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-068-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-068-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-068-sd.png new file mode 100644 index 00000000..ef915ee3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-068-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-069-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-069-hd.png new file mode 100644 index 00000000..e4f392b2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-069-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-069-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-069-sd.png new file mode 100644 index 00000000..3b193368 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-069-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-070-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-070-hd.png new file mode 100644 index 00000000..0e52d3b9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-070-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-070-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-070-sd.png new file mode 100644 index 00000000..e398c349 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-070-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-071-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-071-hd.png new file mode 100644 index 00000000..b950211c Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-071-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-071-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-071-sd.png new file mode 100644 index 00000000..c28c14fc Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-071-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-072-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-072-hd.png new file mode 100644 index 00000000..6b36c9af Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-072-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-072-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-072-sd.png new file mode 100644 index 00000000..338f6362 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-072-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-073-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-073-hd.png new file mode 100644 index 00000000..305067a4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-073-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-073-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-073-sd.png new file mode 100644 index 00000000..87a2437b Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-073-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-074-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-074-hd.png new file mode 100644 index 00000000..79b0abc6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-074-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-074-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-074-sd.png new file mode 100644 index 00000000..8c6e9e2f Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-074-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-075-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-075-hd.png new file mode 100644 index 00000000..facea0d4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-075-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-075-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-075-sd.png new file mode 100644 index 00000000..37186597 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-075-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-076-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-076-hd.png new file mode 100644 index 00000000..0b9dd8e0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-076-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-076-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-076-sd.png new file mode 100644 index 00000000..75de3093 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-076-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-077-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-077-hd.png new file mode 100644 index 00000000..7648de91 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-077-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-077-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-077-sd.png new file mode 100644 index 00000000..dc922b61 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-077-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-078-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-078-hd.png new file mode 100644 index 00000000..b7eb972c Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-078-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-078-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-078-sd.png new file mode 100644 index 00000000..03c3023f Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-078-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-079-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-079-hd.png new file mode 100644 index 00000000..70b8ec2c Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-079-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-079-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-079-sd.png new file mode 100644 index 00000000..a67adbc2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-079-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-080-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-080-hd.png new file mode 100644 index 00000000..8ef49a7e Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-080-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-080-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-080-sd.png new file mode 100644 index 00000000..aa34b7a6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-080-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-081-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-081-hd.png new file mode 100644 index 00000000..faea85e2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-081-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-081-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-081-sd.png new file mode 100644 index 00000000..e586b9d7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-081-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-082-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-082-hd.png new file mode 100644 index 00000000..eec93317 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-082-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-082-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-082-sd.png new file mode 100644 index 00000000..b1ae9b1d Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-082-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-083-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-083-hd.png new file mode 100644 index 00000000..227fab28 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-083-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-083-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-083-sd.png new file mode 100644 index 00000000..f88344ec Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-083-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-084-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-084-hd.png new file mode 100644 index 00000000..fb28aeed Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-084-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-084-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-084-sd.png new file mode 100644 index 00000000..9d9f295f Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-084-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-085-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-085-hd.png new file mode 100644 index 00000000..d6d0b306 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-085-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-085-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-085-sd.png new file mode 100644 index 00000000..a4bd2f5e Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-085-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-086-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-086-hd.png new file mode 100644 index 00000000..31c7fd12 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-086-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-086-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-086-sd.png new file mode 100644 index 00000000..ed481d11 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-086-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-087-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-087-hd.png new file mode 100644 index 00000000..cb24d96a Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-087-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-087-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-087-sd.png new file mode 100644 index 00000000..55055635 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-087-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-088-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-088-hd.png new file mode 100644 index 00000000..8efed3f5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-088-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-088-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-088-sd.png new file mode 100644 index 00000000..aa72fce0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-088-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-089-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-089-hd.png new file mode 100644 index 00000000..500cbeea Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-089-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-089-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-089-sd.png new file mode 100644 index 00000000..cf4dcb45 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-089-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-090-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-090-hd.png new file mode 100644 index 00000000..9c6e6de1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-090-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-090-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-090-sd.png new file mode 100644 index 00000000..cef26940 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-090-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-091-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-091-hd.png new file mode 100644 index 00000000..b1390d7f Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-091-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-091-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-091-sd.png new file mode 100644 index 00000000..0298ba3e Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-091-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-092-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-092-hd.png new file mode 100644 index 00000000..f22aaf64 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-092-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-092-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-092-sd.png new file mode 100644 index 00000000..182a4ed8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-092-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-093-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-093-hd.png new file mode 100644 index 00000000..500f7335 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-093-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-093-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-093-sd.png new file mode 100644 index 00000000..46a6f1e4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-093-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-094-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-094-hd.png new file mode 100644 index 00000000..e198acc9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-094-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-094-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-094-sd.png new file mode 100644 index 00000000..7639a6f3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-094-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-095-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-095-hd.png new file mode 100644 index 00000000..26fb4873 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-095-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-095-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-095-sd.png new file mode 100644 index 00000000..a5297ab2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-095-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-096-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-096-hd.png new file mode 100644 index 00000000..f007bd59 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-096-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-096-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-096-sd.png new file mode 100644 index 00000000..0322f86e Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-096-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-097-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-097-hd.png new file mode 100644 index 00000000..8e63d00c Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-097-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-097-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-097-sd.png new file mode 100644 index 00000000..e93cd622 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-097-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-098-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-098-hd.png new file mode 100644 index 00000000..08d64cc0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-098-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-098-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-098-sd.png new file mode 100644 index 00000000..1c6b10ab Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-098-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-099-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-099-hd.png new file mode 100644 index 00000000..ef7fb43c Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-099-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-099-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-099-sd.png new file mode 100644 index 00000000..cb6e4306 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-099-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-100-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-100-hd.png new file mode 100644 index 00000000..b1773617 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-100-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-100-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-100-sd.png new file mode 100644 index 00000000..328c769b Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-100-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-101-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-101-hd.png new file mode 100644 index 00000000..5c385e71 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-101-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-101-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-101-sd.png new file mode 100644 index 00000000..1e52dc11 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-101-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-102-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-102-hd.png new file mode 100644 index 00000000..abf8c0e2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-102-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-102-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-102-sd.png new file mode 100644 index 00000000..a378fe20 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-102-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-103-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-103-hd.png new file mode 100644 index 00000000..c97e386c Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-103-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-103-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-103-sd.png new file mode 100644 index 00000000..40748d15 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-103-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-104-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-104-hd.png new file mode 100644 index 00000000..00428447 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-104-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-104-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-104-sd.png new file mode 100644 index 00000000..044dab40 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-104-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-105-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-105-hd.png new file mode 100644 index 00000000..c0d3a573 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-105-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-105-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-105-sd.png new file mode 100644 index 00000000..d176ab98 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-105-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-106-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-106-hd.png new file mode 100644 index 00000000..41f8491f Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-106-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-106-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-106-sd.png new file mode 100644 index 00000000..fe3b134c Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-106-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-107-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-107-hd.png new file mode 100644 index 00000000..f13f9235 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-107-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-107-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-107-sd.png new file mode 100644 index 00000000..5739fd9c Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-107-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-108-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-108-hd.png new file mode 100644 index 00000000..c3cb8138 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-108-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-108-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-108-sd.png new file mode 100644 index 00000000..7f3dcc91 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-108-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-109-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-109-hd.png new file mode 100644 index 00000000..a3c97c17 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-109-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-109-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-109-sd.png new file mode 100644 index 00000000..316ed177 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-109-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-110-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-110-hd.png new file mode 100644 index 00000000..5b7ecce6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-110-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-110-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-110-sd.png new file mode 100644 index 00000000..e33ceecd Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-110-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-111-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-111-hd.png new file mode 100644 index 00000000..33019702 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-111-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-111-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-111-sd.png new file mode 100644 index 00000000..5bff553b Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-111-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-112-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-112-hd.png new file mode 100644 index 00000000..e0a7339b Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-112-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-112-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-112-sd.png new file mode 100644 index 00000000..77a2483e Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-112-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-113-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-113-hd.png new file mode 100644 index 00000000..f0f0eee5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-113-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-113-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-113-sd.png new file mode 100644 index 00000000..c17d4cfc Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-113-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-114-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-114-hd.png new file mode 100644 index 00000000..6af1b249 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-114-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-114-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-114-sd.png new file mode 100644 index 00000000..fcb19e5a Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-114-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-115-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-115-hd.png new file mode 100644 index 00000000..184b4a5d Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-115-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-115-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-115-sd.png new file mode 100644 index 00000000..79ab5eaa Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-115-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-116-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-116-hd.png new file mode 100644 index 00000000..3bdca309 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-116-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-116-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-116-sd.png new file mode 100644 index 00000000..aab90ae4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-116-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-117-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-117-hd.png new file mode 100644 index 00000000..c32e4198 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-117-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-117-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-117-sd.png new file mode 100644 index 00000000..a6608390 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-117-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-118-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-118-hd.png new file mode 100644 index 00000000..517d9b7d Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-118-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-118-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-118-sd.png new file mode 100644 index 00000000..d03e0a51 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-118-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-119-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-119-hd.png new file mode 100644 index 00000000..264090a3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-119-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-119-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-119-sd.png new file mode 100644 index 00000000..fcfff99d Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-119-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-120-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-120-hd.png new file mode 100644 index 00000000..f5601d75 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-120-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-120-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-120-sd.png new file mode 100644 index 00000000..adfd3bca Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-120-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-121-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-121-hd.png new file mode 100644 index 00000000..d89b0955 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-121-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-121-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-121-sd.png new file mode 100644 index 00000000..8e90f2f2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-121-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-122-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-122-hd.png new file mode 100644 index 00000000..0fd92d4e Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-122-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-122-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-122-sd.png new file mode 100644 index 00000000..fc249086 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-122-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-123-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-123-hd.png new file mode 100644 index 00000000..5558a08c Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-123-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-123-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-123-sd.png new file mode 100644 index 00000000..9e29a876 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-123-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-124-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-124-hd.png new file mode 100644 index 00000000..9013e81b Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-124-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-124-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-124-sd.png new file mode 100644 index 00000000..2bc3dd5d Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-124-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-125-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-125-hd.png new file mode 100644 index 00000000..4f11298b Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-125-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-125-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-125-sd.png new file mode 100644 index 00000000..21d24771 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-125-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-126-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-126-hd.png new file mode 100644 index 00000000..4a635678 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-126-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-126-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-126-sd.png new file mode 100644 index 00000000..26eae7db Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-126-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-127-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-127-hd.png new file mode 100644 index 00000000..9a2a69cd Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-127-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-127-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-127-sd.png new file mode 100644 index 00000000..fe5d0717 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-127-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-128-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-128-hd.png new file mode 100644 index 00000000..0d042f13 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-128-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-128-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-128-sd.png new file mode 100644 index 00000000..12885e2f Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-128-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-129-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-129-hd.png new file mode 100644 index 00000000..46f9b955 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-129-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-129-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-129-sd.png new file mode 100644 index 00000000..df59268a Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-129-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-130-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-130-hd.png new file mode 100644 index 00000000..c8820aef Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-130-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-130-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-130-sd.png new file mode 100644 index 00000000..611e1b8c Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-130-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-131-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-131-hd.png new file mode 100644 index 00000000..557a0c7c Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-131-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-131-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-131-sd.png new file mode 100644 index 00000000..eabb6fcc Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-131-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-132-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-132-hd.png new file mode 100644 index 00000000..242c70ec Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-132-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-132-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-132-sd.png new file mode 100644 index 00000000..62517e70 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-132-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-133-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-133-hd.png new file mode 100644 index 00000000..77b92282 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-133-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-133-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-133-sd.png new file mode 100644 index 00000000..b63488eb Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-133-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-134-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-134-hd.png new file mode 100644 index 00000000..92e32531 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-134-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-134-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-134-sd.png new file mode 100644 index 00000000..2dabdf49 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-134-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-135-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-135-hd.png new file mode 100644 index 00000000..160d17c9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-135-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-135-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-135-sd.png new file mode 100644 index 00000000..46a7c9d0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-135-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-136-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-136-hd.png new file mode 100644 index 00000000..759a82af Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-136-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-136-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-136-sd.png new file mode 100644 index 00000000..e9b1d9bb Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-136-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-137-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-137-hd.png new file mode 100644 index 00000000..783830b7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-137-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-137-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-137-sd.png new file mode 100644 index 00000000..3791210c Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-137-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-138-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-138-hd.png new file mode 100644 index 00000000..35851ffe Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-138-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-138-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-138-sd.png new file mode 100644 index 00000000..51bee46b Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-138-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-139-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-139-hd.png new file mode 100644 index 00000000..6b2ae301 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-139-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-139-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-139-sd.png new file mode 100644 index 00000000..9487d576 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-139-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-140-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-140-hd.png new file mode 100644 index 00000000..a53534c4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-140-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-140-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-140-sd.png new file mode 100644 index 00000000..cfe3b03e Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-140-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-141-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-141-hd.png new file mode 100644 index 00000000..8186e3f5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-141-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-141-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-141-sd.png new file mode 100644 index 00000000..adead99c Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-141-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-142-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-142-hd.png new file mode 100644 index 00000000..387768d3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-142-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-142-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-142-sd.png new file mode 100644 index 00000000..290e47be Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-142-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-143-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-143-hd.png new file mode 100644 index 00000000..7a9b73cf Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-143-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-143-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-143-sd.png new file mode 100644 index 00000000..093cdd2a Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-143-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-144-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-144-hd.png new file mode 100644 index 00000000..d3d70e33 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-144-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-144-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-144-sd.png new file mode 100644 index 00000000..7e372be4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-144-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-145-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-145-hd.png new file mode 100644 index 00000000..c0400a5b Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-145-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-145-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-145-sd.png new file mode 100644 index 00000000..3c222b28 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-145-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-146-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-146-hd.png new file mode 100644 index 00000000..cf7941dd Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-146-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-146-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-146-sd.png new file mode 100644 index 00000000..eb1a59cb Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-146-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-147-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-147-hd.png new file mode 100644 index 00000000..22b8e128 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-147-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-147-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-147-sd.png new file mode 100644 index 00000000..e82cc861 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-147-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-148-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-148-hd.png new file mode 100644 index 00000000..bf6b702b Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-148-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-148-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-148-sd.png new file mode 100644 index 00000000..fda802bd Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-148-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-149-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-149-hd.png new file mode 100644 index 00000000..3f950f00 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-149-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-149-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-149-sd.png new file mode 100644 index 00000000..8c1ab277 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-149-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-150-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-150-hd.png new file mode 100644 index 00000000..65d5b963 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-150-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-150-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-150-sd.png new file mode 100644 index 00000000..d9030019 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-150-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-151-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-151-hd.png new file mode 100644 index 00000000..f7234cb2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-151-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-151-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-151-sd.png new file mode 100644 index 00000000..18141747 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-151-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-152-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-152-hd.png new file mode 100644 index 00000000..b071218d Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-152-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-152-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-152-sd.png new file mode 100644 index 00000000..b55e097f Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-152-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-153-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-153-hd.png new file mode 100644 index 00000000..1148db93 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-153-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-153-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-153-sd.png new file mode 100644 index 00000000..321613f4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-153-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-154-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-154-hd.png new file mode 100644 index 00000000..a11dfd82 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-154-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-154-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-154-sd.png new file mode 100644 index 00000000..e3380458 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-154-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-155-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-155-hd.png new file mode 100644 index 00000000..27bc5d24 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-155-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-155-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-155-sd.png new file mode 100644 index 00000000..8fbd3fba Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-155-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-156-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-156-hd.png new file mode 100644 index 00000000..77066d83 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-156-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-156-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-156-sd.png new file mode 100644 index 00000000..37027240 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-156-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-157-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-157-hd.png new file mode 100644 index 00000000..e3025a62 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-157-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-157-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-157-sd.png new file mode 100644 index 00000000..2f380c19 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-157-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-158-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-158-hd.png new file mode 100644 index 00000000..1a0e9d0b Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-158-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-158-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-158-sd.png new file mode 100644 index 00000000..71ca6a04 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-158-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-159-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-159-hd.png new file mode 100644 index 00000000..b1468c0a Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-159-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-159-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-159-sd.png new file mode 100644 index 00000000..c75f1ff3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-159-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-160-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-160-hd.png new file mode 100644 index 00000000..09d34720 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-160-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-160-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-160-sd.png new file mode 100644 index 00000000..3b9deb90 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-160-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-161-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-161-hd.png new file mode 100644 index 00000000..b5fe95ac Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-161-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-161-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-161-sd.png new file mode 100644 index 00000000..7b1d5b2e Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-161-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-162-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-162-hd.png new file mode 100644 index 00000000..608b9811 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-162-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-162-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-162-sd.png new file mode 100644 index 00000000..f92ae3d0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-162-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-163-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-163-hd.png new file mode 100644 index 00000000..a30e49be Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-163-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-163-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-163-sd.png new file mode 100644 index 00000000..3f1b97a5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-163-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-164-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-164-hd.png new file mode 100644 index 00000000..67073bc3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-164-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-164-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-164-sd.png new file mode 100644 index 00000000..12fc2720 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-164-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-165-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-165-hd.png new file mode 100644 index 00000000..9b40a5ac Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-165-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-165-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-165-sd.png new file mode 100644 index 00000000..48a7d081 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-165-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-166-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-166-hd.png new file mode 100644 index 00000000..d1fabd06 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-166-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-166-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-166-sd.png new file mode 100644 index 00000000..d9fdc949 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-166-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-167-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-167-hd.png new file mode 100644 index 00000000..faf56173 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-167-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-167-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-167-sd.png new file mode 100644 index 00000000..dd009525 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-167-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-168-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-168-hd.png new file mode 100644 index 00000000..c327fda8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-168-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-168-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-168-sd.png new file mode 100644 index 00000000..82e16331 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-168-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-169-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-169-hd.png new file mode 100644 index 00000000..51ec1449 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-169-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-169-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-169-sd.png new file mode 100644 index 00000000..45928531 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-169-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-170-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-170-hd.png new file mode 100644 index 00000000..84ec6986 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-170-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-170-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-170-sd.png new file mode 100644 index 00000000..0dac4b8a Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-170-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-171-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-171-hd.png new file mode 100644 index 00000000..00b41cae Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-171-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-171-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-171-sd.png new file mode 100644 index 00000000..6337f4e3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-171-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-172-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-172-hd.png new file mode 100644 index 00000000..e742fc04 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-172-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-172-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-172-sd.png new file mode 100644 index 00000000..a3c854c5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-172-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-173-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-173-hd.png new file mode 100644 index 00000000..a922b05a Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-173-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-173-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-173-sd.png new file mode 100644 index 00000000..f58d8c38 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-173-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-174-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-174-hd.png new file mode 100644 index 00000000..1c16f833 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-174-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-174-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-174-sd.png new file mode 100644 index 00000000..9d15c40f Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-174-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-175-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-175-hd.png new file mode 100644 index 00000000..e6801ded Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-175-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-175-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-175-sd.png new file mode 100644 index 00000000..3b85da46 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-175-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-176-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-176-hd.png new file mode 100644 index 00000000..f764f662 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-176-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-176-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-176-sd.png new file mode 100644 index 00000000..71bba005 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-176-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-177-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-177-hd.png new file mode 100644 index 00000000..f520e907 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-177-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-177-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-177-sd.png new file mode 100644 index 00000000..2f5a709a Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-177-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-178-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-178-hd.png new file mode 100644 index 00000000..e27beb46 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-178-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-178-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-178-sd.png new file mode 100644 index 00000000..cef08e2d Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-178-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-179-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-179-hd.png new file mode 100644 index 00000000..e2e71714 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-179-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-179-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-179-sd.png new file mode 100644 index 00000000..06adddf9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-179-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-180-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-180-hd.png new file mode 100644 index 00000000..dbb7a576 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-180-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-180-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-180-sd.png new file mode 100644 index 00000000..ad24dfac Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-180-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-181-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-181-hd.png new file mode 100644 index 00000000..ad4a59b6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-181-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-181-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-181-sd.png new file mode 100644 index 00000000..e65b0f49 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-181-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-182-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-182-hd.png new file mode 100644 index 00000000..95156b4d Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-182-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-182-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-182-sd.png new file mode 100644 index 00000000..cc1a5122 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-182-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-183-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-183-hd.png new file mode 100644 index 00000000..64701883 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-183-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-183-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-183-sd.png new file mode 100644 index 00000000..33639968 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-183-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-184-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-184-hd.png new file mode 100644 index 00000000..9a4cc257 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-184-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-184-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-184-sd.png new file mode 100644 index 00000000..a8593ae2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-184-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-185-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-185-hd.png new file mode 100644 index 00000000..e8fe7d50 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-185-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-185-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-185-sd.png new file mode 100644 index 00000000..a962d31a Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-185-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-186-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-186-hd.png new file mode 100644 index 00000000..cb753a21 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-186-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-186-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-186-sd.png new file mode 100644 index 00000000..bb1efe28 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-186-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-187-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-187-hd.png new file mode 100644 index 00000000..203e0355 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-187-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-187-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-187-sd.png new file mode 100644 index 00000000..1b2c22de Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-187-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-188-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-188-hd.png new file mode 100644 index 00000000..a313526c Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-188-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-188-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-188-sd.png new file mode 100644 index 00000000..1e8b2560 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-188-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-189-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-189-hd.png new file mode 100644 index 00000000..5bc1bc20 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-189-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-189-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-189-sd.png new file mode 100644 index 00000000..adbd9c67 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-189-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-190-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-190-hd.png new file mode 100644 index 00000000..dcdb6144 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-190-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-190-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-190-sd.png new file mode 100644 index 00000000..b0b06e75 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-190-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-191-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-191-hd.png new file mode 100644 index 00000000..b70fdeec Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-191-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-191-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-191-sd.png new file mode 100644 index 00000000..5d625c03 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-191-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-192-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-192-hd.png new file mode 100644 index 00000000..bb53305a Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-192-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-192-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-192-sd.png new file mode 100644 index 00000000..7d7ea4c2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-192-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-193-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-193-hd.png new file mode 100644 index 00000000..e820628a Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-193-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-193-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-193-sd.png new file mode 100644 index 00000000..e43e7e95 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-193-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-194-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-194-hd.png new file mode 100644 index 00000000..c1adb9ed Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-194-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-194-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-194-sd.png new file mode 100644 index 00000000..d7bda261 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-194-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-195-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-195-hd.png new file mode 100644 index 00000000..f05b22bc Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-195-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-195-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-195-sd.png new file mode 100644 index 00000000..7eb4d1cb Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-195-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-196-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-196-hd.png new file mode 100644 index 00000000..5c20e235 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-196-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-196-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-196-sd.png new file mode 100644 index 00000000..9fa5ccc1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-196-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-197-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-197-hd.png new file mode 100644 index 00000000..552fedd3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-197-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-197-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-197-sd.png new file mode 100644 index 00000000..d1a5e93e Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-197-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-198-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-198-hd.png new file mode 100644 index 00000000..845cfdb7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-198-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-198-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-198-sd.png new file mode 100644 index 00000000..4a4bd914 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-198-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-199-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-199-hd.png new file mode 100644 index 00000000..b8c798b9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-199-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-199-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-199-sd.png new file mode 100644 index 00000000..2594c05c Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-199-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-200-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-200-hd.png new file mode 100644 index 00000000..1010c3fc Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-200-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-200-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-200-sd.png new file mode 100644 index 00000000..b003b0a0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-200-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-201-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-201-hd.png new file mode 100644 index 00000000..31fc1d6a Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-201-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-201-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-201-sd.png new file mode 100644 index 00000000..67b15aca Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-201-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-202-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-202-hd.png new file mode 100644 index 00000000..30c65213 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-202-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-202-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-202-sd.png new file mode 100644 index 00000000..53a38808 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-202-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-203-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-203-hd.png new file mode 100644 index 00000000..9e1e334e Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-203-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-203-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-203-sd.png new file mode 100644 index 00000000..e2315142 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-203-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-204-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-204-hd.png new file mode 100644 index 00000000..25ee745e Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-204-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-204-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-204-sd.png new file mode 100644 index 00000000..802d553b Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-204-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-205-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-205-hd.png new file mode 100644 index 00000000..60fd171e Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-205-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-205-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-205-sd.png new file mode 100644 index 00000000..7f5c8405 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-205-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-206-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-206-hd.png new file mode 100644 index 00000000..953314c5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-206-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-206-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-206-sd.png new file mode 100644 index 00000000..fa45549c Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-206-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-207-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-207-hd.png new file mode 100644 index 00000000..31eeb94e Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-207-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-207-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-207-sd.png new file mode 100644 index 00000000..e20e50ca Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-207-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-208-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-208-hd.png new file mode 100644 index 00000000..a498bdb5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-208-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-208-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-208-sd.png new file mode 100644 index 00000000..18743c28 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-208-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-209-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-209-hd.png new file mode 100644 index 00000000..23029a04 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-209-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-209-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-209-sd.png new file mode 100644 index 00000000..a7473c7b Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-209-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-210-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-210-hd.png new file mode 100644 index 00000000..801d60cb Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-210-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-210-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-210-sd.png new file mode 100644 index 00000000..8507ce7f Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-210-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-211-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-211-hd.png new file mode 100644 index 00000000..c1417510 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-211-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-211-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-211-sd.png new file mode 100644 index 00000000..ee747b28 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-211-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-212-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-212-hd.png new file mode 100644 index 00000000..7d0e7ec4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-212-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-212-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-212-sd.png new file mode 100644 index 00000000..930c953f Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-212-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-213-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-213-hd.png new file mode 100644 index 00000000..d9fc54a4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-213-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-213-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-213-sd.png new file mode 100644 index 00000000..9a787fc2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-213-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-214-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-214-hd.png new file mode 100644 index 00000000..d666212b Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-214-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-214-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-214-sd.png new file mode 100644 index 00000000..f3d96879 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-214-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-215-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-215-hd.png new file mode 100644 index 00000000..e01e6672 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-215-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-215-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-215-sd.png new file mode 100644 index 00000000..2f777f85 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-215-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-216-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-216-hd.png new file mode 100644 index 00000000..8d631fdb Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-216-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-216-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-216-sd.png new file mode 100644 index 00000000..9c58af0d Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-216-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-217-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-217-hd.png new file mode 100644 index 00000000..e130bf64 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-217-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-217-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-217-sd.png new file mode 100644 index 00000000..3428c9b8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-217-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-218-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-218-hd.png new file mode 100644 index 00000000..dd02fa3c Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-218-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-218-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-218-sd.png new file mode 100644 index 00000000..bc7afe75 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-218-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-219-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-219-hd.png new file mode 100644 index 00000000..98d6abc3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-219-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-219-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-219-sd.png new file mode 100644 index 00000000..1f93fdf8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-219-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-220-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-220-hd.png new file mode 100644 index 00000000..f6fa8205 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-220-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-220-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-220-sd.png new file mode 100644 index 00000000..ba8fc9d1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-220-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-221-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-221-hd.png new file mode 100644 index 00000000..6e79f7d5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-221-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-221-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-221-sd.png new file mode 100644 index 00000000..9a07d361 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-221-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-222-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-222-hd.png new file mode 100644 index 00000000..47c93bdb Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-222-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-222-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-222-sd.png new file mode 100644 index 00000000..f9d95327 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-222-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-223-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-223-hd.png new file mode 100644 index 00000000..0c6b1d40 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-223-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-223-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-223-sd.png new file mode 100644 index 00000000..aac51147 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-223-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-224-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-224-hd.png new file mode 100644 index 00000000..d7bffb39 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-224-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-224-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-224-sd.png new file mode 100644 index 00000000..57f8c3a8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-224-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-225-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-225-hd.png new file mode 100644 index 00000000..a11b5f43 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-225-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-225-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-225-sd.png new file mode 100644 index 00000000..b3be2160 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-225-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-226-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-226-hd.png new file mode 100644 index 00000000..45dacf44 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-226-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-226-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-226-sd.png new file mode 100644 index 00000000..ed47ca68 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-226-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-227-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-227-hd.png new file mode 100644 index 00000000..635bd983 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-227-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-227-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-227-sd.png new file mode 100644 index 00000000..bb3556bb Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-227-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-228-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-228-hd.png new file mode 100644 index 00000000..d83a1add Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-228-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-228-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-228-sd.png new file mode 100644 index 00000000..6b564d1d Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-228-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-229-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-229-hd.png new file mode 100644 index 00000000..bcdb5124 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-229-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-229-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-229-sd.png new file mode 100644 index 00000000..e6355e86 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-229-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-230-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-230-hd.png new file mode 100644 index 00000000..ea081245 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-230-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-230-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-230-sd.png new file mode 100644 index 00000000..782acc05 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-230-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-231-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-231-hd.png new file mode 100644 index 00000000..03bcceb1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-231-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-231-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-231-sd.png new file mode 100644 index 00000000..5da64e57 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-231-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-232-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-232-hd.png new file mode 100644 index 00000000..11ec4743 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-232-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-232-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-232-sd.png new file mode 100644 index 00000000..59d2b402 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-232-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-233-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-233-hd.png new file mode 100644 index 00000000..d2af9512 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-233-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-233-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-233-sd.png new file mode 100644 index 00000000..1b9357bd Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-233-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-234-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-234-hd.png new file mode 100644 index 00000000..d1bb9e08 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-234-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-234-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-234-sd.png new file mode 100644 index 00000000..91b05e0d Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-234-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-235-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-235-hd.png new file mode 100644 index 00000000..918cb251 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-235-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-235-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-235-sd.png new file mode 100644 index 00000000..dd3ea05d Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-235-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-236-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-236-hd.png new file mode 100644 index 00000000..1ac86d68 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-236-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-236-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-236-sd.png new file mode 100644 index 00000000..cd703ea2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-236-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-237-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-237-hd.png new file mode 100644 index 00000000..953a46aa Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-237-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-237-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-237-sd.png new file mode 100644 index 00000000..01f4007e Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-237-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-238-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-238-hd.png new file mode 100644 index 00000000..6edda929 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-238-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-238-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-238-sd.png new file mode 100644 index 00000000..22f939a6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-238-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-239-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-239-hd.png new file mode 100644 index 00000000..8254783a Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-239-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-239-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-239-sd.png new file mode 100644 index 00000000..0151cd52 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-239-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-240-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-240-hd.png new file mode 100644 index 00000000..10fca0e1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-240-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-240-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-240-sd.png new file mode 100644 index 00000000..33b28d02 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-240-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-241-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-241-hd.png new file mode 100644 index 00000000..66716402 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-241-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-241-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-241-sd.png new file mode 100644 index 00000000..a87d81fd Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-241-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-242-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-242-hd.png new file mode 100644 index 00000000..0d2e0b7b Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-242-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-242-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-242-sd.png new file mode 100644 index 00000000..a5680dea Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-242-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-243-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-243-hd.png new file mode 100644 index 00000000..a2787391 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-243-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-243-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-243-sd.png new file mode 100644 index 00000000..45e9af6a Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-243-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-244-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-244-hd.png new file mode 100644 index 00000000..aecc7811 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-244-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-244-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-244-sd.png new file mode 100644 index 00000000..468aa35e Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-244-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-245-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-245-hd.png new file mode 100644 index 00000000..2108d6bc Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-245-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-245-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-245-sd.png new file mode 100644 index 00000000..f0bae46e Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-245-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-246-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-246-hd.png new file mode 100644 index 00000000..9fe16965 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-246-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-246-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-246-sd.png new file mode 100644 index 00000000..23d9e94e Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-246-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-247-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-247-hd.png new file mode 100644 index 00000000..c71f8cee Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-247-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-247-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-247-sd.png new file mode 100644 index 00000000..7760576e Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-247-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-248-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-248-hd.png new file mode 100644 index 00000000..86e79387 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-248-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-248-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-248-sd.png new file mode 100644 index 00000000..d0d00755 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-248-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-249-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-249-hd.png new file mode 100644 index 00000000..626efb22 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-249-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-249-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-249-sd.png new file mode 100644 index 00000000..f62632af Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-249-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-250-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-250-hd.png new file mode 100644 index 00000000..fe501064 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-250-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-250-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-250-sd.png new file mode 100644 index 00000000..98f1981d Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-250-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-251-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-251-hd.png new file mode 100644 index 00000000..a1d89e47 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-251-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-251-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-251-sd.png new file mode 100644 index 00000000..05eaa3f8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-251-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-252-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-252-hd.png new file mode 100644 index 00000000..c5542a04 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-252-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-252-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-252-sd.png new file mode 100644 index 00000000..ff417010 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-252-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-253-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-253-hd.png new file mode 100644 index 00000000..c2a3dd09 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-253-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-253-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-253-sd.png new file mode 100644 index 00000000..05dd17eb Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-253-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-254-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-254-hd.png new file mode 100644 index 00000000..092d9164 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-254-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-254-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-254-sd.png new file mode 100644 index 00000000..7b90bdd4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-254-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-255-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-255-hd.png new file mode 100644 index 00000000..f68cabf0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-255-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-255-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-255-sd.png new file mode 100644 index 00000000..962bc4a4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-255-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-256-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-256-hd.png new file mode 100644 index 00000000..9c15cc94 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-256-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-256-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-256-sd.png new file mode 100644 index 00000000..c7c5488c Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-256-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-257-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-257-hd.png new file mode 100644 index 00000000..4420e1b7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-257-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-257-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-257-sd.png new file mode 100644 index 00000000..d26a7f58 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-257-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-258-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-258-hd.png new file mode 100644 index 00000000..bc66eb35 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-258-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-258-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-258-sd.png new file mode 100644 index 00000000..ac2d69db Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-258-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-259-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-259-hd.png new file mode 100644 index 00000000..906883ff Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-259-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-259-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-259-sd.png new file mode 100644 index 00000000..54e12144 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-259-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-260-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-260-hd.png new file mode 100644 index 00000000..0a89ad1c Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-260-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-260-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-260-sd.png new file mode 100644 index 00000000..416342e5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-260-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-261-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-261-hd.png new file mode 100644 index 00000000..9ef7227b Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-261-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-261-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-261-sd.png new file mode 100644 index 00000000..a63a30fa Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-261-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-262-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-262-hd.png new file mode 100644 index 00000000..5f124f31 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-262-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-262-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-262-sd.png new file mode 100644 index 00000000..2f02ffbf Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-262-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-263-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-263-hd.png new file mode 100644 index 00000000..9193231e Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-263-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-263-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-263-sd.png new file mode 100644 index 00000000..8f367563 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-263-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-264-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-264-hd.png new file mode 100644 index 00000000..913e0ddb Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-264-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-264-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-264-sd.png new file mode 100644 index 00000000..0eaea6fc Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-264-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-265-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-265-hd.png new file mode 100644 index 00000000..de23e12b Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-265-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-265-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-265-sd.png new file mode 100644 index 00000000..e4a67108 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-265-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-266-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-266-hd.png new file mode 100644 index 00000000..a051addd Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-266-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-266-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-266-sd.png new file mode 100644 index 00000000..f8e26295 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-266-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-267-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-267-hd.png new file mode 100644 index 00000000..6f9337a6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-267-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-267-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-267-sd.png new file mode 100644 index 00000000..0410e2e3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-267-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-268-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-268-hd.png new file mode 100644 index 00000000..f4f6b825 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-268-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-268-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-268-sd.png new file mode 100644 index 00000000..678b135e Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-268-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-269-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-269-hd.png new file mode 100644 index 00000000..97b7789a Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-269-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-269-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-269-sd.png new file mode 100644 index 00000000..597f0396 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-269-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-270-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-270-hd.png new file mode 100644 index 00000000..c7250620 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-270-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-270-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-270-sd.png new file mode 100644 index 00000000..8ee97eaf Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-270-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-271-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-271-hd.png new file mode 100644 index 00000000..e30618d9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-271-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-271-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-271-sd.png new file mode 100644 index 00000000..d6fc575e Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-271-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-272-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-272-hd.png new file mode 100644 index 00000000..244b5151 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-272-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-272-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-272-sd.png new file mode 100644 index 00000000..29149d33 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-272-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-273-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-273-hd.png new file mode 100644 index 00000000..15e86c48 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-273-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-273-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-273-sd.png new file mode 100644 index 00000000..f1b6ca13 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-273-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-274-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-274-hd.png new file mode 100644 index 00000000..be8b8f14 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-274-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-274-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-274-sd.png new file mode 100644 index 00000000..4ff731fa Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-274-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-275-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-275-hd.png new file mode 100644 index 00000000..c32118c3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-275-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-275-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-275-sd.png new file mode 100644 index 00000000..c5bf4475 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-275-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-276-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-276-hd.png new file mode 100644 index 00000000..8e100df7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-276-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-276-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-276-sd.png new file mode 100644 index 00000000..b5f37a6c Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-276-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-277-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-277-hd.png new file mode 100644 index 00000000..204365cc Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-277-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-277-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-277-sd.png new file mode 100644 index 00000000..1b613dff Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-277-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-278-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-278-hd.png new file mode 100644 index 00000000..c5fc72bf Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-278-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-278-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-278-sd.png new file mode 100644 index 00000000..21b28646 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-278-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-279-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-279-hd.png new file mode 100644 index 00000000..71b8ab1a Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-279-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-279-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-279-sd.png new file mode 100644 index 00000000..ff7ea743 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-279-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-280-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-280-hd.png new file mode 100644 index 00000000..f5f6d622 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-280-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-280-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-280-sd.png new file mode 100644 index 00000000..fa12f3a8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-280-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-281-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-281-hd.png new file mode 100644 index 00000000..5cd7dcfa Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-281-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-281-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-281-sd.png new file mode 100644 index 00000000..12519e85 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-281-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-282-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-282-hd.png new file mode 100644 index 00000000..86e91ce3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-282-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-282-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-282-sd.png new file mode 100644 index 00000000..11f2b2a0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-282-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-283-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-283-hd.png new file mode 100644 index 00000000..b48b2a20 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-283-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-283-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-283-sd.png new file mode 100644 index 00000000..d02c3ced Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-283-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-284-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-284-hd.png new file mode 100644 index 00000000..f5bd687a Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-284-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-284-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-284-sd.png new file mode 100644 index 00000000..e09d1eda Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-284-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-285-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-285-hd.png new file mode 100644 index 00000000..c496c2a1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-285-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-285-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-285-sd.png new file mode 100644 index 00000000..4a5fbe2c Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-285-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-286-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-286-hd.png new file mode 100644 index 00000000..b38aa12e Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-286-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-286-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-286-sd.png new file mode 100644 index 00000000..8f6cd2bc Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-286-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-287-hd.png b/mods/iron_coast_stage2_mission_3/art/tile-287-hd.png new file mode 100644 index 00000000..0462161b Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-287-hd.png differ diff --git a/mods/iron_coast_stage2_mission_3/art/tile-287-sd.png b/mods/iron_coast_stage2_mission_3/art/tile-287-sd.png new file mode 100644 index 00000000..531f9253 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/art/tile-287-sd.png differ diff --git a/mods/iron_coast_stage2_mission_3/asset-report.json b/mods/iron_coast_stage2_mission_3/asset-report.json new file mode 100644 index 00000000..32e385b6 --- /dev/null +++ b/mods/iron_coast_stage2_mission_3/asset-report.json @@ -0,0 +1,129 @@ +{ + "palette_sha256": "1cf6adb926d1dee1888b3e3d33b51a7049b3e5eb5f90a3067ef71c8970547204", + "ordinary_palette_entries_only": true, + "audio": { + "approach": { + "path": "audio/approach.wav", + "sha256": "92fdd1f3ad28dc8a501385626cfed5c5a0c494890ad986bfdefe4ef876409220", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "samples": 17199, + "seconds": 0.78, + "seed": 2199, + "peak": 20316, + "recipe": "deterministic seeded chirp/noise, original synthesis, no recordings" + }, + "target_alarm": { + "path": "audio/target_alarm.wav", + "sha256": "1a978f5a590b13fdcc6c69812d076227821995383d7535d060c9f8d7d6123b54", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "samples": 9261, + "seconds": 0.42, + "seed": 2200, + "peak": 15728, + "recipe": "deterministic seeded chirp/noise, original synthesis, no recordings" + }, + "boss_alarm": { + "path": "audio/boss_alarm.wav", + "sha256": "752a7fc750ba466058a8fcab7f405a36ba643f53cce152f1948af9ac6fee2921", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "samples": 14332, + "seconds": 0.6499773242630386, + "seed": 2201, + "peak": 15728, + "recipe": "deterministic seeded chirp/noise, original synthesis, no recordings" + }, + "salvage": { + "path": "audio/salvage.wav", + "sha256": "b8a73abb96986cec9e37063433356117a5fb79161a9fe5f15de966df40e89394", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "samples": 7056, + "seconds": 0.32, + "seed": 2202, + "peak": 20316, + "recipe": "deterministic seeded chirp/noise, original synthesis, no recordings" + }, + "victory": { + "path": "audio/victory.wav", + "sha256": "d69675d0d6c6cf8738fc826c9743ebab74ebb5fa90c97661055628c35c8edc2c", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "samples": 24255, + "seconds": 1.1, + "seed": 2203, + "peak": 20316, + "recipe": "deterministic seeded chirp/noise, original synthesis, no recordings" + } + }, + "target": { + "master": "art/target-source-v1.png", + "master_sha256": "6bd85c922d2be0a2671777e8f7f9a7e0623ff7abc709e7b489140db9c2a74964", + "master_size": [ + 1536, + 1024 + ], + "crop_runtime_invisible_padding": [ + 418, + 187, + 1116, + 823 + ], + "crop_threshold": 16, + "runtime_alpha_threshold": 128, + "logical_canvas": [ + 32, + 32 + ], + "hd_canvas": [ + 256, + 256 + ], + "sd_bounds": [ + 3, + 4, + 29, + 28 + ], + "hd_bounds": [ + 25, + 33, + 232, + 223 + ], + "frame_count": 1, + "origin": [ + 0, + 0 + ], + "generated_art_repainted": false + }, + "terrain": { + "master_sha256": "3911a9cc2b231e67684eae3bbc104c3793d913f481d11e8ad7bb7a94d07a489d", + "master_size": [ + 941, + 1672 + ], + "logical_joined_size": [ + 288, + 512 + ], + "hd_joined_size": [ + 1152, + 2048 + ], + "tiles": 288, + "period_rows": 32, + "repeat": "forward16 rows then reflected16 rows, both periodboundaries identical", + "joined_before_quantizing_and_splitting": true, + "seam_checks": true, + "briefing": "320x200 /1280x800 central wide crop from same genuine terrain master" + } +} diff --git a/mods/iron_coast_stage2_mission_3/audio-recipe.json b/mods/iron_coast_stage2_mission_3/audio-recipe.json new file mode 100644 index 00000000..e641fbbd --- /dev/null +++ b/mods/iron_coast_stage2_mission_3/audio-recipe.json @@ -0,0 +1,62 @@ +{ + "approach": { + "path": "audio/approach.wav", + "sha256": "92fdd1f3ad28dc8a501385626cfed5c5a0c494890ad986bfdefe4ef876409220", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "samples": 17199, + "seconds": 0.78, + "seed": 2199, + "peak": 20316, + "recipe": "deterministic seeded chirp/noise, original synthesis, no recordings" + }, + "target_alarm": { + "path": "audio/target_alarm.wav", + "sha256": "1a978f5a590b13fdcc6c69812d076227821995383d7535d060c9f8d7d6123b54", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "samples": 9261, + "seconds": 0.42, + "seed": 2200, + "peak": 15728, + "recipe": "deterministic seeded chirp/noise, original synthesis, no recordings" + }, + "boss_alarm": { + "path": "audio/boss_alarm.wav", + "sha256": "752a7fc750ba466058a8fcab7f405a36ba643f53cce152f1948af9ac6fee2921", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "samples": 14332, + "seconds": 0.6499773242630386, + "seed": 2201, + "peak": 15728, + "recipe": "deterministic seeded chirp/noise, original synthesis, no recordings" + }, + "salvage": { + "path": "audio/salvage.wav", + "sha256": "b8a73abb96986cec9e37063433356117a5fb79161a9fe5f15de966df40e89394", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "samples": 7056, + "seconds": 0.32, + "seed": 2202, + "peak": 20316, + "recipe": "deterministic seeded chirp/noise, original synthesis, no recordings" + }, + "victory": { + "path": "audio/victory.wav", + "sha256": "d69675d0d6c6cf8738fc826c9743ebab74ebb5fa90c97661055628c35c8edc2c", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "samples": 24255, + "seconds": 1.1, + "seed": 2203, + "peak": 20316, + "recipe": "deterministic seeded chirp/noise, original synthesis, no recordings" + } +} diff --git a/mods/iron_coast_stage2_mission_3/audio/approach.wav b/mods/iron_coast_stage2_mission_3/audio/approach.wav new file mode 100644 index 00000000..71ea402c Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/audio/approach.wav differ diff --git a/mods/iron_coast_stage2_mission_3/audio/boss_alarm.wav b/mods/iron_coast_stage2_mission_3/audio/boss_alarm.wav new file mode 100644 index 00000000..f7881205 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/audio/boss_alarm.wav differ diff --git a/mods/iron_coast_stage2_mission_3/audio/salvage.wav b/mods/iron_coast_stage2_mission_3/audio/salvage.wav new file mode 100644 index 00000000..2d890940 Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/audio/salvage.wav differ diff --git a/mods/iron_coast_stage2_mission_3/audio/target_alarm.wav b/mods/iron_coast_stage2_mission_3/audio/target_alarm.wav new file mode 100644 index 00000000..54ec4a9a Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/audio/target_alarm.wav differ diff --git a/mods/iron_coast_stage2_mission_3/audio/victory.wav b/mods/iron_coast_stage2_mission_3/audio/victory.wav new file mode 100644 index 00000000..d01a849d Binary files /dev/null and b/mods/iron_coast_stage2_mission_3/audio/victory.wav differ diff --git a/mods/iron_coast_stage2_mission_3/build_assets.py b/mods/iron_coast_stage2_mission_3/build_assets.py new file mode 100644 index 00000000..03e8dd14 --- /dev/null +++ b/mods/iron_coast_stage2_mission_3/build_assets.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python3 +"""Reproduce packaged artwork footprints and seeded local PCM audio. + +Builtin imagegen masters are preserved byte-for-byte. This recipe only crops +empty/runtime-subthreshold transparent padding, fits/resamples canvases, splits joined terrain and +quantizes SD to ordinary game palette colors; it never paints generated pixels. +""" +from pathlib import Path +import argparse,hashlib,json,math,random,struct,wave +from PIL import Image,ImageOps +ROOT=Path(__file__).resolve().parent +hashfile=lambda p:hashlib.sha256(p.read_bytes()).hexdigest() +def palette(path): + raw=path.read_bytes();assert len(raw)==768 + colors=[(min(v,63)<<2)|(min(v,63)>>4) for v in raw] + colors[720:]=colors[:48];im=Image.new('P',(1,1));im.putpalette(colors);return im + +def sd(im,size,pal): + im=im.convert('RGBA').resize(size,Image.Resampling.BOX);alpha=im.getchannel('A').point(lambda v:255 if v>=128 else 0) + out=im.convert('RGB').quantize(palette=pal,dither=Image.Dither.NONE).convert('RGBA');out.putalpha(alpha);return out + +def footprint(stem,logical,pal): + p=ROOT/'art'/f'{stem}-source-v1.png';raw=Image.open(p).convert('RGBA');assert raw.getchannel('A').getextrema()[0]==0,'genuine transparent master required' + # Keep every visible alpha>=128 sample. Imagegen adds isolated alpha1 noise + # across the canvas; threshold16 bounds remove only runtime-invisible padding, + # while the raw master and its original alpha remain untouched. + box=raw.getchannel('A').point(lambda v:255 if v>=16 else 0).getbbox();assert box;assert raw.getchannel('A').point(lambda v:255 if v>=128 else 0).getbbox();crop=raw.crop(box);size=tuple(v*8 for v in logical);margin=8 if stem=='shell' else 24 + hd=Image.new('RGBA',size);fitted=ImageOps.contain(crop,(size[0]-margin*2,size[1]-margin*2),Image.Resampling.LANCZOS);hd.alpha_composite(fitted,((size[0]-fitted.width)//2,(size[1]-fitted.height)//2));low=sd(hd,logical,pal) + for suffix,im in [('hd',hd),('sd',low)]: + bounds=im.getchannel('A').point(lambda v:255 if v>=128 else 0).getbbox();assert bounds and bounds[0]>0 and bounds[1]>0 and bounds[2]=128 else 0).getbbox()),'frame_count':1,'origin':[0,0],'generated_art_repainted':False} + +def synth(name,duration,seed,mode): + rate=22050;rng=random.Random(seed);count=round(rate*duration);phase=0;slow=0;v=[] + for i in range(count): + u=i/(count-1);t=i/rate;noise=rng.uniform(-1,1);slow=slow*.90+noise*.10 + if mode=='warning':freq=440+220*int(u*2);signal=math.sin(phase)*.60+math.sin(phase*2)*.15;env=math.sin(math.pi*u)**1.4 + elif mode=='shot':freq=440*(1-u)**2+65;signal=math.sin(phase)*.5+noise*.20+math.sin(phase*2.13)*.13;env=math.exp(-5*u) + elif mode=='death':freq=75-50*u;signal=slow*.6+noise*.18+math.sin(phase)*.25;env=math.exp(-4.5*u) + else: + notes=[294,370,440,587] if mode=='victory' else [220,294,440];freq=notes[min(len(notes)-1,int(u*len(notes)))];signal=math.sin(phase)*.65+math.sin(phase*2)*.12;env=min(1,(u*len(notes)%1)*20)*(1-u)**.6 + phase+=2*math.pi*freq/rate;env*=min(1,t/.004)*min(1,(count-1-i)/(rate*.005));v.append(signal*max(0,env)) + peak=max(abs(x) for x in v);target=.48 if mode=='warning' else .62;pcm=[round(x/peak*32767*target) for x in v];p=ROOT/'audio'/f'{name}.wav' + with wave.open(str(p),'wb') as w:w.setnchannels(1);w.setsampwidth(2);w.setframerate(rate);w.writeframes(struct.pack('<'+'h'*count,*pcm)) + return {'path':str(p.relative_to(ROOT)),'sha256':hashfile(p),'sample_rate':rate,'bits':16,'channels':1,'samples':count,'seconds':count/rate,'seed':seed,'peak':max(abs(x) for x in pcm),'recipe':'deterministic seeded chirp/noise, original synthesis, no recordings'} + +def main(): + ap=argparse.ArgumentParser();ap.add_argument('--palette',type=Path,default=ROOT.parents[1]/'data/misc/PALETTE_DAT');ap.add_argument('--audio-only',action='store_true');a=ap.parse_args();is_boss='boss' in ROOT.name;stage=int(ROOT.name[-1]);sounds={} + sound_specs=[('warning',.36,'warning'),('shot',.20,'shot'),('death',.95,'death')] if is_boss else [('approach',.78,'tone'),('target_alarm',.42,'warning'),('boss_alarm',.65,'warning'),('salvage',.32,'tone'),('victory',1.10,'victory')] + for i,(n,d,m) in enumerate(sound_specs):sounds[n]=synth(n,d,stage*733+i,m) + (ROOT/'audio-recipe.json').write_text(json.dumps(sounds,indent=2)+'\n') + if a.audio_only:return + pal=palette(a.palette);report={'palette_sha256':hashfile(a.palette),'ordinary_palette_entries_only':True,'audio':sounds} + if is_boss: + report['unit']=footprint('unit',(104,72 if stage==3 else 64),pal);report['shell']=footprint('shell',(8,8),pal) + else: + report['target']=footprint('target',(32,32),pal);p=ROOT/'art/terrain-source-v1.png';source=Image.open(p).convert('RGBA');assert source.getchannel('A').getextrema()[0]>=128,'terrain must be fully opaque' + hd=ImageOps.fit(source,(1152,2048),Image.Resampling.LANCZOS);low=sd(hd,(288,512),pal);tiles=0 + for reverse in [False,True]: + hi=ImageOps.flip(hd) if reverse else hd;lo=ImageOps.flip(low) if reverse else low + for row in range(16): + for col in range(9): + hi.crop((col*128,row*128,(col+1)*128,(row+1)*128)).save(ROOT/'art'/f'tile-{tiles:03}-hd.png');lo.crop((col*32,row*32,(col+1)*32,(row+1)*32)).save(ROOT/'art'/f'tile-{tiles:03}-sd.png');tiles+=1 + for im in [hd,low]:assert im.crop((0,im.height-1,im.width,im.height)).tobytes()==ImageOps.flip(im).crop((0,0,im.width,1)).tobytes() + # Briefing is a truthful wide crop of the generated terrain, not new artwork. + briefing=ImageOps.fit(source,(1280,800),Image.Resampling.LANCZOS);briefing.save(ROOT/'art/briefing-hd.png');sd(briefing,(320,200),pal).save(ROOT/'art/briefing-sd.png');low.save(ROOT/'art/terrain-preview-sd.png');hd.save(ROOT/'art/terrain-preview-hd.png') + report['terrain']={'master_sha256':hashfile(p),'master_size':list(source.size),'logical_joined_size':[288,512],'hd_joined_size':[1152,2048],'tiles':tiles,'period_rows':32,'repeat':'forward16 rows then reflected16 rows, both periodboundaries identical','joined_before_quantizing_and_splitting':True,'seam_checks':True,'briefing':'320x200 /1280x800 central wide crop from same genuine terrain master'} + (ROOT/'asset-report.json').write_text(json.dumps(report,indent=2)+'\n');print(ROOT.name,'assets/sounds ready') +if __name__=='__main__':main() diff --git a/mods/iron_coast_stage2_mission_3/content.json b/mods/iron_coast_stage2_mission_3/content.json new file mode 100644 index 00000000..91a83fbe --- /dev/null +++ b/mods/iron_coast_stage2_mission_3/content.json @@ -0,0 +1,5158 @@ +{ + "enemies": [ + { + "id": "iron_coast_stage2_mission_3:target", + "name": "Refinery Fuel Battery", + "health": 22, + "speed": 0, + "reward": 450, + "ground": true, + "boss": false, + "art": { + "png": "art/target-sd.png", + "hd_png": "art/target-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + }, + "script": "scripts/target.rhai" + } + ], + "sounds": [ + { + "id": "iron_coast_stage2_mission_3:approach", + "name": "Approach", + "file": "audio/approach.wav", + "volume": 72, + "pan": 127, + "pitch": 128, + "priority": 2 + }, + { + "id": "iron_coast_stage2_mission_3:target_alarm", + "name": "Target Alarm", + "file": "audio/target_alarm.wav", + "volume": 72, + "pan": 127, + "pitch": 128, + "priority": 2 + }, + { + "id": "iron_coast_stage2_mission_3:boss_alarm", + "name": "Boss Alarm", + "file": "audio/boss_alarm.wav", + "volume": 72, + "pan": 127, + "pitch": 128, + "priority": 2 + }, + { + "id": "iron_coast_stage2_mission_3:salvage", + "name": "Salvage", + "file": "audio/salvage.wav", + "volume": 72, + "pan": 127, + "pitch": 128, + "priority": 2 + }, + { + "id": "iron_coast_stage2_mission_3:victory", + "name": "Victory", + "file": "audio/victory.wav", + "volume": 95, + "pan": 127, + "pitch": 128, + "priority": 2 + } + ], + "missions": [ + { + "id": "iron_coast_stage2_mission_3:mission_03", + "name": "Iron Coast II 3 \u2014 Stormglass Refinery", + "duration": 3300, + "auto_complete": false, + "columns": 9, + "layout": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 216, + 217, + 218, + 219, + 220, + 221, + 222, + 223, + 224, + 225, + 226, + 227, + 228, + 229, + 230, + 231, + 232, + 233, + 234, + 235, + 236, + 237, + 238, + 239, + 240, + 241, + 242, + 243, + 244, + 245, + 246, + 247, + 248, + 249, + 250, + 251, + 252, + 253, + 254, + 255, + 256, + 257, + 258, + 259, + 260, + 261, + 262, + 263, + 264, + 265, + 266, + 267, + 268, + 269, + 270, + 271, + 272, + 273, + 274, + 275, + 276, + 277, + 278, + 279, + 280, + 281, + 282, + 283, + 284, + 285, + 286, + 287, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 216, + 217, + 218, + 219, + 220, + 221, + 222, + 223, + 224, + 225, + 226, + 227, + 228, + 229, + 230, + 231, + 232, + 233, + 234, + 235, + 236, + 237, + 238, + 239, + 240, + 241, + 242, + 243, + 244, + 245, + 246, + 247, + 248, + 249, + 250, + 251, + 252, + 253, + 254, + 255, + 256, + 257, + 258, + 259, + 260, + 261, + 262, + 263, + 264, + 265, + 266, + 267, + 268, + 269, + 270, + 271, + 272, + 273, + 274, + 275, + 276, + 277, + 278, + 279, + 280, + 281, + 282, + 283, + 284, + 285, + 286, + 287, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 216, + 217, + 218, + 219, + 220, + 221, + 222, + 223, + 224, + 225, + 226, + 227, + 228, + 229, + 230, + 231, + 232, + 233, + 234, + 235, + 236, + 237, + 238, + 239, + 240, + 241, + 242, + 243, + 244, + 245, + 246, + 247, + 248, + 249, + 250, + 251, + 252, + 253, + 254, + 255, + 256, + 257, + 258, + 259, + 260, + 261, + 262, + 263, + 264, + 265, + 266, + 267, + 268, + 269, + 270, + 271, + 272, + 273, + 274, + 275, + 276, + 277, + 278, + 279, + 280, + 281, + 282, + 283, + 284, + 285, + 286, + 287, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 216, + 217, + 218, + 219, + 220, + 221, + 222, + 223, + 224, + 225, + 226, + 227, + 228, + 229, + 230, + 231, + 232, + 233, + 234, + 235, + 236, + 237, + 238, + 239, + 240, + 241, + 242, + 243, + 244, + 245, + 246, + 247, + 248, + 249, + 250, + 251, + 252, + 253, + 254, + 255, + 256, + 257, + 258, + 259, + 260, + 261, + 262, + 263, + 264, + 265, + 266, + 267, + 268, + 269, + 270, + 271, + 272, + 273, + 274, + 275, + 276, + 277, + 278, + 279, + 280, + 281, + 282, + 283, + 284, + 285, + 286, + 287, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 216, + 217, + 218, + 219, + 220, + 221, + 222, + 223, + 224, + 225, + 226, + 227, + 228, + 229, + 230, + 231, + 232, + 233, + 234, + 235, + 236, + 237, + 238, + 239, + 240, + 241, + 242, + 243, + 244, + 245, + 246, + 247, + 248, + 249, + 250, + 251, + 252, + 253, + 254, + 255, + 256, + 257, + 258, + 259, + 260, + 261, + 262, + 263, + 264, + 265, + 266, + 267, + 268, + 269, + 270, + 271, + 272, + 273, + 274, + 275, + 276, + 277, + 278, + 279, + 280, + 281, + 282, + 283, + 284, + 285, + 286, + 287, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 216, + 217, + 218, + 219, + 220, + 221, + 222, + 223, + 224, + 225, + 226, + 227, + 228, + 229, + 230, + 231, + 232, + 233, + 234, + 235, + 236, + 237, + 238, + 239, + 240, + 241, + 242, + 243, + 244, + 245, + 246, + 247, + 248, + 249, + 250, + 251, + 252, + 253, + 254, + 255, + 256, + 257, + 258, + 259, + 260, + 261, + 262, + 263, + 264, + 265, + 266, + 267, + 268, + 269, + 270, + 271, + 272, + 273, + 274, + 275, + 276, + 277, + 278, + 279, + 280, + 281, + 282, + 283, + 284, + 285, + 286, + 287, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 216, + 217, + 218, + 219, + 220, + 221, + 222, + 223, + 224, + 225, + 226, + 227, + 228, + 229, + 230, + 231, + 232, + 233, + 234, + 235, + 236, + 237, + 238, + 239, + 240, + 241, + 242, + 243, + 244, + 245, + 246, + 247, + 248, + 249, + 250, + 251, + 252, + 253, + 254, + 255, + 256, + 257, + 258, + 259, + 260, + 261, + 262, + 263, + 264, + 265, + 266, + 267, + 268, + 269, + 270, + 271, + 272, + 273, + 274, + 275, + 276, + 277, + 278, + 279, + 280, + 281, + 282, + 283, + 284, + 285, + 286, + 287, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 216, + 217, + 218, + 219, + 220, + 221, + 222, + 223, + 224, + 225, + 226, + 227, + 228, + 229, + 230, + 231, + 232, + 233, + 234, + 235, + 236, + 237, + 238, + 239, + 240, + 241, + 242, + 243, + 244, + 245, + 246, + 247, + 248, + 249, + 250, + 251, + 252, + 253, + 254, + 255, + 256, + 257, + 258, + 259, + 260, + 261, + 262, + 263, + 264, + 265, + 266, + 267, + 268, + 269, + 270, + 271, + 272, + 273, + 274, + 275, + 276, + 277, + 278, + 279, + 280, + 281, + 282, + 283, + 284, + 285, + 286, + 287 + ], + "spawns": [ + { + "tick": 80, + "enemy": "base:enemy_0_73", + "x": 180, + "y": -80, + "difficulty": 0 + }, + { + "tick": 180, + "enemy": "iron_coast_stage2_mission_3:target", + "x": 56, + "y": -32, + "difficulty": 0 + }, + { + "tick": 230, + "enemy": "iron_coast_stage2_interceptor:unit", + "x": 104, + "y": -40, + "difficulty": 0 + }, + { + "tick": 300, + "enemy": "base:enemy_2_25", + "x": 240, + "y": -40, + "difficulty": 0 + }, + { + "tick": 390, + "enemy": "iron_coast_stage2_siege:unit", + "x": 216, + "y": -40, + "difficulty": 0 + }, + { + "tick": 470, + "enemy": "base:enemy_0_20", + "x": 112, + "y": -88, + "difficulty": 0 + }, + { + "tick": 620, + "enemy": "iron_coast_stage2_mission_3:target", + "x": 216, + "y": -32, + "difficulty": 0 + }, + { + "tick": 720, + "enemy": "iron_coast_stage2_interceptor:unit", + "x": 200, + "y": -40, + "difficulty": 0 + }, + { + "tick": 820, + "enemy": "base:enemy_0_79", + "x": 200, + "y": -32, + "difficulty": 0 + }, + { + "tick": 970, + "enemy": "iron_coast_stage2_siege:unit", + "x": 56, + "y": -40, + "difficulty": 0 + }, + { + "tick": 1030, + "enemy": "base:enemy_0_74", + "x": 72, + "y": -88, + "difficulty": 0 + }, + { + "tick": 1100, + "enemy": "iron_coast_stage2_mission_3:target", + "x": 96, + "y": -32, + "difficulty": 0 + }, + { + "tick": 1190, + "enemy": "iron_coast_stage2_interceptor:unit", + "x": 72, + "y": -40, + "difficulty": 0 + }, + { + "tick": 1280, + "enemy": "base:enemy_2_26", + "x": 40, + "y": -40, + "difficulty": 0 + }, + { + "tick": 1460, + "enemy": "iron_coast_stage2_siege:unit", + "x": 224, + "y": -40, + "difficulty": 0 + }, + { + "tick": 1520, + "enemy": "base:enemy_0_21", + "x": 224, + "y": -40, + "difficulty": 0 + }, + { + "tick": 1630, + "enemy": "iron_coast_stage2_mission_3:target", + "x": 184, + "y": -32, + "difficulty": 0 + }, + { + "tick": 1780, + "enemy": "iron_coast_stage2_interceptor:unit", + "x": 184, + "y": -40, + "difficulty": 0 + }, + { + "tick": 1840, + "enemy": "base:enemy_0_22", + "x": 56, + "y": -40, + "difficulty": 0 + }, + { + "tick": 2000, + "enemy": "iron_coast_stage2_siege:unit", + "x": 80, + "y": -40, + "difficulty": 0 + }, + { + "tick": 2100, + "enemy": "iron_coast_stage2_boss_3:unit", + "x": 108, + "y": -72, + "difficulty": 0 + }, + { + "tick": 2250, + "enemy": "iron_coast_stage2_interceptor:unit", + "x": 224, + "y": -40, + "difficulty": 0 + } + ], + "art": { + "png": "art/briefing-sd.png", + "hd_png": "art/briefing-hd.png", + "logical_width": 320, + "logical_height": 200, + "frames": 1 + }, + "script": "scripts/mission.rhai", + "music_track": "iron_coast_stage2_music:assault", + "tiles": [ + { + "art": { + "png": "art/tile-000-sd.png", + "hd_png": "art/tile-000-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-001-sd.png", + "hd_png": "art/tile-001-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-002-sd.png", + "hd_png": "art/tile-002-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-003-sd.png", + "hd_png": "art/tile-003-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-004-sd.png", + "hd_png": "art/tile-004-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-005-sd.png", + "hd_png": "art/tile-005-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-006-sd.png", + "hd_png": "art/tile-006-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-007-sd.png", + "hd_png": "art/tile-007-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-008-sd.png", + "hd_png": "art/tile-008-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-009-sd.png", + "hd_png": "art/tile-009-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-010-sd.png", + "hd_png": "art/tile-010-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-011-sd.png", + "hd_png": "art/tile-011-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-012-sd.png", + "hd_png": "art/tile-012-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-013-sd.png", + "hd_png": "art/tile-013-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-014-sd.png", + "hd_png": "art/tile-014-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-015-sd.png", + "hd_png": "art/tile-015-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-016-sd.png", + "hd_png": "art/tile-016-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-017-sd.png", + "hd_png": "art/tile-017-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-018-sd.png", + "hd_png": "art/tile-018-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-019-sd.png", + "hd_png": "art/tile-019-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-020-sd.png", + "hd_png": "art/tile-020-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-021-sd.png", + "hd_png": "art/tile-021-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-022-sd.png", + "hd_png": "art/tile-022-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-023-sd.png", + "hd_png": "art/tile-023-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-024-sd.png", + "hd_png": "art/tile-024-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-025-sd.png", + "hd_png": "art/tile-025-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-026-sd.png", + "hd_png": "art/tile-026-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-027-sd.png", + "hd_png": "art/tile-027-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-028-sd.png", + "hd_png": "art/tile-028-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-029-sd.png", + "hd_png": "art/tile-029-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-030-sd.png", + "hd_png": "art/tile-030-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-031-sd.png", + "hd_png": "art/tile-031-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-032-sd.png", + "hd_png": "art/tile-032-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-033-sd.png", + "hd_png": "art/tile-033-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-034-sd.png", + "hd_png": "art/tile-034-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-035-sd.png", + "hd_png": "art/tile-035-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-036-sd.png", + "hd_png": "art/tile-036-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-037-sd.png", + "hd_png": "art/tile-037-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-038-sd.png", + "hd_png": "art/tile-038-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-039-sd.png", + "hd_png": "art/tile-039-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-040-sd.png", + "hd_png": "art/tile-040-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-041-sd.png", + "hd_png": "art/tile-041-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-042-sd.png", + "hd_png": "art/tile-042-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-043-sd.png", + "hd_png": "art/tile-043-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-044-sd.png", + "hd_png": "art/tile-044-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-045-sd.png", + "hd_png": "art/tile-045-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-046-sd.png", + "hd_png": "art/tile-046-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-047-sd.png", + "hd_png": "art/tile-047-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-048-sd.png", + "hd_png": "art/tile-048-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-049-sd.png", + "hd_png": "art/tile-049-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-050-sd.png", + "hd_png": "art/tile-050-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-051-sd.png", + "hd_png": "art/tile-051-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-052-sd.png", + "hd_png": "art/tile-052-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-053-sd.png", + "hd_png": "art/tile-053-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-054-sd.png", + "hd_png": "art/tile-054-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-055-sd.png", + "hd_png": "art/tile-055-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-056-sd.png", + "hd_png": "art/tile-056-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-057-sd.png", + "hd_png": "art/tile-057-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-058-sd.png", + "hd_png": "art/tile-058-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-059-sd.png", + "hd_png": "art/tile-059-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-060-sd.png", + "hd_png": "art/tile-060-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-061-sd.png", + "hd_png": "art/tile-061-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-062-sd.png", + "hd_png": "art/tile-062-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-063-sd.png", + "hd_png": "art/tile-063-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-064-sd.png", + "hd_png": "art/tile-064-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-065-sd.png", + "hd_png": "art/tile-065-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-066-sd.png", + "hd_png": "art/tile-066-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-067-sd.png", + "hd_png": "art/tile-067-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-068-sd.png", + "hd_png": "art/tile-068-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-069-sd.png", + "hd_png": "art/tile-069-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-070-sd.png", + "hd_png": "art/tile-070-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-071-sd.png", + "hd_png": "art/tile-071-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-072-sd.png", + "hd_png": "art/tile-072-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-073-sd.png", + "hd_png": "art/tile-073-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-074-sd.png", + "hd_png": "art/tile-074-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-075-sd.png", + "hd_png": "art/tile-075-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-076-sd.png", + "hd_png": "art/tile-076-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-077-sd.png", + "hd_png": "art/tile-077-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-078-sd.png", + "hd_png": "art/tile-078-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-079-sd.png", + "hd_png": "art/tile-079-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-080-sd.png", + "hd_png": "art/tile-080-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-081-sd.png", + "hd_png": "art/tile-081-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-082-sd.png", + "hd_png": "art/tile-082-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-083-sd.png", + "hd_png": "art/tile-083-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-084-sd.png", + "hd_png": "art/tile-084-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-085-sd.png", + "hd_png": "art/tile-085-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-086-sd.png", + "hd_png": "art/tile-086-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-087-sd.png", + "hd_png": "art/tile-087-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-088-sd.png", + "hd_png": "art/tile-088-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-089-sd.png", + "hd_png": "art/tile-089-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-090-sd.png", + "hd_png": "art/tile-090-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-091-sd.png", + "hd_png": "art/tile-091-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-092-sd.png", + "hd_png": "art/tile-092-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-093-sd.png", + "hd_png": "art/tile-093-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-094-sd.png", + "hd_png": "art/tile-094-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-095-sd.png", + "hd_png": "art/tile-095-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-096-sd.png", + "hd_png": "art/tile-096-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-097-sd.png", + "hd_png": "art/tile-097-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-098-sd.png", + "hd_png": "art/tile-098-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-099-sd.png", + "hd_png": "art/tile-099-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-100-sd.png", + "hd_png": "art/tile-100-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-101-sd.png", + "hd_png": "art/tile-101-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-102-sd.png", + "hd_png": "art/tile-102-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-103-sd.png", + "hd_png": "art/tile-103-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-104-sd.png", + "hd_png": "art/tile-104-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-105-sd.png", + "hd_png": "art/tile-105-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-106-sd.png", + "hd_png": "art/tile-106-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-107-sd.png", + "hd_png": "art/tile-107-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-108-sd.png", + "hd_png": "art/tile-108-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-109-sd.png", + "hd_png": "art/tile-109-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-110-sd.png", + "hd_png": "art/tile-110-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-111-sd.png", + "hd_png": "art/tile-111-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-112-sd.png", + "hd_png": "art/tile-112-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-113-sd.png", + "hd_png": "art/tile-113-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-114-sd.png", + "hd_png": "art/tile-114-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-115-sd.png", + "hd_png": "art/tile-115-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-116-sd.png", + "hd_png": "art/tile-116-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-117-sd.png", + "hd_png": "art/tile-117-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-118-sd.png", + "hd_png": "art/tile-118-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-119-sd.png", + "hd_png": "art/tile-119-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-120-sd.png", + "hd_png": "art/tile-120-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-121-sd.png", + "hd_png": "art/tile-121-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-122-sd.png", + "hd_png": "art/tile-122-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-123-sd.png", + "hd_png": "art/tile-123-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-124-sd.png", + "hd_png": "art/tile-124-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-125-sd.png", + "hd_png": "art/tile-125-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-126-sd.png", + "hd_png": "art/tile-126-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-127-sd.png", + "hd_png": "art/tile-127-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-128-sd.png", + "hd_png": "art/tile-128-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-129-sd.png", + "hd_png": "art/tile-129-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-130-sd.png", + "hd_png": "art/tile-130-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-131-sd.png", + "hd_png": "art/tile-131-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-132-sd.png", + "hd_png": "art/tile-132-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-133-sd.png", + "hd_png": "art/tile-133-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-134-sd.png", + "hd_png": "art/tile-134-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-135-sd.png", + "hd_png": "art/tile-135-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-136-sd.png", + "hd_png": "art/tile-136-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-137-sd.png", + "hd_png": "art/tile-137-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-138-sd.png", + "hd_png": "art/tile-138-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-139-sd.png", + "hd_png": "art/tile-139-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-140-sd.png", + "hd_png": "art/tile-140-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-141-sd.png", + "hd_png": "art/tile-141-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-142-sd.png", + "hd_png": "art/tile-142-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-143-sd.png", + "hd_png": "art/tile-143-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-144-sd.png", + "hd_png": "art/tile-144-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-145-sd.png", + "hd_png": "art/tile-145-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-146-sd.png", + "hd_png": "art/tile-146-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-147-sd.png", + "hd_png": "art/tile-147-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-148-sd.png", + "hd_png": "art/tile-148-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-149-sd.png", + "hd_png": "art/tile-149-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-150-sd.png", + "hd_png": "art/tile-150-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-151-sd.png", + "hd_png": "art/tile-151-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-152-sd.png", + "hd_png": "art/tile-152-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-153-sd.png", + "hd_png": "art/tile-153-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-154-sd.png", + "hd_png": "art/tile-154-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-155-sd.png", + "hd_png": "art/tile-155-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-156-sd.png", + "hd_png": "art/tile-156-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-157-sd.png", + "hd_png": "art/tile-157-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-158-sd.png", + "hd_png": "art/tile-158-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-159-sd.png", + "hd_png": "art/tile-159-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-160-sd.png", + "hd_png": "art/tile-160-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-161-sd.png", + "hd_png": "art/tile-161-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-162-sd.png", + "hd_png": "art/tile-162-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-163-sd.png", + "hd_png": "art/tile-163-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-164-sd.png", + "hd_png": "art/tile-164-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-165-sd.png", + "hd_png": "art/tile-165-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-166-sd.png", + "hd_png": "art/tile-166-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-167-sd.png", + "hd_png": "art/tile-167-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-168-sd.png", + "hd_png": "art/tile-168-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-169-sd.png", + "hd_png": "art/tile-169-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-170-sd.png", + "hd_png": "art/tile-170-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-171-sd.png", + "hd_png": "art/tile-171-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-172-sd.png", + "hd_png": "art/tile-172-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-173-sd.png", + "hd_png": "art/tile-173-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-174-sd.png", + "hd_png": "art/tile-174-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-175-sd.png", + "hd_png": "art/tile-175-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-176-sd.png", + "hd_png": "art/tile-176-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-177-sd.png", + "hd_png": "art/tile-177-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-178-sd.png", + "hd_png": "art/tile-178-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-179-sd.png", + "hd_png": "art/tile-179-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-180-sd.png", + "hd_png": "art/tile-180-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-181-sd.png", + "hd_png": "art/tile-181-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-182-sd.png", + "hd_png": "art/tile-182-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-183-sd.png", + "hd_png": "art/tile-183-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-184-sd.png", + "hd_png": "art/tile-184-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-185-sd.png", + "hd_png": "art/tile-185-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-186-sd.png", + "hd_png": "art/tile-186-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-187-sd.png", + "hd_png": "art/tile-187-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-188-sd.png", + "hd_png": "art/tile-188-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-189-sd.png", + "hd_png": "art/tile-189-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-190-sd.png", + "hd_png": "art/tile-190-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-191-sd.png", + "hd_png": "art/tile-191-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-192-sd.png", + "hd_png": "art/tile-192-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-193-sd.png", + "hd_png": "art/tile-193-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-194-sd.png", + "hd_png": "art/tile-194-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-195-sd.png", + "hd_png": "art/tile-195-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-196-sd.png", + "hd_png": "art/tile-196-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-197-sd.png", + "hd_png": "art/tile-197-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-198-sd.png", + "hd_png": "art/tile-198-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-199-sd.png", + "hd_png": "art/tile-199-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-200-sd.png", + "hd_png": "art/tile-200-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-201-sd.png", + "hd_png": "art/tile-201-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-202-sd.png", + "hd_png": "art/tile-202-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-203-sd.png", + "hd_png": "art/tile-203-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-204-sd.png", + "hd_png": "art/tile-204-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-205-sd.png", + "hd_png": "art/tile-205-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-206-sd.png", + "hd_png": "art/tile-206-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-207-sd.png", + "hd_png": "art/tile-207-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-208-sd.png", + "hd_png": "art/tile-208-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-209-sd.png", + "hd_png": "art/tile-209-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-210-sd.png", + "hd_png": "art/tile-210-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-211-sd.png", + "hd_png": "art/tile-211-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-212-sd.png", + "hd_png": "art/tile-212-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-213-sd.png", + "hd_png": "art/tile-213-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-214-sd.png", + "hd_png": "art/tile-214-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-215-sd.png", + "hd_png": "art/tile-215-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-216-sd.png", + "hd_png": "art/tile-216-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-217-sd.png", + "hd_png": "art/tile-217-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-218-sd.png", + "hd_png": "art/tile-218-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-219-sd.png", + "hd_png": "art/tile-219-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-220-sd.png", + "hd_png": "art/tile-220-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-221-sd.png", + "hd_png": "art/tile-221-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-222-sd.png", + "hd_png": "art/tile-222-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-223-sd.png", + "hd_png": "art/tile-223-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-224-sd.png", + "hd_png": "art/tile-224-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-225-sd.png", + "hd_png": "art/tile-225-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-226-sd.png", + "hd_png": "art/tile-226-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-227-sd.png", + "hd_png": "art/tile-227-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-228-sd.png", + "hd_png": "art/tile-228-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-229-sd.png", + "hd_png": "art/tile-229-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-230-sd.png", + "hd_png": "art/tile-230-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-231-sd.png", + "hd_png": "art/tile-231-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-232-sd.png", + "hd_png": "art/tile-232-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-233-sd.png", + "hd_png": "art/tile-233-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-234-sd.png", + "hd_png": "art/tile-234-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-235-sd.png", + "hd_png": "art/tile-235-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-236-sd.png", + "hd_png": "art/tile-236-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-237-sd.png", + "hd_png": "art/tile-237-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-238-sd.png", + "hd_png": "art/tile-238-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-239-sd.png", + "hd_png": "art/tile-239-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-240-sd.png", + "hd_png": "art/tile-240-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-241-sd.png", + "hd_png": "art/tile-241-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-242-sd.png", + "hd_png": "art/tile-242-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-243-sd.png", + "hd_png": "art/tile-243-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-244-sd.png", + "hd_png": "art/tile-244-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-245-sd.png", + "hd_png": "art/tile-245-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-246-sd.png", + "hd_png": "art/tile-246-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-247-sd.png", + "hd_png": "art/tile-247-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-248-sd.png", + "hd_png": "art/tile-248-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-249-sd.png", + "hd_png": "art/tile-249-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-250-sd.png", + "hd_png": "art/tile-250-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-251-sd.png", + "hd_png": "art/tile-251-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-252-sd.png", + "hd_png": "art/tile-252-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-253-sd.png", + "hd_png": "art/tile-253-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-254-sd.png", + "hd_png": "art/tile-254-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-255-sd.png", + "hd_png": "art/tile-255-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-256-sd.png", + "hd_png": "art/tile-256-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-257-sd.png", + "hd_png": "art/tile-257-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-258-sd.png", + "hd_png": "art/tile-258-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-259-sd.png", + "hd_png": "art/tile-259-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-260-sd.png", + "hd_png": "art/tile-260-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-261-sd.png", + "hd_png": "art/tile-261-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-262-sd.png", + "hd_png": "art/tile-262-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-263-sd.png", + "hd_png": "art/tile-263-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-264-sd.png", + "hd_png": "art/tile-264-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-265-sd.png", + "hd_png": "art/tile-265-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-266-sd.png", + "hd_png": "art/tile-266-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-267-sd.png", + "hd_png": "art/tile-267-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-268-sd.png", + "hd_png": "art/tile-268-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-269-sd.png", + "hd_png": "art/tile-269-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-270-sd.png", + "hd_png": "art/tile-270-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-271-sd.png", + "hd_png": "art/tile-271-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-272-sd.png", + "hd_png": "art/tile-272-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-273-sd.png", + "hd_png": "art/tile-273-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-274-sd.png", + "hd_png": "art/tile-274-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-275-sd.png", + "hd_png": "art/tile-275-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-276-sd.png", + "hd_png": "art/tile-276-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-277-sd.png", + "hd_png": "art/tile-277-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-278-sd.png", + "hd_png": "art/tile-278-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-279-sd.png", + "hd_png": "art/tile-279-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-280-sd.png", + "hd_png": "art/tile-280-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-281-sd.png", + "hd_png": "art/tile-281-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-282-sd.png", + "hd_png": "art/tile-282-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-283-sd.png", + "hd_png": "art/tile-283-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-284-sd.png", + "hd_png": "art/tile-284-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-285-sd.png", + "hd_png": "art/tile-285-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-286-sd.png", + "hd_png": "art/tile-286-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-287-sd.png", + "hd_png": "art/tile-287-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + } + ] + } + ], + "campaigns": [ + { + "id": "iron_coast_stage2_mission_3:campaign", + "name": "Stormglass Refinery \u2014 Standalone", + "missions": [ + "iron_coast_stage2_mission_3:mission_03" + ], + "art": { + "png": "art/briefing-sd.png", + "hd_png": "art/briefing-hd.png", + "logical_width": 320, + "logical_height": 200, + "frames": 1 + } + } + ] +} diff --git a/mods/iron_coast_stage2_mission_3/design.json b/mods/iron_coast_stage2_mission_3/design.json new file mode 100644 index 00000000..97b8f6c2 --- /dev/null +++ b/mods/iron_coast_stage2_mission_3/design.json @@ -0,0 +1,29 @@ +{ + "title": "Stormglass Refinery", + "required_target_kills": 4, + "boss_arrival_tick": 2100, + "duration_hint_ticks": 3300, + "objective_timeout": false, + "completion_reward": 14500, + "target_reward": 450, + "target_salvage_shield": 12, + "equipment_loans": false, + "classic_ids": [ + "base:enemy_0_73", + "base:enemy_2_25", + "base:enemy_0_20", + "base:enemy_0_79", + "base:enemy_0_74", + "base:enemy_2_26", + "base:enemy_0_21", + "base:enemy_0_22" + ], + "shared_units": [ + "iron_coast_stage2_interceptor:unit", + "iron_coast_stage2_siege:unit" + ], + "music_track": "iron_coast_stage2_music:assault", + "terrain_layout_rows": 256, + "terrain_repeat_period_rows": 32, + "terrain_visual_scroll_span": 8192 +} diff --git a/mods/iron_coast_stage2_mission_3/mod.toml b/mods/iron_coast_stage2_mission_3/mod.toml new file mode 100644 index 00000000..0aa816f7 --- /dev/null +++ b/mods/iron_coast_stage2_mission_3/mod.toml @@ -0,0 +1,13 @@ +id = "iron_coast_stage2_mission_3" +name = "Iron Coast II — Mission 3: Stormglass Refinery" +version = "1.0.0" +api_version = 1 +description = "Stormglass Refinery: four mandatory defenses and the distinct Stormglass boss. Original classic enemies interleave new units; objective survivors stay reachable." +content = "content.json" +scripts = ["scripts/mission.rhai", "scripts/target.rhai"] + +[dependencies] +iron_coast_stage2_boss_3 = "^1.0" +iron_coast_stage2_interceptor = "^1.0" +iron_coast_stage2_siege = "^1.0" +iron_coast_stage2_music = "^1.0" diff --git a/mods/iron_coast_stage2_mission_3/prompts/target-v1.txt b/mods/iron_coast_stage2_mission_3/prompts/target-v1.txt new file mode 100644 index 00000000..f86dede8 --- /dev/null +++ b/mods/iron_coast_stage2_mission_3/prompts/target-v1.txt @@ -0,0 +1,4 @@ +Use case: stylized-concept +Asset type: new Iron Coast II game sprite/terrain master +Style reference is the original Raptor contact sheet: exact top-down mechanical vehicle/terrain shapes, muted gray-bronze steel, worn panels, dark outlines, compact DOS-shooter readability. Create original new artwork matching that visual language with cleaner high-resolution detail, not a copy or a photograph. +Primary request: One isolated refinery fuel battery: square32x32logical ground structure in strict top-down view, four compact bronze fuel cells around a gray steel electrical coupling, small cyan insulators, clean readable industrial square silhouette with distinct dark gaps and silver panel borders. Muted storm-wet material, restrained details, no fire or smoke. Entire source object with generous transparent margins, no surrounding terrain, no text, no cast shadow outside object. diff --git a/mods/iron_coast_stage2_mission_3/prompts/terrain-v1.txt b/mods/iron_coast_stage2_mission_3/prompts/terrain-v1.txt new file mode 100644 index 00000000..92cea3ef --- /dev/null +++ b/mods/iron_coast_stage2_mission_3/prompts/terrain-v1.txt @@ -0,0 +1,4 @@ +Use case: stylized-concept +Asset type: new Iron Coast II game sprite/terrain master +Style reference is the original Raptor contact sheet: exact top-down mechanical vehicle/terrain shapes, muted gray-bronze steel, worn panels, dark outlines, compact DOS-shooter readability. Create original new artwork matching that visual language with cleaner high-resolution detail, not a copy or a photograph. +Primary request: Full opaque portrait top-down game scrolling terrain canvas for Stormglass Refinery: lightning-season industrial coastal fuelworks seen from directly overhead. Low-contrast wet gray-brown concrete platforms and service roads, bronze fuel cylinders/pipes along both side thirds, cool black-blue drainage canals through the center third, occasional thin cyan conduit accents, small rain puddles, no lightning bolts painted over gameplay. Nine tilecolumns by16rows ofcontinuous terrain, no visible tile grid. Broad central flight corridor remains uncluttered for sprite readability. Coherent orthographic industrial geometry, hand-painted pixel-inspired detailed game art. Landscape fills whole portrait image; no sky/horizon, no ships/enemies, no text, no UI or border. Vertical composition approximately9:16. diff --git a/mods/iron_coast_stage2_mission_3/provenance-target.json b/mods/iron_coast_stage2_mission_3/provenance-target.json new file mode 100644 index 00000000..329bdd35 --- /dev/null +++ b/mods/iron_coast_stage2_mission_3/provenance-target.json @@ -0,0 +1,39 @@ +{ + "generator": "built-in image_gen.imagegen", + "owner": "/root/iron_coast_3", + "job_id": "stage2-target3", + "utc": "2026-10-11T08:16:02.527057+00:00", + "default_output": "/home/quintine/.codex/generated_images/01a1245d-8d97-74e2-9a2c-02e88a570589/exec-60328395-1cd8-4531-994b-1295ac28ea6e.png", + "raw_master": "art/target-source-v1.png", + "raw_sha256": "6bd85c922d2be0a2671777e8f7f9a7e0623ff7abc709e7b489140db9c2a74964", + "prompt": "prompts/target-v1.txt", + "prompt_sha256": "974b78bd3daa8968cb5f0a4e051f19412e28d7cc083ce0d83fef51c2791c99bd", + "style_reference_role": "Original Raptor style only; decoded style reference is intentionally external to authored mod.", + "reference_sha256": "685307409d68baa9413975b59427c74d29f6a09b2b039a3d88ee69abf19e9a9d", + "original_style_source_hashes": [ + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/enemies-200cc-200cd/sources/200cc.png", + "sha256": "c3f92b8a04370029652cfff20dc00ec41228c5adead37affaacd3b9511bb520d", + "role": "Original Raptor style reference; not copied into authored mods." + }, + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/enemies-2008d-2008d/sources/2008d.png", + "sha256": "419514e3b7cbd9fb7283f0550f12991f5570c2de16c367330fa2e8a9b6bb3725", + "role": "Original Raptor style reference; not copied into authored mods." + }, + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/bosses-10310-10310/sources/10310.png", + "sha256": "39404e604c4d535e868ffea924ba206c690e19f7df9c289ce14612cb2451bbef", + "role": "Original Raptor style reference; not copied into authored mods." + }, + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/terrain-10360-1036f/sources/10360.png", + "sha256": "ee5348dbdf57952027349c64cd13c9d2991a33b0378a54f4750622d9bff50dc0", + "role": "Original Raptor style reference; not copied into authored mods." + } + ], + "transparent_background_requested": true, + "gate_lease": "312b8f03-fa93-4f69-bc62-a36373c4ae96", + "gate_outcome": "success", + "source_pixels_modified": false +} diff --git a/mods/iron_coast_stage2_mission_3/provenance-terrain.json b/mods/iron_coast_stage2_mission_3/provenance-terrain.json new file mode 100644 index 00000000..e33bbca2 --- /dev/null +++ b/mods/iron_coast_stage2_mission_3/provenance-terrain.json @@ -0,0 +1,39 @@ +{ + "generator": "built-in image_gen.imagegen", + "owner": "/root/iron_coast_3", + "job_id": "stage2-terrain3", + "utc": "2026-10-11T08:14:52.181170+00:00", + "default_output": "/home/quintine/.codex/generated_images/01a1245d-8d97-74e2-9a2c-02e88a570589/exec-8a28fa6d-df18-4c97-b91c-a3e86d139621.png", + "raw_master": "art/terrain-source-v1.png", + "raw_sha256": "3911a9cc2b231e67684eae3bbc104c3793d913f481d11e8ad7bb7a94d07a489d", + "prompt": "prompts/terrain-v1.txt", + "prompt_sha256": "6564b0c21c77241b1931dc8dc5bf90bee96cbc8661ae01fd939b3c37d57fd4f1", + "style_reference_role": "Original Raptor style only; decoded style reference is intentionally external to authored mod.", + "reference_sha256": "685307409d68baa9413975b59427c74d29f6a09b2b039a3d88ee69abf19e9a9d", + "original_style_source_hashes": [ + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/enemies-200cc-200cd/sources/200cc.png", + "sha256": "c3f92b8a04370029652cfff20dc00ec41228c5adead37affaacd3b9511bb520d", + "role": "Original Raptor style reference; not copied into authored mods." + }, + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/enemies-2008d-2008d/sources/2008d.png", + "sha256": "419514e3b7cbd9fb7283f0550f12991f5570c2de16c367330fa2e8a9b6bb3725", + "role": "Original Raptor style reference; not copied into authored mods." + }, + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/bosses-10310-10310/sources/10310.png", + "sha256": "39404e604c4d535e868ffea924ba206c690e19f7df9c289ce14612cb2451bbef", + "role": "Original Raptor style reference; not copied into authored mods." + }, + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/terrain-10360-1036f/sources/10360.png", + "sha256": "ee5348dbdf57952027349c64cd13c9d2991a33b0378a54f4750622d9bff50dc0", + "role": "Original Raptor style reference; not copied into authored mods." + } + ], + "transparent_background_requested": false, + "gate_lease": "c5ef40aa-bd0a-469c-a269-247aef4c2e46", + "gate_outcome": "success", + "source_pixels_modified": false +} diff --git a/mods/iron_coast_stage2_mission_3/scripts/mission.rhai b/mods/iron_coast_stage2_mission_3/scripts/mission.rhai new file mode 100644 index 00000000..04d68340 --- /dev/null +++ b/mods/iron_coast_stage2_mission_3/scripts/mission.rhai @@ -0,0 +1,21 @@ +fn on_mission_start(event,state,random) { + #{commands:[#{op:"objective",key:"iron_coast_stage2_mission_3:phase",value:1},#{op:"objective",key:"iron_coast_stage2_mission_3:targets_required",value:4},#{op:"objective",key:"iron_coast_stage2_mission_3:targets_destroyed",value:0},#{op:"objective",key:"iron_coast_stage2_mission_3:complete",value:0},#{op:"objective",key:"iron_coast_stage2_boss_3:defeated",value:0},#{op:"play_sound",sound:"iron_coast_stage2_mission_3:approach"}],state:#{boss_alarm:false,complete:false}} +} +fn on_tick(event,state,random) { + let commands=[]; + if event.tick==2100 && !state.boss_alarm { + state.boss_alarm=true;commands.push(#{op:"objective",key:"iron_coast_stage2_mission_3:phase",value:3});commands.push(#{op:"play_sound",sound:"iron_coast_stage2_mission_3:boss_alarm"}); + } + if event.tick==1100 {commands.push(#{op:"objective",key:"iron_coast_stage2_mission_3:phase",value:2});commands.push(#{op:"play_sound",sound:"iron_coast_stage2_mission_3:target_alarm"});} + if event.tick%420==210 { + let left=random[0]%2==0;let x=if left {20} else {300}; + commands.push(#{op:"arc",x:x,y:4,to_x:x-4,to_y:112,ticks:6}); + } + let kills=if event.objectives.contains("iron_coast_stage2_mission_3:targets_destroyed") {event.objectives["iron_coast_stage2_mission_3:targets_destroyed"]} else {0}; + let boss=if event.objectives.contains("iron_coast_stage2_boss_3:defeated") {event.objectives["iron_coast_stage2_boss_3:defeated"]} else {0}; + if event.tick>=2100 && kills>=4 && boss>=1 && !state.complete { + state.complete=true;commands.push(#{op:"objective",key:"iron_coast_stage2_mission_3:complete",value:1});commands.push(#{op:"objective",key:"iron_coast_stage2_mission_3:phase",value:4});commands.push(#{op:"credits",amount:14500});commands.push(#{op:"play_sound",sound:"iron_coast_stage2_mission_3:victory"});commands.push(#{op:"complete"}); + } + #{commands:commands,state:state} +} +fn on_mission_end(event,state,random) {#{commands:[#{op:"objective",key:"iron_coast_stage2_mission_3:debrief",value:if event.success {1} else {0}}],state:state}} diff --git a/mods/iron_coast_stage2_mission_3/scripts/target.rhai b/mods/iron_coast_stage2_mission_3/scripts/target.rhai new file mode 100644 index 00000000..920bbfa4 --- /dev/null +++ b/mods/iron_coast_stage2_mission_3/scripts/target.rhai @@ -0,0 +1,36 @@ +// Retain at most128 recently retired entity IDs. Older checkpoints lacking +// the FIFO migrate deterministically before any new spawn/death is processed. +fn ready(state) { + if !state.contains("dead") {state.dead=#{};} + if !state.contains("dead_order") { + let retained=#{};let order=[]; + for key in state.dead.keys() { + if order.len()>=128 {let oldest=order.remove(0);retained.remove(oldest);} + retained[key]=true;order.push(key); + } + state.dead=retained;state.dead_order=order; + } + state +} +fn live(event) {for e in event.entities {if e.entity==event.entity && e.health>0 {return true;}}false} +fn on_spawn(event,state,random) { + state=ready(state); + let key=event.entity.to_string();state.dead.remove(key); + let keep=[];for old in state.dead_order {if old!=key {keep.push(old);}}state.dead_order=keep; + #{commands:[],state:state} +} +fn on_tick(event,state,random) { + if event.health<=0 || !live(event) {return #{commands:[],state:state};} + // Ground scroll is rebased every tick after arrival so a mandatory survivor + // remains reachable indefinitely. No target escapes or disappears on a timer. + if event.y>=60 {return #{commands:[#{op:"move",entity:event.entity,x:event.x,y:60},#{op:"velocity",entity:event.entity,vx:0,vy:0}],state:state};} + #{commands:[],state:state} +} +fn on_death(event,state,random) { + state=ready(state); + let key=event.entity.to_string();if state.dead.contains(key) {return #{commands:[],state:state};} + if state.dead_order.len()>=128 {let oldest=state.dead_order.remove(0);state.dead.remove(oldest);} + state.dead[key]=true;state.dead_order.push(key); + let count=if event.objectives.contains("iron_coast_stage2_mission_3:targets_destroyed") {event.objectives["iron_coast_stage2_mission_3:targets_destroyed"]+1} else {1}; + #{commands:[#{op:"objective",key:"iron_coast_stage2_mission_3:targets_destroyed",value:count},#{op:"shield",amount:12},#{op:"play_sound",sound:"iron_coast_stage2_mission_3:salvage"}],state:state} +} diff --git a/mods/iron_coast_stage2_mission_3/validation/Cargo.toml b/mods/iron_coast_stage2_mission_3/validation/Cargo.toml new file mode 100644 index 00000000..a9848179 --- /dev/null +++ b/mods/iron_coast_stage2_mission_3/validation/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "iron-coast-stage2-mission-3-validation" +version = "1.0.0" +edition = "2024" +publish = false + +[workspace] + +[dependencies] +raptor-replica = { path = "../../..", default-features = false } +serde_json = "1" + +[[bin]] +name = "validate" +path = "validate.rs" + +[[bin]] +name = "retained-state" +path = "retained_state.rs" diff --git a/mods/iron_coast_stage2_mission_3/validation/acceptance.json b/mods/iron_coast_stage2_mission_3/validation/acceptance.json new file mode 100644 index 00000000..087175e9 --- /dev/null +++ b/mods/iron_coast_stage2_mission_3/validation/acceptance.json @@ -0,0 +1,297 @@ +{ + "audio": [ + { + "decoded_samples": 20948, + "file": "audio/death.wav", + "id": "iron_coast_stage2_boss_3:death", + "mixed_stereo_peak": 7040 + }, + { + "decoded_samples": 4410, + "file": "audio/shot.wav", + "id": "iron_coast_stage2_boss_3:shot", + "mixed_stereo_peak": 5888 + }, + { + "decoded_samples": 7938, + "file": "audio/warning.wav", + "id": "iron_coast_stage2_boss_3:warning", + "mixed_stereo_peak": 3840 + }, + { + "decoded_samples": 17199, + "file": "audio/approach.wav", + "id": "iron_coast_stage2_mission_3:approach", + "mixed_stereo_peak": 4992 + }, + { + "decoded_samples": 14332, + "file": "audio/boss_alarm.wav", + "id": "iron_coast_stage2_mission_3:boss_alarm", + "mixed_stereo_peak": 3968 + }, + { + "decoded_samples": 7056, + "file": "audio/salvage.wav", + "id": "iron_coast_stage2_mission_3:salvage", + "mixed_stereo_peak": 4992 + }, + { + "decoded_samples": 9261, + "file": "audio/target_alarm.wav", + "id": "iron_coast_stage2_mission_3:target_alarm", + "mixed_stereo_peak": 3968 + }, + { + "decoded_samples": 24255, + "file": "audio/victory.wav", + "id": "iron_coast_stage2_mission_3:victory", + "mixed_stereo_peak": 6656 + } + ], + "capture_scope": "actual Rust PNG palette conversion and indexed Canvas from real World states; desktop Host live screenshots handled independently", + "deterministic_resume_from_tick": 1200, + "full_inventory": { + "credits": 32630, + "equipment_preserved": true, + "shield": 90, + "slots": 20, + "tick": 2360 + }, + "gated_completion_and_once_bonus": true, + "mission": "iron_coast_stage2_mission_3:mission_03", + "playthroughs": [ + { + "credits": 32630, + "difficulty": 0, + "initial_credits": 10000, + "initial_shield": 75, + "minimum_shield": 74, + "mod_sound_cues": [ + "iron_coast_stage2_boss_3:death", + "iron_coast_stage2_boss_3:shot", + "iron_coast_stage2_boss_3:warning", + "iron_coast_stage2_interceptor:death", + "iron_coast_stage2_interceptor:shot", + "iron_coast_stage2_mission_3:approach", + "iron_coast_stage2_mission_3:boss_alarm", + "iron_coast_stage2_mission_3:salvage", + "iron_coast_stage2_mission_3:target_alarm", + "iron_coast_stage2_mission_3:victory", + "iron_coast_stage2_siege:death", + "iron_coast_stage2_siege:shot", + "iron_coast_stage2_siege:warning" + ], + "native_seen_and_moving": [ + "base:enemy_0_20", + "base:enemy_0_21", + "base:enemy_0_22", + "base:enemy_0_73", + "base:enemy_0_74", + "base:enemy_0_79", + "base:enemy_2_25", + "base:enemy_2_26" + ], + "objectives": { + "iron_coast_stage2_boss_3:defeated": 1, + "iron_coast_stage2_boss_3:phase": 2, + "iron_coast_stage2_interceptor:defeated": 4, + "iron_coast_stage2_mission_3:complete": 1, + "iron_coast_stage2_mission_3:debrief": 1, + "iron_coast_stage2_mission_3:phase": 4, + "iron_coast_stage2_mission_3:targets_destroyed": 4, + "iron_coast_stage2_mission_3:targets_required": 4, + "iron_coast_stage2_siege:defeated": 4 + }, + "shield": 99, + "tick": 2241 + }, + { + "credits": 32630, + "difficulty": 1, + "initial_credits": 10000, + "initial_shield": 75, + "minimum_shield": 73, + "mod_sound_cues": [ + "iron_coast_stage2_boss_3:death", + "iron_coast_stage2_boss_3:shot", + "iron_coast_stage2_boss_3:warning", + "iron_coast_stage2_interceptor:death", + "iron_coast_stage2_interceptor:shot", + "iron_coast_stage2_mission_3:approach", + "iron_coast_stage2_mission_3:boss_alarm", + "iron_coast_stage2_mission_3:salvage", + "iron_coast_stage2_mission_3:target_alarm", + "iron_coast_stage2_mission_3:victory", + "iron_coast_stage2_siege:death", + "iron_coast_stage2_siege:shot", + "iron_coast_stage2_siege:warning" + ], + "native_seen_and_moving": [ + "base:enemy_0_20", + "base:enemy_0_21", + "base:enemy_0_22", + "base:enemy_0_73", + "base:enemy_0_74", + "base:enemy_0_79", + "base:enemy_2_25", + "base:enemy_2_26" + ], + "objectives": { + "iron_coast_stage2_boss_3:defeated": 1, + "iron_coast_stage2_boss_3:phase": 2, + "iron_coast_stage2_interceptor:defeated": 4, + "iron_coast_stage2_mission_3:complete": 1, + "iron_coast_stage2_mission_3:debrief": 1, + "iron_coast_stage2_mission_3:phase": 4, + "iron_coast_stage2_mission_3:targets_destroyed": 4, + "iron_coast_stage2_mission_3:targets_required": 4, + "iron_coast_stage2_siege:defeated": 4 + }, + "shield": 96, + "tick": 2241 + }, + { + "credits": 32630, + "difficulty": 2, + "initial_credits": 10000, + "initial_shield": 75, + "minimum_shield": 73, + "mod_sound_cues": [ + "iron_coast_stage2_boss_3:death", + "iron_coast_stage2_boss_3:shot", + "iron_coast_stage2_boss_3:warning", + "iron_coast_stage2_interceptor:death", + "iron_coast_stage2_interceptor:shot", + "iron_coast_stage2_mission_3:approach", + "iron_coast_stage2_mission_3:boss_alarm", + "iron_coast_stage2_mission_3:salvage", + "iron_coast_stage2_mission_3:target_alarm", + "iron_coast_stage2_mission_3:victory", + "iron_coast_stage2_siege:death", + "iron_coast_stage2_siege:shot", + "iron_coast_stage2_siege:warning" + ], + "native_seen_and_moving": [ + "base:enemy_0_20", + "base:enemy_0_21", + "base:enemy_0_22", + "base:enemy_0_73", + "base:enemy_0_74", + "base:enemy_0_79", + "base:enemy_2_25", + "base:enemy_2_26" + ], + "objectives": { + "iron_coast_stage2_boss_3:defeated": 1, + "iron_coast_stage2_boss_3:phase": 2, + "iron_coast_stage2_interceptor:defeated": 4, + "iron_coast_stage2_mission_3:complete": 1, + "iron_coast_stage2_mission_3:debrief": 1, + "iron_coast_stage2_mission_3:phase": 4, + "iron_coast_stage2_mission_3:targets_destroyed": 4, + "iron_coast_stage2_mission_3:targets_required": 4, + "iron_coast_stage2_siege:defeated": 4 + }, + "shield": 96, + "tick": 2359 + }, + { + "credits": 32630, + "difficulty": 3, + "initial_credits": 10000, + "initial_shield": 75, + "minimum_shield": 73, + "mod_sound_cues": [ + "iron_coast_stage2_boss_3:death", + "iron_coast_stage2_boss_3:shot", + "iron_coast_stage2_boss_3:warning", + "iron_coast_stage2_interceptor:death", + "iron_coast_stage2_interceptor:shot", + "iron_coast_stage2_mission_3:approach", + "iron_coast_stage2_mission_3:boss_alarm", + "iron_coast_stage2_mission_3:salvage", + "iron_coast_stage2_mission_3:target_alarm", + "iron_coast_stage2_mission_3:victory", + "iron_coast_stage2_siege:death", + "iron_coast_stage2_siege:shot", + "iron_coast_stage2_siege:warning" + ], + "native_seen_and_moving": [ + "base:enemy_0_20", + "base:enemy_0_21", + "base:enemy_0_22", + "base:enemy_0_73", + "base:enemy_0_74", + "base:enemy_0_79", + "base:enemy_2_25", + "base:enemy_2_26" + ], + "objectives": { + "iron_coast_stage2_boss_3:defeated": 1, + "iron_coast_stage2_boss_3:phase": 2, + "iron_coast_stage2_interceptor:defeated": 4, + "iron_coast_stage2_mission_3:complete": 1, + "iron_coast_stage2_mission_3:debrief": 1, + "iron_coast_stage2_mission_3:phase": 4, + "iron_coast_stage2_mission_3:targets_destroyed": 4, + "iron_coast_stage2_mission_3:targets_required": 4, + "iron_coast_stage2_siege:defeated": 4 + }, + "shield": 97, + "tick": 2361 + }, + { + "credits": 22630, + "difficulty": 2, + "initial_credits": 0, + "initial_shield": 100, + "minimum_shield": 88, + "mod_sound_cues": [ + "iron_coast_stage2_boss_3:death", + "iron_coast_stage2_boss_3:shot", + "iron_coast_stage2_boss_3:warning", + "iron_coast_stage2_interceptor:death", + "iron_coast_stage2_interceptor:shot", + "iron_coast_stage2_mission_3:approach", + "iron_coast_stage2_mission_3:boss_alarm", + "iron_coast_stage2_mission_3:salvage", + "iron_coast_stage2_mission_3:target_alarm", + "iron_coast_stage2_mission_3:victory", + "iron_coast_stage2_siege:death", + "iron_coast_stage2_siege:shot", + "iron_coast_stage2_siege:warning" + ], + "native_seen_and_moving": [ + "base:enemy_0_20", + "base:enemy_0_21", + "base:enemy_0_22", + "base:enemy_0_73", + "base:enemy_0_74", + "base:enemy_0_79", + "base:enemy_2_25", + "base:enemy_2_26" + ], + "objectives": { + "iron_coast_stage2_boss_3:defeated": 1, + "iron_coast_stage2_boss_3:phase": 2, + "iron_coast_stage2_interceptor:defeated": 4, + "iron_coast_stage2_mission_3:complete": 1, + "iron_coast_stage2_mission_3:debrief": 1, + "iron_coast_stage2_mission_3:phase": 4, + "iron_coast_stage2_mission_3:targets_destroyed": 4, + "iron_coast_stage2_mission_3:targets_required": 4, + "iron_coast_stage2_siege:defeated": 4 + }, + "shield": 97, + "tick": 2361 + } + ], + "retention": { + "boss": 1, + "outcome": "playing", + "shield_controlled_only_here": true, + "targets": 4, + "tick": 4500 + } +} diff --git a/mods/iron_coast_stage2_mission_3/validation/acceptance.log b/mods/iron_coast_stage2_mission_3/validation/acceptance.log new file mode 100644 index 00000000..a0d72553 --- /dev/null +++ b/mods/iron_coast_stage2_mission_3/validation/acceptance.log @@ -0,0 +1,6 @@ +stage3 difficulty0 initial75/10000: win tick2241 shield100 min74 credits32630 +stage3 difficulty1 initial75/10000: win tick2241 shield99 min73 credits32630 +stage3 difficulty2 initial75/10000: win tick2359 shield96 min73 credits32630 +stage3 difficulty3 initial75/10000: win tick2361 shield97 min73 credits32630 +stage3 difficulty2 initial100/0: win tick2361 shield97 min88 credits22630 +retention4500/restart/full20/once-bonus/deterministic saved state+RNG/mixed WAVs: passed diff --git a/mods/iron_coast_stage2_mission_3/validation/bounded-cache-review.md b/mods/iron_coast_stage2_mission_3/validation/bounded-cache-review.md new file mode 100644 index 00000000..e5b8e3a6 --- /dev/null +++ b/mods/iron_coast_stage2_mission_3/validation/bounded-cache-review.md @@ -0,0 +1,9 @@ +# Retained lifecycle cache correction + +The independent native-collision probe found an unbounded pre-correction retired-ID map that exhausted the Rhai object-map limit at distinct-lifetime index1009. Historical package folders and the previous four-package freeze are retained outside the distribution. + +The gameplay definitions, health, attack patterns, objectives, prices, images and sounds are unchanged. A separate independent timing probe also found that changing the old warning-clock modulo at half-health could release a low-phase volley after only two ticks. Bosses now latch their phase and restart its warning clock on a phase transition, preserving the advertised full 14-tick telegraph. The actual World regression tests transition immediately after the second high-phase warning at every difficulty, including an old checkpoint lacking the latch. The script now stores a FIFO of at most 128 recent retired IDs, removes reused IDs on spawn before checking their health, and migrates pre-FIFO states into a deterministic bounded subset. Boss clocks absent from the new World's snapshot are discarded; live peer clocks remain intact. + +The package-local retained-state proof checks real bundled Catalog activation and a test-only native stationary lethal projectile, 1,205 lives (1,200 unique plus five reused IDs), exact one-death rewards, current-lifecycle callback deduplication, nine JSON checkpoint/RNG roundtrips, old 960-ID cache migration and all four difficulty kills. Boss probes add 1,205 abandoned-live replays and simultaneous peer-clock preservation. This is a lifecycle stress proof, not a combat-balance shortcut. Normal mission acceptance and boss phase probes were rerun independently of this stress fixture. + +A duplicate callback for an entity retired more than 128 deaths ago is outside the retained guard window; the engine emits each real death once and queued callbacks are not delayed across 128 later deaths. Reusing an ID through an actual spawn always starts a fresh guarded lifecycle. diff --git a/mods/iron_coast_stage2_mission_3/validation/bounded-cli.log b/mods/iron_coast_stage2_mission_3/validation/bounded-cli.log new file mode 100644 index 00000000..83810a55 --- /dev/null +++ b/mods/iron_coast_stage2_mission_3/validation/bounded-cli.log @@ -0,0 +1 @@ +Validated 8 mods; 0 override(s) diff --git a/mods/iron_coast_stage2_mission_3/validation/bounded-normal.log b/mods/iron_coast_stage2_mission_3/validation/bounded-normal.log new file mode 100644 index 00000000..8aa468a0 --- /dev/null +++ b/mods/iron_coast_stage2_mission_3/validation/bounded-normal.log @@ -0,0 +1,6 @@ +stage3 difficulty0 initial75/10000: win tick2241 shield99 min74 credits32630 +stage3 difficulty1 initial75/10000: win tick2241 shield96 min73 credits32630 +stage3 difficulty2 initial75/10000: win tick2359 shield96 min73 credits32630 +stage3 difficulty3 initial75/10000: win tick2361 shield97 min73 credits32630 +stage3 difficulty2 initial100/0: win tick2361 shield97 min88 credits22630 +retention4500/restart/full20/once-bonus/deterministic saved state+RNG/mixed WAVs: passed diff --git a/mods/iron_coast_stage2_mission_3/validation/cli.log b/mods/iron_coast_stage2_mission_3/validation/cli.log new file mode 100644 index 00000000..d97e0af1 --- /dev/null +++ b/mods/iron_coast_stage2_mission_3/validation/cli.log @@ -0,0 +1 @@ +Validated 5 mods; 0 override(s) diff --git a/mods/iron_coast_stage2_mission_3/validation/combined-cli.log b/mods/iron_coast_stage2_mission_3/validation/combined-cli.log new file mode 100644 index 00000000..83810a55 --- /dev/null +++ b/mods/iron_coast_stage2_mission_3/validation/combined-cli.log @@ -0,0 +1 @@ +Validated 8 mods; 0 override(s) diff --git a/mods/iron_coast_stage2_mission_3/validation/compiler-binding.json b/mods/iron_coast_stage2_mission_3/validation/compiler-binding.json new file mode 100644 index 00000000..43fbdba8 --- /dev/null +++ b/mods/iron_coast_stage2_mission_3/validation/compiler-binding.json @@ -0,0 +1,22 @@ +{ + "/home/quintine/Projects/RaptorReplica/RustRaptor/target/release/deps/libraptor_replica-f9adab78fd4d2969.rlib": { + "bytes": 13308296, + "sha256": "eb190ba6ad88d1939938a30c69bd1d8c705ecfb77eb12c36ae0686f10f82bae7", + "mtime_ns": 1791706754209530916 + }, + "/home/quintine/Projects/RaptorReplica/RustRaptor/target/release/deps/libserde_json-11c796c0bcf3a604.rlib": { + "bytes": 2057816, + "sha256": "7a13e07716f46f559cb9acf05c81ce0845e5633dfd3d77e6020e14af31a3a878", + "mtime_ns": 1791706698162048372 + }, + "/home/quintine/Projects/RaptorReplica/RustRaptor/mods/iron_coast_stage2_mission_3/validation/validate.rs": { + "bytes": 18969, + "sha256": "3a255f8bb3a9afcb15e59ddfc98e79a1b32b3ce5e787e8dba1068e337b274ba7", + "mtime_ns": 1791707446281702229 + }, + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/mission-3-validate": { + "bytes": 8458112, + "sha256": "459ef4a43459a7be1a8a4340f617f4a7853050f9868d686940766312df3bd292", + "mtime_ns": 1791707496392450352 + } +} diff --git a/mods/iron_coast_stage2_mission_3/validation/retained-state-compiler-binding.json b/mods/iron_coast_stage2_mission_3/validation/retained-state-compiler-binding.json new file mode 100644 index 00000000..5d4e874f --- /dev/null +++ b/mods/iron_coast_stage2_mission_3/validation/retained-state-compiler-binding.json @@ -0,0 +1,22 @@ +{ + "/home/quintine/Projects/RaptorReplica/RustRaptor/target/release/deps/libraptor_replica-f9adab78fd4d2969.rlib": { + "bytes": 13308296, + "sha256": "eb190ba6ad88d1939938a30c69bd1d8c705ecfb77eb12c36ae0686f10f82bae7", + "mtime_ns": 1791706754209530916 + }, + "/home/quintine/Projects/RaptorReplica/RustRaptor/target/release/deps/libserde_json-11c796c0bcf3a604.rlib": { + "bytes": 2057816, + "sha256": "7a13e07716f46f559cb9acf05c81ce0845e5633dfd3d77e6020e14af31a3a878", + "mtime_ns": 1791706698162048372 + }, + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/retained-state": { + "bytes": 8421248, + "sha256": "ece9f14a0a69754c8515ccc1c3c98968b8023b1978ad36497028c11208abe1e8", + "mtime_ns": 1791708664346644142 + }, + "/home/quintine/Projects/RaptorReplica/RustRaptor/mods/iron_coast_stage2_mission_3/validation/retained_state.rs": { + "bytes": 12558, + "sha256": "e1c4f9f1d78ba98c423cfe41cd90eb72a811398a7ba4dc334e342b89336f5a64", + "mtime_ns": 1791708663764657723 + } +} diff --git a/mods/iron_coast_stage2_mission_3/validation/retained-state.json b/mods/iron_coast_stage2_mission_3/validation/retained-state.json new file mode 100644 index 00000000..09ac25e9 --- /dev/null +++ b/mods/iron_coast_stage2_mission_3/validation/retained-state.json @@ -0,0 +1,61 @@ +{ + "abandoned_live_replays": 0, + "actual_native_collision_lives": 1205, + "actual_phase_transition_warnings": [], + "checkpoint_json_roundtrips": 9, + "difficulty_kills": [ + 0, + 1, + 2, + 3 + ], + "distinct_ids": 1200, + "duplicate_callback_commands": 0, + "enabled": [ + "iron_coast_stage2_boss_3", + "iron_coast_stage2_interceptor", + "iron_coast_stage2_mission_3", + "iron_coast_stage2_music", + "iron_coast_stage2_siege" + ], + "fixture": "actual bundled Catalog; test-only stationary lethal projectile; native World collision, death, reward and retained ScriptRuntime", + "legacy_960_guard_migration": true, + "maximum_abandoned_state_bytes": 0, + "maximum_death_state_bytes": 2713, + "migration_state_bytes": 2724, + "owner": "iron_coast_stage2_mission_3", + "package_pins_at_execution": [ + { + "hash": "a0903d54311e729e5d18347373717a439e8a869d004675489ddba3d30fd28349", + "id": "iron_coast_stage2_boss_3", + "version": "1.0.0" + }, + { + "hash": "026d61084d595ee3a0db524420e47708c5fef469702b11730bffe7b91fd4c70a", + "id": "iron_coast_stage2_interceptor", + "version": "1.0.0" + }, + { + "hash": "d57e82ed2278609ef7635d722c526605c831e0c5d34a01c88a79a204b07f51d9", + "id": "iron_coast_stage2_music", + "version": "1.0.0" + }, + { + "hash": "342d190cf09babb7530a4c8459124c921641f4a8b537ebca922c40cb2f0c0d3c", + "id": "iron_coast_stage2_siege", + "version": "1.0.0" + }, + { + "hash": "c18047335f5c7f8aacd2a452561310686580fb6d96fa46fe938dc9613856de47", + "id": "iron_coast_stage2_mission_3", + "version": "1.0.0" + } + ], + "retired_guard_capacity": 128, + "reused_id_lives": 5, + "reward_per_life": 450, + "scope": "callback lifecycle/bounded-state proof, not mission combat balance", + "target_shield_restore": 12, + "two_live_clocks_retained": false, + "unit": "iron_coast_stage2_mission_3:target" +} \ No newline at end of file diff --git a/mods/iron_coast_stage2_mission_3/validation/retained-state.log b/mods/iron_coast_stage2_mission_3/validation/retained-state.log new file mode 100644 index 00000000..a43c15dd --- /dev/null +++ b/mods/iron_coast_stage2_mission_3/validation/retained-state.log @@ -0,0 +1,12 @@ +iron_coast_stage2_mission_3 retained native kills=1; statebytes=46 retired=1 +iron_coast_stage2_mission_3 retained native kills=129; statebytes=2713 retired=128 +iron_coast_stage2_mission_3 retained native kills=257; statebytes=2713 retired=128 +iron_coast_stage2_mission_3 retained native kills=385; statebytes=2713 retired=128 +iron_coast_stage2_mission_3 retained native kills=513; statebytes=2713 retired=128 +iron_coast_stage2_mission_3 retained native kills=641; statebytes=2713 retired=128 +iron_coast_stage2_mission_3 retained native kills=769; statebytes=2713 retired=128 +iron_coast_stage2_mission_3 retained native kills=897; statebytes=2713 retired=128 +iron_coast_stage2_mission_3 retained native kills=1025; statebytes=2713 retired=128 +iron_coast_stage2_mission_3 retained native kills=1153; statebytes=2713 retired=128 +iron_coast_stage2_mission_3 retained native kills=1205; statebytes=2713 retired=128 +iron_coast_stage2_mission_3: all actual collision/reward, migration, deduplication, retained-state and abandoned-live checks passed diff --git a/mods/iron_coast_stage2_mission_3/validation/retained_state.rs b/mods/iron_coast_stage2_mission_3/validation/retained_state.rs new file mode 100644 index 00000000..910b75ff --- /dev/null +++ b/mods/iron_coast_stage2_mission_3/validation/retained_state.rs @@ -0,0 +1,305 @@ +//! Real native lethal-collision stress with retained serializable Rhai state. +use raptor_replica::{ + assets::Catalog, + content::{ContentPack, Registry}, + modding::{self, ActiveMods, Discovery, ScriptRuntime}, + persistence::Pilot, + simulation::{Input, Projectile, World}, +}; +use serde_json::{Value, json}; +use std::{ + collections::{BTreeMap, BTreeSet}, + path::PathBuf, +}; +type Result = std::result::Result>; +fn closure(d: &Discovery, id: &str, out: &mut BTreeSet) { + if !out.insert(id.into()) { + return; + } + for dep in d.mods[id].manifest.dependencies.keys() { + closure(d, dep, out); + } +} +fn input() -> Input { + Input { + absolute: Some([282, 160]), + ..Input::default() + } +} +fn pilot(difficulty: u32) -> Pilot { + let mut p = Pilot::default(); + p.difficulty = difficulty; + p.credits = 10000; + p.inventory.insert("base:energy".into(), 75); + p +} +fn restore(active: &mut ActiveMods, discovery: &Discovery, enabled: &[String]) -> Result<()> { + let cp = active.scripts.checkpoints(); + let encoded = serde_json::to_vec(&cp)?; + let mut scripts = ScriptRuntime::new(); + for owner in enabled { + for path in &discovery.mods[owner].manifest.scripts { + scripts.add( + owner, + path, + &std::fs::read_to_string(discovery.mods[owner].root.join(path))?, + )?; + } + } + scripts.restore(serde_json::from_slice(&encoded)?); + active.scripts = scripts; + Ok(()) +} +fn event(id: u64, hp: i32, key: &str, count: i32) -> Value { + json!({"entity":id,"x":88,"y":24,"health":hp,"tick":999,"player_x":282,"player_y":160,"entities":[{"entity":id,"health":hp}],"objectives":{key:count}}) +} +fn guard(active: &ActiveMods, key: &str) -> usize { + let state = &active.scripts.states[key]; + let dead = state["dead"].as_object().unwrap(); + let fifo = state["dead_order"].as_array().unwrap(); + assert!(dead.len() <= 128); + assert!(fifo.len() <= 128); + assert_eq!(dead.len(), fifo.len()); + let unique = fifo + .iter() + .map(|v| v.as_str().unwrap()) + .collect::>(); + assert_eq!(unique.len(), fifo.len()); + assert_eq!( + dead.keys().map(|v| v.as_str()).collect::>(), + unique + ); + if let Some(units) = state.get("units") { + assert!(units.as_object().unwrap().is_empty()); + } + serde_json::to_vec(state).unwrap().len() +} +fn kill( + active: &mut ActiveMods, + unit: &str, + id: u64, + objective: &str, + reward: u32, + target: bool, + difficulty: u32, +) -> Result { + let mut w = World::new( + &"review:retained".into(), + &pilot(difficulty), + &active.registry, + )?; + w.next_entity = id; + let y = if target { 60 } else { 24 }; + w.projectiles.push(Projectile { + entity: 500000, + weapon: "review:lethal".into(), + x: 90, + y: y + 6, + px: 90, + py: y + 6, + vx: 0, + vy: 0, + hostile: false, + age: 0, + legacy: None, + legacy_enemy: None, + }); + for _ in 0..3 { + w.step(input(), &active.registry, &mut active.scripts)?; + } + assert!(w.enemies.is_empty(), "{unit} survived"); + assert_eq!(w.objectives.get(objective), Some(&1)); + assert_eq!(w.player.credits, 10000 + reward); + assert_eq!(w.player.shield, if target { 87 } else { 75 }); + w.step(input(), &active.registry, &mut active.scripts)?; + assert_eq!(w.objectives.get(objective), Some(&1)); + assert_eq!(w.player.credits, 10000 + reward); + Ok(w) +} +fn phase_warnings(active: &mut ActiveMods, owner: &str, key: &str) -> Result> { + let warning = format!("{owner}:warning"); + let objective = format!("{owner}:phase"); + let mut rows = vec![]; + for difficulty in 0..=3 { + let mut w = World::new( + &"review:retained".into(), + &pilot(difficulty), + &active.registry, + )?; + w.next_entity = 95000 + difficulty as u64; + let mut high_warnings = vec![]; + while high_warnings.len() < 2 { + assert!(w.tick < 100); + w.step(input(), &active.registry, &mut active.scripts)?; + if w.mod_sounds.iter().any(|s| s.0 == warning) { + high_warnings.push(w.tick); + } + w.projectiles.retain(|p| !p.hostile); + } + let entity = w.enemies[0].entity; + let max_hp = w.enemies[0].health; + w.enemies[0].health = max_hp / 2; + // Exercise the upgrade path for a saved pre-latch live entity as well. + if difficulty == 0 { + active.scripts.states.get_mut(key).unwrap()["units"][entity.to_string()] + .as_object_mut() + .unwrap() + .remove("phase"); + } + let mut new_warning = 0; + let mut release = 0; + for offset in 0..=14 { + w.step(input(), &active.registry, &mut active.scripts)?; + let warnings = w.mod_sounds.iter().filter(|s| s.0 == warning).count(); + let shots = w + .projectiles + .iter() + .filter(|p| p.hostile && p.age == 0) + .count(); + if offset == 0 { + assert_eq!(warnings, 1); + new_warning = w.tick; + assert_eq!(w.objectives.get(&objective), Some(&2)); + } else { + assert_eq!(warnings, 0); + } + if offset < 14 { + assert_eq!(shots, 0, "new health phase fired before full warning"); + } else { + assert_eq!(shots, if owner.ends_with('3') { 3 } else { 4 }); + release = w.tick; + } + w.projectiles.retain(|p| !p.hostile); + } + assert_eq!(release - new_warning, 14); + println!( + "{owner} actual difficulty{difficulty}: health transition after high warning{}; new warning{new_warning} release{release}, full14ticks", + high_warnings[1] + ); + rows.push(json!({"difficulty":difficulty,"actual_spawn_health":max_hp,"high_phase_warnings":high_warnings,"phase2_warning":new_warning,"phase2_release":release,"new_phase_warning_ticks":release-new_warning,"old_phase_latch_absent":difficulty==0})); + } + Ok(rows) +} +fn main() -> Result<()> { + let package = PathBuf::from(std::env::args().nth(1).expect("pass own package")); + let package = package.canonicalize()?; + let owner = package.file_name().unwrap().to_str().unwrap(); + let target = owner.contains("mission"); + let hook = if target { + "scripts/target.rhai" + } else { + "scripts/ai.rhai" + }; + let key = format!("{owner}/{hook}"); + let unit = format!("{owner}:{}", if target { "target" } else { "unit" }); + let objective = format!( + "{owner}:{}", + if target { + "targets_destroyed" + } else { + "defeated" + } + ); + let root = package.parent().unwrap().parent().unwrap(); + let cat = Catalog::open(&root.join("data"))?; + let mut base = Registry::base(&cat)?; + let content: ContentPack = serde_json::from_value( + json!({"missions":[{"id":"review:retained","name":"Test-only retained collision fixture","duration":10000,"auto_complete":false,"spawns":[{"tick":0,"enemy":unit,"x":88,"y":if target{60}else{24}}]}],"weapons":[{"id":"review:lethal","name":"Test-only stationary lethal projectile","damage":10000,"speed":0,"cooldown":1,"target":"all","behavior":"straight"}]}), + )?; + base.apply(content, "review")?; + let discovery = modding::discover(&root.join("mods")); + let mut enabled = BTreeSet::new(); + closure(&discovery, owner, &mut enabled); + let enabled = enabled.into_iter().collect::>(); + let mut a = ActiveMods::build(&base, &discovery, &enabled, Some(&cat))?; + let reward = a.registry.enemies[&unit.as_str().into()].reward; + let phase_transitions = if target { + vec![] + } else { + phase_warnings(&mut a, owner, &key)? + }; + let mut max_bytes = 0; + for life in 0..1205u64 { + let id = if life >= 1200 { 10000 } else { 10000 + life }; + let world = kill(&mut a, &unit, id, &objective, reward, target, 2)?; + let commands = + a.scripts + .invoke(owner, hook, "on_death", &event(id, 0, &objective, 1), 303)?; + assert!(commands.is_empty(), "duplicate death emitted commands"); + assert_eq!(world.player.credits, 10000 + reward); + max_bytes = max_bytes.max(guard(&a, &key)); + if life % 137 == 0 { + restore(&mut a, &discovery, &enabled)?; + } + if life % 128 == 0 || life == 1204 { + println!( + "{owner} retained native kills={}; statebytes={} retired={}", + life + 1, + guard(&a, &key), + a.scripts.states[&key]["dead"].as_object().unwrap().len() + ); + } + } + // Earlier pre-FIFO checkpoints migrate within the real engine limits. This + // includes a death flag for the entity killed before queued on_spawn executes. + let old_dead = (0..960) + .map(|n| (format!("{}", 60000 + n), json!(true))) + .collect::>(); + a.scripts + .states + .insert(key.clone(), json!({"dead":old_dead,"units":{}})); + restore(&mut a, &discovery, &enabled)?; + kill(&mut a, &unit, 60001, &objective, reward, target, 2)?; + assert_eq!(a.scripts.states[&key]["dead"]["60001"], json!(true)); + guard(&a, &key); + let migrated_state_bytes = serde_json::to_vec(&a.scripts.states[&key])?.len(); + for difficulty in 0..=3 { + kill( + &mut a, + &unit, + 70000 + difficulty as u64, + &objective, + reward, + target, + difficulty, + )?; + guard(&a, &key); + } + // Two live same-definition entities keep separate state; abandoned-world + // entity clocks are discarded at the next actual spawn instead of accumulating. + let mut abandoned_peak = 0; + if !target { + for life in 0..1205u64 { + let mut w = World::new(&"review:retained".into(), &pilot(2), &a.registry)?; + w.next_entity = 80000 + life; + w.step(input(), &a.registry, &mut a.scripts)?; + assert_eq!(w.enemies.len(), 1); + assert_eq!( + a.scripts.states[&key]["units"].as_object().unwrap().len(), + 1 + ); + abandoned_peak = abandoned_peak.max(serde_json::to_vec(&a.scripts.states[&key])?.len()); + } + let mut e1 = event(90000, 240, &objective, 0); + e1["entities"] = json!([{"entity":90000,"health":240}]); + a.scripts.invoke(owner, hook, "on_spawn", &e1, 303)?; + for _ in 0..20 { + a.scripts.invoke(owner, hook, "on_tick", &e1, 303)?; + } + let age = a.scripts.states[&key]["units"]["90000"]["age"].clone(); + let mut e2 = event(90001, 240, &objective, 0); + e2["entities"] = json!([{"entity":90000,"health":240},{"entity":90001,"health":240}]); + a.scripts.invoke(owner, hook, "on_spawn", &e2, 303)?; + assert_eq!(a.scripts.states[&key]["units"]["90000"]["age"], age); + assert_eq!(a.scripts.states[&key]["units"]["90001"]["age"], 0); + } + let report = json!({"fixture":"actual bundled Catalog; test-only stationary lethal projectile; native World collision, death, reward and retained ScriptRuntime","owner":owner,"unit":unit,"actual_native_collision_lives":1205,"distinct_ids":1200,"reused_id_lives":5,"checkpoint_json_roundtrips":9,"maximum_death_state_bytes":max_bytes,"actual_phase_transition_warnings":phase_transitions,"retired_guard_capacity":128,"duplicate_callback_commands":0,"reward_per_life":reward,"target_shield_restore":if target {12}else{0},"legacy_960_guard_migration":true,"migration_state_bytes":migrated_state_bytes,"difficulty_kills":[0,1,2,3],"abandoned_live_replays":if target {0}else{1205},"maximum_abandoned_state_bytes":abandoned_peak,"two_live_clocks_retained":!target,"enabled":enabled,"package_pins_at_execution":a.pins,"scope":"callback lifecycle/bounded-state proof, not mission combat balance"}); + std::fs::write( + package.join("validation/retained-state.json"), + serde_json::to_vec_pretty(&report)?, + )?; + println!( + "{owner}: all actual collision/reward, migration, deduplication, retained-state and abandoned-live checks passed" + ); + Ok(()) +} diff --git a/mods/iron_coast_stage2_mission_3/validation/validate.rs b/mods/iron_coast_stage2_mission_3/validation/validate.rs new file mode 100644 index 00000000..a770b0d6 --- /dev/null +++ b/mods/iron_coast_stage2_mission_3/validation/validate.rs @@ -0,0 +1,491 @@ +//! Original-catalog standalone mission acceptance. Starter guns only; no package/pilot changes. +use raptor_replica::{ + assets::{Catalog, Sprite, TRANSPARENT}, + audio::Mixer, + content::{self, ContentPack, Registry}, + modding::{self, ActiveMods, ScriptRuntime}, + persistence::Pilot, + render::{Canvas, draw_world_lightning_arcs, nearest}, + simulation::{Input, Outcome, World}, + sound::SoundBank, +}; +use serde_json::json; +use std::{ + collections::{BTreeMap, BTreeSet}, + io::Write, + path::{Path, PathBuf}, +}; +fn namespaces(stage: u32) -> (String, String) { + ( + format!("iron_coast_stage2_mission_{stage}"), + format!("iron_coast_stage2_boss_{stage}"), + ) +} +fn active(root: &Path, stage: u32) -> ActiveMods { + let catalog = Catalog::open(root.join("data")).unwrap(); + let base = Registry::base(&catalog).unwrap(); + let (owner, boss) = namespaces(stage); + let ids = vec![ + owner, + boss, + "iron_coast_stage2_interceptor".into(), + if stage == 3 { + "iron_coast_stage2_siege".into() + } else { + "iron_coast_stage2_skimmer".into() + }, + "iron_coast_stage2_music".into(), + ]; + let discovery = modding::discover(&root.join("mods")); + let active = ActiveMods::build(&base, &discovery, &ids, Some(&catalog)).unwrap(); + assert_eq!(active.pins.len(), 5); + active +} +fn pilot(stage: u32, shield: u32, credits: u32, difficulty: u32) -> Pilot { + let mut pilot = Pilot::default(); + pilot.mission = format!("iron_coast_stage2_mission_{stage}:mission_0{stage}") + .as_str() + .into(); + pilot.difficulty = difficulty; + pilot.credits = credits; + pilot.inventory.insert("base:energy".into(), shield); + pilot +} +fn input(world: &World, registry: &Registry) -> Input { + let prefix = format!("{}:", world.mission.0.split_once(':').unwrap().0); + let target = world + .enemies + .iter() + .filter(|e| e.health > 0 && e.y >= 0 && e.y < 145) + .min_by_key(|e| { + let def = ®istry.enemies[&e.definition]; + ( + if e.definition.0.starts_with(&prefix) { + 0 + } else if def.boss { + 1 + } else if def.ground { + 2 + } else { + 3 + }, + e.entity, + ) + }); + let goal = target + .map(|e| e.x + e.width / 2 - 16) + .unwrap_or(144) + .clamp(5, 282); + Input { + fire: true, + absolute: Some([world.player.x + (goal - world.player.x).clamp(-4, 4), 160]), + ..Input::default() + } +} +fn observe( + world: &World, + seen: &mut BTreeSet, + moving: &mut BTreeSet, + positions: &mut BTreeMap, +) { + for e in &world.enemies { + if e.definition.0.starts_with("base:enemy_") { + seen.insert(e.definition.0.clone()); + if let Some(prior) = positions.insert(e.entity, (e.x, e.y)) { + if prior != (e.x, e.y) { + moving.insert(e.definition.0.clone()); + } + } + } + } +} +fn restored_runtime(root: &Path, active: &ActiveMods) -> ScriptRuntime { + let discovery = modding::discover(&root.join("mods")); + let mut result = ScriptRuntime::new(); + for pin in &active.pins { + let package = &discovery.mods[&pin.id]; + for script in &package.manifest.scripts { + result + .add( + &pin.id, + script, + &std::fs::read_to_string(package.root.join(script)).unwrap(), + ) + .unwrap(); + } + } + result.restore(active.scripts.checkpoints()); + result +} +fn fit(sprite: &Sprite, width: usize, height: usize) -> Sprite { + let mut out = Sprite::blank(width, height); + for y in 0..height { + for x in 0..width { + out.pixels[y * width + x] = sprite.pixels + [(y * sprite.height / height) * sprite.width + x * sprite.width / width]; + } + } + out +} +fn load( + catalog: &Catalog, + registry: &Registry, + id: &str, + art: &content::Art, + frame: u32, + hd: bool, + scale: usize, +) -> Sprite { + let owner = ®istry.owners[&id.into()]; + let raw = content::art_sprite_variant(catalog, registry, owner, art, frame, hd).unwrap(); + let result = fit( + &raw, + art.logical_width as usize * scale, + art.logical_height as usize * scale, + ); + assert!( + result + .pixels + .iter() + .all(|p| *p < 240 || *p == TRANSPARENT || art.asset.is_some()) + ); + result +} +fn ppm(path: &Path, canvas: &Canvas, palette: &[[u8; 3]; 256]) { + let mut file = std::fs::File::create(path).unwrap(); + write!( + file, + "P6\n{} {}\n255\n", + canvas.image.width, canvas.image.height + ) + .unwrap(); + for p in &canvas.image.pixels { + let rgb = if *p == TRANSPARENT { + [0, 0, 0] + } else { + palette[*p as usize] + }; + file.write_all(&rgb).unwrap(); + } +} +fn capture(root: &Path, stage: u32, world: &World, registry: &Registry) { + let catalog = Catalog::open(root.join("data")).unwrap(); + let palette = catalog.palette().unwrap(); + let mission = ®istry.missions[&world.mission]; + let rows = mission.layout.len() / mission.columns as usize; + let offset = 200 - rows as i32 * 32 + world.scroll; + let out = root + .parent() + .unwrap() + .join(".reference/iron-coast-3-stage2/captures"); + std::fs::create_dir_all(&out).unwrap(); + for (name, scale, hd) in [("sd", 1, false), ("hd", 4, true)] { + let mut canvas = Canvas::new(scale); + canvas.clear(0); + for (row, tiles) in mission.layout.chunks(mission.columns as usize).enumerate() { + let y = offset + row as i32 * 32; + if y <= -32 || y >= 200 { + continue; + } + for (col, index) in tiles.iter().enumerate() { + let tile = &mission.tiles[*index]; + let sprite = load( + &catalog, + registry, + &world.mission.0, + &tile.art, + 0, + hd, + scale, + ); + canvas.blit( + &sprite, + (16 + col as i32 * 32) * scale as i32, + y * scale as i32, + ); + } + } + for ground in [true, false] { + for enemy in &world.enemies { + let def = ®istry.enemies[&enemy.definition]; + if def.ground != ground || enemy.health <= 0 { + continue; + } + if let Some(art) = &def.art { + let sprite = load( + &catalog, + registry, + &enemy.definition.0, + art, + enemy.art_frame, + hd, + scale, + ); + canvas.blit(&sprite, enemy.x * scale as i32, enemy.y * scale as i32); + } + } + } + for shot in &world.projectiles { + if let Some(art) = registry.weapons[&shot.weapon].art.as_ref() { + let sprite = load(&catalog, registry, &shot.weapon.0, art, shot.age, hd, scale); + canvas.blit(&sprite, shot.x * scale as i32, shot.y * scale as i32); + } + } + let player = catalog + .sprite(catalog.id("LPLAYER_PIC").unwrap() + world.player.bank as u32) + .unwrap(); + canvas.blit( + &nearest(&player, scale), + world.player.x * scale as i32, + world.player.y * scale as i32, + ); + draw_world_lightning_arcs(&mut canvas, world, &palette, 1.0); + ppm( + &out.join(format!("stage{stage}-tick{}-{name}.ppm", world.tick)), + &canvas, + &palette, + ); + } +} +fn main() { + let root = PathBuf::from(std::env::args().nth(1).expect("pass RustRaptor root")); + let stage: u32 = std::env::args().nth(2).unwrap().parse().unwrap(); + let (owner, boss) = namespaces(stage); + let mission = format!("{owner}:mission_0{stage}"); + let target = format!("{owner}:target"); + let target_counter = format!("{owner}:targets_destroyed"); + let boss_counter = format!("{boss}:defeated"); + let bonus = if stage == 3 { 14500 } else { 16500 }; + let arrival = if stage == 3 { 2100 } else { 2250 }; + let mut active = active(&root, stage); + let mut reports = vec![]; + // The exact shared dependencies have real scripts/artwork/music, no fixture replacements. + for (shield, credits, difficulty) in [ + (75, 10_000, 0), + (75, 10_000, 1), + (75, 10_000, 2), + (75, 10_000, 3), + (100, 0, 2), + ] { + let pilot = pilot(stage, shield, credits, difficulty); + let mut world = World::new(&mission.as_str().into(), &pilot, &active.registry).unwrap(); + let mut seen = BTreeSet::new(); + let mut moving = BTreeSet::new(); + let mut positions = BTreeMap::new(); + let mut min_shield = shield as i32; + let mut sounds = BTreeSet::new(); + let mut continuation = None; + let mut detail_captures = BTreeSet::new(); + for _ in 0..4500 { + let commands = input(&world, &active.registry); + world + .step(commands, &active.registry, &mut active.scripts) + .unwrap(); + min_shield = min_shield.min(world.player.shield); + observe(&world, &mut seen, &mut moving, &mut positions); + sounds.extend(world.mod_sounds.iter().map(|s| s.0.clone())); + if difficulty == 2 + && shield == 75 + && [300, 1200, arrival + 75, arrival + 120].contains(&world.tick) + { + capture(&root, stage, &world, &active.registry); + } + if difficulty == 2 && shield == 75 { + let phase = world + .objectives + .get(&format!("{boss}:phase")) + .copied() + .unwrap_or(0); + for cue in ["warning", "shot"] { + if world + .mod_sounds + .iter() + .any(|s| s.0 == format!("{boss}:{cue}")) + && detail_captures.insert(format!("{cue}-{phase}")) + { + capture(&root, stage, &world, &active.registry); + } + } + } + if world.tick == 1200 { + continuation = Some((world.clone(), restored_runtime(&root, &active))); + } else if let Some((ref mut other, ref mut scripts)) = continuation { + other.step(commands, &active.registry, scripts).unwrap(); + assert_eq!(world.digest(), other.digest()); + assert_eq!(world.objectives, other.objectives); + assert_eq!(active.scripts.checkpoints(), scripts.checkpoints()); + } + if world.outcome != Outcome::Playing { + break; + } + } + assert_eq!( + world.outcome, + Outcome::Complete, + "difficulty{difficulty} tick{} shield{} {:?}", + world.tick, + world.player.shield, + world.objectives + ); + assert!(world.tick >= arrival && world.tick <= 3300); + assert_eq!(world.objectives[&target_counter], 4); + assert_eq!(world.objectives[&boss_counter], 1); + assert_eq!(world.objectives[&format!("{owner}:complete")], 1); + assert_eq!(world.objectives[&format!("{owner}:debrief")], 1); + assert!(!seen.is_empty()); + assert_eq!( + seen, moving, + "all genuine classic definitions must be observed moving" + ); + assert!(sounds.contains(&format!("{owner}:victory"))); + assert!(sounds.contains(&format!("{boss}:warning"))); + let end = world.player.credits; + world + .step(Input::default(), &active.registry, &mut active.scripts) + .unwrap(); + assert_eq!(world.player.credits, end); + reports.push(json!({"initial_shield":shield,"initial_credits":credits,"difficulty":difficulty,"tick":world.tick,"shield":world.player.shield,"minimum_shield":min_shield,"credits":end,"native_seen_and_moving":seen,"objectives":world.objectives,"mod_sound_cues":sounds})); + println!( + "stage{stage} difficulty{difficulty} initial{shield}/{credits}: win tick{} shield{} min{min_shield} credits{end}", + world.tick, world.player.shield + ); + } + // Deliberately refrain from shooting. Health controlled ONLY to inspect survivors after duration. + let mut held = World::new( + &mission.as_str().into(), + &pilot(stage, 75, 10_000, 2), + &active.registry, + ) + .unwrap(); + for _ in 0..4500 { + held.player.shield = 100; + held.step( + Input { + absolute: Some([5, 160]), + ..Input::default() + }, + &active.registry, + &mut active.scripts, + ) + .unwrap(); + if held.tick == 1800 { + capture(&root, stage, &held, &active.registry); + } + } + assert_eq!(held.outcome, Outcome::Playing); + let targets = held + .enemies + .iter() + .filter(|e| e.definition.0 == target && e.health > 0) + .collect::>(); + assert_eq!(targets.len(), 4); + assert!( + targets + .iter() + .all(|e| e.y == 60 && e.x >= 16 && e.x + e.width <= 304) + ); + let bosses = held + .enemies + .iter() + .filter(|e| e.definition.0 == format!("{boss}:unit") && e.health > 0) + .collect::>(); + assert_eq!(bosses.len(), 1); + assert_eq!(bosses[0].y, 24); + assert_eq!(held.objectives[&target_counter], 0); + assert_eq!(held.objectives[&boss_counter], 0); + // Mission start resets stale state; a full inventory has 18 unarmed synthetic test items. + let items = (0..18) + .map(|n| json!({"id":format!("fixture:slot_{n}"),"name":format!("Slot{n}"),"price":0})) + .collect::>(); + let pack: ContentPack = serde_json::from_value(json!({"items":items})).unwrap(); + active.registry.apply(pack, "fixture").unwrap(); + let mut full = pilot(stage, 75, 10_000, 2); + for n in 0..18 { + full.inventory + .insert(format!("fixture:slot_{n}").as_str().into(), 1); + } + assert_eq!(full.inventory_slots(), 20); + let before = full.inventory.clone(); + let mut flight = World::new(&mission.as_str().into(), &full, &active.registry).unwrap(); + flight + .step(Input::default(), &active.registry, &mut active.scripts) + .unwrap(); + assert_eq!(flight.player.inventory, before); + assert_eq!(flight.objectives[&target_counter], 0); + assert_eq!(flight.objectives[&boss_counter], 0); + for _ in 0..4500 { + flight + .step( + input(&flight, &active.registry), + &active.registry, + &mut active.scripts, + ) + .unwrap(); + if flight.outcome != Outcome::Playing { + break; + } + } + assert_eq!(flight.outcome, Outcome::Complete); + assert_eq!(flight.player.inventory.len(), 20); + for (id, count) in before { + if id.0 != "base:energy" { + assert_eq!(flight.player.inventory.get(&id), Some(&count)); + } + } + let full_report = json!({"slots":20,"tick":flight.tick,"shield":flight.player.shield,"credits":flight.player.credits,"equipment_preserved":true}); + // Controlled callback gating: boss alone, then only3targets cannot complete; time cannot bypass. + let mut gate = World::new(&mission.as_str().into(), &full, &active.registry).unwrap(); + gate.step(Input::default(), &active.registry, &mut active.scripts) + .unwrap(); + gate.tick = arrival + 200; + gate.spawn_cursor = active.registry.missions[&mission.as_str().into()] + .spawns + .len(); + gate.objectives.insert(boss_counter.clone(), 1); + gate.objectives.insert(target_counter.clone(), 3); + gate.step(Input::default(), &active.registry, &mut active.scripts) + .unwrap(); + assert_eq!(gate.outcome, Outcome::Playing); + assert_eq!(gate.player.credits, 10_000); + gate.objectives.insert(target_counter.clone(), 4); + gate.step(Input::default(), &active.registry, &mut active.scripts) + .unwrap(); + assert_eq!(gate.outcome, Outcome::Complete); + assert_eq!(gate.player.credits, 10_000 + bonus); + gate.step(Input::default(), &active.registry, &mut active.scripts) + .unwrap(); + assert_eq!(gate.player.credits, 10_000 + bonus); + // Real resolver+native mixer for every authored cue; bounded unsigned decoded PCM and stereo output. + let catalog = Catalog::open(root.join("data")).unwrap(); + let instruments = catalog.named("GENMIDI_OP2").unwrap(); + let mut bank = SoundBank::default(); + let mut audio = vec![]; + for (id, definition) in &active.registry.sounds { + if !id.0.starts_with(&owner) && !id.0.starts_with(&boss) { + continue; + } + let sample = bank.mod_sample(&active.registry, id).unwrap(); + assert_eq!(sample.rate, 22050); + assert!(sample.data.iter().any(|s| *s != 128)); + let mut mixer = Mixer::new(44100, &instruments).unwrap(); + mixer.fx_volume = 127; + bank.queue_mod(&active.registry, &mut mixer, id).unwrap(); + let mut pcm = vec![0; 44100 * 2]; + mixer.mix(&mut pcm); + assert!(pcm.iter().any(|v| *v != 0)); + let peak = pcm.iter().map(|v| (*v as i32).abs()).max().unwrap(); + assert!(peak < 32767); + audio.push(json!({"id":id.0,"file":definition.file,"decoded_samples":sample.data.len(),"mixed_stereo_peak":peak})); + } + let report = json!({"mission":mission,"playthroughs":reports,"full_inventory":full_report,"retention":{"tick":4500,"targets":4,"boss":1,"outcome":"playing","shield_controlled_only_here":true},"deterministic_resume_from_tick":1200,"gated_completion_and_once_bonus":true,"audio":audio,"capture_scope":"actual Rust PNG palette conversion and indexed Canvas from real World states; desktop Host live screenshots handled independently"}); + std::fs::write( + root.join("mods") + .join(owner) + .join("validation/acceptance.json"), + serde_json::to_string_pretty(&report).unwrap() + "\n", + ) + .unwrap(); + println!( + "retention4500/restart/full20/once-bonus/deterministic saved state+RNG/mixed WAVs: passed" + ); +} diff --git a/mods/iron_coast_stage2_mission_3/validation/visual-review.json b/mods/iron_coast_stage2_mission_3/validation/visual-review.json new file mode 100644 index 00000000..e38bd427 --- /dev/null +++ b/mods/iron_coast_stage2_mission_3/validation/visual-review.json @@ -0,0 +1,48 @@ +{ + "scope": "Actual Rust PNG decoder + ordinary palette conversion + logical fitting + indexed Canvas + real World snapshots. Full desktop Host scene independent.", + "pages": { + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/captures/stage3-tick1200-hd.ppm": "c6fb6ff64751da4810f012ac3035401c07615c57475e5c25e9ff41daddf93a07", + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/captures/stage3-tick1200-sd.ppm": "19334f01a3a5d4dd66529ec3ce03cb8ad7a4e037d6a325d76d338ee6e125422d", + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/captures/stage3-tick1800-hd.ppm": "4990c0a053530bae696574d8c4ea833d740f7763ba525a64364b6d1da5863426", + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/captures/stage3-tick1800-sd.ppm": "a55cbf2a66c9dbcf2edb6ee62ee2af190207805bbeefe65e151e6464c2a9ed8d", + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/captures/stage3-tick2149-hd.ppm": "ea61a15060e218c7a4a2e0036d578232a75b019031942d211bceb7740635843b", + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/captures/stage3-tick2149-sd.ppm": "d0e968cbb7621332a7afbbccd00b8916e2e3e3ac9bd1b67f9482a22d8a3744c7", + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/captures/stage3-tick2163-hd.ppm": "6c639b39c34000e2c7d986391b04569cf10b2f0c7ded86003957122f66fccef6", + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/captures/stage3-tick2163-sd.ppm": "a0f4b54603bbe0aac89dc85cdeedeff9d4a89113b8800c99bddd6575ad8d7aed", + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/captures/stage3-tick2175-hd.ppm": "9eac384912b58664b2968373d5a5d6a982b05d27266b1615ecc5994695f4a5ab", + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/captures/stage3-tick2175-sd.ppm": "4e0fed1c2007b78855ef87363d5dbab7aeb5acfef2287c618e578e8839117fa8", + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/captures/stage3-tick2220-hd.ppm": "8c3b2cf5b7e466c08c0180b8d10cf0e4d5e11356280b36d4f943307dacd33be6", + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/captures/stage3-tick2220-sd.ppm": "089150a1935064bf2c3e89a7e655c2219444b57ea741f98f885c0035ae7afaa3", + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/captures/stage3-tick2269-hd.ppm": "616e1ea8ad3c3b86f485362ee2e62c1234c7f82b2424c57d31d0def2b5c38332", + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/captures/stage3-tick2269-sd.ppm": "e89e5b1beabbcf35edaa33ab41731512e023a30155d667414a6d12224c694f85", + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/captures/stage3-tick2283-hd.ppm": "93b7a07e3e85252125cbcf54832b3a46f3e4066b8375750003d8a35618324770", + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/captures/stage3-tick2283-sd.ppm": "6828f96bf979bc001e08decc53a56f74696f7b4cd4a62cdf565b569f93121173", + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/captures/stage3-tick300-hd.ppm": "0527df918a133273472485eb907c9f1ff47508f55dba5dbd13361a2e627f3fdc", + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/captures/stage3-tick300-sd.ppm": "1c06020ba25b69f3c68c185dd4fb738c14a7a1b12c3df2b88394ea1fe7c69baf" + }, + "visual_review": { + "terrain": "Paired SD1x/HD4x scenes retain contiguous terrain across horizontal tiles and reflected rows, dark central flight corridor, intact drainage/dam walls and no tile seams seen.", + "targets": "All four required target silhouettes individually readable with transparent padding, consistent32x32 alignment; narrow pair touches collision canvas boundaries but visible artwork remains separate.", + "boss": "Distinct tracked refinery crawler / teal hydraulic mobile dam hull, bilateral structure and stable104x72/64 canvases; high-detail source and pixel SD share alignment.", + "telegraph": "Both phase warning arcs inspected in actual Rust views; cosmetic blue strokes end before damaging volley. Bright amber source v2 retains11SD foreground pixels and223peak for visible projectiles.", + "limitations": "This static indexed compositor does not claim desktop HUD/interpolation/shadow/audio callback screenshots; root independently covers real Host scenes." + }, + "reviewed_pages": [ + "world-scenes.png", + "target-warning-shot-contact.png" + ], + "gallery_paths_outside_package": true, + "bounded_phase_recheck": { + "gallery": "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/bounded-render-review/stage3-current-rows.png", + "gallery_sha256": "97a9f815f9bb507ecc8fbbf35d0edbec264f9bd87c649eb07268c61beefba0a0", + "reviewed_current_rows": [ + 300, + 1800, + 2269, + 2283 + ], + "views": "Paired actual SD1x and HD4x; gallery SD enlarged nearest for inspection, raw PPMs retained.", + "decision": "Accepted. Required targets and boss remain aligned/readable, warning arcs and bright shell pixels visible, terrain joins intact. Historical original visual report preserved in full-folder pre-correction archive.", + "limits": "Static indexed World views; no new live Host/cinematic assertion." + } +} diff --git a/mods/iron_coast_stage2_mission_4/README.md b/mods/iron_coast_stage2_mission_4/README.md new file mode 100644 index 00000000..3d78da71 --- /dev/null +++ b/mods/iron_coast_stage2_mission_4/README.md @@ -0,0 +1,13 @@ +# Iron Coast II — Mission 4: Floodgate Zero + +Enable **Iron Coast II — Mission 4: Floodgate Zero** in Mods at the main menu. Its own boss, shared interceptor, shared skimmer and Stage2 music are required; the dependency check selects them when installed. This single-mission campaign also works alongside the eight-mission Black Tide campaign pack. It has no explicit next mission, overrides, gear grant or equipment loan. + +Follow a river through canyon crossings and dam defenses, mixing classic zigzag fighters and naval skimmers with Needlewing interceptors, Wakeknife skimmers and the Floodgate mobile dam platform. Destroy all **four crossing defenses** and the boss. Required defenses stop at y60 and the boss patrols at y24 until destroyed; elapsed time and escaping ordinary enemies never count as kills or finish the mission. Cosmetic storm flashes cause no damage. + +Use ordinary game controls: Fire shoots equipped guns, Space drops owned bombs, Alt or Shift cycles selected weapons. Starter guns can destroy every required target. New campaign equipment is optional and can be purchased separately; this mission never modifies owned equipment or consumes inventory slots. Each objective grants 500 credits and restores12 shield. The boss pays 2800 credits, and a single completion bonus pays 16500. The boss enters at tick2250; expected complete sorties run roughly90–140seconds at70/3Hz. + +Each authored32×32 target has SD and8×HD art. The opaque industrial/river panorama is quantized as one joined image before splitting into288SD/HD terrain tiles; its forward/reflected32-row period repeats eight times across256rows, covering8192scroll pixels. The briefing is a wide crop from the same genuine terrain master. Originals, tracked prompts, exact builtin provenance, `asset-report.json`, `audio-recipe.json` and `build_assets.py` accompany the final assets. The recipe defaults to the bundled `RustRaptor/data/misc/PALETTE_DAT`; decoded original style references remain outside the package. Generated mono16-bit22050Hz WAVs use original seeded synthesis. + +From `RustRaptor/`, validate the complete dependency set with `target/release/raptor-rust --data data --mods mods --validate-mods iron_coast_stage2_mission_4,iron_coast_stage2_boss_4,iron_coast_stage2_interceptor,iron_coast_stage2_skimmer,iron_coast_stage2_music`. Run the package-local original-catalog probe with `cargo run --manifest-path mods/iron_coast_stage2_mission_4/validation/Cargo.toml --target-dir target/mod-validation --bin validate --release -- . 4`. It checks actual starter/full-inventory combat, genuine native movement, saved script-state/RNG continuation,4500-tick delayed objectives, replay reset, completion gating and every authored cue through the native PCM mixer. Local render evidence uses actual Rust asset conversion/indexed Canvas from World states; full desktop Host review is separate. + +Retired death guards are bounded to the most recent128 entity IDs, including deterministic migration of older checkpoints. Spawn resets a reused ID before any alive check; duplicate deaths for the current lifecycle emit no commands. The `retained-state` validation binary exercises1,205 actual-catalog/native lethal-collision lives, including1,200 distinct IDs, five reused-ID lives, JSON state/RNG restoration, a960-guard old checkpoint, duplicate callbacks, exact rewards and difficulty0–3. Run it from `RustRaptor/` with `cargo run --manifest-path mods/iron_coast_stage2_mission_4/validation/Cargo.toml --target-dir target/mod-validation --bin retained-state --release -- mods/iron_coast_stage2_mission_4`. The corresponding `validation/retained-state.json` records actual observations; package pins there identify the activation before generated proof files were finalized. The final external freeze ledger binds the complete resulting package. diff --git a/mods/iron_coast_stage2_mission_4/art/briefing-hd.png b/mods/iron_coast_stage2_mission_4/art/briefing-hd.png new file mode 100644 index 00000000..0ee647ec Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/briefing-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/briefing-sd.png b/mods/iron_coast_stage2_mission_4/art/briefing-sd.png new file mode 100644 index 00000000..a379d731 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/briefing-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/target-hd.png b/mods/iron_coast_stage2_mission_4/art/target-hd.png new file mode 100644 index 00000000..2a52c532 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/target-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/target-sd.png b/mods/iron_coast_stage2_mission_4/art/target-sd.png new file mode 100644 index 00000000..6ec26843 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/target-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/target-source-v1.png b/mods/iron_coast_stage2_mission_4/art/target-source-v1.png new file mode 100644 index 00000000..a2792a77 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/target-source-v1.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/terrain-preview-hd.png b/mods/iron_coast_stage2_mission_4/art/terrain-preview-hd.png new file mode 100644 index 00000000..2a928813 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/terrain-preview-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/terrain-preview-sd.png b/mods/iron_coast_stage2_mission_4/art/terrain-preview-sd.png new file mode 100644 index 00000000..89599ec7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/terrain-preview-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/terrain-source-v1.png b/mods/iron_coast_stage2_mission_4/art/terrain-source-v1.png new file mode 100644 index 00000000..317a4421 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/terrain-source-v1.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-000-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-000-hd.png new file mode 100644 index 00000000..0ae54f99 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-000-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-000-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-000-sd.png new file mode 100644 index 00000000..b0cde5fb Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-000-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-001-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-001-hd.png new file mode 100644 index 00000000..6ac0db07 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-001-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-001-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-001-sd.png new file mode 100644 index 00000000..a00d9df0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-001-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-002-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-002-hd.png new file mode 100644 index 00000000..6fce52a7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-002-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-002-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-002-sd.png new file mode 100644 index 00000000..0856ebd9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-002-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-003-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-003-hd.png new file mode 100644 index 00000000..65e4a980 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-003-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-003-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-003-sd.png new file mode 100644 index 00000000..71251579 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-003-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-004-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-004-hd.png new file mode 100644 index 00000000..5e9d8c2c Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-004-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-004-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-004-sd.png new file mode 100644 index 00000000..bafdc17e Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-004-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-005-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-005-hd.png new file mode 100644 index 00000000..9a44e3e7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-005-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-005-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-005-sd.png new file mode 100644 index 00000000..e9a32279 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-005-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-006-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-006-hd.png new file mode 100644 index 00000000..c7da59e2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-006-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-006-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-006-sd.png new file mode 100644 index 00000000..4b0e6e4a Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-006-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-007-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-007-hd.png new file mode 100644 index 00000000..0d1a8fe8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-007-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-007-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-007-sd.png new file mode 100644 index 00000000..51fc7837 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-007-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-008-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-008-hd.png new file mode 100644 index 00000000..fda4c3ff Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-008-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-008-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-008-sd.png new file mode 100644 index 00000000..47fce8ad Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-008-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-009-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-009-hd.png new file mode 100644 index 00000000..098d65f4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-009-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-009-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-009-sd.png new file mode 100644 index 00000000..21c9ebac Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-009-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-010-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-010-hd.png new file mode 100644 index 00000000..df52d898 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-010-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-010-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-010-sd.png new file mode 100644 index 00000000..b7dea5ff Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-010-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-011-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-011-hd.png new file mode 100644 index 00000000..62d7dd5d Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-011-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-011-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-011-sd.png new file mode 100644 index 00000000..b6270462 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-011-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-012-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-012-hd.png new file mode 100644 index 00000000..5cf5253f Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-012-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-012-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-012-sd.png new file mode 100644 index 00000000..dbff5768 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-012-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-013-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-013-hd.png new file mode 100644 index 00000000..447f93fd Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-013-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-013-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-013-sd.png new file mode 100644 index 00000000..6bfcccc0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-013-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-014-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-014-hd.png new file mode 100644 index 00000000..5e154dc5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-014-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-014-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-014-sd.png new file mode 100644 index 00000000..46e7be91 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-014-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-015-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-015-hd.png new file mode 100644 index 00000000..fd7a989c Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-015-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-015-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-015-sd.png new file mode 100644 index 00000000..fce3ee27 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-015-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-016-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-016-hd.png new file mode 100644 index 00000000..f468b647 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-016-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-016-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-016-sd.png new file mode 100644 index 00000000..c969c022 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-016-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-017-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-017-hd.png new file mode 100644 index 00000000..3ef26bce Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-017-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-017-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-017-sd.png new file mode 100644 index 00000000..2e0f105b Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-017-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-018-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-018-hd.png new file mode 100644 index 00000000..5a6fc5bf Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-018-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-018-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-018-sd.png new file mode 100644 index 00000000..faa79a83 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-018-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-019-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-019-hd.png new file mode 100644 index 00000000..0c0d2681 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-019-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-019-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-019-sd.png new file mode 100644 index 00000000..c8522f85 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-019-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-020-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-020-hd.png new file mode 100644 index 00000000..31d39d19 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-020-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-020-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-020-sd.png new file mode 100644 index 00000000..d93934a4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-020-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-021-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-021-hd.png new file mode 100644 index 00000000..fd141c67 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-021-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-021-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-021-sd.png new file mode 100644 index 00000000..51f1370f Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-021-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-022-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-022-hd.png new file mode 100644 index 00000000..b97bf61c Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-022-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-022-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-022-sd.png new file mode 100644 index 00000000..cf122e9f Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-022-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-023-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-023-hd.png new file mode 100644 index 00000000..706aece1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-023-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-023-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-023-sd.png new file mode 100644 index 00000000..8ff8d823 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-023-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-024-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-024-hd.png new file mode 100644 index 00000000..d7f83612 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-024-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-024-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-024-sd.png new file mode 100644 index 00000000..b6dd5710 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-024-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-025-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-025-hd.png new file mode 100644 index 00000000..dea143da Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-025-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-025-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-025-sd.png new file mode 100644 index 00000000..a1e2a27d Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-025-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-026-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-026-hd.png new file mode 100644 index 00000000..34ca612f Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-026-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-026-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-026-sd.png new file mode 100644 index 00000000..6a20a0eb Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-026-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-027-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-027-hd.png new file mode 100644 index 00000000..7361f225 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-027-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-027-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-027-sd.png new file mode 100644 index 00000000..3088e20d Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-027-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-028-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-028-hd.png new file mode 100644 index 00000000..3842457a Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-028-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-028-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-028-sd.png new file mode 100644 index 00000000..f82ec674 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-028-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-029-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-029-hd.png new file mode 100644 index 00000000..f81aa6bc Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-029-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-029-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-029-sd.png new file mode 100644 index 00000000..b9ec8a0c Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-029-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-030-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-030-hd.png new file mode 100644 index 00000000..32c06eb6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-030-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-030-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-030-sd.png new file mode 100644 index 00000000..53203318 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-030-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-031-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-031-hd.png new file mode 100644 index 00000000..9d2263ef Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-031-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-031-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-031-sd.png new file mode 100644 index 00000000..7af76bb6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-031-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-032-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-032-hd.png new file mode 100644 index 00000000..7b4c4512 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-032-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-032-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-032-sd.png new file mode 100644 index 00000000..159fd226 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-032-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-033-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-033-hd.png new file mode 100644 index 00000000..2167578b Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-033-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-033-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-033-sd.png new file mode 100644 index 00000000..77c27b96 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-033-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-034-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-034-hd.png new file mode 100644 index 00000000..0b63c355 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-034-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-034-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-034-sd.png new file mode 100644 index 00000000..e04ecceb Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-034-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-035-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-035-hd.png new file mode 100644 index 00000000..81f60f24 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-035-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-035-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-035-sd.png new file mode 100644 index 00000000..8e14f87a Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-035-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-036-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-036-hd.png new file mode 100644 index 00000000..7d119270 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-036-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-036-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-036-sd.png new file mode 100644 index 00000000..323eb3d5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-036-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-037-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-037-hd.png new file mode 100644 index 00000000..445cd797 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-037-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-037-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-037-sd.png new file mode 100644 index 00000000..bc9d87f1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-037-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-038-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-038-hd.png new file mode 100644 index 00000000..c39f5c1b Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-038-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-038-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-038-sd.png new file mode 100644 index 00000000..6b1a4181 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-038-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-039-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-039-hd.png new file mode 100644 index 00000000..dbb8f5c5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-039-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-039-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-039-sd.png new file mode 100644 index 00000000..b9201f02 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-039-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-040-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-040-hd.png new file mode 100644 index 00000000..30267f73 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-040-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-040-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-040-sd.png new file mode 100644 index 00000000..201c42c8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-040-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-041-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-041-hd.png new file mode 100644 index 00000000..147e638d Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-041-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-041-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-041-sd.png new file mode 100644 index 00000000..66aa2826 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-041-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-042-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-042-hd.png new file mode 100644 index 00000000..98250a42 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-042-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-042-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-042-sd.png new file mode 100644 index 00000000..660914ca Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-042-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-043-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-043-hd.png new file mode 100644 index 00000000..ad8037f3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-043-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-043-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-043-sd.png new file mode 100644 index 00000000..ae8dde42 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-043-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-044-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-044-hd.png new file mode 100644 index 00000000..735fbf68 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-044-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-044-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-044-sd.png new file mode 100644 index 00000000..331348c3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-044-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-045-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-045-hd.png new file mode 100644 index 00000000..056fab05 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-045-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-045-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-045-sd.png new file mode 100644 index 00000000..fd88454e Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-045-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-046-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-046-hd.png new file mode 100644 index 00000000..7fbf51dd Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-046-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-046-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-046-sd.png new file mode 100644 index 00000000..2a9ea814 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-046-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-047-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-047-hd.png new file mode 100644 index 00000000..337d56e5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-047-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-047-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-047-sd.png new file mode 100644 index 00000000..4fef5ec2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-047-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-048-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-048-hd.png new file mode 100644 index 00000000..ee38c8a7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-048-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-048-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-048-sd.png new file mode 100644 index 00000000..932b8a3e Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-048-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-049-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-049-hd.png new file mode 100644 index 00000000..1b09be04 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-049-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-049-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-049-sd.png new file mode 100644 index 00000000..fabe0388 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-049-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-050-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-050-hd.png new file mode 100644 index 00000000..c48a7115 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-050-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-050-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-050-sd.png new file mode 100644 index 00000000..9bd74c7c Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-050-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-051-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-051-hd.png new file mode 100644 index 00000000..cb60bfb0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-051-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-051-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-051-sd.png new file mode 100644 index 00000000..609cba73 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-051-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-052-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-052-hd.png new file mode 100644 index 00000000..74faa0d1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-052-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-052-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-052-sd.png new file mode 100644 index 00000000..4cce8c92 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-052-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-053-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-053-hd.png new file mode 100644 index 00000000..5c8d17fd Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-053-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-053-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-053-sd.png new file mode 100644 index 00000000..f727822d Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-053-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-054-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-054-hd.png new file mode 100644 index 00000000..fdabd790 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-054-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-054-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-054-sd.png new file mode 100644 index 00000000..c0ad0f67 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-054-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-055-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-055-hd.png new file mode 100644 index 00000000..95e624f3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-055-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-055-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-055-sd.png new file mode 100644 index 00000000..79143927 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-055-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-056-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-056-hd.png new file mode 100644 index 00000000..b00b234f Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-056-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-056-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-056-sd.png new file mode 100644 index 00000000..5ce913cc Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-056-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-057-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-057-hd.png new file mode 100644 index 00000000..157cd400 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-057-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-057-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-057-sd.png new file mode 100644 index 00000000..10c52a2d Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-057-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-058-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-058-hd.png new file mode 100644 index 00000000..a00b3ead Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-058-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-058-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-058-sd.png new file mode 100644 index 00000000..9a9d7189 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-058-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-059-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-059-hd.png new file mode 100644 index 00000000..fad180d7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-059-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-059-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-059-sd.png new file mode 100644 index 00000000..d5ff1933 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-059-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-060-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-060-hd.png new file mode 100644 index 00000000..2b0cf801 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-060-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-060-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-060-sd.png new file mode 100644 index 00000000..dfb6ef9c Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-060-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-061-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-061-hd.png new file mode 100644 index 00000000..e5fc1e2e Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-061-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-061-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-061-sd.png new file mode 100644 index 00000000..3d3fae87 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-061-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-062-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-062-hd.png new file mode 100644 index 00000000..f7bedf48 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-062-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-062-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-062-sd.png new file mode 100644 index 00000000..29ce9abb Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-062-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-063-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-063-hd.png new file mode 100644 index 00000000..0667de03 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-063-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-063-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-063-sd.png new file mode 100644 index 00000000..b2d30566 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-063-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-064-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-064-hd.png new file mode 100644 index 00000000..b18e3767 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-064-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-064-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-064-sd.png new file mode 100644 index 00000000..60c8963e Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-064-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-065-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-065-hd.png new file mode 100644 index 00000000..7c015357 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-065-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-065-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-065-sd.png new file mode 100644 index 00000000..797a1e61 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-065-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-066-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-066-hd.png new file mode 100644 index 00000000..910ad071 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-066-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-066-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-066-sd.png new file mode 100644 index 00000000..8cbdb4ad Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-066-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-067-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-067-hd.png new file mode 100644 index 00000000..faa56fe7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-067-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-067-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-067-sd.png new file mode 100644 index 00000000..1c479679 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-067-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-068-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-068-hd.png new file mode 100644 index 00000000..abf762b8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-068-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-068-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-068-sd.png new file mode 100644 index 00000000..0c7946dd Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-068-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-069-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-069-hd.png new file mode 100644 index 00000000..5f950807 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-069-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-069-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-069-sd.png new file mode 100644 index 00000000..a7761e7a Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-069-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-070-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-070-hd.png new file mode 100644 index 00000000..2536a354 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-070-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-070-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-070-sd.png new file mode 100644 index 00000000..bba947a6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-070-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-071-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-071-hd.png new file mode 100644 index 00000000..a9deec15 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-071-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-071-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-071-sd.png new file mode 100644 index 00000000..4e6d2080 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-071-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-072-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-072-hd.png new file mode 100644 index 00000000..cb33db96 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-072-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-072-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-072-sd.png new file mode 100644 index 00000000..3c275db9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-072-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-073-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-073-hd.png new file mode 100644 index 00000000..0ac76c30 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-073-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-073-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-073-sd.png new file mode 100644 index 00000000..e0dc759b Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-073-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-074-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-074-hd.png new file mode 100644 index 00000000..50308e9a Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-074-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-074-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-074-sd.png new file mode 100644 index 00000000..b082adf7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-074-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-075-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-075-hd.png new file mode 100644 index 00000000..42eff4cd Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-075-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-075-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-075-sd.png new file mode 100644 index 00000000..15766a4c Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-075-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-076-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-076-hd.png new file mode 100644 index 00000000..f4e3d4ee Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-076-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-076-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-076-sd.png new file mode 100644 index 00000000..c27b41ca Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-076-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-077-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-077-hd.png new file mode 100644 index 00000000..d3d43b88 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-077-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-077-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-077-sd.png new file mode 100644 index 00000000..97906399 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-077-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-078-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-078-hd.png new file mode 100644 index 00000000..e6320119 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-078-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-078-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-078-sd.png new file mode 100644 index 00000000..86729ea2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-078-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-079-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-079-hd.png new file mode 100644 index 00000000..1da8361d Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-079-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-079-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-079-sd.png new file mode 100644 index 00000000..26a667e5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-079-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-080-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-080-hd.png new file mode 100644 index 00000000..ba0c85cf Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-080-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-080-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-080-sd.png new file mode 100644 index 00000000..30424b91 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-080-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-081-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-081-hd.png new file mode 100644 index 00000000..aa7dcfa6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-081-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-081-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-081-sd.png new file mode 100644 index 00000000..49756a4f Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-081-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-082-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-082-hd.png new file mode 100644 index 00000000..b9e5cd43 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-082-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-082-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-082-sd.png new file mode 100644 index 00000000..35f8b5a7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-082-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-083-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-083-hd.png new file mode 100644 index 00000000..05eb161a Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-083-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-083-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-083-sd.png new file mode 100644 index 00000000..97f63246 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-083-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-084-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-084-hd.png new file mode 100644 index 00000000..9dc0b62e Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-084-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-084-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-084-sd.png new file mode 100644 index 00000000..98677b04 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-084-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-085-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-085-hd.png new file mode 100644 index 00000000..f238f557 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-085-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-085-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-085-sd.png new file mode 100644 index 00000000..b9bdf044 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-085-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-086-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-086-hd.png new file mode 100644 index 00000000..e3a49877 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-086-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-086-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-086-sd.png new file mode 100644 index 00000000..63a8eb3d Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-086-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-087-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-087-hd.png new file mode 100644 index 00000000..2da37d8d Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-087-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-087-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-087-sd.png new file mode 100644 index 00000000..46a87ca9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-087-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-088-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-088-hd.png new file mode 100644 index 00000000..d4ca0f75 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-088-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-088-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-088-sd.png new file mode 100644 index 00000000..71f847a1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-088-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-089-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-089-hd.png new file mode 100644 index 00000000..8e8a76fb Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-089-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-089-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-089-sd.png new file mode 100644 index 00000000..e9dfe71c Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-089-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-090-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-090-hd.png new file mode 100644 index 00000000..1f8298c3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-090-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-090-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-090-sd.png new file mode 100644 index 00000000..83b4df7a Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-090-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-091-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-091-hd.png new file mode 100644 index 00000000..84ca2ab4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-091-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-091-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-091-sd.png new file mode 100644 index 00000000..a69afac3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-091-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-092-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-092-hd.png new file mode 100644 index 00000000..c72cd61b Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-092-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-092-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-092-sd.png new file mode 100644 index 00000000..454e9261 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-092-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-093-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-093-hd.png new file mode 100644 index 00000000..1157e5d0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-093-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-093-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-093-sd.png new file mode 100644 index 00000000..f4fa4a0e Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-093-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-094-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-094-hd.png new file mode 100644 index 00000000..ed5aac52 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-094-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-094-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-094-sd.png new file mode 100644 index 00000000..3f8ff9c4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-094-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-095-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-095-hd.png new file mode 100644 index 00000000..1a5772b6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-095-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-095-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-095-sd.png new file mode 100644 index 00000000..54607c1d Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-095-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-096-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-096-hd.png new file mode 100644 index 00000000..804be012 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-096-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-096-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-096-sd.png new file mode 100644 index 00000000..32223a39 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-096-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-097-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-097-hd.png new file mode 100644 index 00000000..f2acfe1c Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-097-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-097-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-097-sd.png new file mode 100644 index 00000000..1150996a Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-097-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-098-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-098-hd.png new file mode 100644 index 00000000..a93562ff Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-098-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-098-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-098-sd.png new file mode 100644 index 00000000..405915e8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-098-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-099-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-099-hd.png new file mode 100644 index 00000000..2b637127 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-099-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-099-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-099-sd.png new file mode 100644 index 00000000..da841369 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-099-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-100-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-100-hd.png new file mode 100644 index 00000000..dd1321c4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-100-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-100-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-100-sd.png new file mode 100644 index 00000000..24f74f7e Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-100-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-101-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-101-hd.png new file mode 100644 index 00000000..cc5853f7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-101-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-101-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-101-sd.png new file mode 100644 index 00000000..4ccfd24c Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-101-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-102-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-102-hd.png new file mode 100644 index 00000000..9d0a11c3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-102-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-102-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-102-sd.png new file mode 100644 index 00000000..85753793 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-102-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-103-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-103-hd.png new file mode 100644 index 00000000..289d9ecf Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-103-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-103-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-103-sd.png new file mode 100644 index 00000000..246a7055 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-103-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-104-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-104-hd.png new file mode 100644 index 00000000..1c9d13dc Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-104-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-104-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-104-sd.png new file mode 100644 index 00000000..26d262ab Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-104-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-105-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-105-hd.png new file mode 100644 index 00000000..e6d4270f Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-105-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-105-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-105-sd.png new file mode 100644 index 00000000..2658a056 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-105-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-106-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-106-hd.png new file mode 100644 index 00000000..eaff36a2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-106-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-106-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-106-sd.png new file mode 100644 index 00000000..39b1d8ba Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-106-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-107-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-107-hd.png new file mode 100644 index 00000000..2d00c01d Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-107-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-107-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-107-sd.png new file mode 100644 index 00000000..1f1b3f0a Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-107-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-108-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-108-hd.png new file mode 100644 index 00000000..e0df917c Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-108-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-108-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-108-sd.png new file mode 100644 index 00000000..e952f242 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-108-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-109-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-109-hd.png new file mode 100644 index 00000000..2026fa70 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-109-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-109-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-109-sd.png new file mode 100644 index 00000000..5bf68270 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-109-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-110-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-110-hd.png new file mode 100644 index 00000000..ff016380 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-110-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-110-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-110-sd.png new file mode 100644 index 00000000..3e5688b9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-110-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-111-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-111-hd.png new file mode 100644 index 00000000..5ce7cc7e Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-111-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-111-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-111-sd.png new file mode 100644 index 00000000..0837f9ac Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-111-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-112-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-112-hd.png new file mode 100644 index 00000000..a01f246a Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-112-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-112-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-112-sd.png new file mode 100644 index 00000000..adca94dc Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-112-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-113-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-113-hd.png new file mode 100644 index 00000000..a54a9dd1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-113-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-113-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-113-sd.png new file mode 100644 index 00000000..ff780cac Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-113-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-114-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-114-hd.png new file mode 100644 index 00000000..6b5f776e Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-114-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-114-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-114-sd.png new file mode 100644 index 00000000..fe8feda1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-114-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-115-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-115-hd.png new file mode 100644 index 00000000..ff7c18cb Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-115-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-115-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-115-sd.png new file mode 100644 index 00000000..e92fd001 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-115-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-116-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-116-hd.png new file mode 100644 index 00000000..a0121860 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-116-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-116-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-116-sd.png new file mode 100644 index 00000000..6b9e7f18 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-116-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-117-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-117-hd.png new file mode 100644 index 00000000..7f5b77be Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-117-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-117-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-117-sd.png new file mode 100644 index 00000000..d67a9244 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-117-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-118-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-118-hd.png new file mode 100644 index 00000000..29f8c706 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-118-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-118-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-118-sd.png new file mode 100644 index 00000000..963b7533 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-118-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-119-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-119-hd.png new file mode 100644 index 00000000..e58ba104 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-119-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-119-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-119-sd.png new file mode 100644 index 00000000..d89b7ef0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-119-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-120-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-120-hd.png new file mode 100644 index 00000000..a1d2ef2d Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-120-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-120-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-120-sd.png new file mode 100644 index 00000000..8c18bd4d Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-120-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-121-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-121-hd.png new file mode 100644 index 00000000..f943cb6f Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-121-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-121-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-121-sd.png new file mode 100644 index 00000000..14fab364 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-121-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-122-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-122-hd.png new file mode 100644 index 00000000..1e0a67e6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-122-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-122-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-122-sd.png new file mode 100644 index 00000000..0bba533c Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-122-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-123-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-123-hd.png new file mode 100644 index 00000000..3ee18217 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-123-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-123-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-123-sd.png new file mode 100644 index 00000000..0470c567 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-123-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-124-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-124-hd.png new file mode 100644 index 00000000..d742b8aa Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-124-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-124-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-124-sd.png new file mode 100644 index 00000000..bdaced44 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-124-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-125-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-125-hd.png new file mode 100644 index 00000000..4a0178a5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-125-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-125-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-125-sd.png new file mode 100644 index 00000000..e146a1ea Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-125-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-126-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-126-hd.png new file mode 100644 index 00000000..57c4fe27 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-126-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-126-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-126-sd.png new file mode 100644 index 00000000..7466ef38 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-126-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-127-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-127-hd.png new file mode 100644 index 00000000..091aba6a Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-127-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-127-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-127-sd.png new file mode 100644 index 00000000..f49cfd28 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-127-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-128-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-128-hd.png new file mode 100644 index 00000000..ff806d1d Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-128-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-128-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-128-sd.png new file mode 100644 index 00000000..c5a709f0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-128-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-129-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-129-hd.png new file mode 100644 index 00000000..86f11254 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-129-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-129-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-129-sd.png new file mode 100644 index 00000000..3c5fd1bd Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-129-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-130-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-130-hd.png new file mode 100644 index 00000000..f06b4907 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-130-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-130-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-130-sd.png new file mode 100644 index 00000000..f452517a Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-130-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-131-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-131-hd.png new file mode 100644 index 00000000..b161fadb Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-131-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-131-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-131-sd.png new file mode 100644 index 00000000..8ff626ee Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-131-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-132-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-132-hd.png new file mode 100644 index 00000000..3767028c Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-132-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-132-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-132-sd.png new file mode 100644 index 00000000..2c9050d5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-132-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-133-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-133-hd.png new file mode 100644 index 00000000..5a1898ff Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-133-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-133-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-133-sd.png new file mode 100644 index 00000000..82996754 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-133-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-134-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-134-hd.png new file mode 100644 index 00000000..7fa4cdcd Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-134-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-134-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-134-sd.png new file mode 100644 index 00000000..56149f78 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-134-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-135-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-135-hd.png new file mode 100644 index 00000000..43e0642f Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-135-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-135-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-135-sd.png new file mode 100644 index 00000000..9e389460 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-135-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-136-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-136-hd.png new file mode 100644 index 00000000..1a1f2e95 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-136-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-136-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-136-sd.png new file mode 100644 index 00000000..f85ed186 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-136-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-137-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-137-hd.png new file mode 100644 index 00000000..aa0b9839 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-137-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-137-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-137-sd.png new file mode 100644 index 00000000..df34465b Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-137-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-138-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-138-hd.png new file mode 100644 index 00000000..7b6172a6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-138-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-138-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-138-sd.png new file mode 100644 index 00000000..820c9646 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-138-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-139-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-139-hd.png new file mode 100644 index 00000000..71762674 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-139-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-139-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-139-sd.png new file mode 100644 index 00000000..777dff14 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-139-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-140-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-140-hd.png new file mode 100644 index 00000000..56817d40 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-140-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-140-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-140-sd.png new file mode 100644 index 00000000..8c3c1db5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-140-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-141-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-141-hd.png new file mode 100644 index 00000000..746f45e7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-141-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-141-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-141-sd.png new file mode 100644 index 00000000..b9582ef1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-141-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-142-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-142-hd.png new file mode 100644 index 00000000..12f70546 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-142-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-142-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-142-sd.png new file mode 100644 index 00000000..a76af7c9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-142-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-143-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-143-hd.png new file mode 100644 index 00000000..f7c3c7cf Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-143-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-143-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-143-sd.png new file mode 100644 index 00000000..062f0ea7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-143-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-144-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-144-hd.png new file mode 100644 index 00000000..dbf3c18a Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-144-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-144-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-144-sd.png new file mode 100644 index 00000000..aeedb1fd Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-144-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-145-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-145-hd.png new file mode 100644 index 00000000..49d447e5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-145-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-145-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-145-sd.png new file mode 100644 index 00000000..6f0adf55 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-145-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-146-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-146-hd.png new file mode 100644 index 00000000..6501666f Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-146-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-146-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-146-sd.png new file mode 100644 index 00000000..2a813cd7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-146-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-147-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-147-hd.png new file mode 100644 index 00000000..9abdbd33 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-147-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-147-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-147-sd.png new file mode 100644 index 00000000..569568b7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-147-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-148-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-148-hd.png new file mode 100644 index 00000000..5ebf395e Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-148-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-148-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-148-sd.png new file mode 100644 index 00000000..7ebc2ac6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-148-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-149-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-149-hd.png new file mode 100644 index 00000000..61e53e52 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-149-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-149-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-149-sd.png new file mode 100644 index 00000000..b30eaa0c Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-149-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-150-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-150-hd.png new file mode 100644 index 00000000..802e282f Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-150-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-150-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-150-sd.png new file mode 100644 index 00000000..736fcae7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-150-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-151-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-151-hd.png new file mode 100644 index 00000000..d6ac8670 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-151-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-151-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-151-sd.png new file mode 100644 index 00000000..e01b1295 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-151-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-152-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-152-hd.png new file mode 100644 index 00000000..7d94028b Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-152-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-152-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-152-sd.png new file mode 100644 index 00000000..efc3b038 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-152-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-153-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-153-hd.png new file mode 100644 index 00000000..09912384 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-153-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-153-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-153-sd.png new file mode 100644 index 00000000..f6bc7c1c Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-153-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-154-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-154-hd.png new file mode 100644 index 00000000..8daa1a04 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-154-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-154-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-154-sd.png new file mode 100644 index 00000000..94c19c7d Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-154-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-155-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-155-hd.png new file mode 100644 index 00000000..df8cc41e Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-155-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-155-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-155-sd.png new file mode 100644 index 00000000..0b53799e Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-155-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-156-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-156-hd.png new file mode 100644 index 00000000..a413d506 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-156-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-156-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-156-sd.png new file mode 100644 index 00000000..c99c3cc3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-156-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-157-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-157-hd.png new file mode 100644 index 00000000..d0e91952 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-157-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-157-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-157-sd.png new file mode 100644 index 00000000..6d5aeb47 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-157-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-158-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-158-hd.png new file mode 100644 index 00000000..bfde4998 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-158-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-158-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-158-sd.png new file mode 100644 index 00000000..42f00219 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-158-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-159-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-159-hd.png new file mode 100644 index 00000000..f7dfe29a Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-159-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-159-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-159-sd.png new file mode 100644 index 00000000..3ea35384 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-159-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-160-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-160-hd.png new file mode 100644 index 00000000..7756ab70 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-160-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-160-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-160-sd.png new file mode 100644 index 00000000..5b104127 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-160-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-161-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-161-hd.png new file mode 100644 index 00000000..60f995f5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-161-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-161-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-161-sd.png new file mode 100644 index 00000000..288e32fe Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-161-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-162-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-162-hd.png new file mode 100644 index 00000000..767d5047 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-162-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-162-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-162-sd.png new file mode 100644 index 00000000..f1c92cc9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-162-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-163-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-163-hd.png new file mode 100644 index 00000000..e0c4df1a Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-163-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-163-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-163-sd.png new file mode 100644 index 00000000..10516999 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-163-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-164-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-164-hd.png new file mode 100644 index 00000000..b6a19ad1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-164-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-164-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-164-sd.png new file mode 100644 index 00000000..a488a829 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-164-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-165-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-165-hd.png new file mode 100644 index 00000000..7ec11597 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-165-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-165-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-165-sd.png new file mode 100644 index 00000000..0125c4d5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-165-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-166-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-166-hd.png new file mode 100644 index 00000000..b8b428a1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-166-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-166-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-166-sd.png new file mode 100644 index 00000000..3faad31c Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-166-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-167-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-167-hd.png new file mode 100644 index 00000000..14263f3b Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-167-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-167-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-167-sd.png new file mode 100644 index 00000000..2c44641d Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-167-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-168-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-168-hd.png new file mode 100644 index 00000000..3aa4b2c7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-168-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-168-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-168-sd.png new file mode 100644 index 00000000..f39626f4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-168-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-169-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-169-hd.png new file mode 100644 index 00000000..72c2b419 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-169-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-169-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-169-sd.png new file mode 100644 index 00000000..198549a6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-169-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-170-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-170-hd.png new file mode 100644 index 00000000..d23a2e3b Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-170-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-170-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-170-sd.png new file mode 100644 index 00000000..cebe9542 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-170-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-171-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-171-hd.png new file mode 100644 index 00000000..4204aadd Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-171-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-171-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-171-sd.png new file mode 100644 index 00000000..c4de5809 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-171-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-172-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-172-hd.png new file mode 100644 index 00000000..10a39501 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-172-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-172-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-172-sd.png new file mode 100644 index 00000000..4a59c9ac Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-172-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-173-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-173-hd.png new file mode 100644 index 00000000..3b8d5b7f Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-173-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-173-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-173-sd.png new file mode 100644 index 00000000..93880c7c Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-173-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-174-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-174-hd.png new file mode 100644 index 00000000..a8f8166c Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-174-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-174-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-174-sd.png new file mode 100644 index 00000000..d57c06c3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-174-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-175-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-175-hd.png new file mode 100644 index 00000000..3d6fc83d Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-175-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-175-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-175-sd.png new file mode 100644 index 00000000..e4b0cffd Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-175-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-176-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-176-hd.png new file mode 100644 index 00000000..f13e4f49 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-176-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-176-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-176-sd.png new file mode 100644 index 00000000..2d76e431 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-176-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-177-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-177-hd.png new file mode 100644 index 00000000..39f08a3d Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-177-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-177-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-177-sd.png new file mode 100644 index 00000000..c996221d Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-177-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-178-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-178-hd.png new file mode 100644 index 00000000..10432922 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-178-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-178-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-178-sd.png new file mode 100644 index 00000000..fd3962da Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-178-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-179-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-179-hd.png new file mode 100644 index 00000000..84039a20 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-179-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-179-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-179-sd.png new file mode 100644 index 00000000..89f51b83 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-179-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-180-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-180-hd.png new file mode 100644 index 00000000..ca39ea16 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-180-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-180-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-180-sd.png new file mode 100644 index 00000000..309992de Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-180-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-181-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-181-hd.png new file mode 100644 index 00000000..9f3bd86a Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-181-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-181-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-181-sd.png new file mode 100644 index 00000000..812bbf0f Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-181-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-182-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-182-hd.png new file mode 100644 index 00000000..997f8c26 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-182-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-182-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-182-sd.png new file mode 100644 index 00000000..b8e89b6b Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-182-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-183-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-183-hd.png new file mode 100644 index 00000000..92e8af27 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-183-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-183-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-183-sd.png new file mode 100644 index 00000000..21cd6f60 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-183-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-184-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-184-hd.png new file mode 100644 index 00000000..293804da Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-184-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-184-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-184-sd.png new file mode 100644 index 00000000..8439d0c3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-184-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-185-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-185-hd.png new file mode 100644 index 00000000..60aa53d4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-185-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-185-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-185-sd.png new file mode 100644 index 00000000..842eec78 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-185-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-186-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-186-hd.png new file mode 100644 index 00000000..a47e8712 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-186-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-186-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-186-sd.png new file mode 100644 index 00000000..865f33de Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-186-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-187-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-187-hd.png new file mode 100644 index 00000000..3e3f72fa Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-187-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-187-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-187-sd.png new file mode 100644 index 00000000..38809c6b Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-187-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-188-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-188-hd.png new file mode 100644 index 00000000..3b392d4f Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-188-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-188-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-188-sd.png new file mode 100644 index 00000000..8dcf0b54 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-188-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-189-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-189-hd.png new file mode 100644 index 00000000..1d11644e Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-189-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-189-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-189-sd.png new file mode 100644 index 00000000..0d787c35 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-189-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-190-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-190-hd.png new file mode 100644 index 00000000..99196e28 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-190-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-190-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-190-sd.png new file mode 100644 index 00000000..ef18da0e Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-190-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-191-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-191-hd.png new file mode 100644 index 00000000..56b311c4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-191-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-191-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-191-sd.png new file mode 100644 index 00000000..96f97ca1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-191-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-192-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-192-hd.png new file mode 100644 index 00000000..42ae723f Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-192-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-192-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-192-sd.png new file mode 100644 index 00000000..f14615b1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-192-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-193-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-193-hd.png new file mode 100644 index 00000000..2fbdbb7d Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-193-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-193-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-193-sd.png new file mode 100644 index 00000000..6cf25cb5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-193-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-194-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-194-hd.png new file mode 100644 index 00000000..0c98cde7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-194-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-194-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-194-sd.png new file mode 100644 index 00000000..05ff8fc4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-194-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-195-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-195-hd.png new file mode 100644 index 00000000..f2e1a2f1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-195-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-195-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-195-sd.png new file mode 100644 index 00000000..1fda7c08 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-195-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-196-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-196-hd.png new file mode 100644 index 00000000..2cf7f1e1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-196-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-196-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-196-sd.png new file mode 100644 index 00000000..968bf84c Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-196-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-197-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-197-hd.png new file mode 100644 index 00000000..e64a24b0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-197-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-197-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-197-sd.png new file mode 100644 index 00000000..fcc54ab6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-197-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-198-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-198-hd.png new file mode 100644 index 00000000..c8beb386 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-198-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-198-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-198-sd.png new file mode 100644 index 00000000..4ff01b69 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-198-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-199-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-199-hd.png new file mode 100644 index 00000000..de7f8824 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-199-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-199-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-199-sd.png new file mode 100644 index 00000000..5954cf54 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-199-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-200-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-200-hd.png new file mode 100644 index 00000000..fec2e0d6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-200-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-200-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-200-sd.png new file mode 100644 index 00000000..015fcc54 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-200-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-201-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-201-hd.png new file mode 100644 index 00000000..81e5f53a Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-201-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-201-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-201-sd.png new file mode 100644 index 00000000..e66dfa80 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-201-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-202-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-202-hd.png new file mode 100644 index 00000000..c3b787b5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-202-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-202-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-202-sd.png new file mode 100644 index 00000000..bdce4c9f Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-202-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-203-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-203-hd.png new file mode 100644 index 00000000..3196a3ff Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-203-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-203-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-203-sd.png new file mode 100644 index 00000000..870af5ea Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-203-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-204-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-204-hd.png new file mode 100644 index 00000000..4afa0860 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-204-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-204-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-204-sd.png new file mode 100644 index 00000000..9f66b73b Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-204-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-205-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-205-hd.png new file mode 100644 index 00000000..2e64411d Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-205-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-205-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-205-sd.png new file mode 100644 index 00000000..a0df893f Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-205-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-206-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-206-hd.png new file mode 100644 index 00000000..0bf67a60 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-206-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-206-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-206-sd.png new file mode 100644 index 00000000..bee2f406 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-206-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-207-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-207-hd.png new file mode 100644 index 00000000..9d5629b2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-207-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-207-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-207-sd.png new file mode 100644 index 00000000..e4ba984d Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-207-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-208-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-208-hd.png new file mode 100644 index 00000000..cdf5a0b5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-208-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-208-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-208-sd.png new file mode 100644 index 00000000..2ddc2919 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-208-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-209-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-209-hd.png new file mode 100644 index 00000000..c5f82ec8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-209-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-209-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-209-sd.png new file mode 100644 index 00000000..5a4b52be Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-209-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-210-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-210-hd.png new file mode 100644 index 00000000..539b4d99 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-210-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-210-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-210-sd.png new file mode 100644 index 00000000..e2b6ce62 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-210-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-211-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-211-hd.png new file mode 100644 index 00000000..6d9e8c2b Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-211-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-211-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-211-sd.png new file mode 100644 index 00000000..33ac6f3e Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-211-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-212-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-212-hd.png new file mode 100644 index 00000000..822be410 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-212-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-212-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-212-sd.png new file mode 100644 index 00000000..4f67887a Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-212-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-213-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-213-hd.png new file mode 100644 index 00000000..005ec91c Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-213-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-213-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-213-sd.png new file mode 100644 index 00000000..5716ec66 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-213-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-214-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-214-hd.png new file mode 100644 index 00000000..35058b9f Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-214-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-214-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-214-sd.png new file mode 100644 index 00000000..d764ef62 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-214-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-215-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-215-hd.png new file mode 100644 index 00000000..3b595f7a Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-215-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-215-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-215-sd.png new file mode 100644 index 00000000..8a0af1a6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-215-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-216-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-216-hd.png new file mode 100644 index 00000000..7837618c Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-216-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-216-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-216-sd.png new file mode 100644 index 00000000..ddcd73d4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-216-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-217-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-217-hd.png new file mode 100644 index 00000000..2992d299 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-217-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-217-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-217-sd.png new file mode 100644 index 00000000..6ec5f12d Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-217-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-218-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-218-hd.png new file mode 100644 index 00000000..e01078d7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-218-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-218-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-218-sd.png new file mode 100644 index 00000000..4c220f4d Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-218-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-219-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-219-hd.png new file mode 100644 index 00000000..392daea1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-219-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-219-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-219-sd.png new file mode 100644 index 00000000..49582c85 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-219-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-220-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-220-hd.png new file mode 100644 index 00000000..976f0e65 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-220-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-220-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-220-sd.png new file mode 100644 index 00000000..91a7eb51 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-220-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-221-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-221-hd.png new file mode 100644 index 00000000..84abb4cf Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-221-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-221-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-221-sd.png new file mode 100644 index 00000000..88e2760b Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-221-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-222-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-222-hd.png new file mode 100644 index 00000000..2e908a9d Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-222-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-222-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-222-sd.png new file mode 100644 index 00000000..d88d17f9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-222-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-223-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-223-hd.png new file mode 100644 index 00000000..a4e1532c Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-223-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-223-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-223-sd.png new file mode 100644 index 00000000..04868250 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-223-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-224-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-224-hd.png new file mode 100644 index 00000000..3d00408a Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-224-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-224-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-224-sd.png new file mode 100644 index 00000000..149eab27 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-224-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-225-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-225-hd.png new file mode 100644 index 00000000..4f193d7c Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-225-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-225-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-225-sd.png new file mode 100644 index 00000000..ae55db92 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-225-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-226-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-226-hd.png new file mode 100644 index 00000000..c2b05f50 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-226-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-226-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-226-sd.png new file mode 100644 index 00000000..ba6cd8c0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-226-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-227-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-227-hd.png new file mode 100644 index 00000000..1b08cf84 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-227-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-227-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-227-sd.png new file mode 100644 index 00000000..a1a12c2c Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-227-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-228-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-228-hd.png new file mode 100644 index 00000000..6c6a7d01 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-228-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-228-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-228-sd.png new file mode 100644 index 00000000..e3071037 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-228-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-229-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-229-hd.png new file mode 100644 index 00000000..aca9c684 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-229-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-229-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-229-sd.png new file mode 100644 index 00000000..4a4f557c Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-229-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-230-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-230-hd.png new file mode 100644 index 00000000..121346c7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-230-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-230-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-230-sd.png new file mode 100644 index 00000000..9f25b4f0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-230-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-231-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-231-hd.png new file mode 100644 index 00000000..a7dda80f Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-231-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-231-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-231-sd.png new file mode 100644 index 00000000..69b30870 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-231-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-232-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-232-hd.png new file mode 100644 index 00000000..beaeea6b Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-232-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-232-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-232-sd.png new file mode 100644 index 00000000..29bdf07d Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-232-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-233-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-233-hd.png new file mode 100644 index 00000000..f672146c Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-233-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-233-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-233-sd.png new file mode 100644 index 00000000..310a7e00 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-233-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-234-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-234-hd.png new file mode 100644 index 00000000..44213122 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-234-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-234-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-234-sd.png new file mode 100644 index 00000000..d4657006 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-234-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-235-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-235-hd.png new file mode 100644 index 00000000..80a0ea75 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-235-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-235-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-235-sd.png new file mode 100644 index 00000000..fa47ea44 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-235-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-236-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-236-hd.png new file mode 100644 index 00000000..7d9ab4eb Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-236-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-236-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-236-sd.png new file mode 100644 index 00000000..41fb1934 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-236-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-237-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-237-hd.png new file mode 100644 index 00000000..da25805a Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-237-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-237-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-237-sd.png new file mode 100644 index 00000000..d399c921 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-237-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-238-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-238-hd.png new file mode 100644 index 00000000..5a710f6d Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-238-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-238-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-238-sd.png new file mode 100644 index 00000000..79b6ecdd Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-238-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-239-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-239-hd.png new file mode 100644 index 00000000..ecfdf3d4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-239-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-239-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-239-sd.png new file mode 100644 index 00000000..d3547f12 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-239-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-240-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-240-hd.png new file mode 100644 index 00000000..22cb877c Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-240-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-240-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-240-sd.png new file mode 100644 index 00000000..dd099148 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-240-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-241-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-241-hd.png new file mode 100644 index 00000000..1d35d74e Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-241-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-241-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-241-sd.png new file mode 100644 index 00000000..2bea7ea7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-241-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-242-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-242-hd.png new file mode 100644 index 00000000..7feab1b9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-242-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-242-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-242-sd.png new file mode 100644 index 00000000..e99d195b Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-242-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-243-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-243-hd.png new file mode 100644 index 00000000..011485b3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-243-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-243-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-243-sd.png new file mode 100644 index 00000000..6734d80f Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-243-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-244-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-244-hd.png new file mode 100644 index 00000000..02cb41b2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-244-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-244-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-244-sd.png new file mode 100644 index 00000000..dd57de66 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-244-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-245-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-245-hd.png new file mode 100644 index 00000000..6c60c96d Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-245-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-245-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-245-sd.png new file mode 100644 index 00000000..6ab6a66e Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-245-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-246-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-246-hd.png new file mode 100644 index 00000000..b27d741f Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-246-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-246-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-246-sd.png new file mode 100644 index 00000000..b11079ce Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-246-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-247-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-247-hd.png new file mode 100644 index 00000000..c942f858 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-247-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-247-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-247-sd.png new file mode 100644 index 00000000..6f190fab Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-247-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-248-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-248-hd.png new file mode 100644 index 00000000..73930438 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-248-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-248-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-248-sd.png new file mode 100644 index 00000000..4dd786b4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-248-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-249-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-249-hd.png new file mode 100644 index 00000000..d8a69865 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-249-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-249-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-249-sd.png new file mode 100644 index 00000000..db54c29d Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-249-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-250-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-250-hd.png new file mode 100644 index 00000000..a21ce99c Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-250-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-250-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-250-sd.png new file mode 100644 index 00000000..e55fbb87 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-250-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-251-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-251-hd.png new file mode 100644 index 00000000..033bd21b Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-251-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-251-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-251-sd.png new file mode 100644 index 00000000..5e0f85cb Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-251-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-252-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-252-hd.png new file mode 100644 index 00000000..b41b0caa Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-252-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-252-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-252-sd.png new file mode 100644 index 00000000..8658fae3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-252-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-253-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-253-hd.png new file mode 100644 index 00000000..98b6ab60 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-253-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-253-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-253-sd.png new file mode 100644 index 00000000..4cf7a2bc Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-253-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-254-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-254-hd.png new file mode 100644 index 00000000..5765bbe6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-254-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-254-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-254-sd.png new file mode 100644 index 00000000..09b9bf9b Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-254-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-255-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-255-hd.png new file mode 100644 index 00000000..2d03a1c6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-255-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-255-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-255-sd.png new file mode 100644 index 00000000..3b8d10d4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-255-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-256-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-256-hd.png new file mode 100644 index 00000000..8ec84af8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-256-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-256-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-256-sd.png new file mode 100644 index 00000000..25aa9822 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-256-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-257-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-257-hd.png new file mode 100644 index 00000000..86c574c7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-257-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-257-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-257-sd.png new file mode 100644 index 00000000..6bdf9a12 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-257-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-258-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-258-hd.png new file mode 100644 index 00000000..f9662c45 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-258-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-258-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-258-sd.png new file mode 100644 index 00000000..689411c1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-258-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-259-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-259-hd.png new file mode 100644 index 00000000..9df0cd3b Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-259-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-259-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-259-sd.png new file mode 100644 index 00000000..51d14248 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-259-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-260-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-260-hd.png new file mode 100644 index 00000000..c9800f51 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-260-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-260-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-260-sd.png new file mode 100644 index 00000000..126c48be Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-260-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-261-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-261-hd.png new file mode 100644 index 00000000..46586368 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-261-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-261-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-261-sd.png new file mode 100644 index 00000000..ba62ed58 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-261-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-262-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-262-hd.png new file mode 100644 index 00000000..91d50a6c Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-262-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-262-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-262-sd.png new file mode 100644 index 00000000..ce0567d6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-262-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-263-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-263-hd.png new file mode 100644 index 00000000..e3442b4f Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-263-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-263-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-263-sd.png new file mode 100644 index 00000000..68893556 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-263-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-264-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-264-hd.png new file mode 100644 index 00000000..bad1f12a Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-264-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-264-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-264-sd.png new file mode 100644 index 00000000..6bb7f11f Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-264-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-265-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-265-hd.png new file mode 100644 index 00000000..4be4fd34 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-265-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-265-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-265-sd.png new file mode 100644 index 00000000..509241b2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-265-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-266-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-266-hd.png new file mode 100644 index 00000000..1479613b Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-266-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-266-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-266-sd.png new file mode 100644 index 00000000..d05a7953 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-266-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-267-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-267-hd.png new file mode 100644 index 00000000..3943eaf8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-267-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-267-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-267-sd.png new file mode 100644 index 00000000..465c5611 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-267-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-268-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-268-hd.png new file mode 100644 index 00000000..46b8a730 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-268-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-268-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-268-sd.png new file mode 100644 index 00000000..a592fc24 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-268-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-269-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-269-hd.png new file mode 100644 index 00000000..de201d11 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-269-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-269-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-269-sd.png new file mode 100644 index 00000000..4e9f29d3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-269-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-270-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-270-hd.png new file mode 100644 index 00000000..64ccf775 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-270-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-270-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-270-sd.png new file mode 100644 index 00000000..4630e8cd Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-270-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-271-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-271-hd.png new file mode 100644 index 00000000..52cb9043 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-271-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-271-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-271-sd.png new file mode 100644 index 00000000..3194dbb1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-271-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-272-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-272-hd.png new file mode 100644 index 00000000..86457bb6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-272-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-272-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-272-sd.png new file mode 100644 index 00000000..4f15ec59 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-272-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-273-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-273-hd.png new file mode 100644 index 00000000..c6b9e9f1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-273-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-273-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-273-sd.png new file mode 100644 index 00000000..4c14bddf Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-273-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-274-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-274-hd.png new file mode 100644 index 00000000..63abb1d1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-274-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-274-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-274-sd.png new file mode 100644 index 00000000..4c535445 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-274-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-275-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-275-hd.png new file mode 100644 index 00000000..daef4a0b Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-275-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-275-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-275-sd.png new file mode 100644 index 00000000..18039cbd Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-275-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-276-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-276-hd.png new file mode 100644 index 00000000..f1a803e2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-276-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-276-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-276-sd.png new file mode 100644 index 00000000..6693ae42 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-276-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-277-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-277-hd.png new file mode 100644 index 00000000..03627bb8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-277-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-277-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-277-sd.png new file mode 100644 index 00000000..a27e9acc Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-277-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-278-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-278-hd.png new file mode 100644 index 00000000..e81f8704 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-278-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-278-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-278-sd.png new file mode 100644 index 00000000..4a98e35b Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-278-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-279-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-279-hd.png new file mode 100644 index 00000000..81d536fc Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-279-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-279-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-279-sd.png new file mode 100644 index 00000000..cfa7b2f0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-279-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-280-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-280-hd.png new file mode 100644 index 00000000..40a50f5d Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-280-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-280-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-280-sd.png new file mode 100644 index 00000000..45c8ec98 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-280-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-281-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-281-hd.png new file mode 100644 index 00000000..303ce16a Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-281-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-281-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-281-sd.png new file mode 100644 index 00000000..45b80d1e Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-281-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-282-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-282-hd.png new file mode 100644 index 00000000..74d5f389 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-282-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-282-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-282-sd.png new file mode 100644 index 00000000..700263ed Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-282-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-283-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-283-hd.png new file mode 100644 index 00000000..0b3f2c4d Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-283-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-283-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-283-sd.png new file mode 100644 index 00000000..352d42e2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-283-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-284-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-284-hd.png new file mode 100644 index 00000000..6dce7393 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-284-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-284-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-284-sd.png new file mode 100644 index 00000000..43f3689e Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-284-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-285-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-285-hd.png new file mode 100644 index 00000000..3d24dbb8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-285-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-285-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-285-sd.png new file mode 100644 index 00000000..abf675ca Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-285-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-286-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-286-hd.png new file mode 100644 index 00000000..4562b102 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-286-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-286-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-286-sd.png new file mode 100644 index 00000000..b52dd877 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-286-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-287-hd.png b/mods/iron_coast_stage2_mission_4/art/tile-287-hd.png new file mode 100644 index 00000000..fe8593ea Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-287-hd.png differ diff --git a/mods/iron_coast_stage2_mission_4/art/tile-287-sd.png b/mods/iron_coast_stage2_mission_4/art/tile-287-sd.png new file mode 100644 index 00000000..df2143d4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/art/tile-287-sd.png differ diff --git a/mods/iron_coast_stage2_mission_4/asset-report.json b/mods/iron_coast_stage2_mission_4/asset-report.json new file mode 100644 index 00000000..a7a785e0 --- /dev/null +++ b/mods/iron_coast_stage2_mission_4/asset-report.json @@ -0,0 +1,129 @@ +{ + "palette_sha256": "1cf6adb926d1dee1888b3e3d33b51a7049b3e5eb5f90a3067ef71c8970547204", + "ordinary_palette_entries_only": true, + "audio": { + "approach": { + "path": "audio/approach.wav", + "sha256": "92fdd1f3ad28dc8a501385626cfed5c5a0c494890ad986bfdefe4ef876409220", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "samples": 17199, + "seconds": 0.78, + "seed": 2932, + "peak": 20316, + "recipe": "deterministic seeded chirp/noise, original synthesis, no recordings" + }, + "target_alarm": { + "path": "audio/target_alarm.wav", + "sha256": "1a978f5a590b13fdcc6c69812d076227821995383d7535d060c9f8d7d6123b54", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "samples": 9261, + "seconds": 0.42, + "seed": 2933, + "peak": 15728, + "recipe": "deterministic seeded chirp/noise, original synthesis, no recordings" + }, + "boss_alarm": { + "path": "audio/boss_alarm.wav", + "sha256": "752a7fc750ba466058a8fcab7f405a36ba643f53cce152f1948af9ac6fee2921", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "samples": 14332, + "seconds": 0.6499773242630386, + "seed": 2934, + "peak": 15728, + "recipe": "deterministic seeded chirp/noise, original synthesis, no recordings" + }, + "salvage": { + "path": "audio/salvage.wav", + "sha256": "b8a73abb96986cec9e37063433356117a5fb79161a9fe5f15de966df40e89394", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "samples": 7056, + "seconds": 0.32, + "seed": 2935, + "peak": 20316, + "recipe": "deterministic seeded chirp/noise, original synthesis, no recordings" + }, + "victory": { + "path": "audio/victory.wav", + "sha256": "d69675d0d6c6cf8738fc826c9743ebab74ebb5fa90c97661055628c35c8edc2c", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "samples": 24255, + "seconds": 1.1, + "seed": 2936, + "peak": 20316, + "recipe": "deterministic seeded chirp/noise, original synthesis, no recordings" + } + }, + "target": { + "master": "art/target-source-v1.png", + "master_sha256": "8751d415ec5f95aadeb5c622c74f2ff945a4426fa5e2902f1e410773b5a9338a", + "master_size": [ + 1283, + 1226 + ], + "crop_runtime_invisible_padding": [ + 277, + 270, + 1006, + 956 + ], + "crop_threshold": 16, + "runtime_alpha_threshold": 128, + "logical_canvas": [ + 32, + 32 + ], + "hd_canvas": [ + 256, + 256 + ], + "sd_bounds": [ + 3, + 4, + 29, + 28 + ], + "hd_bounds": [ + 24, + 30, + 232, + 226 + ], + "frame_count": 1, + "origin": [ + 0, + 0 + ], + "generated_art_repainted": false + }, + "terrain": { + "master_sha256": "8f2198d7827a25d53dd808d4ec7d79842db6152a7e3a0dddcf7ea47465056875", + "master_size": [ + 941, + 1672 + ], + "logical_joined_size": [ + 288, + 512 + ], + "hd_joined_size": [ + 1152, + 2048 + ], + "tiles": 288, + "period_rows": 32, + "repeat": "forward16 rows then reflected16 rows, both periodboundaries identical", + "joined_before_quantizing_and_splitting": true, + "seam_checks": true, + "briefing": "320x200 /1280x800 central wide crop from same genuine terrain master" + } +} diff --git a/mods/iron_coast_stage2_mission_4/audio-recipe.json b/mods/iron_coast_stage2_mission_4/audio-recipe.json new file mode 100644 index 00000000..31d438d1 --- /dev/null +++ b/mods/iron_coast_stage2_mission_4/audio-recipe.json @@ -0,0 +1,62 @@ +{ + "approach": { + "path": "audio/approach.wav", + "sha256": "92fdd1f3ad28dc8a501385626cfed5c5a0c494890ad986bfdefe4ef876409220", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "samples": 17199, + "seconds": 0.78, + "seed": 2932, + "peak": 20316, + "recipe": "deterministic seeded chirp/noise, original synthesis, no recordings" + }, + "target_alarm": { + "path": "audio/target_alarm.wav", + "sha256": "1a978f5a590b13fdcc6c69812d076227821995383d7535d060c9f8d7d6123b54", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "samples": 9261, + "seconds": 0.42, + "seed": 2933, + "peak": 15728, + "recipe": "deterministic seeded chirp/noise, original synthesis, no recordings" + }, + "boss_alarm": { + "path": "audio/boss_alarm.wav", + "sha256": "752a7fc750ba466058a8fcab7f405a36ba643f53cce152f1948af9ac6fee2921", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "samples": 14332, + "seconds": 0.6499773242630386, + "seed": 2934, + "peak": 15728, + "recipe": "deterministic seeded chirp/noise, original synthesis, no recordings" + }, + "salvage": { + "path": "audio/salvage.wav", + "sha256": "b8a73abb96986cec9e37063433356117a5fb79161a9fe5f15de966df40e89394", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "samples": 7056, + "seconds": 0.32, + "seed": 2935, + "peak": 20316, + "recipe": "deterministic seeded chirp/noise, original synthesis, no recordings" + }, + "victory": { + "path": "audio/victory.wav", + "sha256": "d69675d0d6c6cf8738fc826c9743ebab74ebb5fa90c97661055628c35c8edc2c", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "samples": 24255, + "seconds": 1.1, + "seed": 2936, + "peak": 20316, + "recipe": "deterministic seeded chirp/noise, original synthesis, no recordings" + } +} diff --git a/mods/iron_coast_stage2_mission_4/audio/approach.wav b/mods/iron_coast_stage2_mission_4/audio/approach.wav new file mode 100644 index 00000000..71ea402c Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/audio/approach.wav differ diff --git a/mods/iron_coast_stage2_mission_4/audio/boss_alarm.wav b/mods/iron_coast_stage2_mission_4/audio/boss_alarm.wav new file mode 100644 index 00000000..f7881205 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/audio/boss_alarm.wav differ diff --git a/mods/iron_coast_stage2_mission_4/audio/salvage.wav b/mods/iron_coast_stage2_mission_4/audio/salvage.wav new file mode 100644 index 00000000..2d890940 Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/audio/salvage.wav differ diff --git a/mods/iron_coast_stage2_mission_4/audio/target_alarm.wav b/mods/iron_coast_stage2_mission_4/audio/target_alarm.wav new file mode 100644 index 00000000..54ec4a9a Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/audio/target_alarm.wav differ diff --git a/mods/iron_coast_stage2_mission_4/audio/victory.wav b/mods/iron_coast_stage2_mission_4/audio/victory.wav new file mode 100644 index 00000000..d01a849d Binary files /dev/null and b/mods/iron_coast_stage2_mission_4/audio/victory.wav differ diff --git a/mods/iron_coast_stage2_mission_4/build_assets.py b/mods/iron_coast_stage2_mission_4/build_assets.py new file mode 100644 index 00000000..03e8dd14 --- /dev/null +++ b/mods/iron_coast_stage2_mission_4/build_assets.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python3 +"""Reproduce packaged artwork footprints and seeded local PCM audio. + +Builtin imagegen masters are preserved byte-for-byte. This recipe only crops +empty/runtime-subthreshold transparent padding, fits/resamples canvases, splits joined terrain and +quantizes SD to ordinary game palette colors; it never paints generated pixels. +""" +from pathlib import Path +import argparse,hashlib,json,math,random,struct,wave +from PIL import Image,ImageOps +ROOT=Path(__file__).resolve().parent +hashfile=lambda p:hashlib.sha256(p.read_bytes()).hexdigest() +def palette(path): + raw=path.read_bytes();assert len(raw)==768 + colors=[(min(v,63)<<2)|(min(v,63)>>4) for v in raw] + colors[720:]=colors[:48];im=Image.new('P',(1,1));im.putpalette(colors);return im + +def sd(im,size,pal): + im=im.convert('RGBA').resize(size,Image.Resampling.BOX);alpha=im.getchannel('A').point(lambda v:255 if v>=128 else 0) + out=im.convert('RGB').quantize(palette=pal,dither=Image.Dither.NONE).convert('RGBA');out.putalpha(alpha);return out + +def footprint(stem,logical,pal): + p=ROOT/'art'/f'{stem}-source-v1.png';raw=Image.open(p).convert('RGBA');assert raw.getchannel('A').getextrema()[0]==0,'genuine transparent master required' + # Keep every visible alpha>=128 sample. Imagegen adds isolated alpha1 noise + # across the canvas; threshold16 bounds remove only runtime-invisible padding, + # while the raw master and its original alpha remain untouched. + box=raw.getchannel('A').point(lambda v:255 if v>=16 else 0).getbbox();assert box;assert raw.getchannel('A').point(lambda v:255 if v>=128 else 0).getbbox();crop=raw.crop(box);size=tuple(v*8 for v in logical);margin=8 if stem=='shell' else 24 + hd=Image.new('RGBA',size);fitted=ImageOps.contain(crop,(size[0]-margin*2,size[1]-margin*2),Image.Resampling.LANCZOS);hd.alpha_composite(fitted,((size[0]-fitted.width)//2,(size[1]-fitted.height)//2));low=sd(hd,logical,pal) + for suffix,im in [('hd',hd),('sd',low)]: + bounds=im.getchannel('A').point(lambda v:255 if v>=128 else 0).getbbox();assert bounds and bounds[0]>0 and bounds[1]>0 and bounds[2]=128 else 0).getbbox()),'frame_count':1,'origin':[0,0],'generated_art_repainted':False} + +def synth(name,duration,seed,mode): + rate=22050;rng=random.Random(seed);count=round(rate*duration);phase=0;slow=0;v=[] + for i in range(count): + u=i/(count-1);t=i/rate;noise=rng.uniform(-1,1);slow=slow*.90+noise*.10 + if mode=='warning':freq=440+220*int(u*2);signal=math.sin(phase)*.60+math.sin(phase*2)*.15;env=math.sin(math.pi*u)**1.4 + elif mode=='shot':freq=440*(1-u)**2+65;signal=math.sin(phase)*.5+noise*.20+math.sin(phase*2.13)*.13;env=math.exp(-5*u) + elif mode=='death':freq=75-50*u;signal=slow*.6+noise*.18+math.sin(phase)*.25;env=math.exp(-4.5*u) + else: + notes=[294,370,440,587] if mode=='victory' else [220,294,440];freq=notes[min(len(notes)-1,int(u*len(notes)))];signal=math.sin(phase)*.65+math.sin(phase*2)*.12;env=min(1,(u*len(notes)%1)*20)*(1-u)**.6 + phase+=2*math.pi*freq/rate;env*=min(1,t/.004)*min(1,(count-1-i)/(rate*.005));v.append(signal*max(0,env)) + peak=max(abs(x) for x in v);target=.48 if mode=='warning' else .62;pcm=[round(x/peak*32767*target) for x in v];p=ROOT/'audio'/f'{name}.wav' + with wave.open(str(p),'wb') as w:w.setnchannels(1);w.setsampwidth(2);w.setframerate(rate);w.writeframes(struct.pack('<'+'h'*count,*pcm)) + return {'path':str(p.relative_to(ROOT)),'sha256':hashfile(p),'sample_rate':rate,'bits':16,'channels':1,'samples':count,'seconds':count/rate,'seed':seed,'peak':max(abs(x) for x in pcm),'recipe':'deterministic seeded chirp/noise, original synthesis, no recordings'} + +def main(): + ap=argparse.ArgumentParser();ap.add_argument('--palette',type=Path,default=ROOT.parents[1]/'data/misc/PALETTE_DAT');ap.add_argument('--audio-only',action='store_true');a=ap.parse_args();is_boss='boss' in ROOT.name;stage=int(ROOT.name[-1]);sounds={} + sound_specs=[('warning',.36,'warning'),('shot',.20,'shot'),('death',.95,'death')] if is_boss else [('approach',.78,'tone'),('target_alarm',.42,'warning'),('boss_alarm',.65,'warning'),('salvage',.32,'tone'),('victory',1.10,'victory')] + for i,(n,d,m) in enumerate(sound_specs):sounds[n]=synth(n,d,stage*733+i,m) + (ROOT/'audio-recipe.json').write_text(json.dumps(sounds,indent=2)+'\n') + if a.audio_only:return + pal=palette(a.palette);report={'palette_sha256':hashfile(a.palette),'ordinary_palette_entries_only':True,'audio':sounds} + if is_boss: + report['unit']=footprint('unit',(104,72 if stage==3 else 64),pal);report['shell']=footprint('shell',(8,8),pal) + else: + report['target']=footprint('target',(32,32),pal);p=ROOT/'art/terrain-source-v1.png';source=Image.open(p).convert('RGBA');assert source.getchannel('A').getextrema()[0]>=128,'terrain must be fully opaque' + hd=ImageOps.fit(source,(1152,2048),Image.Resampling.LANCZOS);low=sd(hd,(288,512),pal);tiles=0 + for reverse in [False,True]: + hi=ImageOps.flip(hd) if reverse else hd;lo=ImageOps.flip(low) if reverse else low + for row in range(16): + for col in range(9): + hi.crop((col*128,row*128,(col+1)*128,(row+1)*128)).save(ROOT/'art'/f'tile-{tiles:03}-hd.png');lo.crop((col*32,row*32,(col+1)*32,(row+1)*32)).save(ROOT/'art'/f'tile-{tiles:03}-sd.png');tiles+=1 + for im in [hd,low]:assert im.crop((0,im.height-1,im.width,im.height)).tobytes()==ImageOps.flip(im).crop((0,0,im.width,1)).tobytes() + # Briefing is a truthful wide crop of the generated terrain, not new artwork. + briefing=ImageOps.fit(source,(1280,800),Image.Resampling.LANCZOS);briefing.save(ROOT/'art/briefing-hd.png');sd(briefing,(320,200),pal).save(ROOT/'art/briefing-sd.png');low.save(ROOT/'art/terrain-preview-sd.png');hd.save(ROOT/'art/terrain-preview-hd.png') + report['terrain']={'master_sha256':hashfile(p),'master_size':list(source.size),'logical_joined_size':[288,512],'hd_joined_size':[1152,2048],'tiles':tiles,'period_rows':32,'repeat':'forward16 rows then reflected16 rows, both periodboundaries identical','joined_before_quantizing_and_splitting':True,'seam_checks':True,'briefing':'320x200 /1280x800 central wide crop from same genuine terrain master'} + (ROOT/'asset-report.json').write_text(json.dumps(report,indent=2)+'\n');print(ROOT.name,'assets/sounds ready') +if __name__=='__main__':main() diff --git a/mods/iron_coast_stage2_mission_4/content.json b/mods/iron_coast_stage2_mission_4/content.json new file mode 100644 index 00000000..f27b9027 --- /dev/null +++ b/mods/iron_coast_stage2_mission_4/content.json @@ -0,0 +1,5158 @@ +{ + "enemies": [ + { + "id": "iron_coast_stage2_mission_4:target", + "name": "Floodgate Crossing Defense", + "health": 26, + "speed": 0, + "reward": 500, + "ground": true, + "boss": false, + "art": { + "png": "art/target-sd.png", + "hd_png": "art/target-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + }, + "script": "scripts/target.rhai" + } + ], + "sounds": [ + { + "id": "iron_coast_stage2_mission_4:approach", + "name": "Approach", + "file": "audio/approach.wav", + "volume": 72, + "pan": 127, + "pitch": 128, + "priority": 2 + }, + { + "id": "iron_coast_stage2_mission_4:target_alarm", + "name": "Target Alarm", + "file": "audio/target_alarm.wav", + "volume": 72, + "pan": 127, + "pitch": 128, + "priority": 2 + }, + { + "id": "iron_coast_stage2_mission_4:boss_alarm", + "name": "Boss Alarm", + "file": "audio/boss_alarm.wav", + "volume": 72, + "pan": 127, + "pitch": 128, + "priority": 2 + }, + { + "id": "iron_coast_stage2_mission_4:salvage", + "name": "Salvage", + "file": "audio/salvage.wav", + "volume": 72, + "pan": 127, + "pitch": 128, + "priority": 2 + }, + { + "id": "iron_coast_stage2_mission_4:victory", + "name": "Victory", + "file": "audio/victory.wav", + "volume": 95, + "pan": 127, + "pitch": 128, + "priority": 2 + } + ], + "missions": [ + { + "id": "iron_coast_stage2_mission_4:mission_04", + "name": "Iron Coast II 4 \u2014 Floodgate Zero", + "duration": 3300, + "auto_complete": false, + "columns": 9, + "layout": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 216, + 217, + 218, + 219, + 220, + 221, + 222, + 223, + 224, + 225, + 226, + 227, + 228, + 229, + 230, + 231, + 232, + 233, + 234, + 235, + 236, + 237, + 238, + 239, + 240, + 241, + 242, + 243, + 244, + 245, + 246, + 247, + 248, + 249, + 250, + 251, + 252, + 253, + 254, + 255, + 256, + 257, + 258, + 259, + 260, + 261, + 262, + 263, + 264, + 265, + 266, + 267, + 268, + 269, + 270, + 271, + 272, + 273, + 274, + 275, + 276, + 277, + 278, + 279, + 280, + 281, + 282, + 283, + 284, + 285, + 286, + 287, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 216, + 217, + 218, + 219, + 220, + 221, + 222, + 223, + 224, + 225, + 226, + 227, + 228, + 229, + 230, + 231, + 232, + 233, + 234, + 235, + 236, + 237, + 238, + 239, + 240, + 241, + 242, + 243, + 244, + 245, + 246, + 247, + 248, + 249, + 250, + 251, + 252, + 253, + 254, + 255, + 256, + 257, + 258, + 259, + 260, + 261, + 262, + 263, + 264, + 265, + 266, + 267, + 268, + 269, + 270, + 271, + 272, + 273, + 274, + 275, + 276, + 277, + 278, + 279, + 280, + 281, + 282, + 283, + 284, + 285, + 286, + 287, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 216, + 217, + 218, + 219, + 220, + 221, + 222, + 223, + 224, + 225, + 226, + 227, + 228, + 229, + 230, + 231, + 232, + 233, + 234, + 235, + 236, + 237, + 238, + 239, + 240, + 241, + 242, + 243, + 244, + 245, + 246, + 247, + 248, + 249, + 250, + 251, + 252, + 253, + 254, + 255, + 256, + 257, + 258, + 259, + 260, + 261, + 262, + 263, + 264, + 265, + 266, + 267, + 268, + 269, + 270, + 271, + 272, + 273, + 274, + 275, + 276, + 277, + 278, + 279, + 280, + 281, + 282, + 283, + 284, + 285, + 286, + 287, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 216, + 217, + 218, + 219, + 220, + 221, + 222, + 223, + 224, + 225, + 226, + 227, + 228, + 229, + 230, + 231, + 232, + 233, + 234, + 235, + 236, + 237, + 238, + 239, + 240, + 241, + 242, + 243, + 244, + 245, + 246, + 247, + 248, + 249, + 250, + 251, + 252, + 253, + 254, + 255, + 256, + 257, + 258, + 259, + 260, + 261, + 262, + 263, + 264, + 265, + 266, + 267, + 268, + 269, + 270, + 271, + 272, + 273, + 274, + 275, + 276, + 277, + 278, + 279, + 280, + 281, + 282, + 283, + 284, + 285, + 286, + 287, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 216, + 217, + 218, + 219, + 220, + 221, + 222, + 223, + 224, + 225, + 226, + 227, + 228, + 229, + 230, + 231, + 232, + 233, + 234, + 235, + 236, + 237, + 238, + 239, + 240, + 241, + 242, + 243, + 244, + 245, + 246, + 247, + 248, + 249, + 250, + 251, + 252, + 253, + 254, + 255, + 256, + 257, + 258, + 259, + 260, + 261, + 262, + 263, + 264, + 265, + 266, + 267, + 268, + 269, + 270, + 271, + 272, + 273, + 274, + 275, + 276, + 277, + 278, + 279, + 280, + 281, + 282, + 283, + 284, + 285, + 286, + 287, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 216, + 217, + 218, + 219, + 220, + 221, + 222, + 223, + 224, + 225, + 226, + 227, + 228, + 229, + 230, + 231, + 232, + 233, + 234, + 235, + 236, + 237, + 238, + 239, + 240, + 241, + 242, + 243, + 244, + 245, + 246, + 247, + 248, + 249, + 250, + 251, + 252, + 253, + 254, + 255, + 256, + 257, + 258, + 259, + 260, + 261, + 262, + 263, + 264, + 265, + 266, + 267, + 268, + 269, + 270, + 271, + 272, + 273, + 274, + 275, + 276, + 277, + 278, + 279, + 280, + 281, + 282, + 283, + 284, + 285, + 286, + 287, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 216, + 217, + 218, + 219, + 220, + 221, + 222, + 223, + 224, + 225, + 226, + 227, + 228, + 229, + 230, + 231, + 232, + 233, + 234, + 235, + 236, + 237, + 238, + 239, + 240, + 241, + 242, + 243, + 244, + 245, + 246, + 247, + 248, + 249, + 250, + 251, + 252, + 253, + 254, + 255, + 256, + 257, + 258, + 259, + 260, + 261, + 262, + 263, + 264, + 265, + 266, + 267, + 268, + 269, + 270, + 271, + 272, + 273, + 274, + 275, + 276, + 277, + 278, + 279, + 280, + 281, + 282, + 283, + 284, + 285, + 286, + 287, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 216, + 217, + 218, + 219, + 220, + 221, + 222, + 223, + 224, + 225, + 226, + 227, + 228, + 229, + 230, + 231, + 232, + 233, + 234, + 235, + 236, + 237, + 238, + 239, + 240, + 241, + 242, + 243, + 244, + 245, + 246, + 247, + 248, + 249, + 250, + 251, + 252, + 253, + 254, + 255, + 256, + 257, + 258, + 259, + 260, + 261, + 262, + 263, + 264, + 265, + 266, + 267, + 268, + 269, + 270, + 271, + 272, + 273, + 274, + 275, + 276, + 277, + 278, + 279, + 280, + 281, + 282, + 283, + 284, + 285, + 286, + 287 + ], + "spawns": [ + { + "tick": 90, + "enemy": "base:enemy_0_23", + "x": 160, + "y": -88, + "difficulty": 0 + }, + { + "tick": 180, + "enemy": "iron_coast_stage2_mission_4:target", + "x": 56, + "y": -32, + "difficulty": 0 + }, + { + "tick": 230, + "enemy": "iron_coast_stage2_interceptor:unit", + "x": 104, + "y": -40, + "difficulty": 0 + }, + { + "tick": 330, + "enemy": "base:enemy_0_25", + "x": 24, + "y": -40, + "difficulty": 0 + }, + { + "tick": 390, + "enemy": "iron_coast_stage2_skimmer:unit", + "x": 216, + "y": -40, + "difficulty": 0 + }, + { + "tick": 540, + "enemy": "base:enemy_0_74", + "x": 72, + "y": -88, + "difficulty": 0 + }, + { + "tick": 620, + "enemy": "iron_coast_stage2_mission_4:target", + "x": 216, + "y": -32, + "difficulty": 0 + }, + { + "tick": 720, + "enemy": "iron_coast_stage2_interceptor:unit", + "x": 200, + "y": -40, + "difficulty": 0 + }, + { + "tick": 860, + "enemy": "base:enemy_0_24", + "x": 112, + "y": -88, + "difficulty": 0 + }, + { + "tick": 970, + "enemy": "iron_coast_stage2_skimmer:unit", + "x": 56, + "y": -40, + "difficulty": 0 + }, + { + "tick": 1100, + "enemy": "iron_coast_stage2_mission_4:target", + "x": 96, + "y": -32, + "difficulty": 0 + }, + { + "tick": 1120, + "enemy": "base:enemy_0_26", + "x": 232, + "y": -40, + "difficulty": 0 + }, + { + "tick": 1190, + "enemy": "iron_coast_stage2_interceptor:unit", + "x": 72, + "y": -40, + "difficulty": 0 + }, + { + "tick": 1390, + "enemy": "base:enemy_0_20", + "x": 184, + "y": -88, + "difficulty": 0 + }, + { + "tick": 1460, + "enemy": "iron_coast_stage2_skimmer:unit", + "x": 224, + "y": -40, + "difficulty": 0 + }, + { + "tick": 1630, + "enemy": "iron_coast_stage2_mission_4:target", + "x": 184, + "y": -32, + "difficulty": 0 + }, + { + "tick": 1720, + "enemy": "base:enemy_0_73", + "x": 216, + "y": -88, + "difficulty": 0 + }, + { + "tick": 1780, + "enemy": "iron_coast_stage2_interceptor:unit", + "x": 184, + "y": -40, + "difficulty": 0 + }, + { + "tick": 1940, + "enemy": "base:enemy_0_21", + "x": 224, + "y": -40, + "difficulty": 0 + }, + { + "tick": 2000, + "enemy": "iron_coast_stage2_skimmer:unit", + "x": 80, + "y": -40, + "difficulty": 0 + }, + { + "tick": 2250, + "enemy": "iron_coast_stage2_boss_4:unit", + "x": 108, + "y": -72, + "difficulty": 0 + }, + { + "tick": 2400, + "enemy": "iron_coast_stage2_interceptor:unit", + "x": 224, + "y": -40, + "difficulty": 0 + } + ], + "art": { + "png": "art/briefing-sd.png", + "hd_png": "art/briefing-hd.png", + "logical_width": 320, + "logical_height": 200, + "frames": 1 + }, + "script": "scripts/mission.rhai", + "music_track": "iron_coast_stage2_music:pursuit", + "tiles": [ + { + "art": { + "png": "art/tile-000-sd.png", + "hd_png": "art/tile-000-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-001-sd.png", + "hd_png": "art/tile-001-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-002-sd.png", + "hd_png": "art/tile-002-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-003-sd.png", + "hd_png": "art/tile-003-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-004-sd.png", + "hd_png": "art/tile-004-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-005-sd.png", + "hd_png": "art/tile-005-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-006-sd.png", + "hd_png": "art/tile-006-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-007-sd.png", + "hd_png": "art/tile-007-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-008-sd.png", + "hd_png": "art/tile-008-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-009-sd.png", + "hd_png": "art/tile-009-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-010-sd.png", + "hd_png": "art/tile-010-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-011-sd.png", + "hd_png": "art/tile-011-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-012-sd.png", + "hd_png": "art/tile-012-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-013-sd.png", + "hd_png": "art/tile-013-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-014-sd.png", + "hd_png": "art/tile-014-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-015-sd.png", + "hd_png": "art/tile-015-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-016-sd.png", + "hd_png": "art/tile-016-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-017-sd.png", + "hd_png": "art/tile-017-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-018-sd.png", + "hd_png": "art/tile-018-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-019-sd.png", + "hd_png": "art/tile-019-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-020-sd.png", + "hd_png": "art/tile-020-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-021-sd.png", + "hd_png": "art/tile-021-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-022-sd.png", + "hd_png": "art/tile-022-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-023-sd.png", + "hd_png": "art/tile-023-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-024-sd.png", + "hd_png": "art/tile-024-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-025-sd.png", + "hd_png": "art/tile-025-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-026-sd.png", + "hd_png": "art/tile-026-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-027-sd.png", + "hd_png": "art/tile-027-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-028-sd.png", + "hd_png": "art/tile-028-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-029-sd.png", + "hd_png": "art/tile-029-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-030-sd.png", + "hd_png": "art/tile-030-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-031-sd.png", + "hd_png": "art/tile-031-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-032-sd.png", + "hd_png": "art/tile-032-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-033-sd.png", + "hd_png": "art/tile-033-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-034-sd.png", + "hd_png": "art/tile-034-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-035-sd.png", + "hd_png": "art/tile-035-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-036-sd.png", + "hd_png": "art/tile-036-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-037-sd.png", + "hd_png": "art/tile-037-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-038-sd.png", + "hd_png": "art/tile-038-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-039-sd.png", + "hd_png": "art/tile-039-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-040-sd.png", + "hd_png": "art/tile-040-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-041-sd.png", + "hd_png": "art/tile-041-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-042-sd.png", + "hd_png": "art/tile-042-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-043-sd.png", + "hd_png": "art/tile-043-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-044-sd.png", + "hd_png": "art/tile-044-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-045-sd.png", + "hd_png": "art/tile-045-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-046-sd.png", + "hd_png": "art/tile-046-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-047-sd.png", + "hd_png": "art/tile-047-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-048-sd.png", + "hd_png": "art/tile-048-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-049-sd.png", + "hd_png": "art/tile-049-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-050-sd.png", + "hd_png": "art/tile-050-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-051-sd.png", + "hd_png": "art/tile-051-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-052-sd.png", + "hd_png": "art/tile-052-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-053-sd.png", + "hd_png": "art/tile-053-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-054-sd.png", + "hd_png": "art/tile-054-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-055-sd.png", + "hd_png": "art/tile-055-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-056-sd.png", + "hd_png": "art/tile-056-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-057-sd.png", + "hd_png": "art/tile-057-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-058-sd.png", + "hd_png": "art/tile-058-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-059-sd.png", + "hd_png": "art/tile-059-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-060-sd.png", + "hd_png": "art/tile-060-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-061-sd.png", + "hd_png": "art/tile-061-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-062-sd.png", + "hd_png": "art/tile-062-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-063-sd.png", + "hd_png": "art/tile-063-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-064-sd.png", + "hd_png": "art/tile-064-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-065-sd.png", + "hd_png": "art/tile-065-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-066-sd.png", + "hd_png": "art/tile-066-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-067-sd.png", + "hd_png": "art/tile-067-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-068-sd.png", + "hd_png": "art/tile-068-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-069-sd.png", + "hd_png": "art/tile-069-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-070-sd.png", + "hd_png": "art/tile-070-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-071-sd.png", + "hd_png": "art/tile-071-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-072-sd.png", + "hd_png": "art/tile-072-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-073-sd.png", + "hd_png": "art/tile-073-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-074-sd.png", + "hd_png": "art/tile-074-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-075-sd.png", + "hd_png": "art/tile-075-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-076-sd.png", + "hd_png": "art/tile-076-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-077-sd.png", + "hd_png": "art/tile-077-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-078-sd.png", + "hd_png": "art/tile-078-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-079-sd.png", + "hd_png": "art/tile-079-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-080-sd.png", + "hd_png": "art/tile-080-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-081-sd.png", + "hd_png": "art/tile-081-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-082-sd.png", + "hd_png": "art/tile-082-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-083-sd.png", + "hd_png": "art/tile-083-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-084-sd.png", + "hd_png": "art/tile-084-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-085-sd.png", + "hd_png": "art/tile-085-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-086-sd.png", + "hd_png": "art/tile-086-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-087-sd.png", + "hd_png": "art/tile-087-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-088-sd.png", + "hd_png": "art/tile-088-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-089-sd.png", + "hd_png": "art/tile-089-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-090-sd.png", + "hd_png": "art/tile-090-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-091-sd.png", + "hd_png": "art/tile-091-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-092-sd.png", + "hd_png": "art/tile-092-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-093-sd.png", + "hd_png": "art/tile-093-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-094-sd.png", + "hd_png": "art/tile-094-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-095-sd.png", + "hd_png": "art/tile-095-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-096-sd.png", + "hd_png": "art/tile-096-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-097-sd.png", + "hd_png": "art/tile-097-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-098-sd.png", + "hd_png": "art/tile-098-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-099-sd.png", + "hd_png": "art/tile-099-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-100-sd.png", + "hd_png": "art/tile-100-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-101-sd.png", + "hd_png": "art/tile-101-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-102-sd.png", + "hd_png": "art/tile-102-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-103-sd.png", + "hd_png": "art/tile-103-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-104-sd.png", + "hd_png": "art/tile-104-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-105-sd.png", + "hd_png": "art/tile-105-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-106-sd.png", + "hd_png": "art/tile-106-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-107-sd.png", + "hd_png": "art/tile-107-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-108-sd.png", + "hd_png": "art/tile-108-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-109-sd.png", + "hd_png": "art/tile-109-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-110-sd.png", + "hd_png": "art/tile-110-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-111-sd.png", + "hd_png": "art/tile-111-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-112-sd.png", + "hd_png": "art/tile-112-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-113-sd.png", + "hd_png": "art/tile-113-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-114-sd.png", + "hd_png": "art/tile-114-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-115-sd.png", + "hd_png": "art/tile-115-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-116-sd.png", + "hd_png": "art/tile-116-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-117-sd.png", + "hd_png": "art/tile-117-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-118-sd.png", + "hd_png": "art/tile-118-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-119-sd.png", + "hd_png": "art/tile-119-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-120-sd.png", + "hd_png": "art/tile-120-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-121-sd.png", + "hd_png": "art/tile-121-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-122-sd.png", + "hd_png": "art/tile-122-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-123-sd.png", + "hd_png": "art/tile-123-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-124-sd.png", + "hd_png": "art/tile-124-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-125-sd.png", + "hd_png": "art/tile-125-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-126-sd.png", + "hd_png": "art/tile-126-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-127-sd.png", + "hd_png": "art/tile-127-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-128-sd.png", + "hd_png": "art/tile-128-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-129-sd.png", + "hd_png": "art/tile-129-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-130-sd.png", + "hd_png": "art/tile-130-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-131-sd.png", + "hd_png": "art/tile-131-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-132-sd.png", + "hd_png": "art/tile-132-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-133-sd.png", + "hd_png": "art/tile-133-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-134-sd.png", + "hd_png": "art/tile-134-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-135-sd.png", + "hd_png": "art/tile-135-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-136-sd.png", + "hd_png": "art/tile-136-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-137-sd.png", + "hd_png": "art/tile-137-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-138-sd.png", + "hd_png": "art/tile-138-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-139-sd.png", + "hd_png": "art/tile-139-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-140-sd.png", + "hd_png": "art/tile-140-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-141-sd.png", + "hd_png": "art/tile-141-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-142-sd.png", + "hd_png": "art/tile-142-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-143-sd.png", + "hd_png": "art/tile-143-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-144-sd.png", + "hd_png": "art/tile-144-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-145-sd.png", + "hd_png": "art/tile-145-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-146-sd.png", + "hd_png": "art/tile-146-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-147-sd.png", + "hd_png": "art/tile-147-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-148-sd.png", + "hd_png": "art/tile-148-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-149-sd.png", + "hd_png": "art/tile-149-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-150-sd.png", + "hd_png": "art/tile-150-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-151-sd.png", + "hd_png": "art/tile-151-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-152-sd.png", + "hd_png": "art/tile-152-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-153-sd.png", + "hd_png": "art/tile-153-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-154-sd.png", + "hd_png": "art/tile-154-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-155-sd.png", + "hd_png": "art/tile-155-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-156-sd.png", + "hd_png": "art/tile-156-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-157-sd.png", + "hd_png": "art/tile-157-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-158-sd.png", + "hd_png": "art/tile-158-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-159-sd.png", + "hd_png": "art/tile-159-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-160-sd.png", + "hd_png": "art/tile-160-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-161-sd.png", + "hd_png": "art/tile-161-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-162-sd.png", + "hd_png": "art/tile-162-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-163-sd.png", + "hd_png": "art/tile-163-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-164-sd.png", + "hd_png": "art/tile-164-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-165-sd.png", + "hd_png": "art/tile-165-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-166-sd.png", + "hd_png": "art/tile-166-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-167-sd.png", + "hd_png": "art/tile-167-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-168-sd.png", + "hd_png": "art/tile-168-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-169-sd.png", + "hd_png": "art/tile-169-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-170-sd.png", + "hd_png": "art/tile-170-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-171-sd.png", + "hd_png": "art/tile-171-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-172-sd.png", + "hd_png": "art/tile-172-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-173-sd.png", + "hd_png": "art/tile-173-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-174-sd.png", + "hd_png": "art/tile-174-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-175-sd.png", + "hd_png": "art/tile-175-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-176-sd.png", + "hd_png": "art/tile-176-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-177-sd.png", + "hd_png": "art/tile-177-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-178-sd.png", + "hd_png": "art/tile-178-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-179-sd.png", + "hd_png": "art/tile-179-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-180-sd.png", + "hd_png": "art/tile-180-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-181-sd.png", + "hd_png": "art/tile-181-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-182-sd.png", + "hd_png": "art/tile-182-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-183-sd.png", + "hd_png": "art/tile-183-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-184-sd.png", + "hd_png": "art/tile-184-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-185-sd.png", + "hd_png": "art/tile-185-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-186-sd.png", + "hd_png": "art/tile-186-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-187-sd.png", + "hd_png": "art/tile-187-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-188-sd.png", + "hd_png": "art/tile-188-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-189-sd.png", + "hd_png": "art/tile-189-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-190-sd.png", + "hd_png": "art/tile-190-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-191-sd.png", + "hd_png": "art/tile-191-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-192-sd.png", + "hd_png": "art/tile-192-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-193-sd.png", + "hd_png": "art/tile-193-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-194-sd.png", + "hd_png": "art/tile-194-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-195-sd.png", + "hd_png": "art/tile-195-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-196-sd.png", + "hd_png": "art/tile-196-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-197-sd.png", + "hd_png": "art/tile-197-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-198-sd.png", + "hd_png": "art/tile-198-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-199-sd.png", + "hd_png": "art/tile-199-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-200-sd.png", + "hd_png": "art/tile-200-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-201-sd.png", + "hd_png": "art/tile-201-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-202-sd.png", + "hd_png": "art/tile-202-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-203-sd.png", + "hd_png": "art/tile-203-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-204-sd.png", + "hd_png": "art/tile-204-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-205-sd.png", + "hd_png": "art/tile-205-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-206-sd.png", + "hd_png": "art/tile-206-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-207-sd.png", + "hd_png": "art/tile-207-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-208-sd.png", + "hd_png": "art/tile-208-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-209-sd.png", + "hd_png": "art/tile-209-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-210-sd.png", + "hd_png": "art/tile-210-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-211-sd.png", + "hd_png": "art/tile-211-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-212-sd.png", + "hd_png": "art/tile-212-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-213-sd.png", + "hd_png": "art/tile-213-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-214-sd.png", + "hd_png": "art/tile-214-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-215-sd.png", + "hd_png": "art/tile-215-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-216-sd.png", + "hd_png": "art/tile-216-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-217-sd.png", + "hd_png": "art/tile-217-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-218-sd.png", + "hd_png": "art/tile-218-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-219-sd.png", + "hd_png": "art/tile-219-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-220-sd.png", + "hd_png": "art/tile-220-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-221-sd.png", + "hd_png": "art/tile-221-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-222-sd.png", + "hd_png": "art/tile-222-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-223-sd.png", + "hd_png": "art/tile-223-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-224-sd.png", + "hd_png": "art/tile-224-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-225-sd.png", + "hd_png": "art/tile-225-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-226-sd.png", + "hd_png": "art/tile-226-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-227-sd.png", + "hd_png": "art/tile-227-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-228-sd.png", + "hd_png": "art/tile-228-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-229-sd.png", + "hd_png": "art/tile-229-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-230-sd.png", + "hd_png": "art/tile-230-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-231-sd.png", + "hd_png": "art/tile-231-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-232-sd.png", + "hd_png": "art/tile-232-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-233-sd.png", + "hd_png": "art/tile-233-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-234-sd.png", + "hd_png": "art/tile-234-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-235-sd.png", + "hd_png": "art/tile-235-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-236-sd.png", + "hd_png": "art/tile-236-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-237-sd.png", + "hd_png": "art/tile-237-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-238-sd.png", + "hd_png": "art/tile-238-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-239-sd.png", + "hd_png": "art/tile-239-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-240-sd.png", + "hd_png": "art/tile-240-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-241-sd.png", + "hd_png": "art/tile-241-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-242-sd.png", + "hd_png": "art/tile-242-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-243-sd.png", + "hd_png": "art/tile-243-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-244-sd.png", + "hd_png": "art/tile-244-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-245-sd.png", + "hd_png": "art/tile-245-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-246-sd.png", + "hd_png": "art/tile-246-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-247-sd.png", + "hd_png": "art/tile-247-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-248-sd.png", + "hd_png": "art/tile-248-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-249-sd.png", + "hd_png": "art/tile-249-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-250-sd.png", + "hd_png": "art/tile-250-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-251-sd.png", + "hd_png": "art/tile-251-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-252-sd.png", + "hd_png": "art/tile-252-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-253-sd.png", + "hd_png": "art/tile-253-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-254-sd.png", + "hd_png": "art/tile-254-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-255-sd.png", + "hd_png": "art/tile-255-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-256-sd.png", + "hd_png": "art/tile-256-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-257-sd.png", + "hd_png": "art/tile-257-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-258-sd.png", + "hd_png": "art/tile-258-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-259-sd.png", + "hd_png": "art/tile-259-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-260-sd.png", + "hd_png": "art/tile-260-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-261-sd.png", + "hd_png": "art/tile-261-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-262-sd.png", + "hd_png": "art/tile-262-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-263-sd.png", + "hd_png": "art/tile-263-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-264-sd.png", + "hd_png": "art/tile-264-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-265-sd.png", + "hd_png": "art/tile-265-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-266-sd.png", + "hd_png": "art/tile-266-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-267-sd.png", + "hd_png": "art/tile-267-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-268-sd.png", + "hd_png": "art/tile-268-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-269-sd.png", + "hd_png": "art/tile-269-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-270-sd.png", + "hd_png": "art/tile-270-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-271-sd.png", + "hd_png": "art/tile-271-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-272-sd.png", + "hd_png": "art/tile-272-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-273-sd.png", + "hd_png": "art/tile-273-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-274-sd.png", + "hd_png": "art/tile-274-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-275-sd.png", + "hd_png": "art/tile-275-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-276-sd.png", + "hd_png": "art/tile-276-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-277-sd.png", + "hd_png": "art/tile-277-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-278-sd.png", + "hd_png": "art/tile-278-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-279-sd.png", + "hd_png": "art/tile-279-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-280-sd.png", + "hd_png": "art/tile-280-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-281-sd.png", + "hd_png": "art/tile-281-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-282-sd.png", + "hd_png": "art/tile-282-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-283-sd.png", + "hd_png": "art/tile-283-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-284-sd.png", + "hd_png": "art/tile-284-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-285-sd.png", + "hd_png": "art/tile-285-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-286-sd.png", + "hd_png": "art/tile-286-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + }, + { + "art": { + "png": "art/tile-287-sd.png", + "hd_png": "art/tile-287-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + } + } + ] + } + ], + "campaigns": [ + { + "id": "iron_coast_stage2_mission_4:campaign", + "name": "Floodgate Zero \u2014 Standalone", + "missions": [ + "iron_coast_stage2_mission_4:mission_04" + ], + "art": { + "png": "art/briefing-sd.png", + "hd_png": "art/briefing-hd.png", + "logical_width": 320, + "logical_height": 200, + "frames": 1 + } + } + ] +} diff --git a/mods/iron_coast_stage2_mission_4/design.json b/mods/iron_coast_stage2_mission_4/design.json new file mode 100644 index 00000000..ce9e1655 --- /dev/null +++ b/mods/iron_coast_stage2_mission_4/design.json @@ -0,0 +1,29 @@ +{ + "title": "Floodgate Zero", + "required_target_kills": 4, + "boss_arrival_tick": 2250, + "duration_hint_ticks": 3300, + "objective_timeout": false, + "completion_reward": 16500, + "target_reward": 500, + "target_salvage_shield": 12, + "equipment_loans": false, + "classic_ids": [ + "base:enemy_0_23", + "base:enemy_0_25", + "base:enemy_0_74", + "base:enemy_0_24", + "base:enemy_0_26", + "base:enemy_0_20", + "base:enemy_0_73", + "base:enemy_0_21" + ], + "shared_units": [ + "iron_coast_stage2_interceptor:unit", + "iron_coast_stage2_skimmer:unit" + ], + "music_track": "iron_coast_stage2_music:pursuit", + "terrain_layout_rows": 256, + "terrain_repeat_period_rows": 32, + "terrain_visual_scroll_span": 8192 +} diff --git a/mods/iron_coast_stage2_mission_4/mod.toml b/mods/iron_coast_stage2_mission_4/mod.toml new file mode 100644 index 00000000..7572b4a5 --- /dev/null +++ b/mods/iron_coast_stage2_mission_4/mod.toml @@ -0,0 +1,13 @@ +id = "iron_coast_stage2_mission_4" +name = "Iron Coast II — Mission 4: Floodgate Zero" +version = "1.0.0" +api_version = 1 +description = "Floodgate Zero: four mandatory defenses and the distinct Floodgate boss. Original classic enemies interleave new units; objective survivors stay reachable." +content = "content.json" +scripts = ["scripts/mission.rhai", "scripts/target.rhai"] + +[dependencies] +iron_coast_stage2_boss_4 = "^1.0" +iron_coast_stage2_interceptor = "^1.0" +iron_coast_stage2_skimmer = "^1.0" +iron_coast_stage2_music = "^1.0" diff --git a/mods/iron_coast_stage2_mission_4/prompts/target-v1.txt b/mods/iron_coast_stage2_mission_4/prompts/target-v1.txt new file mode 100644 index 00000000..78d6daba --- /dev/null +++ b/mods/iron_coast_stage2_mission_4/prompts/target-v1.txt @@ -0,0 +1,4 @@ +Use case: stylized-concept +Asset type: new Iron Coast II game sprite/terrain master +Style reference is the original Raptor contact sheet: exact top-down mechanical vehicle/terrain shapes, muted gray-bronze steel, worn panels, dark outlines, compact DOS-shooter readability. Create original new artwork matching that visual language with cleaner high-resolution detail, not a copy or a photograph. +Primary request: One isolated Floodgate crossing-defense pylon: square32x32logical armored dam emplacement in strict top-down view, teal-gray central paired short cannon on a concrete foot, exposed copper hydraulic ribs, small amber safety panels, coherent square readable silhouette. Original mechanical game sprite matching Raptor grounded fixtures. Generous true transparent outer padding, no surrounding water or terrain, no text, no fire/smoke, no shadow beyond footprint. diff --git a/mods/iron_coast_stage2_mission_4/prompts/terrain-v1.txt b/mods/iron_coast_stage2_mission_4/prompts/terrain-v1.txt new file mode 100644 index 00000000..8333032b --- /dev/null +++ b/mods/iron_coast_stage2_mission_4/prompts/terrain-v1.txt @@ -0,0 +1,4 @@ +Use case: stylized-concept +Asset type: new Iron Coast II game sprite/terrain master +Style reference is the original Raptor contact sheet: exact top-down mechanical vehicle/terrain shapes, muted gray-bronze steel, worn panels, dark outlines, compact DOS-shooter readability. Create original new artwork matching that visual language with cleaner high-resolution detail, not a copy or a photograph. +Primary request: Full opaque portrait top-down game scrolling terrain for Floodgate Zero: tight slate-brown canyon banks framing a dark teal river, industrial concrete dam crossings and narrow steel service bridges across river, spillway gates, gray flood barriers, low subdued water ripples and restrained hydroelectric cyan lines. Central vertical river corridor remains open/readable for ship fire; canyon walls line both edges, crossings at spaced intervals. Direct orthographic overhead view and coherent flat terrain matching classic Raptor, cleaner high-detail treatment. No sky, no atmospheric horizon, no boats/enemies/aircraft, no text, no UI/borders or tile grid. Seam-friendly low-contrast portrait composition approximately9:16 filling full canvas. diff --git a/mods/iron_coast_stage2_mission_4/provenance-target.json b/mods/iron_coast_stage2_mission_4/provenance-target.json new file mode 100644 index 00000000..6e3adada --- /dev/null +++ b/mods/iron_coast_stage2_mission_4/provenance-target.json @@ -0,0 +1,39 @@ +{ + "generator": "built-in image_gen.imagegen", + "owner": "/root/iron_coast_3", + "job_id": "stage2-target4", + "utc": "2026-10-11T08:20:10.258750+00:00", + "default_output": "/home/quintine/.codex/generated_images/01a1245d-8d97-74e2-9a2c-02e88a570589/exec-07f45ee2-ac26-4a89-9532-4108d743cce9.png", + "raw_master": "art/target-source-v1.png", + "raw_sha256": "8751d415ec5f95aadeb5c622c74f2ff945a4426fa5e2902f1e410773b5a9338a", + "prompt": "prompts/target-v1.txt", + "prompt_sha256": "e0561c55b9d28ad69e53aa17e2a01d0192fa36e95b47307c7f05349f17ed86c0", + "style_reference_role": "Original Raptor style only; decoded style reference is intentionally external to authored mod.", + "reference_sha256": "685307409d68baa9413975b59427c74d29f6a09b2b039a3d88ee69abf19e9a9d", + "original_style_source_hashes": [ + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/enemies-200cc-200cd/sources/200cc.png", + "sha256": "c3f92b8a04370029652cfff20dc00ec41228c5adead37affaacd3b9511bb520d", + "role": "Original Raptor style reference; not copied into authored mods." + }, + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/enemies-2008d-2008d/sources/2008d.png", + "sha256": "419514e3b7cbd9fb7283f0550f12991f5570c2de16c367330fa2e8a9b6bb3725", + "role": "Original Raptor style reference; not copied into authored mods." + }, + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/bosses-10310-10310/sources/10310.png", + "sha256": "39404e604c4d535e868ffea924ba206c690e19f7df9c289ce14612cb2451bbef", + "role": "Original Raptor style reference; not copied into authored mods." + }, + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/terrain-10360-1036f/sources/10360.png", + "sha256": "ee5348dbdf57952027349c64cd13c9d2991a33b0378a54f4750622d9bff50dc0", + "role": "Original Raptor style reference; not copied into authored mods." + } + ], + "transparent_background_requested": true, + "gate_lease": "dc20d245-1231-4309-ac9e-675ce3249a1c", + "gate_outcome": "success", + "source_pixels_modified": false +} diff --git a/mods/iron_coast_stage2_mission_4/provenance-terrain.json b/mods/iron_coast_stage2_mission_4/provenance-terrain.json new file mode 100644 index 00000000..a5e3d5b6 --- /dev/null +++ b/mods/iron_coast_stage2_mission_4/provenance-terrain.json @@ -0,0 +1,39 @@ +{ + "generator": "built-in image_gen.imagegen", + "owner": "/root/iron_coast_3", + "job_id": "stage2-terrain4", + "utc": "2026-10-11T08:15:26.594276+00:00", + "default_output": "/home/quintine/.codex/generated_images/01a1245d-8d97-74e2-9a2c-02e88a570589/exec-074afc5c-4c75-4695-9361-de74b422eeb4.png", + "raw_master": "art/terrain-source-v1.png", + "raw_sha256": "8f2198d7827a25d53dd808d4ec7d79842db6152a7e3a0dddcf7ea47465056875", + "prompt": "prompts/terrain-v1.txt", + "prompt_sha256": "14bb1a5aac60dfea56c898ef4c5300b5fd101b9b5c33a98889a9777d6b85b7cd", + "style_reference_role": "Original Raptor style only; decoded style reference is intentionally external to authored mod.", + "reference_sha256": "685307409d68baa9413975b59427c74d29f6a09b2b039a3d88ee69abf19e9a9d", + "original_style_source_hashes": [ + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/enemies-200cc-200cd/sources/200cc.png", + "sha256": "c3f92b8a04370029652cfff20dc00ec41228c5adead37affaacd3b9511bb520d", + "role": "Original Raptor style reference; not copied into authored mods." + }, + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/enemies-2008d-2008d/sources/2008d.png", + "sha256": "419514e3b7cbd9fb7283f0550f12991f5570c2de16c367330fa2e8a9b6bb3725", + "role": "Original Raptor style reference; not copied into authored mods." + }, + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/bosses-10310-10310/sources/10310.png", + "sha256": "39404e604c4d535e868ffea924ba206c690e19f7df9c289ce14612cb2451bbef", + "role": "Original Raptor style reference; not copied into authored mods." + }, + { + "path": "/home/quintine/Projects/RaptorReplica/data/hd/jobs/terrain-10360-1036f/sources/10360.png", + "sha256": "ee5348dbdf57952027349c64cd13c9d2991a33b0378a54f4750622d9bff50dc0", + "role": "Original Raptor style reference; not copied into authored mods." + } + ], + "transparent_background_requested": false, + "gate_lease": "9ffc8b5e-603b-4319-9f27-17416b6e82c1", + "gate_outcome": "success", + "source_pixels_modified": false +} diff --git a/mods/iron_coast_stage2_mission_4/scripts/mission.rhai b/mods/iron_coast_stage2_mission_4/scripts/mission.rhai new file mode 100644 index 00000000..c87b8a29 --- /dev/null +++ b/mods/iron_coast_stage2_mission_4/scripts/mission.rhai @@ -0,0 +1,18 @@ +fn on_mission_start(event,state,random) { + #{commands:[#{op:"objective",key:"iron_coast_stage2_mission_4:phase",value:1},#{op:"objective",key:"iron_coast_stage2_mission_4:targets_required",value:4},#{op:"objective",key:"iron_coast_stage2_mission_4:targets_destroyed",value:0},#{op:"objective",key:"iron_coast_stage2_mission_4:complete",value:0},#{op:"objective",key:"iron_coast_stage2_boss_4:defeated",value:0},#{op:"play_sound",sound:"iron_coast_stage2_mission_4:approach"}],state:#{boss_alarm:false,complete:false}} +} +fn on_tick(event,state,random) { + let commands=[]; + if event.tick==2250 && !state.boss_alarm { + state.boss_alarm=true;commands.push(#{op:"objective",key:"iron_coast_stage2_mission_4:phase",value:3});commands.push(#{op:"play_sound",sound:"iron_coast_stage2_mission_4:boss_alarm"}); + } + if event.tick==1100 {commands.push(#{op:"objective",key:"iron_coast_stage2_mission_4:phase",value:2});commands.push(#{op:"play_sound",sound:"iron_coast_stage2_mission_4:target_alarm"});} + + let kills=if event.objectives.contains("iron_coast_stage2_mission_4:targets_destroyed") {event.objectives["iron_coast_stage2_mission_4:targets_destroyed"]} else {0}; + let boss=if event.objectives.contains("iron_coast_stage2_boss_4:defeated") {event.objectives["iron_coast_stage2_boss_4:defeated"]} else {0}; + if event.tick>=2250 && kills>=4 && boss>=1 && !state.complete { + state.complete=true;commands.push(#{op:"objective",key:"iron_coast_stage2_mission_4:complete",value:1});commands.push(#{op:"objective",key:"iron_coast_stage2_mission_4:phase",value:4});commands.push(#{op:"credits",amount:16500});commands.push(#{op:"play_sound",sound:"iron_coast_stage2_mission_4:victory"});commands.push(#{op:"complete"}); + } + #{commands:commands,state:state} +} +fn on_mission_end(event,state,random) {#{commands:[#{op:"objective",key:"iron_coast_stage2_mission_4:debrief",value:if event.success {1} else {0}}],state:state}} diff --git a/mods/iron_coast_stage2_mission_4/scripts/target.rhai b/mods/iron_coast_stage2_mission_4/scripts/target.rhai new file mode 100644 index 00000000..44f1d1ec --- /dev/null +++ b/mods/iron_coast_stage2_mission_4/scripts/target.rhai @@ -0,0 +1,36 @@ +// Retain at most128 recently retired entity IDs. Older checkpoints lacking +// the FIFO migrate deterministically before any new spawn/death is processed. +fn ready(state) { + if !state.contains("dead") {state.dead=#{};} + if !state.contains("dead_order") { + let retained=#{};let order=[]; + for key in state.dead.keys() { + if order.len()>=128 {let oldest=order.remove(0);retained.remove(oldest);} + retained[key]=true;order.push(key); + } + state.dead=retained;state.dead_order=order; + } + state +} +fn live(event) {for e in event.entities {if e.entity==event.entity && e.health>0 {return true;}}false} +fn on_spawn(event,state,random) { + state=ready(state); + let key=event.entity.to_string();state.dead.remove(key); + let keep=[];for old in state.dead_order {if old!=key {keep.push(old);}}state.dead_order=keep; + #{commands:[],state:state} +} +fn on_tick(event,state,random) { + if event.health<=0 || !live(event) {return #{commands:[],state:state};} + // Ground scroll is rebased every tick after arrival so a mandatory survivor + // remains reachable indefinitely. No target escapes or disappears on a timer. + if event.y>=60 {return #{commands:[#{op:"move",entity:event.entity,x:event.x,y:60},#{op:"velocity",entity:event.entity,vx:0,vy:0}],state:state};} + #{commands:[],state:state} +} +fn on_death(event,state,random) { + state=ready(state); + let key=event.entity.to_string();if state.dead.contains(key) {return #{commands:[],state:state};} + if state.dead_order.len()>=128 {let oldest=state.dead_order.remove(0);state.dead.remove(oldest);} + state.dead[key]=true;state.dead_order.push(key); + let count=if event.objectives.contains("iron_coast_stage2_mission_4:targets_destroyed") {event.objectives["iron_coast_stage2_mission_4:targets_destroyed"]+1} else {1}; + #{commands:[#{op:"objective",key:"iron_coast_stage2_mission_4:targets_destroyed",value:count},#{op:"shield",amount:12},#{op:"play_sound",sound:"iron_coast_stage2_mission_4:salvage"}],state:state} +} diff --git a/mods/iron_coast_stage2_mission_4/validation/Cargo.toml b/mods/iron_coast_stage2_mission_4/validation/Cargo.toml new file mode 100644 index 00000000..70f32ed9 --- /dev/null +++ b/mods/iron_coast_stage2_mission_4/validation/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "iron-coast-stage2-mission-4-validation" +version = "1.0.0" +edition = "2024" +publish = false + +[workspace] + +[dependencies] +raptor-replica = { path = "../../..", default-features = false } +serde_json = "1" + +[[bin]] +name = "validate" +path = "validate.rs" + +[[bin]] +name = "retained-state" +path = "retained_state.rs" diff --git a/mods/iron_coast_stage2_mission_4/validation/acceptance.json b/mods/iron_coast_stage2_mission_4/validation/acceptance.json new file mode 100644 index 00000000..d662f861 --- /dev/null +++ b/mods/iron_coast_stage2_mission_4/validation/acceptance.json @@ -0,0 +1,297 @@ +{ + "audio": [ + { + "decoded_samples": 20948, + "file": "audio/death.wav", + "id": "iron_coast_stage2_boss_4:death", + "mixed_stereo_peak": 7040 + }, + { + "decoded_samples": 4410, + "file": "audio/shot.wav", + "id": "iron_coast_stage2_boss_4:shot", + "mixed_stereo_peak": 5888 + }, + { + "decoded_samples": 7938, + "file": "audio/warning.wav", + "id": "iron_coast_stage2_boss_4:warning", + "mixed_stereo_peak": 3840 + }, + { + "decoded_samples": 17199, + "file": "audio/approach.wav", + "id": "iron_coast_stage2_mission_4:approach", + "mixed_stereo_peak": 4992 + }, + { + "decoded_samples": 14332, + "file": "audio/boss_alarm.wav", + "id": "iron_coast_stage2_mission_4:boss_alarm", + "mixed_stereo_peak": 3968 + }, + { + "decoded_samples": 7056, + "file": "audio/salvage.wav", + "id": "iron_coast_stage2_mission_4:salvage", + "mixed_stereo_peak": 4992 + }, + { + "decoded_samples": 9261, + "file": "audio/target_alarm.wav", + "id": "iron_coast_stage2_mission_4:target_alarm", + "mixed_stereo_peak": 3968 + }, + { + "decoded_samples": 24255, + "file": "audio/victory.wav", + "id": "iron_coast_stage2_mission_4:victory", + "mixed_stereo_peak": 6656 + } + ], + "capture_scope": "actual Rust PNG palette conversion and indexed Canvas from real World states; desktop Host live screenshots handled independently", + "deterministic_resume_from_tick": 1200, + "full_inventory": { + "credits": 35960, + "equipment_preserved": true, + "shield": 83, + "slots": 20, + "tick": 2535 + }, + "gated_completion_and_once_bonus": true, + "mission": "iron_coast_stage2_mission_4:mission_04", + "playthroughs": [ + { + "credits": 35960, + "difficulty": 0, + "initial_credits": 10000, + "initial_shield": 75, + "minimum_shield": 74, + "mod_sound_cues": [ + "iron_coast_stage2_boss_4:death", + "iron_coast_stage2_boss_4:shot", + "iron_coast_stage2_boss_4:warning", + "iron_coast_stage2_interceptor:death", + "iron_coast_stage2_interceptor:shot", + "iron_coast_stage2_mission_4:approach", + "iron_coast_stage2_mission_4:boss_alarm", + "iron_coast_stage2_mission_4:salvage", + "iron_coast_stage2_mission_4:target_alarm", + "iron_coast_stage2_mission_4:victory", + "iron_coast_stage2_skimmer:death", + "iron_coast_stage2_skimmer:shot", + "iron_coast_stage2_skimmer:warning" + ], + "native_seen_and_moving": [ + "base:enemy_0_20", + "base:enemy_0_21", + "base:enemy_0_23", + "base:enemy_0_24", + "base:enemy_0_25", + "base:enemy_0_26", + "base:enemy_0_73", + "base:enemy_0_74" + ], + "objectives": { + "iron_coast_stage2_boss_4:defeated": 1, + "iron_coast_stage2_boss_4:phase": 2, + "iron_coast_stage2_interceptor:defeated": 4, + "iron_coast_stage2_mission_4:complete": 1, + "iron_coast_stage2_mission_4:debrief": 1, + "iron_coast_stage2_mission_4:phase": 4, + "iron_coast_stage2_mission_4:targets_destroyed": 4, + "iron_coast_stage2_mission_4:targets_required": 4, + "iron_coast_stage2_skimmer:defeated": 4 + }, + "shield": 99, + "tick": 2396 + }, + { + "credits": 35960, + "difficulty": 1, + "initial_credits": 10000, + "initial_shield": 75, + "minimum_shield": 73, + "mod_sound_cues": [ + "iron_coast_stage2_boss_4:death", + "iron_coast_stage2_boss_4:shot", + "iron_coast_stage2_boss_4:warning", + "iron_coast_stage2_interceptor:death", + "iron_coast_stage2_interceptor:shot", + "iron_coast_stage2_mission_4:approach", + "iron_coast_stage2_mission_4:boss_alarm", + "iron_coast_stage2_mission_4:salvage", + "iron_coast_stage2_mission_4:target_alarm", + "iron_coast_stage2_mission_4:victory", + "iron_coast_stage2_skimmer:death", + "iron_coast_stage2_skimmer:shot", + "iron_coast_stage2_skimmer:warning" + ], + "native_seen_and_moving": [ + "base:enemy_0_20", + "base:enemy_0_21", + "base:enemy_0_23", + "base:enemy_0_24", + "base:enemy_0_25", + "base:enemy_0_26", + "base:enemy_0_73", + "base:enemy_0_74" + ], + "objectives": { + "iron_coast_stage2_boss_4:defeated": 1, + "iron_coast_stage2_boss_4:phase": 2, + "iron_coast_stage2_interceptor:defeated": 4, + "iron_coast_stage2_mission_4:complete": 1, + "iron_coast_stage2_mission_4:debrief": 1, + "iron_coast_stage2_mission_4:phase": 4, + "iron_coast_stage2_mission_4:targets_destroyed": 4, + "iron_coast_stage2_mission_4:targets_required": 4, + "iron_coast_stage2_skimmer:defeated": 4 + }, + "shield": 98, + "tick": 2396 + }, + { + "credits": 35960, + "difficulty": 2, + "initial_credits": 10000, + "initial_shield": 75, + "minimum_shield": 73, + "mod_sound_cues": [ + "iron_coast_stage2_boss_4:death", + "iron_coast_stage2_boss_4:shot", + "iron_coast_stage2_boss_4:warning", + "iron_coast_stage2_interceptor:death", + "iron_coast_stage2_interceptor:shot", + "iron_coast_stage2_mission_4:approach", + "iron_coast_stage2_mission_4:boss_alarm", + "iron_coast_stage2_mission_4:salvage", + "iron_coast_stage2_mission_4:target_alarm", + "iron_coast_stage2_mission_4:victory", + "iron_coast_stage2_skimmer:death", + "iron_coast_stage2_skimmer:shot", + "iron_coast_stage2_skimmer:warning" + ], + "native_seen_and_moving": [ + "base:enemy_0_20", + "base:enemy_0_21", + "base:enemy_0_23", + "base:enemy_0_24", + "base:enemy_0_25", + "base:enemy_0_26", + "base:enemy_0_73", + "base:enemy_0_74" + ], + "objectives": { + "iron_coast_stage2_boss_4:defeated": 1, + "iron_coast_stage2_boss_4:phase": 2, + "iron_coast_stage2_interceptor:defeated": 4, + "iron_coast_stage2_mission_4:complete": 1, + "iron_coast_stage2_mission_4:debrief": 1, + "iron_coast_stage2_mission_4:phase": 4, + "iron_coast_stage2_mission_4:targets_destroyed": 4, + "iron_coast_stage2_mission_4:targets_required": 4, + "iron_coast_stage2_skimmer:defeated": 4 + }, + "shield": 83, + "tick": 2536 + }, + { + "credits": 35960, + "difficulty": 3, + "initial_credits": 10000, + "initial_shield": 75, + "minimum_shield": 73, + "mod_sound_cues": [ + "iron_coast_stage2_boss_4:death", + "iron_coast_stage2_boss_4:shot", + "iron_coast_stage2_boss_4:warning", + "iron_coast_stage2_interceptor:death", + "iron_coast_stage2_interceptor:shot", + "iron_coast_stage2_mission_4:approach", + "iron_coast_stage2_mission_4:boss_alarm", + "iron_coast_stage2_mission_4:salvage", + "iron_coast_stage2_mission_4:target_alarm", + "iron_coast_stage2_mission_4:victory", + "iron_coast_stage2_skimmer:death", + "iron_coast_stage2_skimmer:shot", + "iron_coast_stage2_skimmer:warning" + ], + "native_seen_and_moving": [ + "base:enemy_0_20", + "base:enemy_0_21", + "base:enemy_0_23", + "base:enemy_0_24", + "base:enemy_0_25", + "base:enemy_0_26", + "base:enemy_0_73", + "base:enemy_0_74" + ], + "objectives": { + "iron_coast_stage2_boss_4:defeated": 1, + "iron_coast_stage2_boss_4:phase": 2, + "iron_coast_stage2_interceptor:defeated": 4, + "iron_coast_stage2_mission_4:complete": 1, + "iron_coast_stage2_mission_4:debrief": 1, + "iron_coast_stage2_mission_4:phase": 4, + "iron_coast_stage2_mission_4:targets_destroyed": 4, + "iron_coast_stage2_mission_4:targets_required": 4, + "iron_coast_stage2_skimmer:defeated": 4 + }, + "shield": 89, + "tick": 2536 + }, + { + "credits": 25960, + "difficulty": 2, + "initial_credits": 0, + "initial_shield": 100, + "minimum_shield": 83, + "mod_sound_cues": [ + "iron_coast_stage2_boss_4:death", + "iron_coast_stage2_boss_4:shot", + "iron_coast_stage2_boss_4:warning", + "iron_coast_stage2_interceptor:death", + "iron_coast_stage2_interceptor:shot", + "iron_coast_stage2_mission_4:approach", + "iron_coast_stage2_mission_4:boss_alarm", + "iron_coast_stage2_mission_4:salvage", + "iron_coast_stage2_mission_4:target_alarm", + "iron_coast_stage2_mission_4:victory", + "iron_coast_stage2_skimmer:death", + "iron_coast_stage2_skimmer:shot", + "iron_coast_stage2_skimmer:warning" + ], + "native_seen_and_moving": [ + "base:enemy_0_20", + "base:enemy_0_21", + "base:enemy_0_23", + "base:enemy_0_24", + "base:enemy_0_25", + "base:enemy_0_26", + "base:enemy_0_73", + "base:enemy_0_74" + ], + "objectives": { + "iron_coast_stage2_boss_4:defeated": 1, + "iron_coast_stage2_boss_4:phase": 2, + "iron_coast_stage2_interceptor:defeated": 4, + "iron_coast_stage2_mission_4:complete": 1, + "iron_coast_stage2_mission_4:debrief": 1, + "iron_coast_stage2_mission_4:phase": 4, + "iron_coast_stage2_mission_4:targets_destroyed": 4, + "iron_coast_stage2_mission_4:targets_required": 4, + "iron_coast_stage2_skimmer:defeated": 4 + }, + "shield": 83, + "tick": 2536 + } + ], + "retention": { + "boss": 1, + "outcome": "playing", + "shield_controlled_only_here": true, + "targets": 4, + "tick": 4500 + } +} diff --git a/mods/iron_coast_stage2_mission_4/validation/acceptance.log b/mods/iron_coast_stage2_mission_4/validation/acceptance.log new file mode 100644 index 00000000..18b0dc65 --- /dev/null +++ b/mods/iron_coast_stage2_mission_4/validation/acceptance.log @@ -0,0 +1,6 @@ +stage4 difficulty0 initial75/10000: win tick2396 shield99 min74 credits35960 +stage4 difficulty1 initial75/10000: win tick2396 shield98 min73 credits35960 +stage4 difficulty2 initial75/10000: win tick2536 shield83 min73 credits35960 +stage4 difficulty3 initial75/10000: win tick2536 shield83 min73 credits35960 +stage4 difficulty2 initial100/0: win tick2536 shield83 min83 credits25960 +retention4500/restart/full20/once-bonus/deterministic saved state+RNG/mixed WAVs: passed diff --git a/mods/iron_coast_stage2_mission_4/validation/bounded-cache-review.md b/mods/iron_coast_stage2_mission_4/validation/bounded-cache-review.md new file mode 100644 index 00000000..e5b8e3a6 --- /dev/null +++ b/mods/iron_coast_stage2_mission_4/validation/bounded-cache-review.md @@ -0,0 +1,9 @@ +# Retained lifecycle cache correction + +The independent native-collision probe found an unbounded pre-correction retired-ID map that exhausted the Rhai object-map limit at distinct-lifetime index1009. Historical package folders and the previous four-package freeze are retained outside the distribution. + +The gameplay definitions, health, attack patterns, objectives, prices, images and sounds are unchanged. A separate independent timing probe also found that changing the old warning-clock modulo at half-health could release a low-phase volley after only two ticks. Bosses now latch their phase and restart its warning clock on a phase transition, preserving the advertised full 14-tick telegraph. The actual World regression tests transition immediately after the second high-phase warning at every difficulty, including an old checkpoint lacking the latch. The script now stores a FIFO of at most 128 recent retired IDs, removes reused IDs on spawn before checking their health, and migrates pre-FIFO states into a deterministic bounded subset. Boss clocks absent from the new World's snapshot are discarded; live peer clocks remain intact. + +The package-local retained-state proof checks real bundled Catalog activation and a test-only native stationary lethal projectile, 1,205 lives (1,200 unique plus five reused IDs), exact one-death rewards, current-lifecycle callback deduplication, nine JSON checkpoint/RNG roundtrips, old 960-ID cache migration and all four difficulty kills. Boss probes add 1,205 abandoned-live replays and simultaneous peer-clock preservation. This is a lifecycle stress proof, not a combat-balance shortcut. Normal mission acceptance and boss phase probes were rerun independently of this stress fixture. + +A duplicate callback for an entity retired more than 128 deaths ago is outside the retained guard window; the engine emits each real death once and queued callbacks are not delayed across 128 later deaths. Reusing an ID through an actual spawn always starts a fresh guarded lifecycle. diff --git a/mods/iron_coast_stage2_mission_4/validation/bounded-cli.log b/mods/iron_coast_stage2_mission_4/validation/bounded-cli.log new file mode 100644 index 00000000..83810a55 --- /dev/null +++ b/mods/iron_coast_stage2_mission_4/validation/bounded-cli.log @@ -0,0 +1 @@ +Validated 8 mods; 0 override(s) diff --git a/mods/iron_coast_stage2_mission_4/validation/bounded-normal.log b/mods/iron_coast_stage2_mission_4/validation/bounded-normal.log new file mode 100644 index 00000000..0a0b818d --- /dev/null +++ b/mods/iron_coast_stage2_mission_4/validation/bounded-normal.log @@ -0,0 +1,6 @@ +stage4 difficulty0 initial75/10000: win tick2396 shield99 min74 credits35960 +stage4 difficulty1 initial75/10000: win tick2396 shield98 min73 credits35960 +stage4 difficulty2 initial75/10000: win tick2536 shield83 min73 credits35960 +stage4 difficulty3 initial75/10000: win tick2536 shield89 min73 credits35960 +stage4 difficulty2 initial100/0: win tick2536 shield83 min83 credits25960 +retention4500/restart/full20/once-bonus/deterministic saved state+RNG/mixed WAVs: passed diff --git a/mods/iron_coast_stage2_mission_4/validation/cli.log b/mods/iron_coast_stage2_mission_4/validation/cli.log new file mode 100644 index 00000000..d97e0af1 --- /dev/null +++ b/mods/iron_coast_stage2_mission_4/validation/cli.log @@ -0,0 +1 @@ +Validated 5 mods; 0 override(s) diff --git a/mods/iron_coast_stage2_mission_4/validation/combined-cli.log b/mods/iron_coast_stage2_mission_4/validation/combined-cli.log new file mode 100644 index 00000000..83810a55 --- /dev/null +++ b/mods/iron_coast_stage2_mission_4/validation/combined-cli.log @@ -0,0 +1 @@ +Validated 8 mods; 0 override(s) diff --git a/mods/iron_coast_stage2_mission_4/validation/compiler-binding.json b/mods/iron_coast_stage2_mission_4/validation/compiler-binding.json new file mode 100644 index 00000000..64f32abf --- /dev/null +++ b/mods/iron_coast_stage2_mission_4/validation/compiler-binding.json @@ -0,0 +1,22 @@ +{ + "/home/quintine/Projects/RaptorReplica/RustRaptor/target/release/deps/libraptor_replica-f9adab78fd4d2969.rlib": { + "bytes": 13308296, + "sha256": "eb190ba6ad88d1939938a30c69bd1d8c705ecfb77eb12c36ae0686f10f82bae7", + "mtime_ns": 1791706754209530916 + }, + "/home/quintine/Projects/RaptorReplica/RustRaptor/target/release/deps/libserde_json-11c796c0bcf3a604.rlib": { + "bytes": 2057816, + "sha256": "7a13e07716f46f559cb9acf05c81ce0845e5633dfd3d77e6020e14af31a3a878", + "mtime_ns": 1791706698162048372 + }, + "/home/quintine/Projects/RaptorReplica/RustRaptor/mods/iron_coast_stage2_mission_4/validation/validate.rs": { + "bytes": 18969, + "sha256": "3a255f8bb3a9afcb15e59ddfc98e79a1b32b3ce5e787e8dba1068e337b274ba7", + "mtime_ns": 1791707446287702078 + }, + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/mission-4-validate": { + "bytes": 8458112, + "sha256": "97ecdad2eddfba58da3155cd8d361ab741120047ba0e9078df931b6a88a6e6fd", + "mtime_ns": 1791707500520347364 + } +} diff --git a/mods/iron_coast_stage2_mission_4/validation/retained-state-compiler-binding.json b/mods/iron_coast_stage2_mission_4/validation/retained-state-compiler-binding.json new file mode 100644 index 00000000..3fd64a58 --- /dev/null +++ b/mods/iron_coast_stage2_mission_4/validation/retained-state-compiler-binding.json @@ -0,0 +1,22 @@ +{ + "/home/quintine/Projects/RaptorReplica/RustRaptor/target/release/deps/libraptor_replica-f9adab78fd4d2969.rlib": { + "bytes": 13308296, + "sha256": "eb190ba6ad88d1939938a30c69bd1d8c705ecfb77eb12c36ae0686f10f82bae7", + "mtime_ns": 1791706754209530916 + }, + "/home/quintine/Projects/RaptorReplica/RustRaptor/target/release/deps/libserde_json-11c796c0bcf3a604.rlib": { + "bytes": 2057816, + "sha256": "7a13e07716f46f559cb9acf05c81ce0845e5633dfd3d77e6020e14af31a3a878", + "mtime_ns": 1791706698162048372 + }, + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/retained-state": { + "bytes": 8421248, + "sha256": "ece9f14a0a69754c8515ccc1c3c98968b8023b1978ad36497028c11208abe1e8", + "mtime_ns": 1791708664346644142 + }, + "/home/quintine/Projects/RaptorReplica/RustRaptor/mods/iron_coast_stage2_mission_4/validation/retained_state.rs": { + "bytes": 12558, + "sha256": "e1c4f9f1d78ba98c423cfe41cd90eb72a811398a7ba4dc334e342b89336f5a64", + "mtime_ns": 1791708663779657373 + } +} diff --git a/mods/iron_coast_stage2_mission_4/validation/retained-state.json b/mods/iron_coast_stage2_mission_4/validation/retained-state.json new file mode 100644 index 00000000..5ab7476a --- /dev/null +++ b/mods/iron_coast_stage2_mission_4/validation/retained-state.json @@ -0,0 +1,61 @@ +{ + "abandoned_live_replays": 0, + "actual_native_collision_lives": 1205, + "actual_phase_transition_warnings": [], + "checkpoint_json_roundtrips": 9, + "difficulty_kills": [ + 0, + 1, + 2, + 3 + ], + "distinct_ids": 1200, + "duplicate_callback_commands": 0, + "enabled": [ + "iron_coast_stage2_boss_4", + "iron_coast_stage2_interceptor", + "iron_coast_stage2_mission_4", + "iron_coast_stage2_music", + "iron_coast_stage2_skimmer" + ], + "fixture": "actual bundled Catalog; test-only stationary lethal projectile; native World collision, death, reward and retained ScriptRuntime", + "legacy_960_guard_migration": true, + "maximum_abandoned_state_bytes": 0, + "maximum_death_state_bytes": 2713, + "migration_state_bytes": 2724, + "owner": "iron_coast_stage2_mission_4", + "package_pins_at_execution": [ + { + "hash": "f3bee341196458f566e68577f6de9562b022fff0ecf5f0ae01b239900cb9d73d", + "id": "iron_coast_stage2_boss_4", + "version": "1.0.0" + }, + { + "hash": "026d61084d595ee3a0db524420e47708c5fef469702b11730bffe7b91fd4c70a", + "id": "iron_coast_stage2_interceptor", + "version": "1.0.0" + }, + { + "hash": "d57e82ed2278609ef7635d722c526605c831e0c5d34a01c88a79a204b07f51d9", + "id": "iron_coast_stage2_music", + "version": "1.0.0" + }, + { + "hash": "683b5a6e6793d43f003fb7d9afd5950aa8360cc9bc06792ef328b0270906b4f2", + "id": "iron_coast_stage2_skimmer", + "version": "1.0.0" + }, + { + "hash": "f48edc677e3817e3c40c44e324407d9b1396d5ed2795047608caa802f2be7761", + "id": "iron_coast_stage2_mission_4", + "version": "1.0.0" + } + ], + "retired_guard_capacity": 128, + "reused_id_lives": 5, + "reward_per_life": 500, + "scope": "callback lifecycle/bounded-state proof, not mission combat balance", + "target_shield_restore": 12, + "two_live_clocks_retained": false, + "unit": "iron_coast_stage2_mission_4:target" +} \ No newline at end of file diff --git a/mods/iron_coast_stage2_mission_4/validation/retained-state.log b/mods/iron_coast_stage2_mission_4/validation/retained-state.log new file mode 100644 index 00000000..ce30ffbc --- /dev/null +++ b/mods/iron_coast_stage2_mission_4/validation/retained-state.log @@ -0,0 +1,12 @@ +iron_coast_stage2_mission_4 retained native kills=1; statebytes=46 retired=1 +iron_coast_stage2_mission_4 retained native kills=129; statebytes=2713 retired=128 +iron_coast_stage2_mission_4 retained native kills=257; statebytes=2713 retired=128 +iron_coast_stage2_mission_4 retained native kills=385; statebytes=2713 retired=128 +iron_coast_stage2_mission_4 retained native kills=513; statebytes=2713 retired=128 +iron_coast_stage2_mission_4 retained native kills=641; statebytes=2713 retired=128 +iron_coast_stage2_mission_4 retained native kills=769; statebytes=2713 retired=128 +iron_coast_stage2_mission_4 retained native kills=897; statebytes=2713 retired=128 +iron_coast_stage2_mission_4 retained native kills=1025; statebytes=2713 retired=128 +iron_coast_stage2_mission_4 retained native kills=1153; statebytes=2713 retired=128 +iron_coast_stage2_mission_4 retained native kills=1205; statebytes=2713 retired=128 +iron_coast_stage2_mission_4: all actual collision/reward, migration, deduplication, retained-state and abandoned-live checks passed diff --git a/mods/iron_coast_stage2_mission_4/validation/retained_state.rs b/mods/iron_coast_stage2_mission_4/validation/retained_state.rs new file mode 100644 index 00000000..910b75ff --- /dev/null +++ b/mods/iron_coast_stage2_mission_4/validation/retained_state.rs @@ -0,0 +1,305 @@ +//! Real native lethal-collision stress with retained serializable Rhai state. +use raptor_replica::{ + assets::Catalog, + content::{ContentPack, Registry}, + modding::{self, ActiveMods, Discovery, ScriptRuntime}, + persistence::Pilot, + simulation::{Input, Projectile, World}, +}; +use serde_json::{Value, json}; +use std::{ + collections::{BTreeMap, BTreeSet}, + path::PathBuf, +}; +type Result = std::result::Result>; +fn closure(d: &Discovery, id: &str, out: &mut BTreeSet) { + if !out.insert(id.into()) { + return; + } + for dep in d.mods[id].manifest.dependencies.keys() { + closure(d, dep, out); + } +} +fn input() -> Input { + Input { + absolute: Some([282, 160]), + ..Input::default() + } +} +fn pilot(difficulty: u32) -> Pilot { + let mut p = Pilot::default(); + p.difficulty = difficulty; + p.credits = 10000; + p.inventory.insert("base:energy".into(), 75); + p +} +fn restore(active: &mut ActiveMods, discovery: &Discovery, enabled: &[String]) -> Result<()> { + let cp = active.scripts.checkpoints(); + let encoded = serde_json::to_vec(&cp)?; + let mut scripts = ScriptRuntime::new(); + for owner in enabled { + for path in &discovery.mods[owner].manifest.scripts { + scripts.add( + owner, + path, + &std::fs::read_to_string(discovery.mods[owner].root.join(path))?, + )?; + } + } + scripts.restore(serde_json::from_slice(&encoded)?); + active.scripts = scripts; + Ok(()) +} +fn event(id: u64, hp: i32, key: &str, count: i32) -> Value { + json!({"entity":id,"x":88,"y":24,"health":hp,"tick":999,"player_x":282,"player_y":160,"entities":[{"entity":id,"health":hp}],"objectives":{key:count}}) +} +fn guard(active: &ActiveMods, key: &str) -> usize { + let state = &active.scripts.states[key]; + let dead = state["dead"].as_object().unwrap(); + let fifo = state["dead_order"].as_array().unwrap(); + assert!(dead.len() <= 128); + assert!(fifo.len() <= 128); + assert_eq!(dead.len(), fifo.len()); + let unique = fifo + .iter() + .map(|v| v.as_str().unwrap()) + .collect::>(); + assert_eq!(unique.len(), fifo.len()); + assert_eq!( + dead.keys().map(|v| v.as_str()).collect::>(), + unique + ); + if let Some(units) = state.get("units") { + assert!(units.as_object().unwrap().is_empty()); + } + serde_json::to_vec(state).unwrap().len() +} +fn kill( + active: &mut ActiveMods, + unit: &str, + id: u64, + objective: &str, + reward: u32, + target: bool, + difficulty: u32, +) -> Result { + let mut w = World::new( + &"review:retained".into(), + &pilot(difficulty), + &active.registry, + )?; + w.next_entity = id; + let y = if target { 60 } else { 24 }; + w.projectiles.push(Projectile { + entity: 500000, + weapon: "review:lethal".into(), + x: 90, + y: y + 6, + px: 90, + py: y + 6, + vx: 0, + vy: 0, + hostile: false, + age: 0, + legacy: None, + legacy_enemy: None, + }); + for _ in 0..3 { + w.step(input(), &active.registry, &mut active.scripts)?; + } + assert!(w.enemies.is_empty(), "{unit} survived"); + assert_eq!(w.objectives.get(objective), Some(&1)); + assert_eq!(w.player.credits, 10000 + reward); + assert_eq!(w.player.shield, if target { 87 } else { 75 }); + w.step(input(), &active.registry, &mut active.scripts)?; + assert_eq!(w.objectives.get(objective), Some(&1)); + assert_eq!(w.player.credits, 10000 + reward); + Ok(w) +} +fn phase_warnings(active: &mut ActiveMods, owner: &str, key: &str) -> Result> { + let warning = format!("{owner}:warning"); + let objective = format!("{owner}:phase"); + let mut rows = vec![]; + for difficulty in 0..=3 { + let mut w = World::new( + &"review:retained".into(), + &pilot(difficulty), + &active.registry, + )?; + w.next_entity = 95000 + difficulty as u64; + let mut high_warnings = vec![]; + while high_warnings.len() < 2 { + assert!(w.tick < 100); + w.step(input(), &active.registry, &mut active.scripts)?; + if w.mod_sounds.iter().any(|s| s.0 == warning) { + high_warnings.push(w.tick); + } + w.projectiles.retain(|p| !p.hostile); + } + let entity = w.enemies[0].entity; + let max_hp = w.enemies[0].health; + w.enemies[0].health = max_hp / 2; + // Exercise the upgrade path for a saved pre-latch live entity as well. + if difficulty == 0 { + active.scripts.states.get_mut(key).unwrap()["units"][entity.to_string()] + .as_object_mut() + .unwrap() + .remove("phase"); + } + let mut new_warning = 0; + let mut release = 0; + for offset in 0..=14 { + w.step(input(), &active.registry, &mut active.scripts)?; + let warnings = w.mod_sounds.iter().filter(|s| s.0 == warning).count(); + let shots = w + .projectiles + .iter() + .filter(|p| p.hostile && p.age == 0) + .count(); + if offset == 0 { + assert_eq!(warnings, 1); + new_warning = w.tick; + assert_eq!(w.objectives.get(&objective), Some(&2)); + } else { + assert_eq!(warnings, 0); + } + if offset < 14 { + assert_eq!(shots, 0, "new health phase fired before full warning"); + } else { + assert_eq!(shots, if owner.ends_with('3') { 3 } else { 4 }); + release = w.tick; + } + w.projectiles.retain(|p| !p.hostile); + } + assert_eq!(release - new_warning, 14); + println!( + "{owner} actual difficulty{difficulty}: health transition after high warning{}; new warning{new_warning} release{release}, full14ticks", + high_warnings[1] + ); + rows.push(json!({"difficulty":difficulty,"actual_spawn_health":max_hp,"high_phase_warnings":high_warnings,"phase2_warning":new_warning,"phase2_release":release,"new_phase_warning_ticks":release-new_warning,"old_phase_latch_absent":difficulty==0})); + } + Ok(rows) +} +fn main() -> Result<()> { + let package = PathBuf::from(std::env::args().nth(1).expect("pass own package")); + let package = package.canonicalize()?; + let owner = package.file_name().unwrap().to_str().unwrap(); + let target = owner.contains("mission"); + let hook = if target { + "scripts/target.rhai" + } else { + "scripts/ai.rhai" + }; + let key = format!("{owner}/{hook}"); + let unit = format!("{owner}:{}", if target { "target" } else { "unit" }); + let objective = format!( + "{owner}:{}", + if target { + "targets_destroyed" + } else { + "defeated" + } + ); + let root = package.parent().unwrap().parent().unwrap(); + let cat = Catalog::open(&root.join("data"))?; + let mut base = Registry::base(&cat)?; + let content: ContentPack = serde_json::from_value( + json!({"missions":[{"id":"review:retained","name":"Test-only retained collision fixture","duration":10000,"auto_complete":false,"spawns":[{"tick":0,"enemy":unit,"x":88,"y":if target{60}else{24}}]}],"weapons":[{"id":"review:lethal","name":"Test-only stationary lethal projectile","damage":10000,"speed":0,"cooldown":1,"target":"all","behavior":"straight"}]}), + )?; + base.apply(content, "review")?; + let discovery = modding::discover(&root.join("mods")); + let mut enabled = BTreeSet::new(); + closure(&discovery, owner, &mut enabled); + let enabled = enabled.into_iter().collect::>(); + let mut a = ActiveMods::build(&base, &discovery, &enabled, Some(&cat))?; + let reward = a.registry.enemies[&unit.as_str().into()].reward; + let phase_transitions = if target { + vec![] + } else { + phase_warnings(&mut a, owner, &key)? + }; + let mut max_bytes = 0; + for life in 0..1205u64 { + let id = if life >= 1200 { 10000 } else { 10000 + life }; + let world = kill(&mut a, &unit, id, &objective, reward, target, 2)?; + let commands = + a.scripts + .invoke(owner, hook, "on_death", &event(id, 0, &objective, 1), 303)?; + assert!(commands.is_empty(), "duplicate death emitted commands"); + assert_eq!(world.player.credits, 10000 + reward); + max_bytes = max_bytes.max(guard(&a, &key)); + if life % 137 == 0 { + restore(&mut a, &discovery, &enabled)?; + } + if life % 128 == 0 || life == 1204 { + println!( + "{owner} retained native kills={}; statebytes={} retired={}", + life + 1, + guard(&a, &key), + a.scripts.states[&key]["dead"].as_object().unwrap().len() + ); + } + } + // Earlier pre-FIFO checkpoints migrate within the real engine limits. This + // includes a death flag for the entity killed before queued on_spawn executes. + let old_dead = (0..960) + .map(|n| (format!("{}", 60000 + n), json!(true))) + .collect::>(); + a.scripts + .states + .insert(key.clone(), json!({"dead":old_dead,"units":{}})); + restore(&mut a, &discovery, &enabled)?; + kill(&mut a, &unit, 60001, &objective, reward, target, 2)?; + assert_eq!(a.scripts.states[&key]["dead"]["60001"], json!(true)); + guard(&a, &key); + let migrated_state_bytes = serde_json::to_vec(&a.scripts.states[&key])?.len(); + for difficulty in 0..=3 { + kill( + &mut a, + &unit, + 70000 + difficulty as u64, + &objective, + reward, + target, + difficulty, + )?; + guard(&a, &key); + } + // Two live same-definition entities keep separate state; abandoned-world + // entity clocks are discarded at the next actual spawn instead of accumulating. + let mut abandoned_peak = 0; + if !target { + for life in 0..1205u64 { + let mut w = World::new(&"review:retained".into(), &pilot(2), &a.registry)?; + w.next_entity = 80000 + life; + w.step(input(), &a.registry, &mut a.scripts)?; + assert_eq!(w.enemies.len(), 1); + assert_eq!( + a.scripts.states[&key]["units"].as_object().unwrap().len(), + 1 + ); + abandoned_peak = abandoned_peak.max(serde_json::to_vec(&a.scripts.states[&key])?.len()); + } + let mut e1 = event(90000, 240, &objective, 0); + e1["entities"] = json!([{"entity":90000,"health":240}]); + a.scripts.invoke(owner, hook, "on_spawn", &e1, 303)?; + for _ in 0..20 { + a.scripts.invoke(owner, hook, "on_tick", &e1, 303)?; + } + let age = a.scripts.states[&key]["units"]["90000"]["age"].clone(); + let mut e2 = event(90001, 240, &objective, 0); + e2["entities"] = json!([{"entity":90000,"health":240},{"entity":90001,"health":240}]); + a.scripts.invoke(owner, hook, "on_spawn", &e2, 303)?; + assert_eq!(a.scripts.states[&key]["units"]["90000"]["age"], age); + assert_eq!(a.scripts.states[&key]["units"]["90001"]["age"], 0); + } + let report = json!({"fixture":"actual bundled Catalog; test-only stationary lethal projectile; native World collision, death, reward and retained ScriptRuntime","owner":owner,"unit":unit,"actual_native_collision_lives":1205,"distinct_ids":1200,"reused_id_lives":5,"checkpoint_json_roundtrips":9,"maximum_death_state_bytes":max_bytes,"actual_phase_transition_warnings":phase_transitions,"retired_guard_capacity":128,"duplicate_callback_commands":0,"reward_per_life":reward,"target_shield_restore":if target {12}else{0},"legacy_960_guard_migration":true,"migration_state_bytes":migrated_state_bytes,"difficulty_kills":[0,1,2,3],"abandoned_live_replays":if target {0}else{1205},"maximum_abandoned_state_bytes":abandoned_peak,"two_live_clocks_retained":!target,"enabled":enabled,"package_pins_at_execution":a.pins,"scope":"callback lifecycle/bounded-state proof, not mission combat balance"}); + std::fs::write( + package.join("validation/retained-state.json"), + serde_json::to_vec_pretty(&report)?, + )?; + println!( + "{owner}: all actual collision/reward, migration, deduplication, retained-state and abandoned-live checks passed" + ); + Ok(()) +} diff --git a/mods/iron_coast_stage2_mission_4/validation/validate.rs b/mods/iron_coast_stage2_mission_4/validation/validate.rs new file mode 100644 index 00000000..a770b0d6 --- /dev/null +++ b/mods/iron_coast_stage2_mission_4/validation/validate.rs @@ -0,0 +1,491 @@ +//! Original-catalog standalone mission acceptance. Starter guns only; no package/pilot changes. +use raptor_replica::{ + assets::{Catalog, Sprite, TRANSPARENT}, + audio::Mixer, + content::{self, ContentPack, Registry}, + modding::{self, ActiveMods, ScriptRuntime}, + persistence::Pilot, + render::{Canvas, draw_world_lightning_arcs, nearest}, + simulation::{Input, Outcome, World}, + sound::SoundBank, +}; +use serde_json::json; +use std::{ + collections::{BTreeMap, BTreeSet}, + io::Write, + path::{Path, PathBuf}, +}; +fn namespaces(stage: u32) -> (String, String) { + ( + format!("iron_coast_stage2_mission_{stage}"), + format!("iron_coast_stage2_boss_{stage}"), + ) +} +fn active(root: &Path, stage: u32) -> ActiveMods { + let catalog = Catalog::open(root.join("data")).unwrap(); + let base = Registry::base(&catalog).unwrap(); + let (owner, boss) = namespaces(stage); + let ids = vec![ + owner, + boss, + "iron_coast_stage2_interceptor".into(), + if stage == 3 { + "iron_coast_stage2_siege".into() + } else { + "iron_coast_stage2_skimmer".into() + }, + "iron_coast_stage2_music".into(), + ]; + let discovery = modding::discover(&root.join("mods")); + let active = ActiveMods::build(&base, &discovery, &ids, Some(&catalog)).unwrap(); + assert_eq!(active.pins.len(), 5); + active +} +fn pilot(stage: u32, shield: u32, credits: u32, difficulty: u32) -> Pilot { + let mut pilot = Pilot::default(); + pilot.mission = format!("iron_coast_stage2_mission_{stage}:mission_0{stage}") + .as_str() + .into(); + pilot.difficulty = difficulty; + pilot.credits = credits; + pilot.inventory.insert("base:energy".into(), shield); + pilot +} +fn input(world: &World, registry: &Registry) -> Input { + let prefix = format!("{}:", world.mission.0.split_once(':').unwrap().0); + let target = world + .enemies + .iter() + .filter(|e| e.health > 0 && e.y >= 0 && e.y < 145) + .min_by_key(|e| { + let def = ®istry.enemies[&e.definition]; + ( + if e.definition.0.starts_with(&prefix) { + 0 + } else if def.boss { + 1 + } else if def.ground { + 2 + } else { + 3 + }, + e.entity, + ) + }); + let goal = target + .map(|e| e.x + e.width / 2 - 16) + .unwrap_or(144) + .clamp(5, 282); + Input { + fire: true, + absolute: Some([world.player.x + (goal - world.player.x).clamp(-4, 4), 160]), + ..Input::default() + } +} +fn observe( + world: &World, + seen: &mut BTreeSet, + moving: &mut BTreeSet, + positions: &mut BTreeMap, +) { + for e in &world.enemies { + if e.definition.0.starts_with("base:enemy_") { + seen.insert(e.definition.0.clone()); + if let Some(prior) = positions.insert(e.entity, (e.x, e.y)) { + if prior != (e.x, e.y) { + moving.insert(e.definition.0.clone()); + } + } + } + } +} +fn restored_runtime(root: &Path, active: &ActiveMods) -> ScriptRuntime { + let discovery = modding::discover(&root.join("mods")); + let mut result = ScriptRuntime::new(); + for pin in &active.pins { + let package = &discovery.mods[&pin.id]; + for script in &package.manifest.scripts { + result + .add( + &pin.id, + script, + &std::fs::read_to_string(package.root.join(script)).unwrap(), + ) + .unwrap(); + } + } + result.restore(active.scripts.checkpoints()); + result +} +fn fit(sprite: &Sprite, width: usize, height: usize) -> Sprite { + let mut out = Sprite::blank(width, height); + for y in 0..height { + for x in 0..width { + out.pixels[y * width + x] = sprite.pixels + [(y * sprite.height / height) * sprite.width + x * sprite.width / width]; + } + } + out +} +fn load( + catalog: &Catalog, + registry: &Registry, + id: &str, + art: &content::Art, + frame: u32, + hd: bool, + scale: usize, +) -> Sprite { + let owner = ®istry.owners[&id.into()]; + let raw = content::art_sprite_variant(catalog, registry, owner, art, frame, hd).unwrap(); + let result = fit( + &raw, + art.logical_width as usize * scale, + art.logical_height as usize * scale, + ); + assert!( + result + .pixels + .iter() + .all(|p| *p < 240 || *p == TRANSPARENT || art.asset.is_some()) + ); + result +} +fn ppm(path: &Path, canvas: &Canvas, palette: &[[u8; 3]; 256]) { + let mut file = std::fs::File::create(path).unwrap(); + write!( + file, + "P6\n{} {}\n255\n", + canvas.image.width, canvas.image.height + ) + .unwrap(); + for p in &canvas.image.pixels { + let rgb = if *p == TRANSPARENT { + [0, 0, 0] + } else { + palette[*p as usize] + }; + file.write_all(&rgb).unwrap(); + } +} +fn capture(root: &Path, stage: u32, world: &World, registry: &Registry) { + let catalog = Catalog::open(root.join("data")).unwrap(); + let palette = catalog.palette().unwrap(); + let mission = ®istry.missions[&world.mission]; + let rows = mission.layout.len() / mission.columns as usize; + let offset = 200 - rows as i32 * 32 + world.scroll; + let out = root + .parent() + .unwrap() + .join(".reference/iron-coast-3-stage2/captures"); + std::fs::create_dir_all(&out).unwrap(); + for (name, scale, hd) in [("sd", 1, false), ("hd", 4, true)] { + let mut canvas = Canvas::new(scale); + canvas.clear(0); + for (row, tiles) in mission.layout.chunks(mission.columns as usize).enumerate() { + let y = offset + row as i32 * 32; + if y <= -32 || y >= 200 { + continue; + } + for (col, index) in tiles.iter().enumerate() { + let tile = &mission.tiles[*index]; + let sprite = load( + &catalog, + registry, + &world.mission.0, + &tile.art, + 0, + hd, + scale, + ); + canvas.blit( + &sprite, + (16 + col as i32 * 32) * scale as i32, + y * scale as i32, + ); + } + } + for ground in [true, false] { + for enemy in &world.enemies { + let def = ®istry.enemies[&enemy.definition]; + if def.ground != ground || enemy.health <= 0 { + continue; + } + if let Some(art) = &def.art { + let sprite = load( + &catalog, + registry, + &enemy.definition.0, + art, + enemy.art_frame, + hd, + scale, + ); + canvas.blit(&sprite, enemy.x * scale as i32, enemy.y * scale as i32); + } + } + } + for shot in &world.projectiles { + if let Some(art) = registry.weapons[&shot.weapon].art.as_ref() { + let sprite = load(&catalog, registry, &shot.weapon.0, art, shot.age, hd, scale); + canvas.blit(&sprite, shot.x * scale as i32, shot.y * scale as i32); + } + } + let player = catalog + .sprite(catalog.id("LPLAYER_PIC").unwrap() + world.player.bank as u32) + .unwrap(); + canvas.blit( + &nearest(&player, scale), + world.player.x * scale as i32, + world.player.y * scale as i32, + ); + draw_world_lightning_arcs(&mut canvas, world, &palette, 1.0); + ppm( + &out.join(format!("stage{stage}-tick{}-{name}.ppm", world.tick)), + &canvas, + &palette, + ); + } +} +fn main() { + let root = PathBuf::from(std::env::args().nth(1).expect("pass RustRaptor root")); + let stage: u32 = std::env::args().nth(2).unwrap().parse().unwrap(); + let (owner, boss) = namespaces(stage); + let mission = format!("{owner}:mission_0{stage}"); + let target = format!("{owner}:target"); + let target_counter = format!("{owner}:targets_destroyed"); + let boss_counter = format!("{boss}:defeated"); + let bonus = if stage == 3 { 14500 } else { 16500 }; + let arrival = if stage == 3 { 2100 } else { 2250 }; + let mut active = active(&root, stage); + let mut reports = vec![]; + // The exact shared dependencies have real scripts/artwork/music, no fixture replacements. + for (shield, credits, difficulty) in [ + (75, 10_000, 0), + (75, 10_000, 1), + (75, 10_000, 2), + (75, 10_000, 3), + (100, 0, 2), + ] { + let pilot = pilot(stage, shield, credits, difficulty); + let mut world = World::new(&mission.as_str().into(), &pilot, &active.registry).unwrap(); + let mut seen = BTreeSet::new(); + let mut moving = BTreeSet::new(); + let mut positions = BTreeMap::new(); + let mut min_shield = shield as i32; + let mut sounds = BTreeSet::new(); + let mut continuation = None; + let mut detail_captures = BTreeSet::new(); + for _ in 0..4500 { + let commands = input(&world, &active.registry); + world + .step(commands, &active.registry, &mut active.scripts) + .unwrap(); + min_shield = min_shield.min(world.player.shield); + observe(&world, &mut seen, &mut moving, &mut positions); + sounds.extend(world.mod_sounds.iter().map(|s| s.0.clone())); + if difficulty == 2 + && shield == 75 + && [300, 1200, arrival + 75, arrival + 120].contains(&world.tick) + { + capture(&root, stage, &world, &active.registry); + } + if difficulty == 2 && shield == 75 { + let phase = world + .objectives + .get(&format!("{boss}:phase")) + .copied() + .unwrap_or(0); + for cue in ["warning", "shot"] { + if world + .mod_sounds + .iter() + .any(|s| s.0 == format!("{boss}:{cue}")) + && detail_captures.insert(format!("{cue}-{phase}")) + { + capture(&root, stage, &world, &active.registry); + } + } + } + if world.tick == 1200 { + continuation = Some((world.clone(), restored_runtime(&root, &active))); + } else if let Some((ref mut other, ref mut scripts)) = continuation { + other.step(commands, &active.registry, scripts).unwrap(); + assert_eq!(world.digest(), other.digest()); + assert_eq!(world.objectives, other.objectives); + assert_eq!(active.scripts.checkpoints(), scripts.checkpoints()); + } + if world.outcome != Outcome::Playing { + break; + } + } + assert_eq!( + world.outcome, + Outcome::Complete, + "difficulty{difficulty} tick{} shield{} {:?}", + world.tick, + world.player.shield, + world.objectives + ); + assert!(world.tick >= arrival && world.tick <= 3300); + assert_eq!(world.objectives[&target_counter], 4); + assert_eq!(world.objectives[&boss_counter], 1); + assert_eq!(world.objectives[&format!("{owner}:complete")], 1); + assert_eq!(world.objectives[&format!("{owner}:debrief")], 1); + assert!(!seen.is_empty()); + assert_eq!( + seen, moving, + "all genuine classic definitions must be observed moving" + ); + assert!(sounds.contains(&format!("{owner}:victory"))); + assert!(sounds.contains(&format!("{boss}:warning"))); + let end = world.player.credits; + world + .step(Input::default(), &active.registry, &mut active.scripts) + .unwrap(); + assert_eq!(world.player.credits, end); + reports.push(json!({"initial_shield":shield,"initial_credits":credits,"difficulty":difficulty,"tick":world.tick,"shield":world.player.shield,"minimum_shield":min_shield,"credits":end,"native_seen_and_moving":seen,"objectives":world.objectives,"mod_sound_cues":sounds})); + println!( + "stage{stage} difficulty{difficulty} initial{shield}/{credits}: win tick{} shield{} min{min_shield} credits{end}", + world.tick, world.player.shield + ); + } + // Deliberately refrain from shooting. Health controlled ONLY to inspect survivors after duration. + let mut held = World::new( + &mission.as_str().into(), + &pilot(stage, 75, 10_000, 2), + &active.registry, + ) + .unwrap(); + for _ in 0..4500 { + held.player.shield = 100; + held.step( + Input { + absolute: Some([5, 160]), + ..Input::default() + }, + &active.registry, + &mut active.scripts, + ) + .unwrap(); + if held.tick == 1800 { + capture(&root, stage, &held, &active.registry); + } + } + assert_eq!(held.outcome, Outcome::Playing); + let targets = held + .enemies + .iter() + .filter(|e| e.definition.0 == target && e.health > 0) + .collect::>(); + assert_eq!(targets.len(), 4); + assert!( + targets + .iter() + .all(|e| e.y == 60 && e.x >= 16 && e.x + e.width <= 304) + ); + let bosses = held + .enemies + .iter() + .filter(|e| e.definition.0 == format!("{boss}:unit") && e.health > 0) + .collect::>(); + assert_eq!(bosses.len(), 1); + assert_eq!(bosses[0].y, 24); + assert_eq!(held.objectives[&target_counter], 0); + assert_eq!(held.objectives[&boss_counter], 0); + // Mission start resets stale state; a full inventory has 18 unarmed synthetic test items. + let items = (0..18) + .map(|n| json!({"id":format!("fixture:slot_{n}"),"name":format!("Slot{n}"),"price":0})) + .collect::>(); + let pack: ContentPack = serde_json::from_value(json!({"items":items})).unwrap(); + active.registry.apply(pack, "fixture").unwrap(); + let mut full = pilot(stage, 75, 10_000, 2); + for n in 0..18 { + full.inventory + .insert(format!("fixture:slot_{n}").as_str().into(), 1); + } + assert_eq!(full.inventory_slots(), 20); + let before = full.inventory.clone(); + let mut flight = World::new(&mission.as_str().into(), &full, &active.registry).unwrap(); + flight + .step(Input::default(), &active.registry, &mut active.scripts) + .unwrap(); + assert_eq!(flight.player.inventory, before); + assert_eq!(flight.objectives[&target_counter], 0); + assert_eq!(flight.objectives[&boss_counter], 0); + for _ in 0..4500 { + flight + .step( + input(&flight, &active.registry), + &active.registry, + &mut active.scripts, + ) + .unwrap(); + if flight.outcome != Outcome::Playing { + break; + } + } + assert_eq!(flight.outcome, Outcome::Complete); + assert_eq!(flight.player.inventory.len(), 20); + for (id, count) in before { + if id.0 != "base:energy" { + assert_eq!(flight.player.inventory.get(&id), Some(&count)); + } + } + let full_report = json!({"slots":20,"tick":flight.tick,"shield":flight.player.shield,"credits":flight.player.credits,"equipment_preserved":true}); + // Controlled callback gating: boss alone, then only3targets cannot complete; time cannot bypass. + let mut gate = World::new(&mission.as_str().into(), &full, &active.registry).unwrap(); + gate.step(Input::default(), &active.registry, &mut active.scripts) + .unwrap(); + gate.tick = arrival + 200; + gate.spawn_cursor = active.registry.missions[&mission.as_str().into()] + .spawns + .len(); + gate.objectives.insert(boss_counter.clone(), 1); + gate.objectives.insert(target_counter.clone(), 3); + gate.step(Input::default(), &active.registry, &mut active.scripts) + .unwrap(); + assert_eq!(gate.outcome, Outcome::Playing); + assert_eq!(gate.player.credits, 10_000); + gate.objectives.insert(target_counter.clone(), 4); + gate.step(Input::default(), &active.registry, &mut active.scripts) + .unwrap(); + assert_eq!(gate.outcome, Outcome::Complete); + assert_eq!(gate.player.credits, 10_000 + bonus); + gate.step(Input::default(), &active.registry, &mut active.scripts) + .unwrap(); + assert_eq!(gate.player.credits, 10_000 + bonus); + // Real resolver+native mixer for every authored cue; bounded unsigned decoded PCM and stereo output. + let catalog = Catalog::open(root.join("data")).unwrap(); + let instruments = catalog.named("GENMIDI_OP2").unwrap(); + let mut bank = SoundBank::default(); + let mut audio = vec![]; + for (id, definition) in &active.registry.sounds { + if !id.0.starts_with(&owner) && !id.0.starts_with(&boss) { + continue; + } + let sample = bank.mod_sample(&active.registry, id).unwrap(); + assert_eq!(sample.rate, 22050); + assert!(sample.data.iter().any(|s| *s != 128)); + let mut mixer = Mixer::new(44100, &instruments).unwrap(); + mixer.fx_volume = 127; + bank.queue_mod(&active.registry, &mut mixer, id).unwrap(); + let mut pcm = vec![0; 44100 * 2]; + mixer.mix(&mut pcm); + assert!(pcm.iter().any(|v| *v != 0)); + let peak = pcm.iter().map(|v| (*v as i32).abs()).max().unwrap(); + assert!(peak < 32767); + audio.push(json!({"id":id.0,"file":definition.file,"decoded_samples":sample.data.len(),"mixed_stereo_peak":peak})); + } + let report = json!({"mission":mission,"playthroughs":reports,"full_inventory":full_report,"retention":{"tick":4500,"targets":4,"boss":1,"outcome":"playing","shield_controlled_only_here":true},"deterministic_resume_from_tick":1200,"gated_completion_and_once_bonus":true,"audio":audio,"capture_scope":"actual Rust PNG palette conversion and indexed Canvas from real World states; desktop Host live screenshots handled independently"}); + std::fs::write( + root.join("mods") + .join(owner) + .join("validation/acceptance.json"), + serde_json::to_string_pretty(&report).unwrap() + "\n", + ) + .unwrap(); + println!( + "retention4500/restart/full20/once-bonus/deterministic saved state+RNG/mixed WAVs: passed" + ); +} diff --git a/mods/iron_coast_stage2_mission_4/validation/visual-review.json b/mods/iron_coast_stage2_mission_4/validation/visual-review.json new file mode 100644 index 00000000..fda1036c --- /dev/null +++ b/mods/iron_coast_stage2_mission_4/validation/visual-review.json @@ -0,0 +1,48 @@ +{ + "scope": "Actual Rust PNG decoder + ordinary palette conversion + logical fitting + indexed Canvas + real World snapshots. Full desktop Host scene independent.", + "pages": { + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/captures/stage4-tick1200-hd.ppm": "1062b1d7806231dae60720c30e49989378e05f317075cdc021d23a694ebd578d", + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/captures/stage4-tick1200-sd.ppm": "ed14038a0873979393182258a099967cf02d0b1db72b630bb6d6d5954c2e0f10", + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/captures/stage4-tick1800-hd.ppm": "9c4b1d44061aa5574b766370b83ed16c3a045b1ac0538d86268a707bf9c08c4d", + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/captures/stage4-tick1800-sd.ppm": "02299971ba9aeb83c62c79fd4924ff4c79acbd4ab976cedae10f1adc4668ad85", + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/captures/stage4-tick2299-hd.ppm": "bfa16a8217e097cd6891062c0d246a160c3db3f27c140840abbc9c6d539f8506", + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/captures/stage4-tick2299-sd.ppm": "3e589a709fadf02b57a66c8215f6b336bd3a7245a3e13546bfa0cb3e7c12761a", + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/captures/stage4-tick2313-hd.ppm": "5e97ecf9dc86b264fde3f7f23727e4d1751d73124cdfa162ab0b39b6e742597f", + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/captures/stage4-tick2313-sd.ppm": "b992a3af5e7198c5cf5b14a694197b91e06a2dc417540c7880746b54b1b52b12", + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/captures/stage4-tick2325-hd.ppm": "91b68c0a4a02b9027fcf2aebf4f185f444d00c422e940f4a1714079ee411a92b", + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/captures/stage4-tick2325-sd.ppm": "7d0020dff6c4896ad36490ad1c3d80e75d4149a978396aa3f41af88660ef8c1f", + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/captures/stage4-tick2370-hd.ppm": "d9387a256bc5b6072b448dd974a118803b15d1ec1fadf2e9d09258e95dbad608", + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/captures/stage4-tick2370-sd.ppm": "92393944ae63719fae8a2eebfa1d091a44409ed9fb4e75c766f0971827cd950a", + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/captures/stage4-tick2427-hd.ppm": "3d9062a83b5ee297bab45df00e5a456da82a6520ed6b35709ffbebf2e141381e", + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/captures/stage4-tick2427-sd.ppm": "c2b71e7808893f27808527515bc3ad7b97b0819f892203d4187d9e530d1247ad", + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/captures/stage4-tick2441-hd.ppm": "c04befcaa1483c665403cf1a18a7c6864e386f4160a4c090ab94b3b0603a2c3a", + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/captures/stage4-tick2441-sd.ppm": "3f9800b7533ce7c412291cf99eead11871c2f287706991586794f81024a861db", + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/captures/stage4-tick300-hd.ppm": "a61050e7a44c03a05401308059b5c30663c9bdbc2940ee4e1cecb6eaf715baed", + "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/captures/stage4-tick300-sd.ppm": "9b6ed2a54b8b7b72c63c84b0a4550baea29e38f38e1e21b1b128f76e1843f030" + }, + "visual_review": { + "terrain": "Paired SD1x/HD4x scenes retain contiguous terrain across horizontal tiles and reflected rows, dark central flight corridor, intact drainage/dam walls and no tile seams seen.", + "targets": "All four required target silhouettes individually readable with transparent padding, consistent32x32 alignment; narrow pair touches collision canvas boundaries but visible artwork remains separate.", + "boss": "Distinct tracked refinery crawler / teal hydraulic mobile dam hull, bilateral structure and stable104x72/64 canvases; high-detail source and pixel SD share alignment.", + "telegraph": "Both phase warning arcs inspected in actual Rust views; cosmetic blue strokes end before damaging volley. Bright amber source v2 retains11SD foreground pixels and223peak for visible projectiles.", + "limitations": "This static indexed compositor does not claim desktop HUD/interpolation/shadow/audio callback screenshots; root independently covers real Host scenes." + }, + "reviewed_pages": [ + "world-scenes.png", + "stage4-target-warning-shot.png" + ], + "gallery_paths_outside_package": true, + "bounded_phase_recheck": { + "gallery": "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-3-stage2/bounded-render-review/stage4-current-rows.png", + "gallery_sha256": "39608462eb8340717a29b70e964b3451af19676c834c0a5ffee5aab346441398", + "reviewed_current_rows": [ + 300, + 1800, + 2427, + 2441 + ], + "views": "Paired actual SD1x and HD4x; gallery SD enlarged nearest for inspection, raw PPMs retained.", + "decision": "Accepted. Required targets and boss remain aligned/readable, warning arcs and bright shell pixels visible, terrain joins intact. Historical original visual report preserved in full-folder pre-correction archive.", + "limits": "Static indexed World views; no new live Host/cinematic assertion." + } +} diff --git a/mods/iron_coast_stage2_mission_5/README.md b/mods/iron_coast_stage2_mission_5/README.md new file mode 100644 index 00000000..eb81bd3c --- /dev/null +++ b/mods/iron_coast_stage2_mission_5/README.md @@ -0,0 +1,74 @@ +# Iron Coast II: Black Tide — Skybreaker Arsenal + +Standalone mission `iron_coast_stage2_mission_5:mission_05` and single-sortie campaign +`iron_coast_stage2_mission_5:campaign`. The optional `iron_coast_stage2_campaign` assembly +places it in the complete Black Tide route; no cross-mission override is needed. +Enable this package in **Mods**. Dependency selection adds its own boss, +`iron_coast_stage2_music`, `iron_coast_stage2_siege` and +`iron_coast_stage2_interceptor`, all at version 1.x. The package never changes +pilot equipment or grants a premium weapon. + +Use normal controls: **Ctrl** fires, **Space** drops a carried bomb, +**Alt/Shift** cycles selectable weapons. The forward guns hit both required +stations and the boss. Optional Railburst/Depth Charge equipment follows its +own shop price and inventory rules; neither is required by this mission. + +Destroy all 2 persistent ground targets, then destroy Skybreaker. Target +deaths award 900 credits and restore 8 shield each. +The boss awards 6,000; confirmed objectives pay a once-per-sortie +26,000-credit completion bonus. Mid-sortie field support restores 15 shield +at tick 1400 and another 15 on boss arrival. Shields remain capped by the engine. +A target killed after the boss still completes the objective. Escaped ordinary +wave enemies do not block progression. The 3,500-tick duration is descriptive; +there is no automatic success, timer failure or despawn of required targets. +The reflected 18-row terrain period repeats 16 times: 288 rows / 9,216 logical scroll +pixels, covering prolonged objective fights beyond the nominal duration. + +The boss enters at tick 2340. Three outer-lane industrial +hazard shells have an audible warning 24 ticks beforehand; the center stays +clear of those fixed hazards. Difficulty 2 is the intended challenge. Boss +health follows original easier-difficulty scaling, while its second attack +phase uses half of its actual per-instance starting health. + +Native classic definitions are referenced directly, retaining their original +movement: `base:enemy_0_12`, `base:enemy_0_13`, `base:enemy_0_21`, `base:enemy_0_22`, `base:enemy_1_25`, `base:enemy_1_26`. New shared enemies are normal nonlegacy mods. Decorative +runway/docks, cranes, rocks and molten metal are scenery; required targets are +separate destroyable units and are always reachable near the top of the screen. + +Artwork includes 162 joined terrain tiles in both 32px SD and 128px HD, plus a +320×200 /1280×800 briefing. A complete generated square master is resized as one +canvas before cropping. Whole-canvas vertical reflection makes the repeating +scroll join meet exactly on its boundary row. Texture orientation repeats and +HD is more detailed than SD; no claim of unique terrain over the entire mission +or exact zero luminance difference is made. Required station/projectile art +references the original catalog. Runtime palette conversion preserves alpha +and uses ordinary colors rather than reserved cycling colors. + +[`provenance.json`](provenance.json), `prompts/`, unchanged `sources/raw-v1.png`, +[`art-qa.json`](art-qa.json) and [`audio-recipe.json`](audio-recipe.json) track +masters and recipes. Run `python3 mods/iron_coast_stage2_mission_5/tools/build_assets.py` +from RustRaptor; Pillow and bundled `data/misc/PALETTE_DAT` are required. No +external game-data fallback is used. WAVs are original deterministic 22050Hz +PCM16 mono synthesized chirps/noise with faded zero endpoints. + +Validation from RustRaptor: + +```sh +CARGO_TARGET_DIR=target cargo test --locked --manifest-path mods/iron_coast_stage2_boss_5/validation/Cargo.toml --lib +CARGO_TARGET_DIR=target cargo run --release --locked --manifest-path mods/iron_coast_stage2_boss_5/validation/Cargo.toml +cargo run --release --locked --no-default-features -- --data data --mods mods --validate-mods iron_coast_stage2_mission_5,iron_coast_stage2_boss_5,iron_coast_stage2_music,iron_coast_stage2_siege,iron_coast_stage2_interceptor +``` + +The portable callback/boss simulation tests require no original catalog. The +real acceptance runner uses bundled original data and writes only isolated +`.reference/iron-coast-stage2-56-acceptance/` evidence. It checks all difficulties, +registered 75-shield / 10,000-credit and default 100-shield / zero-credit pilots, +full 20 inventory slots and four stacked shield reserves, failure/restart reset, +actual classic enemy movement, complete/debrief flags, single rewards, +identical per-step replay digests and unshot targets still present at tick 5700. +The controlled registered difficulty 2 run completes at tick 2638 +(113.06s), shield 100, credits 48,610, +using forward guns only and at most 4 horizontal pixels per tick. This is an +aim/hold-bottom controller, not a guarantee for all play styles. Both indexed +modes and all eight package/boss cues were decoded through the actual Rust +asset loader/mixer. Live 1080p capture belongs to the aggregate release check. diff --git a/mods/iron_coast_stage2_mission_5/art-preview.png b/mods/iron_coast_stage2_mission_5/art-preview.png new file mode 100644 index 00000000..6cb6993c Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art-preview.png differ diff --git a/mods/iron_coast_stage2_mission_5/art-qa.json b/mods/iron_coast_stage2_mission_5/art-qa.json new file mode 100644 index 00000000..8da3dce0 --- /dev/null +++ b/mods/iron_coast_stage2_mission_5/art-qa.json @@ -0,0 +1,4594 @@ +{ + "files": { + "briefing-hd.png": { + "opaque_bounds": [ + 0, + 0, + 1280, + 800 + ], + "sha256": "10cceecd7160eed8fc15d58c815fe688b64386c62b7d679f500ef2449b65c3df", + "size": [ + 1280, + 800 + ], + "transparent_pixels": 0 + }, + "briefing-sd.png": { + "opaque_bounds": [ + 0, + 0, + 320, + 200 + ], + "sha256": "dba8b8ed08b6c979264d6eec8421823e011a53cc501c8f9b328a16d157a12a32", + "size": [ + 320, + 200 + ], + "transparent_pixels": 0 + }, + "tile-000-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "2610047d4fda24ecd53eb633b6871675945ecc13513589a72ed9c0b50cb208bb", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-000-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "411fb10d4f2719013f85bf2d9504660527a2ecd737ee9d3b5402317745771c2f", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-001-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "36cc3fdcfb2338eb1aeb96d40a60f88f14d001b7b5202ff4c1f4e94c8e1a0675", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-001-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "f0cda461a2d8f05161992d3644e6773f9b1d58c9e8527067eaa7fda968cc5a22", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-002-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "dcc1f651b83be42dd1fe8c34b6c365f6c0d6f0637749a8185d7370a4016ffe26", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-002-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "2edb8fb23b4889484a6438a96e17fe63f7b4fe0947d024324517d60310ead900", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-003-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "8aeefaa4da87fafd96c6a463362aad8aae6edb154a7b2174c3e06868da244b3e", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-003-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "852e979a9df0ab846f0b14024df62ae40d8660f09f39acf6f18bf6c92884f3e9", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-004-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "303adc9b8074aeb92de28cdec7d92c369ab969f64e43b1332640b721cb22a6b6", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-004-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "d7407e94c88196ba01e7059783e8f66fd1156e58373edd67f56c881f16daab69", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-005-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "8a8bb57e1434f62ebb179ba16e5cd3c5144f2acc7e730b286ca83ae296d2a815", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-005-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "be0905a8a95cc988f54a28d58d98014d958386050a401c156987744784d61a60", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-006-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "e4724a1df46f321e71d93cffa07018aea63063701c8976b590a3f604ac9084b6", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-006-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "2fa84c3f1eeec0813f00b7bcaaf1cff8e6c84727b24103d6ed15f564cce52333", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-007-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "a5cdb407080cc0d4524ac0e52cbf012bde6e0f7841da3722edc9673e804ebf39", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-007-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "16930e2f46a57a24347103c79e56b8ad0dd3c92a7d149d82a3abf66f462969d8", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-008-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "31d1aeae8d3866d783d667110c85c87a498d51c1298bcd49bce9b4720cb19ec7", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-008-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "fdcb6f92b030615341cdd8ff10c293b51ffbbd528714653112a8263e778cc361", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-009-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "c415c931009f1733380ca32ccc075899576d63c9b548465a7f8a217fbd664cc6", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-009-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "a6ba302feb5a2c8a6856520e6365049a2f3c7a57abf49ca7caeb98a6fc2154b3", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-010-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "b6d8648f3c9190beb7cfff7b1603b42749762d1844ee465de898e8dccdf6d71e", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-010-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "ccac1c666a97b32097c102d5520c07ea0a575e6644b7e0e7e5565b72fe2b12ba", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-011-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "fe1f56c2c431278a29cc5569c617ee0616459055a9f50c087f3905870d44be82", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-011-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "9615029d82322ce8c97b7461ffd6f4ea7efeff040a2fb784fd510983f16fe262", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-012-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "e9f3d051cc544f3fb48a335cd465285fd0fdebb27e00e15456f6add542ac79fb", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-012-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "75faaa5909d12e3b750f932558db36d1332052786eaddbb4296b72607af60fb7", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-013-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "f20ca6719f6dc67aaf2d69f1e3d37cf3aa5a0252079260850e5515677f80dd66", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-013-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "12c950289931238ea27ba18813d8cb95cc3d5ea6c442ed19ade0ef28a48819c2", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-014-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "6f37ec229251653c91f5623e5d1aa0009d2a426fd35a60545984ed80c773a6c4", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-014-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "3b04b8130067692b2f34e94c5cdd4d54de86f2572c7c48387d4041ebb2f2afcb", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-015-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "7d5fe5329692c9e9c7566d921c470f98b6a0167c3da16026e1ad73743e47d45f", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-015-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "2e5adfd28fdd28059a77b4b39fbe675292c66072c2a19c1efa99a092140f886d", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-016-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "e31c83ff9647b85991c51056a3db6b6effa458a32c9eefc7089db531e6fdf3b5", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-016-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "d569c4df216ff33e5deda18d844bd0ab630016e771669e5cbc09825271dc2f31", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-017-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "3afdf88a8e6445fdab8b74fde135511d03d062327801cb9bc78afb285fb14468", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-017-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "bf968cc3c5f007f6bc18512538e4ddac025bab42c5187202292d120368ee097d", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-018-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "5f61cee3f222d3d133b2954f50346e4e6347b94c12bd6965f59b6e3e1e601848", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-018-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "f6642f6ac160a09e862e9b66cdfbb4a775444eafebf78311c33fc6def6e27378", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-019-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "307b266afd4a16cf922f16b30be6dac9a1698dea957493c0b054fe3982538042", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-019-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "938addf3510c081193e92aabc8ff88f6dd9798872a527ec0a15f12ea7e86acf6", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-020-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "8d9c086e98e0c5f473fa4398713ccd22b68b5027e6002ff95a68e0a2da5fbaf6", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-020-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "92425d79d50c5b8fc56286a3595303c6525ff6994f4304a23957269984e48fa8", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-021-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "9198eb6165f9b05265e18cde0380382d128c3f514f5e5cc9f5724c75c9d75faf", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-021-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "f1382fbf335703c71f8582534cded8a3c339fd5bb6203e774c21c4b18b264c44", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-022-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "2ed007284079dbcc3a2f09575e5a95df878655a03a2734bbd1fb6a1864fb9f7c", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-022-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "15cee4c64863b8dfbc6ebedf83a35043017e3d5d20264c90ad480d4415d6580c", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-023-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "cd3fd3c0c05abc39f25d95a4fd5a2ee17c8784781b301fb682c9471f85d91707", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-023-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "4b74d1058197524dde492e464e0d16d619800e8dba40f78285b724c434a0a879", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-024-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "c4832508e38f5919d824b8f7d6df1a4420dd5bde4631e2b3cdac2ba7142117f7", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-024-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "74e63770aa6f82e25009c59c316e79aed831bb9b26d30ef2b12f039289a8be4f", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-025-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "f35d357950b8186c457dc504ed6a598f5aef1db7f4031d3436c7b38854913e92", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-025-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "0a86c53c245ddba070a77e45bc8a873172feb973dff07f1bf05aa974fd3051d6", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-026-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "d45e875f22d93c257aa916322ca7d53174ed34b968172b21e7c91257d226c7a1", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-026-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "4bf712d41e3792b0d7375991f974df34e4747da65040bc6d500ba2a83c692cf1", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-027-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "ff14f3ae4f5709c85fbf26eb5d0003003acba0538b3754c9247f15862748d181", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-027-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "e6166c42e8076470d91d169a3246548c4cd911800513be04c33e6a8d171ec4e0", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-028-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "580b4717bfaf0494c67a04939803cbc4535b272e6dc00a5081289ae2546df9e8", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-028-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "4a931ce49f5147fc42bc3f1a5a5c928e94ec8f92a7f0c519ea1fbe1f1bf9a017", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-029-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "194b3bb8bcc1fdc4e97126ff14e56007a0b8ae1485e0051b5ad21a6bc1600ffa", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-029-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "c13ab5037c8688c317df13256507bfbc098622559b3efe7e0fbd6e34431ccf80", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-030-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "872c133747d8a6d54c6c6452a89fc316bf2e1fba376ee408149b1f83fc6b5828", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-030-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "25154cdf7fbefee3e26005165306272588965bb1edbe583e502079bcbd29f294", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-031-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "73618637adddf780b8bd31e40731bdb96af15d25ba748365eb7b19b765dfe7e0", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-031-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "3b687d08cd47bee74afa363670302fa61a25bc446e9d87f1f35e747f7c755a9e", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-032-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "6fc9fc4bc80cb051ab3b29b4f2604bcf4c356dd37a9a22ce1bb5022439840c9f", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-032-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "ee977869890b707b12e3631a3ebb6a3136e770582b69d043c482eabfaa421d2d", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-033-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "1aa154414a1f5462926808bbae60ca1195967455149cd1e7a80d96b4e3c83a04", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-033-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "a17a432315cf1fd9cc9432f40c4174b2fee8211bd6415017363b28d3100871d9", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-034-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "7d262510db2a1231d5d77750df2d78f3f151d6867921e8b40998bad29ca3b46a", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-034-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "d4e261e08951e229d1ee822b829723167b596500441a4f96d0a6643ca63636f3", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-035-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "f6915556810d2492dac8994c1142374fdee2e9295e2b26597ac6226120c56d4c", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-035-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "5f14e68e424ec35a04e8c802ef2806ae1a3dba2d141664d126e07f4fed2147ce", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-036-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "93a1f2f2b1d6b6898f914afa39bd82d327eb4b87116dd465af48c335a6e133c4", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-036-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "d9a800b0b90e366f363a5721399a22f6c38bc6eff5a2880d803bf1cbdd367541", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-037-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "17608b218b3dae9c63e36f6584a4f3d4059f581cabf8c15047148277a8fe72df", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-037-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "9401148b9fab113119f8f1e7aa4391d47f4c9882eb3f760f11602e7e1560c27b", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-038-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "88063275e902e63b460bc6da034391fb8400fdd603d042e1de132f99c96c19c7", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-038-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "1c65c05194e1a9a7e0b649fec19546e0e0f45ad63689eb75b1865ca5af19c6ed", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-039-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "542d362b12fa717abc43bedcbf9c33f3e107f5888d756b12ef753ca8b8808627", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-039-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "112e06e2446a1801b1c58a38fe4f4748b7547ab150fed1e0ccf886860ea84c65", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-040-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "34197ba63f7acaf02dc0481492146cfa0e9503c7539ef0e59799345e1b7f17cd", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-040-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "c28527e5ef8fb1c1d2e9c7be6c9e7845b6edff50fd6563a266233f390b0aacb1", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-041-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "32b18548874d5918b2b9b7fed060097276d87c5429b70bfda873b71f368b6153", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-041-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "877b08bb9ae025c93b90c797b57cee7b53678fdfc0935e3fefd64358c17a5cf3", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-042-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "05dc39bc27a1963a93ca7759753b96c13c9927c33fb88c516d61fd87cbbdd466", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-042-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "46be5c031a2226ec6e2df60cbb578538f633984844150ac8b00ae3c4690af818", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-043-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "273f524f67cbf7a2fedfd4082e7f4ad7bd5316c3e1f19c85c90f8531f59f7ed0", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-043-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "3d9c732a9142d1eafb7aad605067b86e0ef70345fd76e8ae776675853dcd2e52", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-044-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "adc56ee8c13aa18150cfb74164056305da2b3be7479e468ec612fac1eab2bd34", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-044-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "50082ffd5c56b18ac34380a7dc5fa0048cb81ee8dbc1b771888433a29a28da2d", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-045-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "d2aeb353caac84da11304ff85ff0b9950ef231641949680b950a735463708ba0", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-045-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "a6a7a48f30a39df58b7b54f7908b9b7bc5e3a6d344e407981ab4b34c6218cafc", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-046-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "8bdc7bd5fe9b49c3e0100853c0ca3865bd59a6df2edc6781fcb5ae6e87fd05fe", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-046-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "24b289c13786a9ecf5578d1d811ae7a0ffa60b4f4818689d1f68a93d0ad2428a", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-047-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "4f9bf541a395436ab1bd37247633305d27592f15b232de22318f25d604bd56d5", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-047-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "662f51114eeb70594c08d50928813d23227a555bebd21f82b50019eb7eac1926", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-048-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "a4ef5ebede3b21da0ca9263efd348a88925ec09a384318453a62f6c390742ac4", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-048-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "438e0daa8a175321574505e9cdd7c16ea96074ec6db0b46b2f6519cc997efb90", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-049-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "8fd4886860d4f82779113347a4721e1d9b70f41fff826cb5eb68177dc49098c1", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-049-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "eb935afcd377bdf60fee6e0bdca1eb49749fa10bb6ea96ed1874454fe193d56b", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-050-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "5ac0d15f7233e9095d0a0e97960fe1515b15a83705f3961dc4df6270140b22a6", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-050-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "8856f24d4edcdc89513ff4ae29a62c7491a85018dee7bfdbb4af69ce6cbb42c6", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-051-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "99c00b7b02011985af58eedba2fe6a40e883eae679695bca5abcc98fce7b3135", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-051-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "d10f061361ac445bc7503c622466f52e6680f70b7503def4b1b91ea2a75e30eb", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-052-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "2713eb73e64573c5a5af56feef70508ba46be610e5d334dff16fbd6859b9118b", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-052-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "e856046ba88b24b7fd918236f11558a53365573e74e99cde4d7dc02412b6efb9", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-053-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "c100cd790fad4d144eea62cc274fb03659148d224e0da696c570cb4070f6b2b2", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-053-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "3864e585e02308ee672afbf3198439629c34f065cc49edee81cbbd62c66f3196", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-054-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "dd43734d00b4c634899548f5cf10c7b5b9fb84abdb247cbc82bfae4e99e17788", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-054-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "66bb2538c1139cb05fdc3a090097f6ca1f91addc3f0931712fade47cb085a0c4", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-055-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "cbab3d1e7e356334f936d8cb80f4e65f828bde88d5d8434dddf9b5ec33f6abb8", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-055-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "fa7badaef405bccaa60a39e80bb9038197c1488ed818913b6286a9bea385497f", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-056-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "d2a69031cbbec7fe4306d4d5e99bf8a27481dda70f1801bb8b19d851782cda63", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-056-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "3ed42a21408b14af6ab2b808f6a8dc7548ca1ab6bdbe89f1bc14ef111fdd276e", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-057-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "e77064623b402a1219fb084a4cfad104364dbc746a4c1fdb1e194e6584548edf", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-057-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "a1708ae915a41b0d97621dfd6e3e7fe6dadef680b3e6d9c5c1cc676fadfc1509", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-058-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "102e217deab88c53b8622b30c808c06c573a06447dfb50ca9129c4d8ac1de5fc", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-058-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "d97057d7ac673f577a6ede6497985d48570e3040220dca9d88e2a06b79dee91f", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-059-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "632fca9c749a64a3deb2ee87834409b0e1bb42178fec2c4c1b51cb51f77040f9", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-059-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "73b0fdfaa9a3f2eed327e9126a8f2e2da3d3b353d95b746bc7a0880b8d08884b", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-060-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "df0bb74b16eceaf0d66d4347bef91afa8d917c6bbab01ffa91e493e0a6123c50", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-060-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "4ffa28f7956328e1be78b93c1d1eda6ddca41cf79901a7fe1960be7c73c17e0b", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-061-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "d1e70df8362b1c32e8fec965ec9510e889723cc2bf0ac20866bb44b92eaf7554", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-061-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "fd0a45ef234af401da8bac202a0980775ea933d3fae9edbe890ec471a442066e", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-062-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "4a13c9c692ebd9f49d33b72d2cab06b00cd24463ab67318e9babe318e611d089", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-062-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "9c29c6536cbec4d100e77f15db1c66413e03e5eaaa27aeb8c33f88d56d2c85ff", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-063-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "243262bbfed665ce2b81b4337d22616de9056bbb66005d50a112b891fba42410", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-063-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "451be47937e925817f74008c190606e573633ffbe60492c9932433fa71ecb50b", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-064-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "a4529932e3b810c4503f0d3e39dbf77c50e0a9bda4e68260ba9ad2169acee2da", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-064-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "f210d75ab6fd88c00343b46222ed50ad74298d9b09025853385f1b0a9d6bc392", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-065-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "93e691359950b078600a09fef6187e82bf66a458cd082dc4e58973e02a986650", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-065-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "97a28ee0f2ce88a8b334ffe86bf078f791a91620d370596ca43a91db56c744aa", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-066-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "8871e305cabb1e1d3b35d376e967f21a8e69e64721f4376e86d8947985d0a7d5", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-066-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "57c0f23dfc947df25cf0f2533329a8a15885da32498488f0d70e6bc4cd140227", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-067-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "8ee6c8881238ec8991bc8dbc4391c6fc2a80ed414b8420557dff789cde6722b8", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-067-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "4dba45f562a41d02a43c4c17ca244e32abbe72934d15a8bcfc9de0eb9e8c36cd", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-068-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "a9cd23c4e39991b3ccd097e4d97f7625ccd3025399815fe00db57c7abd3221be", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-068-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "fee9091bd8d209583fc9ad8eafa1a7f24ec2aa60a242b29ea99cdb85a40a5380", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-069-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "e75ff006ef9712887e4610fe8aa9ff5af66067fdc064ea35a206be046939aec1", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-069-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "0ecaf88b4b385c6b315683c7ddeffde40e4b1225553fce65947c6e0c99ad52c6", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-070-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "a193739c0729e24389aaf054e8d4416f58fd52759ab84978c9d2c26ae84515fe", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-070-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "a9a9a056639e7dee139eb96f1fc860a406f6e63cb2bec681c719460b34a58b92", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-071-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "bb24ee332b6b6e2351efbe7407b5fc65df9381ca359c5645bdce9454a54aee0b", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-071-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "f5d6e2ca9c5b7acee2fa553ffb32012c4bf7030339021274dac51c4582f1aa90", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-072-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "095cee9a9259979c4a6c52072dc55c0a2bbf4ea9abe6e1c8b9924adadc7c8377", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-072-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "7fd2de58bfdede39be6af4cf78c9fe367cbd722f3a427db21667bfad40676d52", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-073-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "f8770274a5bab8f65843c8c628cfbfa558c089204b5975b45c665eed4e87b4e6", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-073-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "2c6bacb8f185b0be82bf666435f48443f99f76bccdd86623d0899176c9ab5af7", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-074-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "d946be6d46d02718338b68b0f9f7f197907dbf604a425250026f43985948ae2e", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-074-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "35a9032b344c6a497fcabd01d918b59edbd7f647a934c7b5ddb67daa918c00aa", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-075-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "05eb5246957de827c146d01b712c2a3cf0abacca481bd7ea446a3107ce911ff4", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-075-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "f171d01e4d22f68678fe74363606407d8e6282f8d6aaea3662e3adb573055012", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-076-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "1396632d26a836fc611efd61a22348bd7650e29c87ece44323379923c36b8448", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-076-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "710b69cd3ec10fcfd46153ca68dea77dcd8791fc4642affbaf353d391d82686f", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-077-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "0e6ad4f2530b47b91ee27d65bab387d0a7d28100109bc653899746ddcb84c718", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-077-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "ac006df0cc5848f7bd75c47e966b7776b857d373777832f78b905d9c5799bf8f", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-078-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "32d869fd24391c87edfdb21a00a63468060b4a1d48f5cb32f19f36885b5ed801", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-078-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "1994ea8266f256ca203d28ee968192d394510db4c0720a300b92dabc76c61d35", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-079-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "5486be2ea80fb10b3b0e7b2681f897b67f5a4a57fcbef47f42914d885bb77a99", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-079-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "17605710894ef2ac2ec72a0d25daa26f42b4c9b110ffe1793f94dacd96e73d72", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-080-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "b45676d1749a4375a7285507026258999c914968bad65e2d35a78e2c06317f24", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-080-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "1f020b51fe120ef601c0f3d1b884694658ecb623b120d9c1e98011a514afc54c", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-081-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "6fa780c64fd7228a2ff7e06fe6c7dcce77fae985b4a1e3d401f9f8c5f303c5ff", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-081-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "7167cea5342acaff3e22e70064b0b766fc6190bdd8cdc2030f3c4923a9a60f70", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-082-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "cde8a7a8f7cdd34a33dbfff80d58c0cc9e8756517fcbeaaf9b881471762efe2f", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-082-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "9ac4c3555223549bb7da8da15c0ea1b4c19279e29ffd26fb433e0606b4f5c699", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-083-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "d0d1dd67bf9c995c6748d1a327072f33e6c25239c93f3a6eb15d43a970b4da29", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-083-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "cc8cf39088835fe08ed37c1886acef094c31559732181cca2019ca8f230b2406", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-084-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "00dda2018f2fc862adeaee63df07909e518f362c06bc6d163ff9c2b3072b1169", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-084-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "e3e2a11a236c25baaa64c221850240fe3cb39e128df9187ba26a753beaea9b98", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-085-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "c4b678a0008f01a519f76ff85e1ecb5f4c3ca73c4b5a26150e79a3a6776b8eb9", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-085-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "963c46ae693674aac5207689e18f5f94dec3a5d524a8787802033f957b34e761", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-086-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "34605f9b5f2dad09bd9bd92e44d678e0b3dcad468e89434416fcfc9a02481097", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-086-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "32d3aec6339774b8b39674537e8ea7b85746d1b12b7d03768d495d0965528056", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-087-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "f5df71dcc6dc7484d36db2dc633415c0f232d58cc0e48f69ffbecbc8c7c245bc", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-087-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "5b5edccc59e6f1678e069e3360ac07230a09eceede35bbb86de2e6b6e33810e9", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-088-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "fa93475ff5eb63533fef14d9a5e046ae22b98dea341ddad485650e6b3b081f0c", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-088-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "158d2e7495f2f69c55bcb432bd71304697617ed5d65e4e92ef123e87926b25e6", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-089-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "a571d6abac4dac05a1717198075108844a60f3e9bab6bcbad52ba7b6c6797a7b", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-089-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "78f45ffb1af0e56d3e461aa21b068b53b72981efe53246945af306c774728a11", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-090-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "f9ff290edccd7dd9173e2818f8fa9502d27d031a69e2026c7115ccbc16116a38", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-090-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "7effe3c29209f334db55529f110f8b99db1f27f31e2b2115c90df0710dc2d8aa", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-091-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "17f43b0a32a7a2b8419873368fd755685af95bac170013ac11b698ec7402d27b", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-091-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "334cd64665580544d45286a8fec62d9f4f0cd4851f44b662124ee46d5a14c87c", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-092-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "4ca6c2674682642169eb9d9de10d2823baec9ddea441677077d2d51f80685862", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-092-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "37d52bd30f68f2cca193eb8d61e9afae51b38002726238def20ddd0c148a79ac", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-093-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "0ce64592ef318324b461816dc5eacbc30626a01807daacfd4f3bf7fe9e8121c8", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-093-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "cade35943a636b86ee9ab565706e1ba23fce287ad187fb2d47b02e0bbae4ca09", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-094-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "9194b75ef8847b322c4cbb4e1ceb2ae1ed1b47d585f67ec19032eba6fc0b0adf", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-094-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "ceadf94f9e45be7f8086d80ee9c2a173c2a4fba0b02431eb3c3ffed1c5f1b846", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-095-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "3bf9c342c1df0b8eb2a47361dd6fc86bcfe7e01df3955f5599e06da130a58a7d", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-095-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "e6d6a59465870bea24037b6a9f122b9b0e8d7ccaf02a7334ebb825ff6d3a329d", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-096-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "a9bae1427ef12a4138074f3eb9e09db63dbb891a83eea286231977176e3a223d", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-096-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "f019d7b8410cda4cb8c288948d020ab881fdadea0b09efdeb42faf05a96b1487", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-097-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "83d1b4bda2c44543bf0e22aed61207709bac9ff83cc5e0c9af7da842398ece6e", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-097-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "78358801a34a65fc9692c04efa1e8393974f2b4c949e6c4c56bab052253393b9", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-098-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "073336d74d38cf929a4dadf9b1549d8c1fdae00106dc6f17f91d4991acf40835", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-098-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "ca9290ea01f2245fa840fcbde531001b272a855ef66a83fa767b45a917be93a8", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-099-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "7ff3842b66a09513e2d1478348df54136afe497f2bce3b6c910776ba0199937f", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-099-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "8fc8f1b02e51676984bfcc0f17b552e572684f76db87ae42f1ef822688710efa", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-100-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "081fbcb1ae65ad070836f7e21040a3ce1e401b1e2d55fbb09d2f386614ea12cf", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-100-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "883cda4bb633207f5687229c492bade522bcd24fac7e9ceb84707ef2252897db", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-101-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "0b80375b156bdc0a2c2985a0dacea5bf170a4ccd0a7d27a9145a7e7bb970a2cc", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-101-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "ada5f6f2c37216479ff1921dc678dc650a4143028c0f997aa7685647d1dc184e", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-102-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "1c87c0f7e4f413b6236c96a2d6b851d248b435d4c57a1b4cc95a0fe1082ddd00", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-102-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "1f90dc81781de0326c333086b08ec3086f21b16f9bd5d35fc6e3b8763ff3482a", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-103-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "2ad077784e68f6a0e35ac7fd750ac88c434aa77f4977a2222582b83feddab967", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-103-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "1d409eef80bb66698c7bdc4a09b464d0815d58bf9d8811f603b42c092206f467", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-104-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "3296a76b11b3d45cce20a2094e90e381042f959686fab567169195b053d9e031", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-104-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "dd6d6e569bdbb9b4859c6bbc7e5c68d14c9e4019adfa3571329f0ece90c8df30", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-105-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "e94605ac17dd4102ce9d57ab461d8ece9e17268ade3d13b720acd2778feed828", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-105-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "06f59c6837edc9dd22440332b72913183cd7298f5c851a10a3445d7fa684833d", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-106-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "6d18b95a580749708b8df1c854d7c8ae93f9c9d5d9698e1c487bafd9dfb2f7a3", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-106-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "cd361b6c7d822c3e2c0212070a66f9a6d7880fc45e238c90db8cd6e36eef6db6", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-107-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "aadc7434cf90f01254b13640f9f5b156630abf17176b054ab73e034a863236df", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-107-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "e2418f1cc98d9a179062b373a9b26b66bc0565cc742615827e68af08b6922c28", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-108-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "e2690cab31a87dd8ecf8d70a830f0d5716a04b6e5cc3dfdb157186a1c3c71ff2", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-108-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "73b9638b788a3922245fc88fae3a8b52d922e3848fcba3c6351d11487345bce3", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-109-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "e672adbb85a49feff8fc428dc01159840dc3e53d5b0644c68fc97b71b6abaac9", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-109-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "82ae04e75010cbe70c8166844566ee3749a4dcee17b0cc7e62133a7d9c8eb29b", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-110-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "61d0ee2266a0e3008157aaafdf99782a85c6b126b1a831fae875f04f6f1da8a5", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-110-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "5289c470738ff068231bfc888a13152f6aadafc48d43305e972094c2627b29c5", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-111-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "ce680205d5518818488d05a68bd6b9778359f2ad1bece84f16b333d3bc528297", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-111-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "8ac6c26bed990b935e8181ec3f971751a1437e0140f033d6783aacc6f275af35", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-112-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "2a9acc9fd463530a20280d1d41d48b5101a452676ca3c2c51e385c2785af777b", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-112-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "aea648c0a01871e1bd7060f1a1bd4dcc5e374a5ada89a769258f66b6c1e994ef", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-113-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "2fbf40e64c209537799d4777a18ab580fe078c5b026b88386197784ccd75cad3", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-113-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "c4d2180a8767886986c2203a4af922002addde6d5ebb677d74b37150e901a2ec", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-114-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "6a18c868e04ac52c21f7c1554aaa3ec36faa023b9e056a66ba091b3006206e55", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-114-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "ebd694cd4db8a127cc57c5c688a864c33349fe47220447455d51afc207afd06c", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-115-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "869d959c50186caa387752468a8eddd07536f07aba1dc518dfbefd17cd4a479d", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-115-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "ce0f55ca0b54a0762ef5bf644d1459925b02e4da211320e28556999ec8b50728", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-116-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "c87be7837f17a037eb89992b907cf04c1cf2eb98cf066f9159d83427a75dbe1e", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-116-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "5ac7eef7406c7c488b110af9ea9e080f869479288f4d727e03d27c17228b8405", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-117-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "718f2e6005bc0705db131184e94b21a0325cf98d206c323f04c8e4d80c0618b2", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-117-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "91ada851f7fde9df23b9f6817c31dea2ea52721a73ac1178fe0da7fa5d84ceff", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-118-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "728e029c3f1c054e900fbf0abf3dcf65946230c9f8399902874eee84b1980d5d", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-118-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "30b3c7605891e8b41bf9cef568cc826ff5c59b307329d0466e4fe4c5eeb439d5", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-119-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "750c8670fcff8427aabbdfc3d41277c947881b25d8b5f842e9c1c723f428b3c8", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-119-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "a7b4979309145227d2649e3d1ae6530cb31e14795ce0dfb841b08b8f33953837", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-120-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "36409a6162212cdb02b43d5d976f6d27380559da8013dfd022985e38b994cb52", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-120-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "027a84c35fb3e71cf9f7ee201a70139011014b34cadd5cff02f16e213601f020", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-121-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "240738a42d648abaec4245e5cf31861e59b907c1f61e441479f62d5f49e24f23", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-121-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "6bed195ed582dc7e200343df87e9255d19fcdd27bc093a609525013aecee7a0f", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-122-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "dae0b0b57684b09946e6060c8384663e06b967f32b4e59d5eb1849d060971b30", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-122-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "0e73ed001c58117baef1bc420108baa9f2fc81d13d9dac98da99ba7c15996c0d", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-123-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "b467c5f57b2ee4bb92731c8ab11e3d2e6d90837d86ee930bb0573d8a7a833f1e", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-123-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "7c5b055b358b45fcb40bfbd10170d2dc36b272e471087125b376d50fa5496785", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-124-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "ec4c8b159e43353008e85fc9d46b6a6a83f3d066348f8b3875c9da4165e15b32", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-124-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "77cdc6cfa953fa4488ae777b944bb3eae3532a7c74c58af86f276df8fad27248", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-125-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "12eb47e65ee10538c292c7621777508af6ad967acbb31c92a4721ed270da1cc8", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-125-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "d4549eac88417baf09ba4ff720618352ce78d78f04b7e2ee354f094aad57aff6", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-126-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "fc7b500c6a02c556d2bb2bc641de3fc9f12122161dfb9027f5f4e0380851b3d7", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-126-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "726db37fbafe02ea344d634ee6e44156a7c65f4ee47843e2279011fbbf1a7ce6", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-127-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "15e4ed58b2602739b59080a03296b4cd30584705a1841cc949f09b5d96f4d63f", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-127-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "9b087a93b587ee5d425b48c037d4e8b055e89465f523d5a47007aa3644d91500", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-128-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "df4e34c7fd3b1fdbebb7c1fc9e249d30f690c71554ca4a419f0d89c26df8824b", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-128-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "da1cb2cd51ebe34adc6cf34701a965e2996f8c93208c05710ed158ccd9627ba5", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-129-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "16ea9680c255581a34637dd99b77124326adae5fd8dec88fc63563ee929859c1", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-129-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "8074ef2aa56b752f8889969505a21251a494bd192f30c18d464b9a006d840952", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-130-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "a853d73b6a83c8c428074a64948f575b892fd8a5f0d141565ce8f481929ea237", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-130-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "4c3ebc86885e898f8f290aec38a2408937200bbbf93e809d01b2c3d7eff1593f", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-131-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "1c37b48a847c33bf62d015f117672f2f779903f593e8c557425407b3c032b566", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-131-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "d49d19b3adea49a41423dcacaef77cdb6f5597125000a2c25460badeeef15a2c", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-132-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "577c4a46a28f9887f49bdb46fdf3f8329bf715865365066a489829118404afff", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-132-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "e152ece5e1620fb7f7c1ac0372ec18fe9bcb9a7882665c2c8f4dc7ff6a8ea288", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-133-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "8c403a277aa6cb06843203628008ea2f56f86b7ea8b910dd15208e60fdbb1132", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-133-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "6fb5d611504773aa824556d4c7bc1dfcdcf1172b3c8836fa8ca179fccb42cb40", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-134-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "c50c3912576324e4d99aaec0359570fa4263cbe34f4016512ee5503a6e2d3bce", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-134-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "4287f4b6a2eeec0705719254a4ad74fa30c88ddb998a278a151dbef2bab189d0", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-135-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "b62339f01e070200053812597d454dfe412c175d7d02613194c5b8b96f04dc6e", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-135-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "4cdf9aefd4a97eb872d909dc51d8af84ac2ca7dba3bc0badbcb76b31e182f017", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-136-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "114d41492be4392bce97af31e6316032fd234a28346f4c15ca288ee5d87b1970", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-136-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "229e8ac16d6d1d7559f475a9434573cbfdd3c15ec22248c0e850de99def4cd0f", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-137-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "d6bc6a6948f29c508352aa03b1de70d249bbb96656551897cb2f00db31d86367", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-137-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "c0cf689dd3cacdbdda82cd712464da8cb8aab6a6a0ef027adc8e6a6d1a3c256c", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-138-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "bb484575204ef09ba0fea284101e05a5c760b65a4168420081a5052dcaf2abec", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-138-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "6f0bd7a959bdb752dd2cb638bc6369cbdc468281fa25545b21e59b7481d5cfb5", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-139-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "2ff8e3a972eafe4317e7eb85c1ead3b0ee0ab81a2096ccd63ebe396199d6804a", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-139-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "81614ae59df8d183883f02af9b3eabda96f8ad91e5b926806f085e0b6c58115b", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-140-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "a49e25614fc263aab3ddcba17fc1d4078a5eefacb1e5c381312c77b2ee10d09d", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-140-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "332c5c9130c1feacc3f2154def827dcdc09b99fe18ab1d037ddb5d32edb195ab", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-141-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "77184740071f0929f85b41fa3c150df48d7a17d345ccab2a88a314d4c72b368e", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-141-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "0a2bda1391ec3831085f862fbb3ffb51256347a521e9ce51fd641f0186c0f123", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-142-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "744544509b7236101c5bf07eaf4238e09facbdabc12c33663eafd6f324a4961e", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-142-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "35d86fb899223c08bd58c5b074cae569686759daefa892df0edf1808ddccde1c", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-143-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "cba868f97c217fb3565fdac531f0a4cc238f92a4db0c45f81fb1bc7b6acffc5c", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-143-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "6c203a929eeb7bedaf2ab44788a5e2dea87892f057b06ae5b5b3063ad403548b", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-144-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "44dacd7a76dbb88ee94c9ae5bbb74eed94301e135fcaca4d041564fbca761ac1", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-144-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "3bdc901722525230d72d46c7ab3c08203d0b28e934643cb8731c330ea77b081a", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-145-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "e5470e561b407f0cfec3e46ed5c8f634441ca2c16c6b8a0559641208c3eeac50", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-145-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "4a93ebee224be6b05bb15cec67f1a8c182c6142e765a391fd40d5a175470e082", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-146-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "3ccb77e1125f795385dbd60daca6f4168fc8e37e1834b049e2d76c8c698bd068", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-146-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "52f69e38decb132c178b6c15a80c5c9f9b443e08cb4c6b08d53bfabca5536474", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-147-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "ece4740d15f217755bd8c78e56824134e3d1d35173dad9bbb86f0eb9884b4ff2", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-147-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "b7d2af154d1e11bc421d32b90c104816d90624f1ee3e1e13546876536b334149", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-148-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "082481322eb5ea4b5f2bdbf4fea96631d1d4d3d3328b9228842d85d894cfc8ae", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-148-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "23c380f4c0ad9a8e22b4912df4502b7cca1cb83b542221c9503d4a5cbd43b43f", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-149-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "3377f416efefa4dc99f0152eda370cf4727ca8d3ab2035c59ce1489179974ed0", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-149-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "73267f604acdae697c8910ce36ed8940bafd28be19d2869505c72d345d66d9a0", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-150-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "cfe0e5615c5d1f85133fc637490b880066e9e14eb0f9fa76697587ff911885fc", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-150-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "a9a41e03053dce4740be457dffcf2c634ae8f14e677ea2cf3eed03dbbeb74f9b", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-151-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "4da71fe3f5dad57994cd362c367daff7a26e68cf3157d1e964e15f8d2e003c77", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-151-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "248fd677f5ae50b1e171a8aace594cbfcbfca57161eda53632bb2eca8c1b983d", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-152-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "973e412071181b1dab106aea06536421518ff7412cb330fdce2ca980f3972d26", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-152-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "658092ab5fc3c758e2ff05cb40ee7369d3a66c2f6308450da834898a92ea18c0", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-153-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "139efdedf74dcda47b4636edbbcc700ddedd8283a5e86cd10fb42a0e2e3e455b", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-153-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "e8d22a7fcbdd705cbae9622a7ca2ca43cb22ad0d6c4b2ff09126da74eeee163b", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-154-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "42cf0068cb522495730f00a6ccbc73693932fffebdd1a0e00a3694da4fb0cdde", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-154-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "5934b45ae7c90ba33cd5f924ff1a19d794e7318a148dce0c6e7cafbcdd0cc1c0", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-155-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "02f2e97259d13fcad160d80839744ed32eb53a199d21360abcc762fac8354201", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-155-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "31fee577973f26c45638dd3133be6ea0452069da1ac65a176e920da483531e67", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-156-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "5956005a7e9e7fbffe271b6ac952d5075c04c7375eb72485b34ed802e3d8b81f", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-156-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "b6e6d23bb95b3508919d328bf5e894f67de66a98ac67de25a8f628202b4f5f93", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-157-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "4e92079595d25f5f635e03bc0337e77801f7238b9890a85a619cc4b32c69f7c5", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-157-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "2d923de5d0f1791e1282f7379f86ea268e0338a32fe64494411842050853a19c", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-158-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "569122cacb1c3b56868f4cf0b3ca1322ca173b5c76b727aaedbe6d1aa45ad5cf", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-158-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "de7c0f97aed25c922716940be6a8b62f59b2d95cc8e44e0d90515f5d587bd730", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-159-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "998069ed6479cc841de5a457b45f0760f0f311a47680384203e2fbc561a14696", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-159-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "bf5b267f23a3c3048f43bcfb5d39c3ed0568f530de1904ce6bebd23854d68bdc", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-160-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "8b66621cae56d6d08280b57b0d68f1739dafc863896eee6c5e465adfdc692f10", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-160-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "f22495159a9099b6c3170f7cdac55757175eb721f518a3c87f6d984fc0b7bb3a", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + }, + "tile-161-hd.png": { + "opaque_bounds": [ + 0, + 0, + 128, + 128 + ], + "sha256": "bc897f5b0c6fda9020d07c052f8601bc6706138598d24bedaeb25341e10bbdae", + "size": [ + 128, + 128 + ], + "transparent_pixels": 0 + }, + "tile-161-sd.png": { + "opaque_bounds": [ + 0, + 0, + 32, + 32 + ], + "sha256": "53d4c9071d2309a77240d2e05247330b5f88ed87cabb5767897e24419e430c65", + "size": [ + 32, + 32 + ], + "transparent_pixels": 0 + } + }, + "ordinary_palette": { + "ordinary_indices": [ + 0, + 239 + ], + "sha256": "1cf6adb926d1dee1888b3e3d33b51a7049b3e5eb5f90a3067ef71c8970547204", + "source": "PALETTE_DAT" + }, + "raw_sha256": "fe28de73c1c4d1e0348d9d482cd01114d26bdb068485487e1ff9cef9aaa1a229", + "raw_size": [ + 1254, + 1254 + ], + "recipe": { + "columns": 9, + "hd_scale": 4, + "logical_tile": [ + 32, + 32 + ], + "master_tiles": 81, + "method": "Whole square master resized into one joined288px SD/1152px HD canvas; SD ordinary-palette quantization once; whole master vertical reflection creates exact adjacent edge rows, then32/128px tiles are cropped. Repeats have identical joining pixel rows, not an inferred zero luma seam.", + "unique_tiles": 162 + }, + "recipe_sha256": "3482e6671b8d6ec63d0f8c1df15fd288ae5d9af8fab19f11f9932ea0837a4f77", + "visual_status": "Both generated masters and derivedSD/HD reviewed; actual Rust indexed SD/HD outputs inspected independently in isolated reference evidence. No live-scene/1080p claim." +} diff --git a/mods/iron_coast_stage2_mission_5/art/briefing-hd.png b/mods/iron_coast_stage2_mission_5/art/briefing-hd.png new file mode 100644 index 00000000..1aa402b5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/briefing-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/briefing-sd.png b/mods/iron_coast_stage2_mission_5/art/briefing-sd.png new file mode 100644 index 00000000..bc505191 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/briefing-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-000-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-000-hd.png new file mode 100644 index 00000000..2ea982ad Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-000-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-000-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-000-sd.png new file mode 100644 index 00000000..60678a96 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-000-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-001-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-001-hd.png new file mode 100644 index 00000000..8d9d071f Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-001-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-001-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-001-sd.png new file mode 100644 index 00000000..7df4d797 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-001-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-002-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-002-hd.png new file mode 100644 index 00000000..385955d3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-002-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-002-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-002-sd.png new file mode 100644 index 00000000..368ff794 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-002-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-003-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-003-hd.png new file mode 100644 index 00000000..91f49d74 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-003-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-003-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-003-sd.png new file mode 100644 index 00000000..474c41ac Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-003-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-004-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-004-hd.png new file mode 100644 index 00000000..9fe4ae97 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-004-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-004-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-004-sd.png new file mode 100644 index 00000000..9486491b Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-004-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-005-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-005-hd.png new file mode 100644 index 00000000..c9e4abfb Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-005-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-005-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-005-sd.png new file mode 100644 index 00000000..eac8485f Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-005-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-006-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-006-hd.png new file mode 100644 index 00000000..730e5df9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-006-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-006-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-006-sd.png new file mode 100644 index 00000000..3bad57c0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-006-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-007-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-007-hd.png new file mode 100644 index 00000000..37ee7c58 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-007-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-007-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-007-sd.png new file mode 100644 index 00000000..8954be02 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-007-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-008-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-008-hd.png new file mode 100644 index 00000000..b3368d5e Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-008-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-008-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-008-sd.png new file mode 100644 index 00000000..fa66d144 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-008-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-009-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-009-hd.png new file mode 100644 index 00000000..3dddc6e3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-009-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-009-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-009-sd.png new file mode 100644 index 00000000..ecf74580 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-009-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-010-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-010-hd.png new file mode 100644 index 00000000..9fd3009e Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-010-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-010-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-010-sd.png new file mode 100644 index 00000000..e90209ed Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-010-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-011-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-011-hd.png new file mode 100644 index 00000000..a148e8a3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-011-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-011-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-011-sd.png new file mode 100644 index 00000000..baad19ac Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-011-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-012-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-012-hd.png new file mode 100644 index 00000000..170c1303 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-012-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-012-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-012-sd.png new file mode 100644 index 00000000..5d7e1c3e Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-012-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-013-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-013-hd.png new file mode 100644 index 00000000..afbd3adc Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-013-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-013-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-013-sd.png new file mode 100644 index 00000000..bf5d9a63 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-013-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-014-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-014-hd.png new file mode 100644 index 00000000..f296a52a Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-014-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-014-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-014-sd.png new file mode 100644 index 00000000..1ecde298 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-014-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-015-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-015-hd.png new file mode 100644 index 00000000..bb9bb226 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-015-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-015-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-015-sd.png new file mode 100644 index 00000000..2187391f Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-015-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-016-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-016-hd.png new file mode 100644 index 00000000..cb6d49df Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-016-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-016-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-016-sd.png new file mode 100644 index 00000000..e2d80479 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-016-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-017-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-017-hd.png new file mode 100644 index 00000000..a5210326 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-017-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-017-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-017-sd.png new file mode 100644 index 00000000..bdff8a4f Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-017-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-018-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-018-hd.png new file mode 100644 index 00000000..f0e0c4bc Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-018-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-018-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-018-sd.png new file mode 100644 index 00000000..18d628b1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-018-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-019-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-019-hd.png new file mode 100644 index 00000000..7581a9a4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-019-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-019-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-019-sd.png new file mode 100644 index 00000000..9d575f37 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-019-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-020-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-020-hd.png new file mode 100644 index 00000000..acf965a4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-020-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-020-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-020-sd.png new file mode 100644 index 00000000..523043c5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-020-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-021-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-021-hd.png new file mode 100644 index 00000000..7dd1ccfd Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-021-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-021-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-021-sd.png new file mode 100644 index 00000000..941b2171 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-021-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-022-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-022-hd.png new file mode 100644 index 00000000..8c45c637 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-022-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-022-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-022-sd.png new file mode 100644 index 00000000..dfc91ed7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-022-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-023-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-023-hd.png new file mode 100644 index 00000000..07bf21ff Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-023-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-023-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-023-sd.png new file mode 100644 index 00000000..8e31d625 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-023-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-024-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-024-hd.png new file mode 100644 index 00000000..68ba1a28 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-024-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-024-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-024-sd.png new file mode 100644 index 00000000..c19944a1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-024-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-025-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-025-hd.png new file mode 100644 index 00000000..e0adff24 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-025-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-025-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-025-sd.png new file mode 100644 index 00000000..2bfb7ad8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-025-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-026-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-026-hd.png new file mode 100644 index 00000000..91853ad8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-026-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-026-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-026-sd.png new file mode 100644 index 00000000..5ca995b7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-026-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-027-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-027-hd.png new file mode 100644 index 00000000..907186ec Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-027-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-027-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-027-sd.png new file mode 100644 index 00000000..07ade2cf Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-027-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-028-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-028-hd.png new file mode 100644 index 00000000..95492bb3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-028-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-028-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-028-sd.png new file mode 100644 index 00000000..445bc5a6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-028-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-029-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-029-hd.png new file mode 100644 index 00000000..eec41734 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-029-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-029-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-029-sd.png new file mode 100644 index 00000000..1501c620 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-029-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-030-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-030-hd.png new file mode 100644 index 00000000..4fac04b4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-030-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-030-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-030-sd.png new file mode 100644 index 00000000..b187ba48 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-030-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-031-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-031-hd.png new file mode 100644 index 00000000..e82eb9d5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-031-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-031-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-031-sd.png new file mode 100644 index 00000000..92f4f6b4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-031-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-032-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-032-hd.png new file mode 100644 index 00000000..5d927602 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-032-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-032-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-032-sd.png new file mode 100644 index 00000000..ac6217c3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-032-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-033-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-033-hd.png new file mode 100644 index 00000000..d1b99df1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-033-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-033-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-033-sd.png new file mode 100644 index 00000000..0b78abe4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-033-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-034-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-034-hd.png new file mode 100644 index 00000000..4da9599f Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-034-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-034-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-034-sd.png new file mode 100644 index 00000000..a6337ed8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-034-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-035-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-035-hd.png new file mode 100644 index 00000000..c0e1a188 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-035-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-035-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-035-sd.png new file mode 100644 index 00000000..eabeb62a Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-035-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-036-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-036-hd.png new file mode 100644 index 00000000..ec2d23fe Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-036-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-036-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-036-sd.png new file mode 100644 index 00000000..934fe013 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-036-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-037-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-037-hd.png new file mode 100644 index 00000000..abfa114d Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-037-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-037-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-037-sd.png new file mode 100644 index 00000000..538f88ee Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-037-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-038-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-038-hd.png new file mode 100644 index 00000000..563ad7f5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-038-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-038-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-038-sd.png new file mode 100644 index 00000000..8b57c60c Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-038-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-039-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-039-hd.png new file mode 100644 index 00000000..e7980319 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-039-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-039-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-039-sd.png new file mode 100644 index 00000000..a3ab290c Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-039-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-040-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-040-hd.png new file mode 100644 index 00000000..20cf22c9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-040-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-040-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-040-sd.png new file mode 100644 index 00000000..1fe85804 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-040-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-041-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-041-hd.png new file mode 100644 index 00000000..4ab781f5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-041-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-041-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-041-sd.png new file mode 100644 index 00000000..c7ea3e0e Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-041-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-042-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-042-hd.png new file mode 100644 index 00000000..805f6383 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-042-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-042-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-042-sd.png new file mode 100644 index 00000000..79f672fb Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-042-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-043-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-043-hd.png new file mode 100644 index 00000000..16483596 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-043-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-043-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-043-sd.png new file mode 100644 index 00000000..3b446550 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-043-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-044-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-044-hd.png new file mode 100644 index 00000000..32f64f69 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-044-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-044-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-044-sd.png new file mode 100644 index 00000000..379c2614 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-044-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-045-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-045-hd.png new file mode 100644 index 00000000..8803b739 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-045-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-045-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-045-sd.png new file mode 100644 index 00000000..b7f1a1f2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-045-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-046-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-046-hd.png new file mode 100644 index 00000000..3110b1d8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-046-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-046-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-046-sd.png new file mode 100644 index 00000000..a22e0f48 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-046-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-047-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-047-hd.png new file mode 100644 index 00000000..93320522 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-047-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-047-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-047-sd.png new file mode 100644 index 00000000..8c14ea3b Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-047-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-048-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-048-hd.png new file mode 100644 index 00000000..3ffbc3d5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-048-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-048-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-048-sd.png new file mode 100644 index 00000000..ca8e2169 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-048-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-049-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-049-hd.png new file mode 100644 index 00000000..c045a462 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-049-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-049-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-049-sd.png new file mode 100644 index 00000000..90f9a501 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-049-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-050-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-050-hd.png new file mode 100644 index 00000000..d5b4a93c Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-050-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-050-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-050-sd.png new file mode 100644 index 00000000..641b1794 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-050-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-051-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-051-hd.png new file mode 100644 index 00000000..709adfc6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-051-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-051-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-051-sd.png new file mode 100644 index 00000000..08cf8472 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-051-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-052-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-052-hd.png new file mode 100644 index 00000000..5ea818ea Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-052-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-052-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-052-sd.png new file mode 100644 index 00000000..ee68c29a Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-052-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-053-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-053-hd.png new file mode 100644 index 00000000..92fa89e7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-053-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-053-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-053-sd.png new file mode 100644 index 00000000..6959e203 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-053-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-054-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-054-hd.png new file mode 100644 index 00000000..8f41e526 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-054-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-054-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-054-sd.png new file mode 100644 index 00000000..a11c426f Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-054-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-055-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-055-hd.png new file mode 100644 index 00000000..c5bf4092 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-055-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-055-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-055-sd.png new file mode 100644 index 00000000..b7b436d3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-055-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-056-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-056-hd.png new file mode 100644 index 00000000..d3bca3d6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-056-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-056-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-056-sd.png new file mode 100644 index 00000000..97d9d479 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-056-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-057-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-057-hd.png new file mode 100644 index 00000000..dc4e1be5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-057-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-057-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-057-sd.png new file mode 100644 index 00000000..31e03045 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-057-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-058-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-058-hd.png new file mode 100644 index 00000000..cab41ede Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-058-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-058-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-058-sd.png new file mode 100644 index 00000000..bbe406c0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-058-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-059-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-059-hd.png new file mode 100644 index 00000000..2a689ee5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-059-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-059-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-059-sd.png new file mode 100644 index 00000000..030d37b0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-059-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-060-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-060-hd.png new file mode 100644 index 00000000..198b7027 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-060-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-060-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-060-sd.png new file mode 100644 index 00000000..479503e0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-060-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-061-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-061-hd.png new file mode 100644 index 00000000..3fb90f9a Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-061-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-061-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-061-sd.png new file mode 100644 index 00000000..0583f465 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-061-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-062-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-062-hd.png new file mode 100644 index 00000000..ab548f26 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-062-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-062-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-062-sd.png new file mode 100644 index 00000000..f151ce7a Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-062-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-063-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-063-hd.png new file mode 100644 index 00000000..cc60f12e Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-063-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-063-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-063-sd.png new file mode 100644 index 00000000..f6531140 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-063-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-064-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-064-hd.png new file mode 100644 index 00000000..756cbf8d Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-064-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-064-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-064-sd.png new file mode 100644 index 00000000..126316ce Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-064-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-065-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-065-hd.png new file mode 100644 index 00000000..3235a950 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-065-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-065-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-065-sd.png new file mode 100644 index 00000000..282e5870 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-065-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-066-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-066-hd.png new file mode 100644 index 00000000..a68bba19 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-066-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-066-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-066-sd.png new file mode 100644 index 00000000..bbbbc60a Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-066-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-067-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-067-hd.png new file mode 100644 index 00000000..bfc941ca Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-067-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-067-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-067-sd.png new file mode 100644 index 00000000..172dd778 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-067-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-068-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-068-hd.png new file mode 100644 index 00000000..f3d7cd66 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-068-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-068-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-068-sd.png new file mode 100644 index 00000000..e90f1a16 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-068-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-069-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-069-hd.png new file mode 100644 index 00000000..a4cac487 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-069-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-069-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-069-sd.png new file mode 100644 index 00000000..7b93c783 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-069-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-070-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-070-hd.png new file mode 100644 index 00000000..99d86ba3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-070-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-070-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-070-sd.png new file mode 100644 index 00000000..c19295e8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-070-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-071-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-071-hd.png new file mode 100644 index 00000000..84228b82 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-071-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-071-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-071-sd.png new file mode 100644 index 00000000..be7976a0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-071-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-072-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-072-hd.png new file mode 100644 index 00000000..b3424153 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-072-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-072-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-072-sd.png new file mode 100644 index 00000000..bdc4e9e3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-072-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-073-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-073-hd.png new file mode 100644 index 00000000..d11098ae Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-073-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-073-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-073-sd.png new file mode 100644 index 00000000..27a452fb Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-073-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-074-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-074-hd.png new file mode 100644 index 00000000..5c85a654 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-074-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-074-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-074-sd.png new file mode 100644 index 00000000..d7e3ce8d Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-074-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-075-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-075-hd.png new file mode 100644 index 00000000..3ae186d0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-075-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-075-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-075-sd.png new file mode 100644 index 00000000..100a0955 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-075-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-076-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-076-hd.png new file mode 100644 index 00000000..f7da63d7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-076-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-076-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-076-sd.png new file mode 100644 index 00000000..88ebccc7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-076-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-077-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-077-hd.png new file mode 100644 index 00000000..e688e10c Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-077-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-077-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-077-sd.png new file mode 100644 index 00000000..da427142 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-077-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-078-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-078-hd.png new file mode 100644 index 00000000..bc096360 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-078-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-078-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-078-sd.png new file mode 100644 index 00000000..6cd1f484 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-078-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-079-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-079-hd.png new file mode 100644 index 00000000..d18d3e80 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-079-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-079-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-079-sd.png new file mode 100644 index 00000000..51b7239f Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-079-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-080-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-080-hd.png new file mode 100644 index 00000000..2b7e9583 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-080-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-080-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-080-sd.png new file mode 100644 index 00000000..aaa671f7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-080-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-081-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-081-hd.png new file mode 100644 index 00000000..9797c9d1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-081-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-081-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-081-sd.png new file mode 100644 index 00000000..05cf944e Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-081-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-082-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-082-hd.png new file mode 100644 index 00000000..84994c60 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-082-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-082-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-082-sd.png new file mode 100644 index 00000000..e4f8b2a9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-082-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-083-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-083-hd.png new file mode 100644 index 00000000..7051ada0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-083-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-083-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-083-sd.png new file mode 100644 index 00000000..e46bd068 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-083-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-084-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-084-hd.png new file mode 100644 index 00000000..338e1919 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-084-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-084-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-084-sd.png new file mode 100644 index 00000000..b37b27e3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-084-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-085-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-085-hd.png new file mode 100644 index 00000000..bd80a662 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-085-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-085-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-085-sd.png new file mode 100644 index 00000000..928571e1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-085-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-086-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-086-hd.png new file mode 100644 index 00000000..e2d94a10 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-086-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-086-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-086-sd.png new file mode 100644 index 00000000..1c64b2dc Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-086-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-087-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-087-hd.png new file mode 100644 index 00000000..4b5bf49d Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-087-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-087-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-087-sd.png new file mode 100644 index 00000000..49e0128b Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-087-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-088-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-088-hd.png new file mode 100644 index 00000000..1f5f68ee Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-088-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-088-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-088-sd.png new file mode 100644 index 00000000..30f7a0f8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-088-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-089-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-089-hd.png new file mode 100644 index 00000000..95a4a239 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-089-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-089-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-089-sd.png new file mode 100644 index 00000000..ea55c924 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-089-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-090-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-090-hd.png new file mode 100644 index 00000000..1f4aaffb Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-090-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-090-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-090-sd.png new file mode 100644 index 00000000..4bedb08b Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-090-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-091-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-091-hd.png new file mode 100644 index 00000000..20f2f7c8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-091-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-091-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-091-sd.png new file mode 100644 index 00000000..b242a1c0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-091-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-092-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-092-hd.png new file mode 100644 index 00000000..d4540aab Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-092-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-092-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-092-sd.png new file mode 100644 index 00000000..eed6c7ee Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-092-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-093-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-093-hd.png new file mode 100644 index 00000000..f8e72dd3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-093-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-093-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-093-sd.png new file mode 100644 index 00000000..09349a37 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-093-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-094-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-094-hd.png new file mode 100644 index 00000000..54974d24 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-094-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-094-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-094-sd.png new file mode 100644 index 00000000..0c2f8470 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-094-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-095-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-095-hd.png new file mode 100644 index 00000000..1996e126 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-095-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-095-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-095-sd.png new file mode 100644 index 00000000..e9beeda6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-095-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-096-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-096-hd.png new file mode 100644 index 00000000..5bf686c3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-096-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-096-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-096-sd.png new file mode 100644 index 00000000..84d21051 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-096-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-097-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-097-hd.png new file mode 100644 index 00000000..bc3f271e Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-097-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-097-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-097-sd.png new file mode 100644 index 00000000..d9d5cd88 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-097-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-098-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-098-hd.png new file mode 100644 index 00000000..dea63f76 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-098-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-098-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-098-sd.png new file mode 100644 index 00000000..4e97f8be Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-098-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-099-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-099-hd.png new file mode 100644 index 00000000..c2fce59d Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-099-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-099-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-099-sd.png new file mode 100644 index 00000000..627ea432 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-099-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-100-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-100-hd.png new file mode 100644 index 00000000..6310ed27 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-100-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-100-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-100-sd.png new file mode 100644 index 00000000..74278639 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-100-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-101-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-101-hd.png new file mode 100644 index 00000000..e9bd2f35 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-101-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-101-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-101-sd.png new file mode 100644 index 00000000..ea568af6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-101-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-102-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-102-hd.png new file mode 100644 index 00000000..12742360 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-102-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-102-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-102-sd.png new file mode 100644 index 00000000..87392599 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-102-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-103-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-103-hd.png new file mode 100644 index 00000000..10e30274 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-103-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-103-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-103-sd.png new file mode 100644 index 00000000..7f5eadaf Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-103-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-104-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-104-hd.png new file mode 100644 index 00000000..7dbb738b Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-104-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-104-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-104-sd.png new file mode 100644 index 00000000..a688c5e7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-104-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-105-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-105-hd.png new file mode 100644 index 00000000..95dbac6d Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-105-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-105-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-105-sd.png new file mode 100644 index 00000000..d2e4f8f1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-105-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-106-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-106-hd.png new file mode 100644 index 00000000..dd24a8ad Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-106-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-106-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-106-sd.png new file mode 100644 index 00000000..da3d182b Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-106-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-107-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-107-hd.png new file mode 100644 index 00000000..266581c6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-107-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-107-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-107-sd.png new file mode 100644 index 00000000..2f8f44b5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-107-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-108-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-108-hd.png new file mode 100644 index 00000000..1a802f68 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-108-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-108-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-108-sd.png new file mode 100644 index 00000000..90559661 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-108-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-109-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-109-hd.png new file mode 100644 index 00000000..a6ff56ba Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-109-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-109-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-109-sd.png new file mode 100644 index 00000000..a1669c83 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-109-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-110-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-110-hd.png new file mode 100644 index 00000000..803e0392 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-110-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-110-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-110-sd.png new file mode 100644 index 00000000..6ccd6573 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-110-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-111-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-111-hd.png new file mode 100644 index 00000000..b4061426 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-111-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-111-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-111-sd.png new file mode 100644 index 00000000..ce9be343 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-111-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-112-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-112-hd.png new file mode 100644 index 00000000..b844b41b Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-112-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-112-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-112-sd.png new file mode 100644 index 00000000..215e76a9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-112-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-113-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-113-hd.png new file mode 100644 index 00000000..5cc835bd Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-113-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-113-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-113-sd.png new file mode 100644 index 00000000..c6967d71 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-113-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-114-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-114-hd.png new file mode 100644 index 00000000..234dc2dd Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-114-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-114-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-114-sd.png new file mode 100644 index 00000000..4fe9b2c2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-114-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-115-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-115-hd.png new file mode 100644 index 00000000..afc8d396 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-115-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-115-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-115-sd.png new file mode 100644 index 00000000..cb411859 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-115-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-116-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-116-hd.png new file mode 100644 index 00000000..0f862c73 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-116-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-116-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-116-sd.png new file mode 100644 index 00000000..64c33af3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-116-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-117-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-117-hd.png new file mode 100644 index 00000000..fcd4d2d7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-117-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-117-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-117-sd.png new file mode 100644 index 00000000..80f391ba Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-117-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-118-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-118-hd.png new file mode 100644 index 00000000..8edab72b Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-118-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-118-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-118-sd.png new file mode 100644 index 00000000..4c81d12f Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-118-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-119-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-119-hd.png new file mode 100644 index 00000000..ab2a8f5b Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-119-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-119-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-119-sd.png new file mode 100644 index 00000000..9ee63f10 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-119-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-120-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-120-hd.png new file mode 100644 index 00000000..aeeff9b7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-120-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-120-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-120-sd.png new file mode 100644 index 00000000..5d8609d9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-120-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-121-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-121-hd.png new file mode 100644 index 00000000..15e69c96 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-121-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-121-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-121-sd.png new file mode 100644 index 00000000..d6565eae Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-121-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-122-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-122-hd.png new file mode 100644 index 00000000..7f664eda Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-122-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-122-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-122-sd.png new file mode 100644 index 00000000..ed39b480 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-122-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-123-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-123-hd.png new file mode 100644 index 00000000..817a6ada Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-123-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-123-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-123-sd.png new file mode 100644 index 00000000..e03ee676 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-123-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-124-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-124-hd.png new file mode 100644 index 00000000..36fc3942 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-124-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-124-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-124-sd.png new file mode 100644 index 00000000..125eaa6f Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-124-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-125-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-125-hd.png new file mode 100644 index 00000000..63fa3a58 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-125-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-125-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-125-sd.png new file mode 100644 index 00000000..84369bb8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-125-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-126-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-126-hd.png new file mode 100644 index 00000000..905881d4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-126-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-126-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-126-sd.png new file mode 100644 index 00000000..e7ed6798 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-126-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-127-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-127-hd.png new file mode 100644 index 00000000..e31eb5e0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-127-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-127-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-127-sd.png new file mode 100644 index 00000000..53d094dd Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-127-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-128-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-128-hd.png new file mode 100644 index 00000000..3f11a41f Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-128-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-128-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-128-sd.png new file mode 100644 index 00000000..2cb00cf6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-128-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-129-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-129-hd.png new file mode 100644 index 00000000..cc0a2e8c Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-129-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-129-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-129-sd.png new file mode 100644 index 00000000..1e47168c Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-129-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-130-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-130-hd.png new file mode 100644 index 00000000..c54e294c Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-130-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-130-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-130-sd.png new file mode 100644 index 00000000..2c02c467 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-130-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-131-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-131-hd.png new file mode 100644 index 00000000..d4f34d71 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-131-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-131-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-131-sd.png new file mode 100644 index 00000000..7723d9af Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-131-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-132-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-132-hd.png new file mode 100644 index 00000000..2da8e719 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-132-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-132-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-132-sd.png new file mode 100644 index 00000000..9b669d5a Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-132-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-133-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-133-hd.png new file mode 100644 index 00000000..c2d2bbda Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-133-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-133-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-133-sd.png new file mode 100644 index 00000000..3d69f763 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-133-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-134-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-134-hd.png new file mode 100644 index 00000000..59ced9bd Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-134-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-134-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-134-sd.png new file mode 100644 index 00000000..a3d21d87 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-134-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-135-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-135-hd.png new file mode 100644 index 00000000..a2f9bbc2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-135-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-135-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-135-sd.png new file mode 100644 index 00000000..fcda935c Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-135-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-136-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-136-hd.png new file mode 100644 index 00000000..cd9c3ed1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-136-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-136-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-136-sd.png new file mode 100644 index 00000000..ca7c7c75 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-136-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-137-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-137-hd.png new file mode 100644 index 00000000..dc6de778 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-137-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-137-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-137-sd.png new file mode 100644 index 00000000..0644efbc Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-137-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-138-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-138-hd.png new file mode 100644 index 00000000..ef8ff23c Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-138-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-138-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-138-sd.png new file mode 100644 index 00000000..41c1d9d6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-138-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-139-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-139-hd.png new file mode 100644 index 00000000..52043b0e Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-139-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-139-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-139-sd.png new file mode 100644 index 00000000..c06e9495 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-139-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-140-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-140-hd.png new file mode 100644 index 00000000..24a28fc4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-140-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-140-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-140-sd.png new file mode 100644 index 00000000..d71d9e88 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-140-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-141-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-141-hd.png new file mode 100644 index 00000000..57f23256 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-141-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-141-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-141-sd.png new file mode 100644 index 00000000..b4645250 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-141-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-142-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-142-hd.png new file mode 100644 index 00000000..3cdecf8a Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-142-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-142-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-142-sd.png new file mode 100644 index 00000000..e16fab0c Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-142-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-143-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-143-hd.png new file mode 100644 index 00000000..a693065c Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-143-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-143-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-143-sd.png new file mode 100644 index 00000000..6682e7c4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-143-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-144-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-144-hd.png new file mode 100644 index 00000000..08336a3b Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-144-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-144-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-144-sd.png new file mode 100644 index 00000000..1530cc13 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-144-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-145-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-145-hd.png new file mode 100644 index 00000000..beb5eedf Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-145-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-145-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-145-sd.png new file mode 100644 index 00000000..fd8d5b92 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-145-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-146-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-146-hd.png new file mode 100644 index 00000000..da65fea6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-146-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-146-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-146-sd.png new file mode 100644 index 00000000..3b0b6df8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-146-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-147-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-147-hd.png new file mode 100644 index 00000000..7518b215 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-147-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-147-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-147-sd.png new file mode 100644 index 00000000..c6d03c3a Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-147-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-148-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-148-hd.png new file mode 100644 index 00000000..77647936 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-148-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-148-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-148-sd.png new file mode 100644 index 00000000..e61b08af Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-148-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-149-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-149-hd.png new file mode 100644 index 00000000..51532566 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-149-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-149-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-149-sd.png new file mode 100644 index 00000000..8c52bb4e Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-149-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-150-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-150-hd.png new file mode 100644 index 00000000..86ad9e08 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-150-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-150-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-150-sd.png new file mode 100644 index 00000000..12af23c1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-150-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-151-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-151-hd.png new file mode 100644 index 00000000..ef0b3429 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-151-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-151-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-151-sd.png new file mode 100644 index 00000000..349976f2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-151-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-152-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-152-hd.png new file mode 100644 index 00000000..1b96785a Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-152-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-152-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-152-sd.png new file mode 100644 index 00000000..30919d58 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-152-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-153-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-153-hd.png new file mode 100644 index 00000000..7fc5d50e Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-153-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-153-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-153-sd.png new file mode 100644 index 00000000..74e1b375 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-153-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-154-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-154-hd.png new file mode 100644 index 00000000..68dc03cc Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-154-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-154-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-154-sd.png new file mode 100644 index 00000000..7a06fa99 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-154-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-155-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-155-hd.png new file mode 100644 index 00000000..25992aa4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-155-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-155-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-155-sd.png new file mode 100644 index 00000000..3c1b8f76 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-155-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-156-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-156-hd.png new file mode 100644 index 00000000..9bee50a0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-156-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-156-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-156-sd.png new file mode 100644 index 00000000..a4a26d30 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-156-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-157-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-157-hd.png new file mode 100644 index 00000000..9b2fd2ba Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-157-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-157-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-157-sd.png new file mode 100644 index 00000000..28bcdc82 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-157-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-158-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-158-hd.png new file mode 100644 index 00000000..057d6c44 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-158-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-158-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-158-sd.png new file mode 100644 index 00000000..98b01ef1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-158-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-159-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-159-hd.png new file mode 100644 index 00000000..f90f18b5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-159-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-159-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-159-sd.png new file mode 100644 index 00000000..56d11edd Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-159-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-160-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-160-hd.png new file mode 100644 index 00000000..1b8810fb Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-160-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-160-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-160-sd.png new file mode 100644 index 00000000..723e900b Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-160-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-161-hd.png b/mods/iron_coast_stage2_mission_5/art/tile-161-hd.png new file mode 100644 index 00000000..b59ed58b Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-161-hd.png differ diff --git a/mods/iron_coast_stage2_mission_5/art/tile-161-sd.png b/mods/iron_coast_stage2_mission_5/art/tile-161-sd.png new file mode 100644 index 00000000..2fba4c85 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/art/tile-161-sd.png differ diff --git a/mods/iron_coast_stage2_mission_5/audio-recipe.json b/mods/iron_coast_stage2_mission_5/audio-recipe.json new file mode 100644 index 00000000..4f948e74 --- /dev/null +++ b/mods/iron_coast_stage2_mission_5/audio-recipe.json @@ -0,0 +1,80 @@ +{ + "files": { + "alarm": { + "bits": 16, + "channels": 1, + "duration_seconds": 0.28, + "file": "audio/alarm.wav", + "first_last_samples": [ + 0, + 0 + ], + "peak": 22282, + "rms": 6783.547743523453, + "sample_rate": 22050, + "seed": 5201, + "sha256": "21abc6ed9b7e4e2843eaabe05885812009ebaf8d28d637ab67f2b614141851b0" + }, + "approach": { + "bits": 16, + "channels": 1, + "duration_seconds": 0.45, + "file": "audio/approach.wav", + "first_last_samples": [ + 0, + 0 + ], + "peak": 22282, + "rms": 7004.925515451308, + "sample_rate": 22050, + "seed": 5200, + "sha256": "6fa43d6b5fb4debe39c1014282ddfbc362057197239d10b918181f45c200fcda" + }, + "hazard": { + "bits": 16, + "channels": 1, + "duration_seconds": 0.22, + "file": "audio/hazard.wav", + "first_last_samples": [ + 0, + 0 + ], + "peak": 22282, + "rms": 7068.641271829282, + "sample_rate": 22050, + "seed": 5202, + "sha256": "f0f4b6f1fc9990acbf1492444e80e5be76c9e87170e6b3c403ee30048a0317ad" + }, + "target_down": { + "bits": 16, + "channels": 1, + "duration_seconds": 0.36, + "file": "audio/target_down.wav", + "first_last_samples": [ + 0, + 0 + ], + "peak": 22282, + "rms": 4290.961982037655, + "sample_rate": 22050, + "seed": 5203, + "sha256": "f13d4d7ab0844e33bb4bbaf66749be1269a6fe33d45518a047ceead71223923d" + }, + "victory": { + "bits": 16, + "channels": 1, + "duration_seconds": 0.75, + "file": "audio/victory.wav", + "first_last_samples": [ + 0, + 0 + ], + "peak": 22282, + "rms": 7477.762781723981, + "sample_rate": 22050, + "seed": 5204, + "sha256": "c4c92eefa644faf14cf5da99fb431832719d621aaff5ed01b8ec1961ac3ee986" + } + }, + "generator": "tools/build_assets.py deterministic sinusoidal chirps, seeded noise and faded envelopes; no recorded audio or third-party samples" +} diff --git a/mods/iron_coast_stage2_mission_5/audio/alarm.wav b/mods/iron_coast_stage2_mission_5/audio/alarm.wav new file mode 100644 index 00000000..8695d70a Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/audio/alarm.wav differ diff --git a/mods/iron_coast_stage2_mission_5/audio/approach.wav b/mods/iron_coast_stage2_mission_5/audio/approach.wav new file mode 100644 index 00000000..1ed8d9af Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/audio/approach.wav differ diff --git a/mods/iron_coast_stage2_mission_5/audio/hazard.wav b/mods/iron_coast_stage2_mission_5/audio/hazard.wav new file mode 100644 index 00000000..f6a30262 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/audio/hazard.wav differ diff --git a/mods/iron_coast_stage2_mission_5/audio/target_down.wav b/mods/iron_coast_stage2_mission_5/audio/target_down.wav new file mode 100644 index 00000000..27cbbfe4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/audio/target_down.wav differ diff --git a/mods/iron_coast_stage2_mission_5/audio/victory.wav b/mods/iron_coast_stage2_mission_5/audio/victory.wav new file mode 100644 index 00000000..fdbc4cca Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/audio/victory.wav differ diff --git a/mods/iron_coast_stage2_mission_5/content.json b/mods/iron_coast_stage2_mission_5/content.json new file mode 100644 index 00000000..45f9848e --- /dev/null +++ b/mods/iron_coast_stage2_mission_5/content.json @@ -0,0 +1,4205 @@ +{ + "enemies": [ + { + "id": "iron_coast_stage2_mission_5:target", + "name": "Arsenal test battery", + "health": 72, + "speed": 0, + "reward": 900, + "ground": true, + "cooldown": 108, + "weapon": "iron_coast_stage2_mission_5:defense_shell", + "art": { + "asset": 65851, + "logical_width": 32, + "logical_height": 32 + }, + "script": "scripts/target.rhai" + } + ], + "weapons": [ + { + "id": "iron_coast_stage2_mission_5:defense_shell", + "name": "Skybreaker Arsenal defensive shell", + "damage": 3, + "speed": 3, + "cooldown": 108, + "behavior": "straight", + "target": "all", + "art": { + "asset": 66006, + "logical_width": 8, + "logical_height": 8, + "frames": 2 + } + }, + { + "id": "iron_coast_stage2_mission_5:hazard_shell", + "name": "Test lane burst", + "damage": 2, + "speed": 4, + "cooldown": 180, + "behavior": "straight", + "target": "all", + "art": { + "asset": 66006, + "logical_width": 8, + "logical_height": 8, + "frames": 2 + } + } + ], + "sounds": [ + { + "id": "iron_coast_stage2_mission_5:approach", + "name": "Skybreaker Arsenal approach", + "file": "audio/approach.wav", + "volume": 86, + "priority": 3 + }, + { + "id": "iron_coast_stage2_mission_5:alarm", + "name": "Skybreaker Arsenal alarm", + "file": "audio/alarm.wav", + "volume": 76, + "priority": 3 + }, + { + "id": "iron_coast_stage2_mission_5:hazard", + "name": "Skybreaker Arsenal hazard", + "file": "audio/hazard.wav", + "volume": 68, + "priority": 3 + }, + { + "id": "iron_coast_stage2_mission_5:target_down", + "name": "Skybreaker Arsenal target_down", + "file": "audio/target_down.wav", + "volume": 82, + "priority": 3 + }, + { + "id": "iron_coast_stage2_mission_5:victory", + "name": "Skybreaker Arsenal victory", + "file": "audio/victory.wav", + "volume": 98, + "priority": 3 + } + ], + "missions": [ + { + "id": "iron_coast_stage2_mission_5:mission_05", + "name": "Black Tide 5 \u2014 Skybreaker Arsenal", + "duration": 3500, + "auto_complete": false, + "columns": 9, + "layout": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161 + ], + "tiles": [ + { + "art": { + "png": "art/tile-000-sd.png", + "hd_png": "art/tile-000-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-001-sd.png", + "hd_png": "art/tile-001-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-002-sd.png", + "hd_png": "art/tile-002-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-003-sd.png", + "hd_png": "art/tile-003-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-004-sd.png", + "hd_png": "art/tile-004-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-005-sd.png", + "hd_png": "art/tile-005-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-006-sd.png", + "hd_png": "art/tile-006-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-007-sd.png", + "hd_png": "art/tile-007-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-008-sd.png", + "hd_png": "art/tile-008-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-009-sd.png", + "hd_png": "art/tile-009-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-010-sd.png", + "hd_png": "art/tile-010-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-011-sd.png", + "hd_png": "art/tile-011-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-012-sd.png", + "hd_png": "art/tile-012-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-013-sd.png", + "hd_png": "art/tile-013-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-014-sd.png", + "hd_png": "art/tile-014-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-015-sd.png", + "hd_png": "art/tile-015-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-016-sd.png", + "hd_png": "art/tile-016-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-017-sd.png", + "hd_png": "art/tile-017-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-018-sd.png", + "hd_png": "art/tile-018-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-019-sd.png", + "hd_png": "art/tile-019-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-020-sd.png", + "hd_png": "art/tile-020-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-021-sd.png", + "hd_png": "art/tile-021-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-022-sd.png", + "hd_png": "art/tile-022-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-023-sd.png", + "hd_png": "art/tile-023-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-024-sd.png", + "hd_png": "art/tile-024-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-025-sd.png", + "hd_png": "art/tile-025-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-026-sd.png", + "hd_png": "art/tile-026-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-027-sd.png", + "hd_png": "art/tile-027-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-028-sd.png", + "hd_png": "art/tile-028-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-029-sd.png", + "hd_png": "art/tile-029-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-030-sd.png", + "hd_png": "art/tile-030-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-031-sd.png", + "hd_png": "art/tile-031-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-032-sd.png", + "hd_png": "art/tile-032-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-033-sd.png", + "hd_png": "art/tile-033-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-034-sd.png", + "hd_png": "art/tile-034-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-035-sd.png", + "hd_png": "art/tile-035-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-036-sd.png", + "hd_png": "art/tile-036-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-037-sd.png", + "hd_png": "art/tile-037-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-038-sd.png", + "hd_png": "art/tile-038-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-039-sd.png", + "hd_png": "art/tile-039-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-040-sd.png", + "hd_png": "art/tile-040-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-041-sd.png", + "hd_png": "art/tile-041-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-042-sd.png", + "hd_png": "art/tile-042-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-043-sd.png", + "hd_png": "art/tile-043-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-044-sd.png", + "hd_png": "art/tile-044-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-045-sd.png", + "hd_png": "art/tile-045-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-046-sd.png", + "hd_png": "art/tile-046-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-047-sd.png", + "hd_png": "art/tile-047-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-048-sd.png", + "hd_png": "art/tile-048-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-049-sd.png", + "hd_png": "art/tile-049-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-050-sd.png", + "hd_png": "art/tile-050-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-051-sd.png", + "hd_png": "art/tile-051-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-052-sd.png", + "hd_png": "art/tile-052-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-053-sd.png", + "hd_png": "art/tile-053-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-054-sd.png", + "hd_png": "art/tile-054-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-055-sd.png", + "hd_png": "art/tile-055-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-056-sd.png", + "hd_png": "art/tile-056-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-057-sd.png", + "hd_png": "art/tile-057-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-058-sd.png", + "hd_png": "art/tile-058-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-059-sd.png", + "hd_png": "art/tile-059-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-060-sd.png", + "hd_png": "art/tile-060-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-061-sd.png", + "hd_png": "art/tile-061-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-062-sd.png", + "hd_png": "art/tile-062-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-063-sd.png", + "hd_png": "art/tile-063-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-064-sd.png", + "hd_png": "art/tile-064-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-065-sd.png", + "hd_png": "art/tile-065-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-066-sd.png", + "hd_png": "art/tile-066-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-067-sd.png", + "hd_png": "art/tile-067-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-068-sd.png", + "hd_png": "art/tile-068-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-069-sd.png", + "hd_png": "art/tile-069-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-070-sd.png", + "hd_png": "art/tile-070-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-071-sd.png", + "hd_png": "art/tile-071-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-072-sd.png", + "hd_png": "art/tile-072-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-073-sd.png", + "hd_png": "art/tile-073-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-074-sd.png", + "hd_png": "art/tile-074-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-075-sd.png", + "hd_png": "art/tile-075-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-076-sd.png", + "hd_png": "art/tile-076-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-077-sd.png", + "hd_png": "art/tile-077-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-078-sd.png", + "hd_png": "art/tile-078-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-079-sd.png", + "hd_png": "art/tile-079-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-080-sd.png", + "hd_png": "art/tile-080-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-081-sd.png", + "hd_png": "art/tile-081-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-082-sd.png", + "hd_png": "art/tile-082-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-083-sd.png", + "hd_png": "art/tile-083-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-084-sd.png", + "hd_png": "art/tile-084-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-085-sd.png", + "hd_png": "art/tile-085-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-086-sd.png", + "hd_png": "art/tile-086-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-087-sd.png", + "hd_png": "art/tile-087-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-088-sd.png", + "hd_png": "art/tile-088-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-089-sd.png", + "hd_png": "art/tile-089-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-090-sd.png", + "hd_png": "art/tile-090-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-091-sd.png", + "hd_png": "art/tile-091-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-092-sd.png", + "hd_png": "art/tile-092-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-093-sd.png", + "hd_png": "art/tile-093-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-094-sd.png", + "hd_png": "art/tile-094-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-095-sd.png", + "hd_png": "art/tile-095-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-096-sd.png", + "hd_png": "art/tile-096-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-097-sd.png", + "hd_png": "art/tile-097-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-098-sd.png", + "hd_png": "art/tile-098-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-099-sd.png", + "hd_png": "art/tile-099-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-100-sd.png", + "hd_png": "art/tile-100-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-101-sd.png", + "hd_png": "art/tile-101-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-102-sd.png", + "hd_png": "art/tile-102-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-103-sd.png", + "hd_png": "art/tile-103-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-104-sd.png", + "hd_png": "art/tile-104-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-105-sd.png", + "hd_png": "art/tile-105-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-106-sd.png", + "hd_png": "art/tile-106-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-107-sd.png", + "hd_png": "art/tile-107-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-108-sd.png", + "hd_png": "art/tile-108-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-109-sd.png", + "hd_png": "art/tile-109-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-110-sd.png", + "hd_png": "art/tile-110-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-111-sd.png", + "hd_png": "art/tile-111-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-112-sd.png", + "hd_png": "art/tile-112-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-113-sd.png", + "hd_png": "art/tile-113-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-114-sd.png", + "hd_png": "art/tile-114-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-115-sd.png", + "hd_png": "art/tile-115-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-116-sd.png", + "hd_png": "art/tile-116-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-117-sd.png", + "hd_png": "art/tile-117-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-118-sd.png", + "hd_png": "art/tile-118-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-119-sd.png", + "hd_png": "art/tile-119-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-120-sd.png", + "hd_png": "art/tile-120-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-121-sd.png", + "hd_png": "art/tile-121-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-122-sd.png", + "hd_png": "art/tile-122-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-123-sd.png", + "hd_png": "art/tile-123-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-124-sd.png", + "hd_png": "art/tile-124-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-125-sd.png", + "hd_png": "art/tile-125-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-126-sd.png", + "hd_png": "art/tile-126-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-127-sd.png", + "hd_png": "art/tile-127-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-128-sd.png", + "hd_png": "art/tile-128-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-129-sd.png", + "hd_png": "art/tile-129-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-130-sd.png", + "hd_png": "art/tile-130-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-131-sd.png", + "hd_png": "art/tile-131-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-132-sd.png", + "hd_png": "art/tile-132-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-133-sd.png", + "hd_png": "art/tile-133-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-134-sd.png", + "hd_png": "art/tile-134-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-135-sd.png", + "hd_png": "art/tile-135-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-136-sd.png", + "hd_png": "art/tile-136-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-137-sd.png", + "hd_png": "art/tile-137-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-138-sd.png", + "hd_png": "art/tile-138-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-139-sd.png", + "hd_png": "art/tile-139-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-140-sd.png", + "hd_png": "art/tile-140-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-141-sd.png", + "hd_png": "art/tile-141-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-142-sd.png", + "hd_png": "art/tile-142-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-143-sd.png", + "hd_png": "art/tile-143-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-144-sd.png", + "hd_png": "art/tile-144-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-145-sd.png", + "hd_png": "art/tile-145-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-146-sd.png", + "hd_png": "art/tile-146-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-147-sd.png", + "hd_png": "art/tile-147-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-148-sd.png", + "hd_png": "art/tile-148-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-149-sd.png", + "hd_png": "art/tile-149-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-150-sd.png", + "hd_png": "art/tile-150-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-151-sd.png", + "hd_png": "art/tile-151-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-152-sd.png", + "hd_png": "art/tile-152-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-153-sd.png", + "hd_png": "art/tile-153-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-154-sd.png", + "hd_png": "art/tile-154-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-155-sd.png", + "hd_png": "art/tile-155-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-156-sd.png", + "hd_png": "art/tile-156-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-157-sd.png", + "hd_png": "art/tile-157-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-158-sd.png", + "hd_png": "art/tile-158-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-159-sd.png", + "hd_png": "art/tile-159-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-160-sd.png", + "hd_png": "art/tile-160-hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile-161-sd.png", + "hd_png": "art/tile-161-hd.png", + "logical_width": 32, + "logical_height": 32 + } + } + ], + "spawns": [ + { + "tick": 90, + "enemy": "base:enemy_0_22", + "x": 48, + "y": -32, + "difficulty": 0 + }, + { + "tick": 142, + "enemy": "iron_coast_stage2_interceptor:unit", + "x": 216, + "y": -32, + "difficulty": 0 + }, + { + "tick": 202, + "enemy": "iron_coast_stage2_interceptor:unit", + "x": 96, + "y": -32, + "difficulty": 0 + }, + { + "tick": 330, + "enemy": "base:enemy_0_21", + "x": 224, + "y": -32, + "difficulty": 0 + }, + { + "tick": 382, + "enemy": "iron_coast_stage2_interceptor:unit", + "x": 56, + "y": -32, + "difficulty": 0 + }, + { + "tick": 400, + "enemy": "iron_coast_stage2_mission_5:target", + "x": 56, + "y": -32, + "difficulty": 0 + }, + { + "tick": 442, + "enemy": "iron_coast_stage2_interceptor:unit", + "x": 176, + "y": -32, + "difficulty": 0 + }, + { + "tick": 470, + "enemy": "iron_coast_stage2_siege:unit", + "x": 96, + "y": -32, + "difficulty": 0 + }, + { + "tick": 650, + "enemy": "base:enemy_1_26", + "x": 64, + "y": -32, + "difficulty": 0 + }, + { + "tick": 702, + "enemy": "iron_coast_stage2_interceptor:unit", + "x": 216, + "y": -32, + "difficulty": 0 + }, + { + "tick": 762, + "enemy": "iron_coast_stage2_interceptor:unit", + "x": 96, + "y": -32, + "difficulty": 0 + }, + { + "tick": 970, + "enemy": "base:enemy_1_25", + "x": 208, + "y": -32, + "difficulty": 0 + }, + { + "tick": 1022, + "enemy": "iron_coast_stage2_interceptor:unit", + "x": 56, + "y": -32, + "difficulty": 0 + }, + { + "tick": 1082, + "enemy": "iron_coast_stage2_interceptor:unit", + "x": 176, + "y": -32, + "difficulty": 0 + }, + { + "tick": 1130, + "enemy": "iron_coast_stage2_siege:unit", + "x": 184, + "y": -32, + "difficulty": 0 + }, + { + "tick": 1240, + "enemy": "iron_coast_stage2_mission_5:target", + "x": 232, + "y": -32, + "difficulty": 0 + }, + { + "tick": 1310, + "enemy": "base:enemy_0_13", + "x": 144, + "y": -32, + "difficulty": 0 + }, + { + "tick": 1362, + "enemy": "iron_coast_stage2_interceptor:unit", + "x": 216, + "y": -32, + "difficulty": 0 + }, + { + "tick": 1422, + "enemy": "iron_coast_stage2_interceptor:unit", + "x": 96, + "y": -32, + "difficulty": 0 + }, + { + "tick": 1630, + "enemy": "base:enemy_0_12", + "x": 136, + "y": -32, + "difficulty": 0 + }, + { + "tick": 1682, + "enemy": "iron_coast_stage2_interceptor:unit", + "x": 56, + "y": -32, + "difficulty": 0 + }, + { + "tick": 1720, + "enemy": "iron_coast_stage2_siege:unit", + "x": 72, + "y": -32, + "difficulty": 0 + }, + { + "tick": 1742, + "enemy": "iron_coast_stage2_interceptor:unit", + "x": 176, + "y": -32, + "difficulty": 0 + }, + { + "tick": 1910, + "enemy": "base:enemy_0_22", + "x": 48, + "y": -32, + "difficulty": 0 + }, + { + "tick": 1962, + "enemy": "iron_coast_stage2_interceptor:unit", + "x": 216, + "y": -32, + "difficulty": 0 + }, + { + "tick": 2022, + "enemy": "iron_coast_stage2_interceptor:unit", + "x": 96, + "y": -32, + "difficulty": 0 + }, + { + "tick": 2340, + "enemy": "iron_coast_stage2_boss_5:unit", + "x": 104, + "y": 24, + "difficulty": 0 + } + ], + "next": null, + "art": { + "png": "art/briefing-sd.png", + "hd_png": "art/briefing-hd.png", + "logical_width": 320, + "logical_height": 200 + }, + "music_track": "iron_coast_stage2_music:assault", + "script": "scripts/mission.rhai" + } + ], + "campaigns": [ + { + "id": "iron_coast_stage2_mission_5:campaign", + "name": "Iron Coast II: Skybreaker Arsenal", + "missions": [ + "iron_coast_stage2_mission_5:mission_05" + ], + "art": { + "png": "art/briefing-sd.png", + "hd_png": "art/briefing-hd.png", + "logical_width": 320, + "logical_height": 200 + } + } + ] +} diff --git a/mods/iron_coast_stage2_mission_5/mod.toml b/mods/iron_coast_stage2_mission_5/mod.toml new file mode 100644 index 00000000..2e2e72c9 --- /dev/null +++ b/mods/iron_coast_stage2_mission_5/mod.toml @@ -0,0 +1,13 @@ +id = "iron_coast_stage2_mission_5" +name = "Black Tide — Mission 5: Skybreaker Arsenal" +version = "1.0.0" +api_version = 1 +description = "Raid a cliffside airborne-weapon test facility, destroy both test batteries and bring down the Skybreaker flying fortress. Objective-driven standalone mission with SD/HD terrain, classic native foes and new audio." +content = "content.json" +scripts = ["scripts/mission.rhai", "scripts/target.rhai"] + +[dependencies] +iron_coast_stage2_boss_5 = "^1.0" +iron_coast_stage2_music = "^1.0" +iron_coast_stage2_interceptor = "^1.0" +iron_coast_stage2_siege = "^1.0" diff --git a/mods/iron_coast_stage2_mission_5/prompts/request-v1.json b/mods/iron_coast_stage2_mission_5/prompts/request-v1.json new file mode 100644 index 00000000..f869cba1 --- /dev/null +++ b/mods/iron_coast_stage2_mission_5/prompts/request-v1.json @@ -0,0 +1,7 @@ +{ + "prompt": "Use case: stylized-concept\nAsset type: opaque square top-down vertically scrolling game terrain master, Skybreaker Arsenal.\nInput image: original Raptor industrial terrain source sheet is a style reference only, not an edit target. Retain top-down orthographic geography, chunky readable steel structures, upper-left light and muted palette.\nScene: cliffside airborne-weapons test facility along a dark teal ocean. The left quarter is dark coastal water, middle is a long gray steel/concrete aircraft test runway and weathered launch pads, right quarter is jagged brown-gray cliff rock supporting a few compact low weapons sheds and ribbed industrial service routes. Narrow crane bases and small repeating catwalk links; facility is military and exposed to sea. Gray gunmetal, weathered stone, restrained rust, tiny cyan markings, muted blue-green water. No aircraft/enemies/characters or projectiles; those are separate sprites.\nComposition: entirely opaque square canvas seen perfectly top-down, no perspective, no sky/horizon, no text/signs/logos. Vertical scrolling orientation: coast and runway travel from top to bottom. Keep top and bottom edge bands materially compatible so the same square terrain section can repeat vertically, without a framed border. Avoid giant hero landmarks, invented 3D buildings, diagonal viewpoint or cinematic lens effects. Fine new HD gritty details must remain readable when downsampled to a 288 by 288 pixel old-game terrain sheet with a 9 by 9 logical 32-pixel tile grid. Fill every pixel with geography; do not draw grid lines.\n", + "referenced_image_paths": [ + "/home/quintine/Projects/RaptorReplica/data/hd/jobs/terrain-3010d-3011c/source-sheet.png" + ], + "transparent_background": false +} diff --git a/mods/iron_coast_stage2_mission_5/prompts/v1.txt b/mods/iron_coast_stage2_mission_5/prompts/v1.txt new file mode 100644 index 00000000..0ccd485d --- /dev/null +++ b/mods/iron_coast_stage2_mission_5/prompts/v1.txt @@ -0,0 +1,5 @@ +Use case: stylized-concept +Asset type: opaque square top-down vertically scrolling game terrain master, Skybreaker Arsenal. +Input image: original Raptor industrial terrain source sheet is a style reference only, not an edit target. Retain top-down orthographic geography, chunky readable steel structures, upper-left light and muted palette. +Scene: cliffside airborne-weapons test facility along a dark teal ocean. The left quarter is dark coastal water, middle is a long gray steel/concrete aircraft test runway and weathered launch pads, right quarter is jagged brown-gray cliff rock supporting a few compact low weapons sheds and ribbed industrial service routes. Narrow crane bases and small repeating catwalk links; facility is military and exposed to sea. Gray gunmetal, weathered stone, restrained rust, tiny cyan markings, muted blue-green water. No aircraft/enemies/characters or projectiles; those are separate sprites. +Composition: entirely opaque square canvas seen perfectly top-down, no perspective, no sky/horizon, no text/signs/logos. Vertical scrolling orientation: coast and runway travel from top to bottom. Keep top and bottom edge bands materially compatible so the same square terrain section can repeat vertically, without a framed border. Avoid giant hero landmarks, invented 3D buildings, diagonal viewpoint or cinematic lens effects. Fine new HD gritty details must remain readable when downsampled to a 288 by 288 pixel old-game terrain sheet with a 9 by 9 logical 32-pixel tile grid. Fill every pixel with geography; do not draw grid lines. diff --git a/mods/iron_coast_stage2_mission_5/provenance.json b/mods/iron_coast_stage2_mission_5/provenance.json new file mode 100644 index 00000000..7df5e4a5 --- /dev/null +++ b/mods/iron_coast_stage2_mission_5/provenance.json @@ -0,0 +1,19 @@ +{ + "begun_utc": "2026-10-11 08:11:24 UTC", + "ended_utc": "2026-10-11 08:11:49 UTC", + "gate_lease": "922bebc5-989f-4155-8cd1-c5405199bc62", + "generator_raw": "/home/quintine/.codex/generated_images/01a1245d-ddd6-7c41-8bab-0a08c2b68f4d/exec-9335d8ca-cc86-4d40-973d-a158111889c0.png", + "mode": "built-in", + "notes": "External original terrain is style reference only; raw master is new original generated art.", + "outcome": "success", + "prompt": "prompts/v1.txt", + "prompt_sha256": "dac00cf75999da2a9adfc1b55b1d289875088a545ee9b22e360ea3fd2d452569", + "raw_copy": "sources/raw-v1.png", + "raw_sha256": "fe28de73c1c4d1e0348d9d482cd01114d26bdb068485487e1ff9cef9aaa1a229", + "reference_hashes": { + "/home/quintine/Projects/RaptorReplica/data/hd/jobs/terrain-3010d-3011c/source-sheet.png": "f3c8b0b1526a9e2c14445ab2054c1df49b6398559830ec0ace2a90470e78e96c" + }, + "request": "prompts/request-v1.json", + "tool": "image_gen.imagegen", + "transparent_background": false +} diff --git a/mods/iron_coast_stage2_mission_5/scripts/mission.rhai b/mods/iron_coast_stage2_mission_5/scripts/mission.rhai new file mode 100644 index 00000000..1f7b866d --- /dev/null +++ b/mods/iron_coast_stage2_mission_5/scripts/mission.rhai @@ -0,0 +1,49 @@ +// All encounter flags reset on entry. No inventory grants, consumption or equipment loans. +fn on_mission_start(event, state, random) { + #{commands:[#{op:"objective",key:"iron_coast_stage2_mission_5:targets_destroyed",value:0},#{op:"objective",key:"iron_coast_stage2_mission_5:targets_required",value:2},#{op:"objective",key:"iron_coast_stage2_mission_5:complete",value:0},#{op:"objective",key:"iron_coast_stage2_mission_5:phase",value:1},#{op:"objective",key:"iron_coast_stage2_mission_5:hazard_lane",value:0},#{op:"objective",key:"iron_coast_stage2_boss_5:defeated",value:0},#{op:"objective",key:"iron_coast_stage2_mission_5:field_repair",value:0},#{op:"objective",key:"iron_coast_stage2_mission_5:debrief",value:0},#{op:"play_sound",sound:"iron_coast_stage2_mission_5:approach"}],state:#{complete:false,repair:false,boss_warning:false}} +} +fn on_tick(event, state, random) { + let commands = []; + if event.tick == 400 || event.tick == 1240 { + commands.push(#{op:"objective",key:"iron_coast_stage2_mission_5:phase",value:2}); + commands.push(#{op:"play_sound",sound:"iron_coast_stage2_mission_5:alarm"}); + } + if event.tick >= 1400 && !state.repair { + state.repair = true; + commands.push(#{op:"shield",amount:15}); + commands.push(#{op:"objective",key:"iron_coast_stage2_mission_5:field_repair",value:1}); + } + // Warning precedes three outer-lane shots by24 ticks. The center remains safe. + if event.tick >= 700 && event.tick < 2200 { + if event.tick % 240 == 0 { + let lane = if (event.tick / 240) % 2 == 0 { -1 } else { 1 }; + commands.push(#{op:"objective",key:"iron_coast_stage2_mission_5:hazard_lane",value:lane}); + commands.push(#{op:"play_sound",sound:"iron_coast_stage2_mission_5:hazard"}); + } + if event.tick % 240 == 24 { + let x = if (event.tick / 240) % 2 == 0 { 48 } else { 248 }; + for dx in [-12,0,12] { commands.push(#{op:"projectile",weapon:"iron_coast_stage2_mission_5:hazard_shell",x:x+dx,y:12,vx:0,vy:4,hostile:true}); } + commands.push(#{op:"objective",key:"iron_coast_stage2_mission_5:hazard_lane",value:0}); + } + } + if event.tick >= 2340 && !state.boss_warning { + state.boss_warning = true; + commands.push(#{op:"objective",key:"iron_coast_stage2_mission_5:phase",value:3}); + commands.push(#{op:"shield",amount:15}); + commands.push(#{op:"play_sound",sound:"iron_coast_stage2_mission_5:alarm"}); + } + let targets = if event.objectives.contains("iron_coast_stage2_mission_5:targets_destroyed") { event.objectives["iron_coast_stage2_mission_5:targets_destroyed"] } else { 0 }; + let boss = if event.objectives.contains("iron_coast_stage2_boss_5:defeated") { event.objectives["iron_coast_stage2_boss_5:defeated"] } else { 0 }; + if targets >= 2 && boss >= 1 && !state.complete { + state.complete = true; + commands.push(#{op:"objective",key:"iron_coast_stage2_mission_5:complete",value:1}); + commands.push(#{op:"objective",key:"iron_coast_stage2_mission_5:phase",value:4}); + commands.push(#{op:"credits",amount:26000}); + commands.push(#{op:"play_sound",sound:"iron_coast_stage2_mission_5:victory"}); + commands.push(#{op:"complete"}); + } + #{commands:commands,state:state} +} +fn on_mission_end(event, state, random) { + #{commands:[#{op:"objective",key:"iron_coast_stage2_mission_5:debrief",value:if event.success { 1 } else { 0 }}],state:state} +} diff --git a/mods/iron_coast_stage2_mission_5/scripts/target.rhai b/mods/iron_coast_stage2_mission_5/scripts/target.rhai new file mode 100644 index 00000000..fa31e556 --- /dev/null +++ b/mods/iron_coast_stage2_mission_5/scripts/target.rhai @@ -0,0 +1,20 @@ +fn alive(event) { + for e in event.entities { if e.entity == event.entity && e.health > 0 { return true; } } + false +} +fn on_spawn(event, state, random) { + #{commands:if alive(event) { [#{op:"velocity",entity:event.entity,vx:0,vy:2}] } else { [] },state:state} +} +fn on_tick(event, state, random) { + if event.health <= 0 || !alive(event) { return #{commands:[],state:state}; } + if event.y < 28 { return #{commands:[#{op:"velocity",entity:event.entity,vx:0,vy:2}],state:state}; } + // Required objectives stay in the player's visible firing corridor until killed. + #{commands:[#{op:"move",entity:event.entity,x:event.x,y:28},#{op:"velocity",entity:event.entity,vx:0,vy:0}],state:state} +} +fn on_fire(event, state, random) { + #{commands:[#{op:"play_sound",sound:"iron_coast_stage2_mission_5:alarm"}],state:state} +} +fn on_death(event, state, random) { + let n = if event.objectives.contains("iron_coast_stage2_mission_5:targets_destroyed") { event.objectives["iron_coast_stage2_mission_5:targets_destroyed"]+1 } else { 1 }; + #{commands:[#{op:"objective",key:"iron_coast_stage2_mission_5:targets_destroyed",value:n},#{op:"shield",amount:8},#{op:"play_sound",sound:"iron_coast_stage2_mission_5:target_down"}],state:state} +} diff --git a/mods/iron_coast_stage2_mission_5/sources/raw-v1.png b/mods/iron_coast_stage2_mission_5/sources/raw-v1.png new file mode 100644 index 00000000..912a9b71 Binary files /dev/null and b/mods/iron_coast_stage2_mission_5/sources/raw-v1.png differ diff --git a/mods/iron_coast_stage2_mission_5/tools/build_assets.py b/mods/iron_coast_stage2_mission_5/tools/build_assets.py new file mode 100644 index 00000000..56f6f52e --- /dev/null +++ b/mods/iron_coast_stage2_mission_5/tools/build_assets.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python3 +"""Prepare game assets from unchanged generated masters and synthesize PCM cues. + +Requires Pillow. Original Raptor reference images stay external. The original +palette is read only for ordinary-color SD quantization; final assets are local. +No generated RGB is retouched: whole-canvas proportional fit, resampling, +cropping into tiles and reflected terrain repetition are explicit derivatives. +""" +from pathlib import Path +import json,hashlib,math,random,struct,wave +from PIL import Image,ImageOps,ImageDraw +ROOT=Path(__file__).resolve().parent.parent +NUMBER=int(ROOT.name.rsplit('_',1)[1]);IS_BOSS='_boss_'in ROOT.name +sha=lambda p:hashlib.sha256(p.read_bytes()).hexdigest() +write=lambda p,j:p.write_text(json.dumps(j,indent=2,sort_keys=True)+'\n') + +def palette(): + path=ROOT.parents[1]/'data/misc/PALETTE_DAT' + b=path.read_bytes();assert len(b)==768 + rgb=[(min(v,63)<<2)|(min(v,63)>>4)for v in b[:720]] + image=Image.new('P',(1,1));image.putpalette(rgb+[0]*48) + return image,{'source':'PALETTE_DAT','sha256':sha(path),'ordinary_indices':[0,239]} + +def sd_quantize(image,pal): + a=image.getchannel('A')if image.mode=='RGBA'else None + # Duplicate palette0 in unused slots so quantization cannot create a reserved class. + pal=pal.copy();p=pal.getpalette();p[720:768]=p[:3]*16;pal.putpalette(p) + q=image.convert('RGB').quantize(palette=pal,dither=Image.Dither.NONE).convert('RGBA') + if a is not None:q.putalpha(a) + return q + +def artwork(): + raw=ROOT/'sources/raw-v1.png';source=Image.open(raw).convert('RGBA');pal,binding=palette();files={} + def save(name,img): + p=ROOT/'art'/name;img.save(p);alpha=img.getchannel('A');mask=alpha.point(lambda a:255 if a>=128 else 0) + files[name]={'size':list(img.size),'sha256':sha(p),'opaque_bounds':list(mask.getbbox())if mask.getbbox()else None,'transparent_pixels':sum(a<128 for a in alpha.get_flattened_data())} + if IS_BOSS: + logical=(112,56 if NUMBER==5 else 72);target=tuple(v*4 for v in logical) + assert source.getchannel('A').getextrema()[0]==0 and source.getchannel('A').getextrema()[1]>=128,'Real generated alpha required' + fit=ImageOps.contain(source,(target[0]-32,target[1]-32),Image.Resampling.LANCZOS) + hd=Image.new('RGBA',target,(0,0,0,0));hd.alpha_composite(fit,((target[0]-fit.width)//2,(target[1]-fit.height)//2)) + sd=sd_quantize(hd.resize(logical,Image.Resampling.LANCZOS),pal) + save('unit-hd.png',hd);save('unit-sd.png',sd) + for name in ['unit-hd.png','unit-sd.png']: + bounds=files[name]['opaque_bounds'];size=files[name]['size'];assert bounds and min(bounds[:2])>=2 and bounds[2]= 1400 && !state.repair { + state.repair = true; + commands.push(#{op:"shield",amount:15}); + commands.push(#{op:"objective",key:"iron_coast_stage2_mission_6:field_repair",value:1}); + } + // Warning precedes three outer-lane shots by24 ticks. The center remains safe. + if event.tick >= 700 && event.tick < 2200 { + if event.tick % 240 == 0 { + let lane = if (event.tick / 240) % 2 == 0 { -1 } else { 1 }; + commands.push(#{op:"objective",key:"iron_coast_stage2_mission_6:hazard_lane",value:lane}); + commands.push(#{op:"play_sound",sound:"iron_coast_stage2_mission_6:hazard"}); + } + if event.tick % 240 == 24 { + let x = if (event.tick / 240) % 2 == 0 { 48 } else { 248 }; + for dx in [-12,0,12] { commands.push(#{op:"projectile",weapon:"iron_coast_stage2_mission_6:hazard_shell",x:x+dx,y:12,vx:0,vy:4,hostile:true}); } + commands.push(#{op:"objective",key:"iron_coast_stage2_mission_6:hazard_lane",value:0}); + } + } + if event.tick >= 2380 && !state.boss_warning { + state.boss_warning = true; + commands.push(#{op:"objective",key:"iron_coast_stage2_mission_6:phase",value:3}); + commands.push(#{op:"shield",amount:15}); + commands.push(#{op:"play_sound",sound:"iron_coast_stage2_mission_6:alarm"}); + } + let targets = if event.objectives.contains("iron_coast_stage2_mission_6:targets_destroyed") { event.objectives["iron_coast_stage2_mission_6:targets_destroyed"] } else { 0 }; + let boss = if event.objectives.contains("iron_coast_stage2_boss_6:defeated") { event.objectives["iron_coast_stage2_boss_6:defeated"] } else { 0 }; + if targets >= 3 && boss >= 1 && !state.complete { + state.complete = true; + commands.push(#{op:"objective",key:"iron_coast_stage2_mission_6:complete",value:1}); + commands.push(#{op:"objective",key:"iron_coast_stage2_mission_6:phase",value:4}); + commands.push(#{op:"credits",amount:32000}); + commands.push(#{op:"play_sound",sound:"iron_coast_stage2_mission_6:victory"}); + commands.push(#{op:"complete"}); + } + #{commands:commands,state:state} +} +fn on_mission_end(event, state, random) { + #{commands:[#{op:"objective",key:"iron_coast_stage2_mission_6:debrief",value:if event.success { 1 } else { 0 }}],state:state} +} diff --git a/mods/iron_coast_stage2_mission_6/scripts/target.rhai b/mods/iron_coast_stage2_mission_6/scripts/target.rhai new file mode 100644 index 00000000..e4bc13aa --- /dev/null +++ b/mods/iron_coast_stage2_mission_6/scripts/target.rhai @@ -0,0 +1,20 @@ +fn alive(event) { + for e in event.entities { if e.entity == event.entity && e.health > 0 { return true; } } + false +} +fn on_spawn(event, state, random) { + #{commands:if alive(event) { [#{op:"velocity",entity:event.entity,vx:0,vy:2}] } else { [] },state:state} +} +fn on_tick(event, state, random) { + if event.health <= 0 || !alive(event) { return #{commands:[],state:state}; } + if event.y < 28 { return #{commands:[#{op:"velocity",entity:event.entity,vx:0,vy:2}],state:state}; } + // Required objectives stay in the player's visible firing corridor until killed. + #{commands:[#{op:"move",entity:event.entity,x:event.x,y:28},#{op:"velocity",entity:event.entity,vx:0,vy:0}],state:state} +} +fn on_fire(event, state, random) { + #{commands:[#{op:"play_sound",sound:"iron_coast_stage2_mission_6:alarm"}],state:state} +} +fn on_death(event, state, random) { + let n = if event.objectives.contains("iron_coast_stage2_mission_6:targets_destroyed") { event.objectives["iron_coast_stage2_mission_6:targets_destroyed"]+1 } else { 1 }; + #{commands:[#{op:"objective",key:"iron_coast_stage2_mission_6:targets_destroyed",value:n},#{op:"shield",amount:8},#{op:"play_sound",sound:"iron_coast_stage2_mission_6:target_down"}],state:state} +} diff --git a/mods/iron_coast_stage2_mission_6/sources/raw-v1.png b/mods/iron_coast_stage2_mission_6/sources/raw-v1.png new file mode 100644 index 00000000..6a089b87 Binary files /dev/null and b/mods/iron_coast_stage2_mission_6/sources/raw-v1.png differ diff --git a/mods/iron_coast_stage2_mission_6/tools/build_assets.py b/mods/iron_coast_stage2_mission_6/tools/build_assets.py new file mode 100644 index 00000000..56f6f52e --- /dev/null +++ b/mods/iron_coast_stage2_mission_6/tools/build_assets.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python3 +"""Prepare game assets from unchanged generated masters and synthesize PCM cues. + +Requires Pillow. Original Raptor reference images stay external. The original +palette is read only for ordinary-color SD quantization; final assets are local. +No generated RGB is retouched: whole-canvas proportional fit, resampling, +cropping into tiles and reflected terrain repetition are explicit derivatives. +""" +from pathlib import Path +import json,hashlib,math,random,struct,wave +from PIL import Image,ImageOps,ImageDraw +ROOT=Path(__file__).resolve().parent.parent +NUMBER=int(ROOT.name.rsplit('_',1)[1]);IS_BOSS='_boss_'in ROOT.name +sha=lambda p:hashlib.sha256(p.read_bytes()).hexdigest() +write=lambda p,j:p.write_text(json.dumps(j,indent=2,sort_keys=True)+'\n') + +def palette(): + path=ROOT.parents[1]/'data/misc/PALETTE_DAT' + b=path.read_bytes();assert len(b)==768 + rgb=[(min(v,63)<<2)|(min(v,63)>>4)for v in b[:720]] + image=Image.new('P',(1,1));image.putpalette(rgb+[0]*48) + return image,{'source':'PALETTE_DAT','sha256':sha(path),'ordinary_indices':[0,239]} + +def sd_quantize(image,pal): + a=image.getchannel('A')if image.mode=='RGBA'else None + # Duplicate palette0 in unused slots so quantization cannot create a reserved class. + pal=pal.copy();p=pal.getpalette();p[720:768]=p[:3]*16;pal.putpalette(p) + q=image.convert('RGB').quantize(palette=pal,dither=Image.Dither.NONE).convert('RGBA') + if a is not None:q.putalpha(a) + return q + +def artwork(): + raw=ROOT/'sources/raw-v1.png';source=Image.open(raw).convert('RGBA');pal,binding=palette();files={} + def save(name,img): + p=ROOT/'art'/name;img.save(p);alpha=img.getchannel('A');mask=alpha.point(lambda a:255 if a>=128 else 0) + files[name]={'size':list(img.size),'sha256':sha(p),'opaque_bounds':list(mask.getbbox())if mask.getbbox()else None,'transparent_pixels':sum(a<128 for a in alpha.get_flattened_data())} + if IS_BOSS: + logical=(112,56 if NUMBER==5 else 72);target=tuple(v*4 for v in logical) + assert source.getchannel('A').getextrema()[0]==0 and source.getchannel('A').getextrema()[1]>=128,'Real generated alpha required' + fit=ImageOps.contain(source,(target[0]-32,target[1]-32),Image.Resampling.LANCZOS) + hd=Image.new('RGBA',target,(0,0,0,0));hd.alpha_composite(fit,((target[0]-fit.width)//2,(target[1]-fit.height)//2)) + sd=sd_quantize(hd.resize(logical,Image.Resampling.LANCZOS),pal) + save('unit-hd.png',hd);save('unit-sd.png',sd) + for name in ['unit-hd.png','unit-sd.png']: + bounds=files[name]['opaque_bounds'];size=files[name]['size'];assert bounds and min(bounds[:2])>=2 and bounds[2]=y { + let x=if unit.x<16 {16} else if unit.x>240 {240} else {unit.x}; + commands.push(#{op:"move",entity:unit.entity,x:x,y:y}); + } + } + } + if !state.second && event.tick>=900 { + state.second=true; + commands.push(#{op:"objective",key:"iron_coast_stage2_mission_7:phase",value:2});commands.push(#{op:"play_sound",sound:"iron_coast_stage2_mission_7:escalation"}); + commands.push(#{op:"shield",amount:15}); + } + if !state.third && event.tick>=1800 { + state.third=true; + commands.push(#{op:"objective",key:"iron_coast_stage2_mission_7:phase",value:3});commands.push(#{op:"play_sound",sound:"iron_coast_stage2_mission_7:escalation"}); + commands.push(#{op:"shield",amount:15}); + } + if !state.boss && event.tick>=2500 { + state.boss=true; + commands.push(#{op:"objective",key:"iron_coast_stage2_mission_7:phase",value:4});commands.push(#{op:"play_sound",sound:"iron_coast_stage2_mission_7:boss_alarm"}); + commands.push(#{op:"shield",amount:20}); + } + let siege=if event.objectives.contains("iron_coast_stage2_siege:defeated") {event.objectives["iron_coast_stage2_siege:defeated"]} else {0}; + let skimmers=if event.objectives.contains("iron_coast_stage2_skimmer:defeated") {event.objectives["iron_coast_stage2_skimmer:defeated"]} else {0}; + let bosses=if event.objectives.contains("iron_coast_stage2_boss_7:defeated") {event.objectives["iron_coast_stage2_boss_7:defeated"]} else {0}; + if !state.complete && state.boss && siege>=4 && skimmers>=3 && bosses>=1 { + state.complete=true; + commands.push(#{op:"objective",key:"iron_coast_stage2_mission_7:phase",value:5});commands.push(#{op:"objective",key:"iron_coast_stage2_mission_7:debrief",value:1});commands.push(#{op:"objective",key:"iron_coast_stage2_mission_7:complete",value:1}); + commands.push(#{op:"credits",amount:32000});commands.push(#{op:"play_sound",sound:"iron_coast_stage2_mission_7:victory"});commands.push(#{op:"complete"}); + } + #{commands:commands,state:state} +} +fn on_mission_end(event,state,random) { #{commands:[],state:state} } diff --git a/mods/iron_coast_stage2_mission_7/validation-summary.json b/mods/iron_coast_stage2_mission_7/validation-summary.json new file mode 100644 index 00000000..3453080b --- /dev/null +++ b/mods/iron_coast_stage2_mission_7/validation-summary.json @@ -0,0 +1,472 @@ +{ + "status": "Author production acceptance passed; independent campaign/SD-HD Host review handled separately", + "package": "iron_coast_stage2_mission_7", + "version": "1.0.0", + "api_version": 1, + "actual_original_catalog": true, + "starter_fire_only": true, + "normal_movement_limit_pixels_per_tick": 4, + "near_shot_sidesteps": { + "hostile_y": [ + 136, + 188 + ], + "horizontal_distance_from_player_center": 24 + }, + "runs": [ + { + "boss_only": false, + "classic_ids": [ + "base:enemy_0_23", + "base:enemy_0_24", + "base:enemy_0_73", + "base:enemy_0_74", + "base:enemy_0_95", + "base:enemy_0_96" + ], + "credits": 56900, + "difficulty": 0, + "digest": "855a0b362de4cb0884822414bfe0b3cff3eb71d298f7e2c789f031101041e4c8", + "initial_credits": 10000, + "initial_shield": 75, + "inventory_preserved": true, + "inventory_slots": 2, + "maximum_live_enemies": 3, + "mission": 7, + "native_movement_ids": [ + "base:enemy_0_23", + "base:enemy_0_24", + "base:enemy_0_73", + "base:enemy_0_74", + "base:enemy_0_95", + "base:enemy_0_96" + ], + "objectives": { + "iron_coast_stage2_boss_7:defeated": 1, + "iron_coast_stage2_boss_7:phase": 2, + "iron_coast_stage2_boss_7:safe_lane": 1, + "iron_coast_stage2_interceptor:defeated": 6, + "iron_coast_stage2_mission_7:complete": 1, + "iron_coast_stage2_mission_7:debrief": 1, + "iron_coast_stage2_mission_7:phase": 5, + "iron_coast_stage2_mission_7:required_siege": 4, + "iron_coast_stage2_mission_7:required_skimmers": 3, + "iron_coast_stage2_siege:defeated": 4, + "iron_coast_stage2_skimmer:defeated": 3 + }, + "outcome": "Complete", + "phase_frames": [ + 0, + 1 + ], + "rewards_once": true, + "shield": 100, + "sound_ids": [ + "iron_coast_stage2_boss_7:death", + "iron_coast_stage2_boss_7:phase", + "iron_coast_stage2_boss_7:shot", + "iron_coast_stage2_boss_7:warning", + "iron_coast_stage2_interceptor:death", + "iron_coast_stage2_interceptor:shot", + "iron_coast_stage2_mission_7:approach", + "iron_coast_stage2_mission_7:boss_alarm", + "iron_coast_stage2_mission_7:escalation", + "iron_coast_stage2_mission_7:victory", + "iron_coast_stage2_siege:death", + "iron_coast_stage2_siege:shot", + "iron_coast_stage2_siege:warning", + "iron_coast_stage2_skimmer:death", + "iron_coast_stage2_skimmer:shot", + "iron_coast_stage2_skimmer:warning" + ], + "tick": 2637 + }, + { + "boss_only": false, + "classic_ids": [ + "base:enemy_0_23", + "base:enemy_0_24", + "base:enemy_0_73", + "base:enemy_0_74", + "base:enemy_0_95", + "base:enemy_0_96" + ], + "credits": 56900, + "difficulty": 1, + "digest": "59e859f9435f608850e32ab68133aecd0fe75aab0c8127043c1b03aeffcf7595", + "initial_credits": 10000, + "initial_shield": 75, + "inventory_preserved": true, + "inventory_slots": 2, + "maximum_live_enemies": 3, + "mission": 7, + "native_movement_ids": [ + "base:enemy_0_23", + "base:enemy_0_24", + "base:enemy_0_73", + "base:enemy_0_74", + "base:enemy_0_95", + "base:enemy_0_96" + ], + "objectives": { + "iron_coast_stage2_boss_7:defeated": 1, + "iron_coast_stage2_boss_7:phase": 2, + "iron_coast_stage2_boss_7:safe_lane": 1, + "iron_coast_stage2_interceptor:defeated": 6, + "iron_coast_stage2_mission_7:complete": 1, + "iron_coast_stage2_mission_7:debrief": 1, + "iron_coast_stage2_mission_7:phase": 5, + "iron_coast_stage2_mission_7:required_siege": 4, + "iron_coast_stage2_mission_7:required_skimmers": 3, + "iron_coast_stage2_siege:defeated": 4, + "iron_coast_stage2_skimmer:defeated": 3 + }, + "outcome": "Complete", + "phase_frames": [ + 0, + 1 + ], + "rewards_once": true, + "shield": 60, + "sound_ids": [ + "iron_coast_stage2_boss_7:death", + "iron_coast_stage2_boss_7:phase", + "iron_coast_stage2_boss_7:shot", + "iron_coast_stage2_boss_7:warning", + "iron_coast_stage2_interceptor:death", + "iron_coast_stage2_interceptor:shot", + "iron_coast_stage2_mission_7:approach", + "iron_coast_stage2_mission_7:boss_alarm", + "iron_coast_stage2_mission_7:escalation", + "iron_coast_stage2_mission_7:victory", + "iron_coast_stage2_siege:death", + "iron_coast_stage2_siege:shot", + "iron_coast_stage2_siege:warning", + "iron_coast_stage2_skimmer:death", + "iron_coast_stage2_skimmer:shot", + "iron_coast_stage2_skimmer:warning" + ], + "tick": 2637 + }, + { + "boss_only": false, + "classic_ids": [ + "base:enemy_0_23", + "base:enemy_0_24", + "base:enemy_0_73", + "base:enemy_0_74", + "base:enemy_0_95", + "base:enemy_0_96" + ], + "credits": 56900, + "difficulty": 2, + "digest": "a99d996194b23291ce8ba9442d2f21d161a2107f05ff0b5d2f7f613f05801f98", + "initial_credits": 10000, + "initial_shield": 75, + "inventory_preserved": true, + "inventory_slots": 2, + "maximum_live_enemies": 3, + "mission": 7, + "native_movement_ids": [ + "base:enemy_0_23", + "base:enemy_0_24", + "base:enemy_0_73", + "base:enemy_0_74", + "base:enemy_0_95", + "base:enemy_0_96" + ], + "objectives": { + "iron_coast_stage2_boss_7:defeated": 1, + "iron_coast_stage2_boss_7:phase": 2, + "iron_coast_stage2_boss_7:safe_lane": 1, + "iron_coast_stage2_interceptor:defeated": 6, + "iron_coast_stage2_mission_7:complete": 1, + "iron_coast_stage2_mission_7:debrief": 1, + "iron_coast_stage2_mission_7:phase": 5, + "iron_coast_stage2_mission_7:required_siege": 4, + "iron_coast_stage2_mission_7:required_skimmers": 3, + "iron_coast_stage2_siege:defeated": 4, + "iron_coast_stage2_skimmer:defeated": 3 + }, + "outcome": "Complete", + "phase_frames": [ + 0, + 1 + ], + "rewards_once": true, + "shield": 60, + "sound_ids": [ + "iron_coast_stage2_boss_7:death", + "iron_coast_stage2_boss_7:phase", + "iron_coast_stage2_boss_7:shot", + "iron_coast_stage2_boss_7:warning", + "iron_coast_stage2_interceptor:death", + "iron_coast_stage2_interceptor:shot", + "iron_coast_stage2_mission_7:approach", + "iron_coast_stage2_mission_7:boss_alarm", + "iron_coast_stage2_mission_7:escalation", + "iron_coast_stage2_mission_7:victory", + "iron_coast_stage2_siege:death", + "iron_coast_stage2_siege:shot", + "iron_coast_stage2_siege:warning", + "iron_coast_stage2_skimmer:death", + "iron_coast_stage2_skimmer:shot", + "iron_coast_stage2_skimmer:warning" + ], + "tick": 2777 + }, + { + "boss_only": false, + "classic_ids": [ + "base:enemy_0_23", + "base:enemy_0_24", + "base:enemy_0_73", + "base:enemy_0_74", + "base:enemy_0_95", + "base:enemy_0_96" + ], + "credits": 56900, + "difficulty": 3, + "digest": "6e3ef516c543e57940d961112e513f96051dbceeb8367c17751aed906bd4367e", + "initial_credits": 10000, + "initial_shield": 75, + "inventory_preserved": true, + "inventory_slots": 2, + "maximum_live_enemies": 3, + "mission": 7, + "native_movement_ids": [ + "base:enemy_0_23", + "base:enemy_0_24", + "base:enemy_0_73", + "base:enemy_0_74", + "base:enemy_0_95", + "base:enemy_0_96" + ], + "objectives": { + "iron_coast_stage2_boss_7:defeated": 1, + "iron_coast_stage2_boss_7:phase": 2, + "iron_coast_stage2_boss_7:safe_lane": 1, + "iron_coast_stage2_interceptor:defeated": 6, + "iron_coast_stage2_mission_7:complete": 1, + "iron_coast_stage2_mission_7:debrief": 1, + "iron_coast_stage2_mission_7:phase": 5, + "iron_coast_stage2_mission_7:required_siege": 4, + "iron_coast_stage2_mission_7:required_skimmers": 3, + "iron_coast_stage2_siege:defeated": 4, + "iron_coast_stage2_skimmer:defeated": 3 + }, + "outcome": "Complete", + "phase_frames": [ + 0, + 1 + ], + "rewards_once": true, + "shield": 60, + "sound_ids": [ + "iron_coast_stage2_boss_7:death", + "iron_coast_stage2_boss_7:phase", + "iron_coast_stage2_boss_7:shot", + "iron_coast_stage2_boss_7:warning", + "iron_coast_stage2_interceptor:death", + "iron_coast_stage2_interceptor:shot", + "iron_coast_stage2_mission_7:approach", + "iron_coast_stage2_mission_7:boss_alarm", + "iron_coast_stage2_mission_7:escalation", + "iron_coast_stage2_mission_7:victory", + "iron_coast_stage2_siege:death", + "iron_coast_stage2_siege:shot", + "iron_coast_stage2_siege:warning", + "iron_coast_stage2_skimmer:death", + "iron_coast_stage2_skimmer:shot", + "iron_coast_stage2_skimmer:warning" + ], + "tick": 2777 + }, + { + "boss_only": false, + "classic_ids": [ + "base:enemy_0_23", + "base:enemy_0_24", + "base:enemy_0_73", + "base:enemy_0_74", + "base:enemy_0_95", + "base:enemy_0_96" + ], + "credits": 46900, + "difficulty": 2, + "digest": "7bf8b1173aded78f27da0a3f1406128038b096258a4498adf711683ecb1565f4", + "initial_credits": 0, + "initial_shield": 100, + "inventory_preserved": true, + "inventory_slots": 2, + "maximum_live_enemies": 3, + "mission": 7, + "native_movement_ids": [ + "base:enemy_0_23", + "base:enemy_0_24", + "base:enemy_0_73", + "base:enemy_0_74", + "base:enemy_0_95", + "base:enemy_0_96" + ], + "objectives": { + "iron_coast_stage2_boss_7:defeated": 1, + "iron_coast_stage2_boss_7:phase": 2, + "iron_coast_stage2_boss_7:safe_lane": 1, + "iron_coast_stage2_interceptor:defeated": 6, + "iron_coast_stage2_mission_7:complete": 1, + "iron_coast_stage2_mission_7:debrief": 1, + "iron_coast_stage2_mission_7:phase": 5, + "iron_coast_stage2_mission_7:required_siege": 4, + "iron_coast_stage2_mission_7:required_skimmers": 3, + "iron_coast_stage2_siege:defeated": 4, + "iron_coast_stage2_skimmer:defeated": 3 + }, + "outcome": "Complete", + "phase_frames": [ + 0, + 1 + ], + "rewards_once": true, + "shield": 70, + "sound_ids": [ + "iron_coast_stage2_boss_7:death", + "iron_coast_stage2_boss_7:phase", + "iron_coast_stage2_boss_7:shot", + "iron_coast_stage2_boss_7:warning", + "iron_coast_stage2_interceptor:death", + "iron_coast_stage2_interceptor:shot", + "iron_coast_stage2_mission_7:approach", + "iron_coast_stage2_mission_7:boss_alarm", + "iron_coast_stage2_mission_7:escalation", + "iron_coast_stage2_mission_7:victory", + "iron_coast_stage2_siege:death", + "iron_coast_stage2_siege:shot", + "iron_coast_stage2_siege:warning", + "iron_coast_stage2_skimmer:death", + "iron_coast_stage2_skimmer:shot", + "iron_coast_stage2_skimmer:warning" + ], + "tick": 2777 + }, + { + "boss_only": false, + "classic_ids": [ + "base:enemy_0_23", + "base:enemy_0_24", + "base:enemy_0_73", + "base:enemy_0_74", + "base:enemy_0_95", + "base:enemy_0_96" + ], + "credits": 56900, + "difficulty": 2, + "digest": "d3ff5a418a828efe7024ce6d1724d377e0991bee3f8e0ac77616f62713bd878c", + "initial_credits": 10000, + "initial_shield": 75, + "inventory_preserved": true, + "inventory_slots": 20, + "maximum_live_enemies": 3, + "mission": 7, + "native_movement_ids": [ + "base:enemy_0_23", + "base:enemy_0_24", + "base:enemy_0_73", + "base:enemy_0_74", + "base:enemy_0_95", + "base:enemy_0_96" + ], + "objectives": { + "iron_coast_stage2_boss_7:defeated": 1, + "iron_coast_stage2_boss_7:phase": 2, + "iron_coast_stage2_boss_7:safe_lane": 1, + "iron_coast_stage2_interceptor:defeated": 6, + "iron_coast_stage2_mission_7:complete": 1, + "iron_coast_stage2_mission_7:debrief": 1, + "iron_coast_stage2_mission_7:phase": 5, + "iron_coast_stage2_mission_7:required_siege": 4, + "iron_coast_stage2_mission_7:required_skimmers": 3, + "iron_coast_stage2_siege:defeated": 4, + "iron_coast_stage2_skimmer:defeated": 3 + }, + "outcome": "Complete", + "phase_frames": [ + 0, + 1 + ], + "rewards_once": true, + "shield": 60, + "sound_ids": [ + "iron_coast_stage2_boss_7:death", + "iron_coast_stage2_boss_7:phase", + "iron_coast_stage2_boss_7:shot", + "iron_coast_stage2_boss_7:warning", + "iron_coast_stage2_interceptor:death", + "iron_coast_stage2_interceptor:shot", + "iron_coast_stage2_mission_7:approach", + "iron_coast_stage2_mission_7:boss_alarm", + "iron_coast_stage2_mission_7:escalation", + "iron_coast_stage2_mission_7:victory", + "iron_coast_stage2_siege:death", + "iron_coast_stage2_siege:shot", + "iron_coast_stage2_siege:warning", + "iron_coast_stage2_skimmer:death", + "iron_coast_stage2_skimmer:shot", + "iron_coast_stage2_skimmer:warning" + ], + "tick": 2777 + } + ], + "actual_production_mixer": [ + { + "actual_mixer_peak": 4864, + "actual_mixer_rms": 1835.7426224827923, + "muted_exact_zero": true, + "sound": "iron_coast_stage2_mission_7:approach" + }, + { + "actual_mixer_peak": 5760, + "actual_mixer_rms": 2242.4113306884624, + "muted_exact_zero": true, + "sound": "iron_coast_stage2_mission_7:boss_alarm" + }, + { + "actual_mixer_peak": 4864, + "actual_mixer_rms": 1660.8207320478632, + "muted_exact_zero": true, + "sound": "iron_coast_stage2_mission_7:escalation" + }, + { + "actual_mixer_peak": 4864, + "actual_mixer_rms": 2214.1028124276436, + "muted_exact_zero": true, + "sound": "iron_coast_stage2_mission_7:victory" + } + ], + "actual_mixer_cues_unclipped": true, + "actual_mute_exact_zero": true, + "per_entity_phase_isolation": true, + "actual_world_repeated_spawn_step_lethal_with_retained_state": true, + "death_and_rewards_once": true, + "PNG_source_and_output_dimensions_checked": true, + "external_proof_hashes": { + "validation-results.json": "d063d101d9e1d5cf1cb94240caba3ddef04b5183def5b6625ebe32d92951b28d", + "boss-validation-results.json": "ef20464533b00c35f63c1add0d3149dc9da341ec580f3221e389a62230143e0a", + "actual-audio-proof.json": "293e8f37a5e0ae776d6b0369207dc80f2e38b52c0c903de412bba9b4fbfc60d4", + "actual-mixer-all-cues.wav": "af00e983a61e1c26e1504a818fa524b31528fa8f44211cc6969bbc0f6e430124", + "asset-validation.json": "7a30c3aaf365a8ac16c97c1b519d93ca39f1723c96b1fac5f93fa88f7757a1f7", + "boss-art-contact.png": "444de75e4c171ddac84e2ae6f3f206e749e1fdc3a59d406aa4c66f7678519aa7", + "terrain-briefing-contact.png": "254895a2296d6972f9fa4132e21d95979b149be960600507633f44847398eb3b" + }, + "reference_visibility_limits": "Art contact sheets are author visual inspection. Sound proof uses actual mixer without a liveSDL occurrence claim. Root/independent Host screenshots bind final gameplay presentation separately.", + "full_inventory_preserved": true, + "physical_reserve_capacity_checked": true, + "mandatory_reachable_after_4050_ticks": true, + "elapsed_duration_never_wins": true, + "every_step_deterministic_replay": true, + "serialized_script_state_continuation_at_every_boss_phase": true, + "restart_reset": true, + "failed_sortie_preserves_gear": true, + "mission_complete_and_debrief_explicit": true, + "layout_scroll_pixels": 12288 +} diff --git a/mods/iron_coast_stage2_mission_8/README.md b/mods/iron_coast_stage2_mission_8/README.md new file mode 100644 index 00000000..7a0a5432 --- /dev/null +++ b/mods/iron_coast_stage2_mission_8/README.md @@ -0,0 +1,19 @@ +# Iron Coast II 8: Black Tide + +Standalone API 1/version 1.0.0 mission mod; the optional eight-sortie campaign links progression. No `next` override or embedded copy of another package is used. + +Mission ID: `iron_coast_stage2_mission_8:mission_08`. Dependencies: the interceptor, siege, skimmer, boss 8 and Stage2 soundtrack mods, each ^1.0. Enabling this mission in Mods selects its dependencies through the normal manager. Optional Railburst/Depth Charge shop upgrades require no loan or mission dependency. + +Destroy **5 Bastion Crawlers, 4 Wakeknife Skimmers and the Leviathan**. All naval spawns are required and are held at y 48/80 once they enter, preserving lateral AI; the final carrier arrives at tick 2850 and remains reachable. Elapsed duration 3800 never completes the mission. Victory is gated by actual shared death counters plus the boss death counter and pays 55000 credits once, in addition to enemy rewards. + +Three assault acts at start/900/1800 lead into the carrier encounter. Authored support repairs +15 shield at each act and +20 at boss arrival, capped by the standard shield system. No item is granted/removed, so full inventories, owned equipment and physical shield reserves retain their identities and capacity. Failed sorties grant no victory reward; the next sortie resets phase/debrief/death objectives. + +Starter strategy: hold Ctrl, use ordinary lateral movement to line up paired forward guns, clear the lowest required naval target first, then the carrier. Native classic loop/sweep entries are retained as `base:enemy_0_73/74/23/24/95/96`; this package never clones, changes or anchors their native paths. Sidestep approaching shots while continuing fire; the reference controller uses at most 4 pixels per tick and reacts only to nearby hostile rounds at y136–188. Boss warning sounds/charge arcs identify firing pods; open deck lanes offer counterplay. Alt/Shift changes selectable weapons, Space remains the normal bomb control. + +Genuine newly generated joined harbor/citadel art is the SD/HD source. Tiles are split only after whole-canvas resampling and palette reduction; reflected half-period rows have exact boundary pixels, with complete reassembly assertions. Briefing artwork is a proportional overview of this map. Tiles are 32×32 logical/128×128 HD, nine columns; sixteen complete mirrored periods cover 12,288 logical scroll pixels, including delayed finale objectives. SD uses ordinary palette 0..239; no original palette classes are invented. Original reference pixels are not shipped. + +The reproducible sibling helper `../iron_coast_stage2_mission_8/build_finale_assets.py` builds all four finale packages using self-contained `RustRaptor/data/misc/PALETTE_DAT` and preserves all raw art/prompts/provenance. Mission 8 v1's painted-aircraft terrain is retained as rejected history; v2 genuinely replaces it with static service decks. WAV cues are deterministic local 22.05 kHz mono 16-bit synthesis, not recordings. Music: `iron_coast_stage2_music:finale`. + +Validation lives in mission 8 `validation/`: real original Catalog/Rhai/World, all difficulties from 75 shield/10,000 credits, 100 shield/0 credits, full 20 slots, all visible boss phases, native movement, no-fire reachability after duration, every-step deterministic replay, preserved mid-boss state and restart/failure checks. Review captures stay outside all mod folders to keep save hashes stable. + +Measured starter runs: 3026 ticks at difficulties 0/1 and 3206 at 2/3, ending with 86/32 shield from 75. The full 20-slot hard-mode run ends with 32 shield. Enemy geometry, wave density and repairs were preserved during controller tuning. diff --git a/mods/iron_coast_stage2_mission_8/art-qa.json b/mods/iron_coast_stage2_mission_8/art-qa.json new file mode 100644 index 00000000..4a867f40 --- /dev/null +++ b/mods/iron_coast_stage2_mission_8/art-qa.json @@ -0,0 +1,32 @@ +{ + "selected_raw": "art/generated-v2.png", + "selected_raw_sha256": "f31fb14f3be1ec0fbc5c1dde0f9fb4755801bdd2498c2a3eec40c8ee89e83683", + "logical_tile": [ + 32, + 32 + ], + "hd_tile": [ + 128, + 128 + ], + "columns": 9, + "rows": 24, + "joined_palette_then_split": true, + "mirrored_loop_boundary_exact": true, + "reassembly_pixel_exact": true, + "logical_collision_unchanged_by_hd": true, + "palette_sha256": "1cf6adb926d1dee1888b3e3d33b51a7049b3e5eb5f90a3067ef71c8970547204", + "palette_classes": "ordinary0..239 only, alpha opaque; runtime mods never claim reserved original palette classes", + "briefing": "centered proportional overview crop of the genuine joined map; no extra entity artwork", + "files": { + "art/briefing-hd.png": "19651ba840b301a1cc0600fcb9ff1ede81fa14aede997c4a42b9a30cb351994a", + "art/briefing-sd.png": "2d127da9957e7f6da4d1219bc7520d951084fa460c6efd24f8ef99405769c8ea", + "art/generated-v1.png": "f101f34926cb90d1cb0ac2a358398ea4cb9558b1755ddd0ac0664800c2b6b22b", + "art/generated-v2.png": "f31fb14f3be1ec0fbc5c1dde0f9fb4755801bdd2498c2a3eec40c8ee89e83683", + "art/terrain-preview-hd.png": "ee57e008ef3bde8ccbf1f200365e8169bd8803117c7ed04fafaaf727123d4328", + "art/terrain-preview-sd.png": "bfbb11834b1712bbc9f556adfed4f89908a62db674b3938222a790f9d1f3e286" + }, + "layout_period_repetitions": 16, + "layout_total_rows": 384, + "logical_scroll_coverage": 12288 +} diff --git a/mods/iron_coast_stage2_mission_8/art/briefing-hd.png b/mods/iron_coast_stage2_mission_8/art/briefing-hd.png new file mode 100644 index 00000000..02ffcb9d Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/briefing-hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/briefing-sd.png b/mods/iron_coast_stage2_mission_8/art/briefing-sd.png new file mode 100644 index 00000000..7029353e Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/briefing-sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/generated-v1.png b/mods/iron_coast_stage2_mission_8/art/generated-v1.png new file mode 100644 index 00000000..49a12b5c Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/generated-v1.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/generated-v2.png b/mods/iron_coast_stage2_mission_8/art/generated-v2.png new file mode 100644 index 00000000..5bfd9e2b Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/generated-v2.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/prompt-v1.txt b/mods/iron_coast_stage2_mission_8/art/prompt-v1.txt new file mode 100644 index 00000000..1c2fb381 --- /dev/null +++ b/mods/iron_coast_stage2_mission_8/art/prompt-v1.txt @@ -0,0 +1 @@ +Paint a joined top-down scrolling terrain master for BLACK TIDE, the final offshore command citadel assault in a faithful HD Raptor expansion. Attached original Raptor pixels establish dark industrial overhead materials only. Pure top-down orthographic2D, portrait3:4 canvas1152x1536. Deep blue-black sea surrounds a huge brutalist steel offshore citadel occupying both outer sides and parts of center, with broad gray armored decks, angular service roads, concrete retaining walls, dark ventilation trenches, restrained red-orange hazard stripes and tiny amber lamps. Three connected command platforms separated by dark-water canals create escalating assault sectors. Keep central flight corridor visually readable and at least one-third of image dark open water. Exact sharp overhead geometry; fine metal grain subordinate to bold SD-readable silhouettes. No drawn ships, boss, turrets, airplanes, explosions, projectiles, people, text, UI or logo: these spawn as real entities. Continuous entire map, no grid/tile panel borders. Top and bottom are open dark water with only short edge walls, so reflective scrolling loop seams remain coherent. Opaque full canvas, no vignette or border. Neutral overhead lighting, muted gray and charcoal metals, Raptor-like disciplined industrial military style, no perspective or isometric angle. diff --git a/mods/iron_coast_stage2_mission_8/art/prompt-v2.txt b/mods/iron_coast_stage2_mission_8/art/prompt-v2.txt new file mode 100644 index 00000000..becd76ef --- /dev/null +++ b/mods/iron_coast_stage2_mission_8/art/prompt-v2.txt @@ -0,0 +1 @@ +Edit this overhead offshore citadel map into a production SCROLLING TERRAIN master. Preserve the exact joined canvas, water, three platform outlines, bridge connections and subdued industrial material. Critical correction: remove the obvious RED AIRCRAFT/SHIP shape painted into the LOWER CENTRAL platform, replacing its complete silhouette with flat gray empty service decking, two rectangular dark ventilation grilles and modest red hazard striping. Remove the large rounded robot/aircraft-shaped feature in the TOP CENTRAL platform, replacing it with flat gray armored command deck, a rectangular central elevator hatch and rectangular small roof vents. Do not merely recolor or camouflage the ships; remove recognizable noses/wings/engines/boss silhouettes. All live ships, enemies and bosses are spawned separately by the game. No turrets, weapons, entities, explosions, people or extra objects. Preserve all other ground geometry. Fully opaque image, pure orthographic top-down, dark water and gray metal, no words/UI/text, no perspective, no grid or tile borders. diff --git a/mods/iron_coast_stage2_mission_8/art/provenance.json b/mods/iron_coast_stage2_mission_8/art/provenance.json new file mode 100644 index 00000000..b9da75f3 --- /dev/null +++ b/mods/iron_coast_stage2_mission_8/art/provenance.json @@ -0,0 +1,44 @@ +{ + "generator": "OpenAI builtin imagegen; exact untouched PNGs preserved", + "utc": "2026-10-11", + "raws": [ + { + "version": 1, + "builtin_file": "/home/quintine/.codex/generated_images/01a1245e-048c-7e92-91d2-78de2e5900ab/exec-6a1fcf7e-50e9-4764-bbd9-6c6476670b65.png", + "builtin_sha256": "f101f34926cb90d1cb0ac2a358398ea4cb9558b1755ddd0ac0664800c2b6b22b", + "raw_file": "art/generated-v1.png", + "raw_sha256": "f101f34926cb90d1cb0ac2a358398ea4cb9558b1755ddd0ac0664800c2b6b22b", + "prompt_file": "art/prompt-v1.txt", + "prompt_sha256": "666a2fdcd687dc9f5b842ab0160a431bf823cb769a33f1758de5594dc988c4e5", + "reference_file": "/home/quintine/Projects/RaptorReplica/.reference/iron-coast-stage2-finale/classic-reference.png", + "reference_sha256": "f093d720ff149c9f12bd12cc7e99e6123386bb5ce767c2676fcdf7a067c121d1", + "builtin_identity_verified": true, + "transparent_requested": false, + "rejected": true, + "gate_owner": "/root/iron_coast_6", + "gate_job": "stage2-blacktide-terrain-v1", + "gate_lease": "6533e770-3571-4536-be9d-f5b641e9d2f0", + "gate_outcome": "success" + }, + { + "version": 2, + "builtin_file": "/home/quintine/.codex/generated_images/01a1245e-048c-7e92-91d2-78de2e5900ab/exec-1ba2d521-d873-4602-8ef2-046c1f241587.png", + "builtin_sha256": "f31fb14f3be1ec0fbc5c1dde0f9fb4755801bdd2498c2a3eec40c8ee89e83683", + "raw_file": "art/generated-v2.png", + "raw_sha256": "f31fb14f3be1ec0fbc5c1dde0f9fb4755801bdd2498c2a3eec40c8ee89e83683", + "prompt_file": "art/prompt-v2.txt", + "prompt_sha256": "4be1bee9e7bc9e0a9e524919c55221a787bc01bf677c1d1fcfc50e5eb019f2ba", + "reference_file": "/home/quintine/Projects/RaptorReplica/RustRaptor/mods/iron_coast_stage2_mission_8/art/generated-v1.png", + "reference_sha256": "f101f34926cb90d1cb0ac2a358398ea4cb9558b1755ddd0ac0664800c2b6b22b", + "builtin_identity_verified": true, + "transparent_requested": false, + "rejected": false, + "gate_owner": "/root/iron_coast_6", + "gate_job": "stage2-blacktide-terrain-v2", + "gate_lease": "d96ef991-fdf2-4189-9865-555a6a42927c", + "gate_outcome": "success" + } + ], + "original_references": "External authentic catalog board; no decoded original reference pixels included in this package", + "historical_hold": "Mission8 v1 painted an aircraft in the platform; v2 genuinely replaces it with empty service deck" +} diff --git a/mods/iron_coast_stage2_mission_8/art/terrain-preview-hd.png b/mods/iron_coast_stage2_mission_8/art/terrain-preview-hd.png new file mode 100644 index 00000000..326911c4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/terrain-preview-hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/terrain-preview-sd.png b/mods/iron_coast_stage2_mission_8/art/terrain-preview-sd.png new file mode 100644 index 00000000..4fb0c60f Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/terrain-preview-sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_000_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_000_hd.png new file mode 100644 index 00000000..b113c12f Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_000_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_000_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_000_sd.png new file mode 100644 index 00000000..9c144e03 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_000_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_001_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_001_hd.png new file mode 100644 index 00000000..ed960bee Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_001_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_001_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_001_sd.png new file mode 100644 index 00000000..09c7a9d1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_001_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_002_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_002_hd.png new file mode 100644 index 00000000..029a5316 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_002_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_002_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_002_sd.png new file mode 100644 index 00000000..92d0bae8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_002_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_003_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_003_hd.png new file mode 100644 index 00000000..47e13f0d Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_003_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_003_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_003_sd.png new file mode 100644 index 00000000..b995bfdd Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_003_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_004_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_004_hd.png new file mode 100644 index 00000000..df66f5a7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_004_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_004_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_004_sd.png new file mode 100644 index 00000000..9fc2366b Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_004_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_005_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_005_hd.png new file mode 100644 index 00000000..0aed429b Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_005_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_005_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_005_sd.png new file mode 100644 index 00000000..3cc710de Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_005_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_006_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_006_hd.png new file mode 100644 index 00000000..581f9d6b Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_006_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_006_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_006_sd.png new file mode 100644 index 00000000..039e0371 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_006_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_007_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_007_hd.png new file mode 100644 index 00000000..56be59be Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_007_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_007_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_007_sd.png new file mode 100644 index 00000000..56d5449f Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_007_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_008_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_008_hd.png new file mode 100644 index 00000000..6ecaded1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_008_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_008_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_008_sd.png new file mode 100644 index 00000000..f6baf710 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_008_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_009_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_009_hd.png new file mode 100644 index 00000000..cce5e808 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_009_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_009_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_009_sd.png new file mode 100644 index 00000000..fda9cddd Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_009_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_010_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_010_hd.png new file mode 100644 index 00000000..49e6ce11 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_010_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_010_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_010_sd.png new file mode 100644 index 00000000..abf0601a Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_010_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_011_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_011_hd.png new file mode 100644 index 00000000..300aed41 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_011_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_011_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_011_sd.png new file mode 100644 index 00000000..ef74d5cf Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_011_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_012_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_012_hd.png new file mode 100644 index 00000000..0a80c9af Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_012_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_012_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_012_sd.png new file mode 100644 index 00000000..e4fcacb6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_012_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_013_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_013_hd.png new file mode 100644 index 00000000..e1ba1ea5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_013_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_013_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_013_sd.png new file mode 100644 index 00000000..a61f2ff4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_013_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_014_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_014_hd.png new file mode 100644 index 00000000..ed5e8478 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_014_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_014_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_014_sd.png new file mode 100644 index 00000000..92f55453 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_014_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_015_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_015_hd.png new file mode 100644 index 00000000..770e230c Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_015_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_015_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_015_sd.png new file mode 100644 index 00000000..73f3bd78 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_015_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_016_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_016_hd.png new file mode 100644 index 00000000..98674122 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_016_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_016_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_016_sd.png new file mode 100644 index 00000000..cc14b1b6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_016_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_017_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_017_hd.png new file mode 100644 index 00000000..17f6c7d3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_017_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_017_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_017_sd.png new file mode 100644 index 00000000..bd7fc775 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_017_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_018_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_018_hd.png new file mode 100644 index 00000000..202f6cfc Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_018_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_018_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_018_sd.png new file mode 100644 index 00000000..56d0c01e Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_018_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_019_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_019_hd.png new file mode 100644 index 00000000..521a7e9b Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_019_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_019_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_019_sd.png new file mode 100644 index 00000000..07f95885 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_019_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_020_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_020_hd.png new file mode 100644 index 00000000..68670e68 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_020_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_020_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_020_sd.png new file mode 100644 index 00000000..00620c4c Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_020_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_021_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_021_hd.png new file mode 100644 index 00000000..aa37832d Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_021_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_021_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_021_sd.png new file mode 100644 index 00000000..93c877b9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_021_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_022_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_022_hd.png new file mode 100644 index 00000000..199a2d3e Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_022_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_022_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_022_sd.png new file mode 100644 index 00000000..bab2f8ac Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_022_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_023_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_023_hd.png new file mode 100644 index 00000000..e6c93ff9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_023_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_023_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_023_sd.png new file mode 100644 index 00000000..73a23587 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_023_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_024_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_024_hd.png new file mode 100644 index 00000000..04db502b Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_024_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_024_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_024_sd.png new file mode 100644 index 00000000..68420f3e Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_024_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_025_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_025_hd.png new file mode 100644 index 00000000..887807e9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_025_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_025_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_025_sd.png new file mode 100644 index 00000000..3163076f Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_025_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_026_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_026_hd.png new file mode 100644 index 00000000..19d779fb Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_026_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_026_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_026_sd.png new file mode 100644 index 00000000..2b6cdae3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_026_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_027_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_027_hd.png new file mode 100644 index 00000000..8f6dc52d Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_027_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_027_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_027_sd.png new file mode 100644 index 00000000..5c05be1d Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_027_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_028_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_028_hd.png new file mode 100644 index 00000000..1a10c507 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_028_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_028_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_028_sd.png new file mode 100644 index 00000000..a1b5afe2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_028_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_029_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_029_hd.png new file mode 100644 index 00000000..06f2796d Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_029_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_029_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_029_sd.png new file mode 100644 index 00000000..af7d1d8d Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_029_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_030_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_030_hd.png new file mode 100644 index 00000000..1b69415a Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_030_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_030_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_030_sd.png new file mode 100644 index 00000000..56bfb594 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_030_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_031_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_031_hd.png new file mode 100644 index 00000000..9cb1337f Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_031_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_031_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_031_sd.png new file mode 100644 index 00000000..98ce2a43 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_031_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_032_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_032_hd.png new file mode 100644 index 00000000..aded9757 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_032_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_032_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_032_sd.png new file mode 100644 index 00000000..6c04c12e Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_032_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_033_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_033_hd.png new file mode 100644 index 00000000..f47c5e66 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_033_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_033_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_033_sd.png new file mode 100644 index 00000000..27d51448 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_033_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_034_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_034_hd.png new file mode 100644 index 00000000..3b2b3a82 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_034_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_034_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_034_sd.png new file mode 100644 index 00000000..d3138bf9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_034_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_035_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_035_hd.png new file mode 100644 index 00000000..bed07469 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_035_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_035_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_035_sd.png new file mode 100644 index 00000000..5c556315 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_035_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_036_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_036_hd.png new file mode 100644 index 00000000..7857c370 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_036_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_036_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_036_sd.png new file mode 100644 index 00000000..c13072cb Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_036_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_037_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_037_hd.png new file mode 100644 index 00000000..60e640f1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_037_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_037_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_037_sd.png new file mode 100644 index 00000000..2fdf68a7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_037_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_038_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_038_hd.png new file mode 100644 index 00000000..b7570ff9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_038_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_038_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_038_sd.png new file mode 100644 index 00000000..6ac5a439 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_038_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_039_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_039_hd.png new file mode 100644 index 00000000..a4c605ea Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_039_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_039_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_039_sd.png new file mode 100644 index 00000000..57c9f516 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_039_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_040_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_040_hd.png new file mode 100644 index 00000000..75e9fc33 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_040_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_040_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_040_sd.png new file mode 100644 index 00000000..bd747c24 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_040_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_041_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_041_hd.png new file mode 100644 index 00000000..b53cdb56 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_041_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_041_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_041_sd.png new file mode 100644 index 00000000..865af367 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_041_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_042_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_042_hd.png new file mode 100644 index 00000000..bcb7d24a Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_042_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_042_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_042_sd.png new file mode 100644 index 00000000..98f521be Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_042_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_043_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_043_hd.png new file mode 100644 index 00000000..18eea06e Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_043_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_043_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_043_sd.png new file mode 100644 index 00000000..26a3bef5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_043_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_044_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_044_hd.png new file mode 100644 index 00000000..8fa3eba3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_044_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_044_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_044_sd.png new file mode 100644 index 00000000..09aa9d0c Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_044_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_045_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_045_hd.png new file mode 100644 index 00000000..1b7c688b Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_045_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_045_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_045_sd.png new file mode 100644 index 00000000..e84ccaab Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_045_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_046_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_046_hd.png new file mode 100644 index 00000000..51b3e180 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_046_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_046_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_046_sd.png new file mode 100644 index 00000000..aa5faeed Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_046_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_047_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_047_hd.png new file mode 100644 index 00000000..d57ba3f4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_047_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_047_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_047_sd.png new file mode 100644 index 00000000..3cc84289 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_047_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_048_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_048_hd.png new file mode 100644 index 00000000..b987ea20 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_048_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_048_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_048_sd.png new file mode 100644 index 00000000..8518a19a Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_048_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_049_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_049_hd.png new file mode 100644 index 00000000..34c372c5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_049_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_049_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_049_sd.png new file mode 100644 index 00000000..ba9d69c5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_049_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_050_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_050_hd.png new file mode 100644 index 00000000..acf765a4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_050_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_050_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_050_sd.png new file mode 100644 index 00000000..4f52ad69 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_050_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_051_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_051_hd.png new file mode 100644 index 00000000..1c3b8ac4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_051_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_051_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_051_sd.png new file mode 100644 index 00000000..701eb545 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_051_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_052_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_052_hd.png new file mode 100644 index 00000000..2708034c Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_052_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_052_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_052_sd.png new file mode 100644 index 00000000..520b660e Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_052_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_053_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_053_hd.png new file mode 100644 index 00000000..79b55730 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_053_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_053_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_053_sd.png new file mode 100644 index 00000000..9f68c87a Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_053_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_054_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_054_hd.png new file mode 100644 index 00000000..199a885e Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_054_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_054_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_054_sd.png new file mode 100644 index 00000000..0abd7fea Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_054_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_055_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_055_hd.png new file mode 100644 index 00000000..a7ecb540 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_055_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_055_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_055_sd.png new file mode 100644 index 00000000..29cfb001 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_055_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_056_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_056_hd.png new file mode 100644 index 00000000..68ef4d9a Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_056_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_056_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_056_sd.png new file mode 100644 index 00000000..850e142a Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_056_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_057_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_057_hd.png new file mode 100644 index 00000000..0da55ece Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_057_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_057_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_057_sd.png new file mode 100644 index 00000000..d21f602f Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_057_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_058_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_058_hd.png new file mode 100644 index 00000000..45f3def0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_058_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_058_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_058_sd.png new file mode 100644 index 00000000..4cc2c093 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_058_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_059_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_059_hd.png new file mode 100644 index 00000000..82c1cc1e Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_059_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_059_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_059_sd.png new file mode 100644 index 00000000..5a1b5a98 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_059_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_060_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_060_hd.png new file mode 100644 index 00000000..6c72b754 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_060_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_060_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_060_sd.png new file mode 100644 index 00000000..8306a88a Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_060_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_061_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_061_hd.png new file mode 100644 index 00000000..29d901d6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_061_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_061_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_061_sd.png new file mode 100644 index 00000000..a178fb2d Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_061_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_062_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_062_hd.png new file mode 100644 index 00000000..88bb7d59 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_062_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_062_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_062_sd.png new file mode 100644 index 00000000..287f87e3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_062_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_063_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_063_hd.png new file mode 100644 index 00000000..b366a787 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_063_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_063_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_063_sd.png new file mode 100644 index 00000000..04212d2e Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_063_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_064_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_064_hd.png new file mode 100644 index 00000000..d1b11467 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_064_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_064_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_064_sd.png new file mode 100644 index 00000000..c18f3b64 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_064_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_065_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_065_hd.png new file mode 100644 index 00000000..b36b71f9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_065_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_065_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_065_sd.png new file mode 100644 index 00000000..64076ce1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_065_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_066_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_066_hd.png new file mode 100644 index 00000000..39c32d6a Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_066_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_066_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_066_sd.png new file mode 100644 index 00000000..b862826a Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_066_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_067_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_067_hd.png new file mode 100644 index 00000000..4745006d Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_067_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_067_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_067_sd.png new file mode 100644 index 00000000..85c488f5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_067_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_068_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_068_hd.png new file mode 100644 index 00000000..973318c4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_068_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_068_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_068_sd.png new file mode 100644 index 00000000..2d07d4bf Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_068_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_069_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_069_hd.png new file mode 100644 index 00000000..2f2a4a38 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_069_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_069_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_069_sd.png new file mode 100644 index 00000000..55737e3d Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_069_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_070_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_070_hd.png new file mode 100644 index 00000000..b168687f Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_070_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_070_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_070_sd.png new file mode 100644 index 00000000..8a41767c Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_070_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_071_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_071_hd.png new file mode 100644 index 00000000..67f5746a Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_071_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_071_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_071_sd.png new file mode 100644 index 00000000..708f108c Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_071_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_072_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_072_hd.png new file mode 100644 index 00000000..92928b68 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_072_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_072_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_072_sd.png new file mode 100644 index 00000000..c21b3ade Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_072_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_073_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_073_hd.png new file mode 100644 index 00000000..db8b64eb Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_073_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_073_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_073_sd.png new file mode 100644 index 00000000..5c363518 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_073_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_074_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_074_hd.png new file mode 100644 index 00000000..1394d214 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_074_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_074_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_074_sd.png new file mode 100644 index 00000000..570147be Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_074_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_075_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_075_hd.png new file mode 100644 index 00000000..b9923b9c Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_075_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_075_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_075_sd.png new file mode 100644 index 00000000..09f1cc08 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_075_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_076_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_076_hd.png new file mode 100644 index 00000000..d4a55456 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_076_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_076_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_076_sd.png new file mode 100644 index 00000000..10b6fd84 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_076_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_077_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_077_hd.png new file mode 100644 index 00000000..29615fdb Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_077_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_077_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_077_sd.png new file mode 100644 index 00000000..aa4bc023 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_077_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_078_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_078_hd.png new file mode 100644 index 00000000..473008fa Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_078_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_078_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_078_sd.png new file mode 100644 index 00000000..da0fcce8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_078_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_079_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_079_hd.png new file mode 100644 index 00000000..75466fb1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_079_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_079_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_079_sd.png new file mode 100644 index 00000000..a207476e Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_079_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_080_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_080_hd.png new file mode 100644 index 00000000..c6378249 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_080_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_080_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_080_sd.png new file mode 100644 index 00000000..cbd49493 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_080_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_081_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_081_hd.png new file mode 100644 index 00000000..615277b4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_081_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_081_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_081_sd.png new file mode 100644 index 00000000..b8555689 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_081_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_082_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_082_hd.png new file mode 100644 index 00000000..3359de81 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_082_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_082_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_082_sd.png new file mode 100644 index 00000000..60a0f72f Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_082_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_083_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_083_hd.png new file mode 100644 index 00000000..4cb8ad2c Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_083_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_083_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_083_sd.png new file mode 100644 index 00000000..8d77bee6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_083_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_084_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_084_hd.png new file mode 100644 index 00000000..a73aa475 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_084_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_084_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_084_sd.png new file mode 100644 index 00000000..57d070e9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_084_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_085_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_085_hd.png new file mode 100644 index 00000000..412347f4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_085_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_085_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_085_sd.png new file mode 100644 index 00000000..7f563205 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_085_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_086_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_086_hd.png new file mode 100644 index 00000000..0b0490d7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_086_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_086_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_086_sd.png new file mode 100644 index 00000000..4dd579a4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_086_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_087_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_087_hd.png new file mode 100644 index 00000000..d14f00b9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_087_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_087_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_087_sd.png new file mode 100644 index 00000000..0db1c031 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_087_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_088_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_088_hd.png new file mode 100644 index 00000000..53fe5da8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_088_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_088_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_088_sd.png new file mode 100644 index 00000000..bc6d6ff0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_088_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_089_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_089_hd.png new file mode 100644 index 00000000..45f030ed Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_089_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_089_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_089_sd.png new file mode 100644 index 00000000..f8958043 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_089_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_090_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_090_hd.png new file mode 100644 index 00000000..9ce124d2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_090_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_090_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_090_sd.png new file mode 100644 index 00000000..b278703a Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_090_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_091_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_091_hd.png new file mode 100644 index 00000000..b3c31bd6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_091_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_091_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_091_sd.png new file mode 100644 index 00000000..eccb8aa3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_091_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_092_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_092_hd.png new file mode 100644 index 00000000..5665838d Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_092_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_092_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_092_sd.png new file mode 100644 index 00000000..dfebc260 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_092_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_093_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_093_hd.png new file mode 100644 index 00000000..5e67b42d Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_093_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_093_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_093_sd.png new file mode 100644 index 00000000..a1b0b68e Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_093_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_094_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_094_hd.png new file mode 100644 index 00000000..454f94f8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_094_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_094_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_094_sd.png new file mode 100644 index 00000000..6a3d6776 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_094_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_095_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_095_hd.png new file mode 100644 index 00000000..d0f6f9dd Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_095_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_095_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_095_sd.png new file mode 100644 index 00000000..14e75271 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_095_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_096_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_096_hd.png new file mode 100644 index 00000000..6a3a5d3a Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_096_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_096_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_096_sd.png new file mode 100644 index 00000000..e1cec496 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_096_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_097_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_097_hd.png new file mode 100644 index 00000000..3a2e6e8a Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_097_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_097_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_097_sd.png new file mode 100644 index 00000000..59eadfff Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_097_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_098_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_098_hd.png new file mode 100644 index 00000000..3aff0430 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_098_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_098_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_098_sd.png new file mode 100644 index 00000000..5fe7a003 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_098_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_099_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_099_hd.png new file mode 100644 index 00000000..c48fdaa5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_099_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_099_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_099_sd.png new file mode 100644 index 00000000..b2cbbac4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_099_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_100_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_100_hd.png new file mode 100644 index 00000000..f9e1aa62 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_100_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_100_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_100_sd.png new file mode 100644 index 00000000..84de9498 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_100_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_101_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_101_hd.png new file mode 100644 index 00000000..b074ffa3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_101_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_101_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_101_sd.png new file mode 100644 index 00000000..73b8236f Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_101_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_102_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_102_hd.png new file mode 100644 index 00000000..c91ee710 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_102_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_102_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_102_sd.png new file mode 100644 index 00000000..db1ac2f3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_102_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_103_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_103_hd.png new file mode 100644 index 00000000..c027a942 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_103_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_103_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_103_sd.png new file mode 100644 index 00000000..b2fd8bfc Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_103_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_104_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_104_hd.png new file mode 100644 index 00000000..da2c2264 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_104_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_104_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_104_sd.png new file mode 100644 index 00000000..dcc9342e Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_104_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_105_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_105_hd.png new file mode 100644 index 00000000..b3c548c1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_105_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_105_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_105_sd.png new file mode 100644 index 00000000..a746874b Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_105_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_106_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_106_hd.png new file mode 100644 index 00000000..bf5dd171 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_106_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_106_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_106_sd.png new file mode 100644 index 00000000..76ef6cc8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_106_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_107_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_107_hd.png new file mode 100644 index 00000000..b98855ce Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_107_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_107_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_107_sd.png new file mode 100644 index 00000000..99256224 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_107_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_108_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_108_hd.png new file mode 100644 index 00000000..21e3a5af Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_108_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_108_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_108_sd.png new file mode 100644 index 00000000..ffacac84 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_108_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_109_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_109_hd.png new file mode 100644 index 00000000..4f88533e Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_109_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_109_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_109_sd.png new file mode 100644 index 00000000..47994dda Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_109_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_110_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_110_hd.png new file mode 100644 index 00000000..39d666cb Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_110_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_110_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_110_sd.png new file mode 100644 index 00000000..32b87956 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_110_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_111_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_111_hd.png new file mode 100644 index 00000000..97d7fec1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_111_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_111_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_111_sd.png new file mode 100644 index 00000000..1e599e84 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_111_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_112_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_112_hd.png new file mode 100644 index 00000000..bd816109 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_112_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_112_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_112_sd.png new file mode 100644 index 00000000..79ac077e Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_112_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_113_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_113_hd.png new file mode 100644 index 00000000..7a4f7215 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_113_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_113_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_113_sd.png new file mode 100644 index 00000000..841f8c0b Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_113_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_114_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_114_hd.png new file mode 100644 index 00000000..1f82c001 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_114_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_114_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_114_sd.png new file mode 100644 index 00000000..02bbbf19 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_114_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_115_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_115_hd.png new file mode 100644 index 00000000..ff09b377 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_115_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_115_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_115_sd.png new file mode 100644 index 00000000..e15296be Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_115_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_116_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_116_hd.png new file mode 100644 index 00000000..7c3a712b Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_116_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_116_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_116_sd.png new file mode 100644 index 00000000..bcea7ddd Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_116_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_117_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_117_hd.png new file mode 100644 index 00000000..0b1eb486 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_117_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_117_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_117_sd.png new file mode 100644 index 00000000..5c4de988 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_117_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_118_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_118_hd.png new file mode 100644 index 00000000..0dd1fa83 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_118_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_118_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_118_sd.png new file mode 100644 index 00000000..e1723394 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_118_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_119_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_119_hd.png new file mode 100644 index 00000000..c29974e8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_119_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_119_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_119_sd.png new file mode 100644 index 00000000..a0cbf6fd Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_119_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_120_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_120_hd.png new file mode 100644 index 00000000..338463c5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_120_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_120_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_120_sd.png new file mode 100644 index 00000000..43d5c605 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_120_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_121_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_121_hd.png new file mode 100644 index 00000000..9e24563e Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_121_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_121_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_121_sd.png new file mode 100644 index 00000000..704fd026 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_121_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_122_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_122_hd.png new file mode 100644 index 00000000..645c155d Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_122_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_122_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_122_sd.png new file mode 100644 index 00000000..17ecd76b Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_122_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_123_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_123_hd.png new file mode 100644 index 00000000..0fa68ed4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_123_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_123_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_123_sd.png new file mode 100644 index 00000000..cad581e3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_123_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_124_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_124_hd.png new file mode 100644 index 00000000..e6ee428f Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_124_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_124_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_124_sd.png new file mode 100644 index 00000000..5c081e34 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_124_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_125_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_125_hd.png new file mode 100644 index 00000000..0b660d6b Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_125_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_125_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_125_sd.png new file mode 100644 index 00000000..0b18bea7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_125_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_126_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_126_hd.png new file mode 100644 index 00000000..a068162e Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_126_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_126_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_126_sd.png new file mode 100644 index 00000000..5ecf0e30 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_126_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_127_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_127_hd.png new file mode 100644 index 00000000..9ffd9841 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_127_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_127_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_127_sd.png new file mode 100644 index 00000000..a4110eaa Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_127_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_128_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_128_hd.png new file mode 100644 index 00000000..ddaa82a2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_128_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_128_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_128_sd.png new file mode 100644 index 00000000..dfbf4366 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_128_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_129_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_129_hd.png new file mode 100644 index 00000000..be711f7e Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_129_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_129_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_129_sd.png new file mode 100644 index 00000000..8028aaef Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_129_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_130_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_130_hd.png new file mode 100644 index 00000000..123b17ce Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_130_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_130_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_130_sd.png new file mode 100644 index 00000000..e2c65185 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_130_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_131_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_131_hd.png new file mode 100644 index 00000000..f8684a59 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_131_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_131_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_131_sd.png new file mode 100644 index 00000000..97458d79 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_131_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_132_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_132_hd.png new file mode 100644 index 00000000..f1e4cb60 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_132_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_132_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_132_sd.png new file mode 100644 index 00000000..96ccac75 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_132_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_133_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_133_hd.png new file mode 100644 index 00000000..c3894679 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_133_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_133_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_133_sd.png new file mode 100644 index 00000000..25f0ccdf Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_133_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_134_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_134_hd.png new file mode 100644 index 00000000..61593e13 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_134_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_134_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_134_sd.png new file mode 100644 index 00000000..a97449cf Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_134_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_135_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_135_hd.png new file mode 100644 index 00000000..d8351719 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_135_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_135_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_135_sd.png new file mode 100644 index 00000000..7bf4d01e Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_135_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_136_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_136_hd.png new file mode 100644 index 00000000..930e33ab Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_136_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_136_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_136_sd.png new file mode 100644 index 00000000..90de6c45 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_136_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_137_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_137_hd.png new file mode 100644 index 00000000..86eb1e30 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_137_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_137_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_137_sd.png new file mode 100644 index 00000000..ea5dc8be Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_137_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_138_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_138_hd.png new file mode 100644 index 00000000..0ab70c6c Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_138_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_138_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_138_sd.png new file mode 100644 index 00000000..3635b229 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_138_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_139_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_139_hd.png new file mode 100644 index 00000000..7df43842 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_139_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_139_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_139_sd.png new file mode 100644 index 00000000..effadec2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_139_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_140_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_140_hd.png new file mode 100644 index 00000000..9be8e0ca Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_140_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_140_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_140_sd.png new file mode 100644 index 00000000..81eae5b1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_140_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_141_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_141_hd.png new file mode 100644 index 00000000..d334f01c Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_141_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_141_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_141_sd.png new file mode 100644 index 00000000..12ee550c Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_141_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_142_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_142_hd.png new file mode 100644 index 00000000..09fde32d Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_142_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_142_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_142_sd.png new file mode 100644 index 00000000..eb5a9832 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_142_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_143_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_143_hd.png new file mode 100644 index 00000000..29805f1d Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_143_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_143_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_143_sd.png new file mode 100644 index 00000000..d9514d33 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_143_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_144_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_144_hd.png new file mode 100644 index 00000000..0fb740f3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_144_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_144_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_144_sd.png new file mode 100644 index 00000000..0aa3552d Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_144_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_145_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_145_hd.png new file mode 100644 index 00000000..f0222070 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_145_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_145_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_145_sd.png new file mode 100644 index 00000000..f97cb7f6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_145_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_146_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_146_hd.png new file mode 100644 index 00000000..57ef1b6d Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_146_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_146_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_146_sd.png new file mode 100644 index 00000000..319767fb Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_146_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_147_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_147_hd.png new file mode 100644 index 00000000..1529fdd6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_147_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_147_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_147_sd.png new file mode 100644 index 00000000..6a2e65ce Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_147_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_148_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_148_hd.png new file mode 100644 index 00000000..4bbdd7f0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_148_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_148_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_148_sd.png new file mode 100644 index 00000000..0a8709f5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_148_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_149_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_149_hd.png new file mode 100644 index 00000000..d0a59577 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_149_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_149_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_149_sd.png new file mode 100644 index 00000000..27860bce Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_149_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_150_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_150_hd.png new file mode 100644 index 00000000..23bb29dd Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_150_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_150_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_150_sd.png new file mode 100644 index 00000000..63984566 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_150_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_151_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_151_hd.png new file mode 100644 index 00000000..1a08651a Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_151_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_151_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_151_sd.png new file mode 100644 index 00000000..494e2153 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_151_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_152_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_152_hd.png new file mode 100644 index 00000000..c3a54cbf Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_152_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_152_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_152_sd.png new file mode 100644 index 00000000..57875baf Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_152_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_153_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_153_hd.png new file mode 100644 index 00000000..59c84a07 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_153_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_153_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_153_sd.png new file mode 100644 index 00000000..1e5bc5a1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_153_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_154_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_154_hd.png new file mode 100644 index 00000000..12af6a44 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_154_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_154_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_154_sd.png new file mode 100644 index 00000000..62708559 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_154_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_155_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_155_hd.png new file mode 100644 index 00000000..1cdf1316 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_155_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_155_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_155_sd.png new file mode 100644 index 00000000..bda97aca Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_155_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_156_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_156_hd.png new file mode 100644 index 00000000..dad793b5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_156_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_156_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_156_sd.png new file mode 100644 index 00000000..57186c4d Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_156_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_157_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_157_hd.png new file mode 100644 index 00000000..d3fe7986 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_157_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_157_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_157_sd.png new file mode 100644 index 00000000..ca42d0f9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_157_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_158_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_158_hd.png new file mode 100644 index 00000000..5bef80cb Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_158_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_158_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_158_sd.png new file mode 100644 index 00000000..e61eaa32 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_158_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_159_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_159_hd.png new file mode 100644 index 00000000..2dba50b3 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_159_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_159_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_159_sd.png new file mode 100644 index 00000000..cc26c871 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_159_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_160_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_160_hd.png new file mode 100644 index 00000000..3213338f Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_160_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_160_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_160_sd.png new file mode 100644 index 00000000..5e201907 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_160_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_161_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_161_hd.png new file mode 100644 index 00000000..6dc5c091 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_161_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_161_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_161_sd.png new file mode 100644 index 00000000..15129a6a Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_161_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_162_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_162_hd.png new file mode 100644 index 00000000..76bce29e Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_162_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_162_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_162_sd.png new file mode 100644 index 00000000..e287cb3d Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_162_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_163_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_163_hd.png new file mode 100644 index 00000000..67f00633 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_163_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_163_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_163_sd.png new file mode 100644 index 00000000..3705acda Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_163_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_164_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_164_hd.png new file mode 100644 index 00000000..a3b53fc8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_164_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_164_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_164_sd.png new file mode 100644 index 00000000..aea4ac5e Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_164_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_165_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_165_hd.png new file mode 100644 index 00000000..4a82cde5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_165_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_165_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_165_sd.png new file mode 100644 index 00000000..3c6e1feb Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_165_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_166_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_166_hd.png new file mode 100644 index 00000000..ad416991 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_166_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_166_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_166_sd.png new file mode 100644 index 00000000..085430dd Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_166_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_167_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_167_hd.png new file mode 100644 index 00000000..281eb9f9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_167_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_167_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_167_sd.png new file mode 100644 index 00000000..77b21433 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_167_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_168_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_168_hd.png new file mode 100644 index 00000000..8aa75695 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_168_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_168_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_168_sd.png new file mode 100644 index 00000000..97d4d423 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_168_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_169_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_169_hd.png new file mode 100644 index 00000000..ad472999 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_169_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_169_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_169_sd.png new file mode 100644 index 00000000..46dabe7e Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_169_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_170_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_170_hd.png new file mode 100644 index 00000000..35233b0d Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_170_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_170_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_170_sd.png new file mode 100644 index 00000000..a109b5c2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_170_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_171_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_171_hd.png new file mode 100644 index 00000000..cf24b4d6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_171_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_171_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_171_sd.png new file mode 100644 index 00000000..76aa1474 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_171_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_172_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_172_hd.png new file mode 100644 index 00000000..02c23ade Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_172_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_172_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_172_sd.png new file mode 100644 index 00000000..48e47362 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_172_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_173_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_173_hd.png new file mode 100644 index 00000000..34f06ed0 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_173_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_173_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_173_sd.png new file mode 100644 index 00000000..d3ddf182 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_173_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_174_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_174_hd.png new file mode 100644 index 00000000..aa8f27ba Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_174_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_174_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_174_sd.png new file mode 100644 index 00000000..6e6665c7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_174_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_175_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_175_hd.png new file mode 100644 index 00000000..7b6a4f74 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_175_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_175_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_175_sd.png new file mode 100644 index 00000000..95585b81 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_175_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_176_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_176_hd.png new file mode 100644 index 00000000..08a03e83 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_176_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_176_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_176_sd.png new file mode 100644 index 00000000..55eb4679 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_176_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_177_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_177_hd.png new file mode 100644 index 00000000..ad44bb60 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_177_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_177_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_177_sd.png new file mode 100644 index 00000000..7f81461a Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_177_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_178_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_178_hd.png new file mode 100644 index 00000000..82eb74bb Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_178_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_178_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_178_sd.png new file mode 100644 index 00000000..cd9a6289 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_178_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_179_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_179_hd.png new file mode 100644 index 00000000..d101ece2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_179_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_179_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_179_sd.png new file mode 100644 index 00000000..0a36eb0d Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_179_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_180_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_180_hd.png new file mode 100644 index 00000000..6ab6e164 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_180_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_180_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_180_sd.png new file mode 100644 index 00000000..0cb8a46a Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_180_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_181_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_181_hd.png new file mode 100644 index 00000000..6f5d2425 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_181_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_181_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_181_sd.png new file mode 100644 index 00000000..45853442 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_181_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_182_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_182_hd.png new file mode 100644 index 00000000..b61f152e Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_182_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_182_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_182_sd.png new file mode 100644 index 00000000..9e62f883 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_182_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_183_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_183_hd.png new file mode 100644 index 00000000..8c8b4d75 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_183_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_183_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_183_sd.png new file mode 100644 index 00000000..6ab47075 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_183_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_184_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_184_hd.png new file mode 100644 index 00000000..db3387c4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_184_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_184_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_184_sd.png new file mode 100644 index 00000000..b2682119 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_184_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_185_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_185_hd.png new file mode 100644 index 00000000..654a75e7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_185_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_185_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_185_sd.png new file mode 100644 index 00000000..acc68dc8 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_185_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_186_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_186_hd.png new file mode 100644 index 00000000..642f96b2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_186_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_186_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_186_sd.png new file mode 100644 index 00000000..a5641f9c Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_186_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_187_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_187_hd.png new file mode 100644 index 00000000..cda316d2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_187_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_187_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_187_sd.png new file mode 100644 index 00000000..dff3e41e Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_187_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_188_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_188_hd.png new file mode 100644 index 00000000..c08654ad Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_188_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_188_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_188_sd.png new file mode 100644 index 00000000..a7f130ce Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_188_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_189_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_189_hd.png new file mode 100644 index 00000000..6d22be10 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_189_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_189_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_189_sd.png new file mode 100644 index 00000000..c07d4c37 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_189_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_190_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_190_hd.png new file mode 100644 index 00000000..e3706676 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_190_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_190_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_190_sd.png new file mode 100644 index 00000000..bdbe3017 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_190_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_191_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_191_hd.png new file mode 100644 index 00000000..6f1ff6f9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_191_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_191_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_191_sd.png new file mode 100644 index 00000000..b50820bb Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_191_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_192_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_192_hd.png new file mode 100644 index 00000000..d3011d41 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_192_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_192_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_192_sd.png new file mode 100644 index 00000000..d350c004 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_192_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_193_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_193_hd.png new file mode 100644 index 00000000..8022e58a Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_193_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_193_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_193_sd.png new file mode 100644 index 00000000..a5e19492 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_193_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_194_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_194_hd.png new file mode 100644 index 00000000..64f7887a Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_194_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_194_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_194_sd.png new file mode 100644 index 00000000..b3127f0e Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_194_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_195_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_195_hd.png new file mode 100644 index 00000000..6766043f Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_195_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_195_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_195_sd.png new file mode 100644 index 00000000..403fb85c Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_195_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_196_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_196_hd.png new file mode 100644 index 00000000..3ca26e2c Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_196_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_196_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_196_sd.png new file mode 100644 index 00000000..cd844d41 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_196_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_197_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_197_hd.png new file mode 100644 index 00000000..2ebc8ba6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_197_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_197_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_197_sd.png new file mode 100644 index 00000000..0bbae8ad Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_197_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_198_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_198_hd.png new file mode 100644 index 00000000..c969f244 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_198_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_198_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_198_sd.png new file mode 100644 index 00000000..ad3ece91 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_198_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_199_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_199_hd.png new file mode 100644 index 00000000..c50637ff Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_199_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_199_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_199_sd.png new file mode 100644 index 00000000..a3a8e5f7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_199_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_200_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_200_hd.png new file mode 100644 index 00000000..a72f8782 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_200_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_200_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_200_sd.png new file mode 100644 index 00000000..d695cfa2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_200_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_201_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_201_hd.png new file mode 100644 index 00000000..0aa9f8a7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_201_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_201_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_201_sd.png new file mode 100644 index 00000000..e94b2e5a Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_201_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_202_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_202_hd.png new file mode 100644 index 00000000..e6a1e5d5 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_202_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_202_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_202_sd.png new file mode 100644 index 00000000..2831bf3f Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_202_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_203_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_203_hd.png new file mode 100644 index 00000000..d3681aac Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_203_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_203_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_203_sd.png new file mode 100644 index 00000000..b961d66a Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_203_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_204_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_204_hd.png new file mode 100644 index 00000000..03102cb1 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_204_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_204_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_204_sd.png new file mode 100644 index 00000000..369ca755 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_204_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_205_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_205_hd.png new file mode 100644 index 00000000..b35eab1c Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_205_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_205_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_205_sd.png new file mode 100644 index 00000000..88257f7a Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_205_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_206_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_206_hd.png new file mode 100644 index 00000000..481aea2e Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_206_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_206_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_206_sd.png new file mode 100644 index 00000000..e921d20a Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_206_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_207_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_207_hd.png new file mode 100644 index 00000000..d446d146 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_207_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_207_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_207_sd.png new file mode 100644 index 00000000..0a32fac9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_207_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_208_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_208_hd.png new file mode 100644 index 00000000..36a528a4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_208_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_208_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_208_sd.png new file mode 100644 index 00000000..08e3a15a Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_208_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_209_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_209_hd.png new file mode 100644 index 00000000..9c303ad4 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_209_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_209_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_209_sd.png new file mode 100644 index 00000000..d9bc89f7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_209_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_210_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_210_hd.png new file mode 100644 index 00000000..a1d2820d Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_210_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_210_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_210_sd.png new file mode 100644 index 00000000..78547897 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_210_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_211_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_211_hd.png new file mode 100644 index 00000000..9bb48eaf Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_211_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_211_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_211_sd.png new file mode 100644 index 00000000..834d5bf7 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_211_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_212_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_212_hd.png new file mode 100644 index 00000000..931f2d41 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_212_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_212_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_212_sd.png new file mode 100644 index 00000000..3f35233b Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_212_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_213_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_213_hd.png new file mode 100644 index 00000000..f5ba6d6e Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_213_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_213_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_213_sd.png new file mode 100644 index 00000000..ebc905df Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_213_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_214_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_214_hd.png new file mode 100644 index 00000000..3495be86 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_214_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_214_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_214_sd.png new file mode 100644 index 00000000..056dffe2 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_214_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_215_hd.png b/mods/iron_coast_stage2_mission_8/art/tile_215_hd.png new file mode 100644 index 00000000..edb563b6 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_215_hd.png differ diff --git a/mods/iron_coast_stage2_mission_8/art/tile_215_sd.png b/mods/iron_coast_stage2_mission_8/art/tile_215_sd.png new file mode 100644 index 00000000..aaf2a4b9 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/art/tile_215_sd.png differ diff --git a/mods/iron_coast_stage2_mission_8/audio-recipe.json b/mods/iron_coast_stage2_mission_8/audio-recipe.json new file mode 100644 index 00000000..5219da18 --- /dev/null +++ b/mods/iron_coast_stage2_mission_8/audio-recipe.json @@ -0,0 +1,49 @@ +{ + "generator": "build_finale_assets.py deterministic note-envelope PCM synthesis; no recordings", + "files": { + "approach": { + "file": "audio/approach.wav", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "seconds": 1.1, + "seed": 80000, + "peak": 23592, + "rms": 12059.816305674522, + "sha256": "1dfbd4ce93625efe94f7aa6855ef6a9c1fc0ed0679534ab0baee96835e5c8f73" + }, + "escalation": { + "file": "audio/escalation.wav", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "seconds": 0.9, + "seed": 80001, + "peak": 23592, + "rms": 12059.61356558418, + "sha256": "cb5c32c1672f7ba66edb0ec88cff872f12b48d0b5cfdb8ee4e42467c35643535" + }, + "boss_alarm": { + "file": "audio/boss_alarm.wav", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "seconds": 1.2, + "seed": 80002, + "peak": 23592, + "rms": 12059.381611466759, + "sha256": "08d210573656ef967663de074cb438b0e489548e9dbc10e7e8f896ce3c9905fd" + }, + "victory": { + "file": "audio/victory.wav", + "sample_rate": 22050, + "bits": 16, + "channels": 1, + "seconds": 1.6, + "seed": 80003, + "peak": 23592, + "rms": 12059.530679957381, + "sha256": "9d724d10118a144d78cd83a30d4e535ca9e4207033f7656c7d033a6098ed590e" + } + } +} diff --git a/mods/iron_coast_stage2_mission_8/audio/approach.wav b/mods/iron_coast_stage2_mission_8/audio/approach.wav new file mode 100644 index 00000000..b77d9320 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/audio/approach.wav differ diff --git a/mods/iron_coast_stage2_mission_8/audio/boss_alarm.wav b/mods/iron_coast_stage2_mission_8/audio/boss_alarm.wav new file mode 100644 index 00000000..33740d16 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/audio/boss_alarm.wav differ diff --git a/mods/iron_coast_stage2_mission_8/audio/escalation.wav b/mods/iron_coast_stage2_mission_8/audio/escalation.wav new file mode 100644 index 00000000..26f45374 Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/audio/escalation.wav differ diff --git a/mods/iron_coast_stage2_mission_8/audio/victory.wav b/mods/iron_coast_stage2_mission_8/audio/victory.wav new file mode 100644 index 00000000..a363469e Binary files /dev/null and b/mods/iron_coast_stage2_mission_8/audio/victory.wav differ diff --git a/mods/iron_coast_stage2_mission_8/build_finale_assets.py b/mods/iron_coast_stage2_mission_8/build_finale_assets.py new file mode 100755 index 00000000..92fba430 --- /dev/null +++ b/mods/iron_coast_stage2_mission_8/build_finale_assets.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python3 +"""Package four genuine imagegen masters and synthesize reproducible local PCM. + +Art operations only extract complete alpha sprites, fit without distortion, +reduce SD, and split joined terrain. Original reference pixels are not shipped. +""" +from pathlib import Path +from PIL import Image, ImageOps +import hashlib,json,math,random,struct,wave +ROOT=Path(__file__).resolve().parent.parent +PALETTE=ROOT.parent/'data/misc/PALETTE_DAT' +GEN=Path('/home/quintine/.codex/generated_images/01a1245e-048c-7e92-91d2-78de2e5900ab') +REFERENCE=ROOT.parent.parent/'.reference/iron-coast-stage2-finale/classic-reference.png' +GATE={('boss', 7, 1): ('stage2-dreadnought-v1', '82daccfc-adb2-4c39-964f-9016d2bde07d'), ('boss', 8, 1): ('stage2-leviathan-v1', 'e5eae8a4-174b-43e7-9b11-c9fadf457ebf'), ('mission', 7, 1): ('stage2-fleet-terrain-v1', 'ae683e17-1f9b-47dd-9f85-5cb4664341f9'), ('mission', 8, 1): ('stage2-blacktide-terrain-v1', '6533e770-3571-4536-be9d-f5b641e9d2f0'), ('mission', 8, 2): ('stage2-blacktide-terrain-v2', 'd96ef991-fdf2-4189-9865-555a6a42927c')} +RAW={('boss',7,1):'exec-d314321c-4fde-4164-affb-67f3fa61a50f.png',('boss',8,1):'exec-34a0f83d-4b85-46ed-b927-6681a113ed09.png',('mission',7,1):'exec-b60ac9a7-fbe0-4ae4-944a-cfaed9bd3df9.png',('mission',8,1):'exec-6a1fcf7e-50e9-4764-bbd9-6c6476670b65.png',('mission',8,2):'exec-1ba2d521-d873-4602-8ef2-046c1f241587.png'} +def sha(p):return hashlib.sha256(p.read_bytes()).hexdigest() +def put(p,v):p.write_text(json.dumps(v,indent=2)+'\n') +def pcm(pkg,name,n,seed): + rate=22050;count=round(n*rate);rng=random.Random(seed);phase=0;low=0;values=[] + for i in range(count): + t=i/rate;p=i/(count-1);noise=rng.uniform(-1,1);low=.91*low+.09*noise + if name in ['warning','phase']: + f=[550,825,1100][min(2,int(p*3))] if name=='warning' else [165,220,330,440][min(3,int(p*4))] + phase+=2*math.pi*f/rate;v=.7*math.sin(phase)+.2*math.sin(phase*2);env=math.sin(math.pi*((p*3)%1))**.7 if name=='warning' else math.sin(math.pi*p)**.6 + elif name=='shot': + phase+=2*math.pi*(60+270*(1-p)**2)/rate;v=.55*math.sin(phase)+.22*noise+.25*low;env=min(1,t/.003)*math.exp(-p*7) + elif name=='death': + phase+=2*math.pi*(55-30*p)/rate;v=.6*low+.2*noise+.3*math.sin(phase);env=min(1,t/.003)*math.exp(-p*4) + else: + notes={'approach':[110,147,165,220],'escalation':[220,165,220,165],'boss_alarm':[147,110,98,73],'victory':[196,262,330,392,524]} + ns=notes[name];f=ns[min(len(ns)-1,int(p*len(ns)))];phase+=2*math.pi*f/rate;v=.8*math.sin(phase)+.18*math.sin(phase*2) + local=(p*len(ns))%1;env=math.sin(math.pi*local)**.65 + env*=min(1,(count-1-i)/(rate*.005));values.append(v*max(0,env)) + peak=max(abs(v) for v in values);samples=[round(v/peak*.72*32767) for v in values];path=pkg/'audio'/f'{name}.wav' + with wave.open(str(path),'wb') as w:w.setparams((1,2,rate,0,'NONE','not compressed'));w.writeframes(struct.pack('<'+'h'*count,*samples)) + return {'file':str(path.relative_to(pkg)),'sample_rate':rate,'bits':16,'channels':1,'seconds':count/rate,'seed':seed,'peak':max(map(abs,samples)),'rms':(sum(v*v for v in samples)/count)**.5,'sha256':sha(path)} +def provenance(pkg,kind,n): + previous_path=pkg/'art/provenance.json' + previous=json.loads(previous_path.read_text()) if previous_path.exists() else {} + old={v['version']:v for v in previous.get('raws',[])} + raws=[] + for (k,num,ver),builtin in RAW.items(): + if (k,num)!=(kind,n):continue + p=pkg/'art'/f'generated-v{ver}.png';original=GEN/builtin + if original.exists():assert sha(p)==sha(original) + prompt=pkg/'art'/f'prompt-v{ver}.txt' + ref=pkg/'art/generated-v1.png' if ver==2 else REFERENCE + raws.append({'version':ver,'gate_owner':'/root/iron_coast_6','gate_job':GATE[(kind,n,ver)][0],'gate_lease':GATE[(kind,n,ver)][1],'gate_outcome':'success','builtin_file':str(original),'builtin_sha256':sha(p),'raw_file':str(p.relative_to(pkg)),'raw_sha256':sha(p),'prompt_file':str(prompt.relative_to(pkg)),'prompt_sha256':sha(prompt),'reference_file':str(ref),'reference_sha256':sha(ref) if ref.exists() else old[ver]['reference_sha256'],'builtin_identity_verified':True,'transparent_requested':kind=='boss','rejected':kind=='mission' and n==8 and ver==1}) + put(pkg/'art/provenance.json',{'generator':'OpenAI builtin imagegen; exact untouched PNGs preserved','utc':'2026-10-11','raws':raws,'original_references':'External authentic catalog board; no decoded original reference pixels included in this package','historical_hold':'Mission8 v1 painted an aircraft in the platform; v2 genuinely replaces it with empty service deck' if n==8 and kind=='mission' else None}) +def boss(n): + pkg=ROOT/f'iron_coast_stage2_boss_{n}';frames=2 if n==7 else 3;logical=(112,88) if n==7 else (112,112);im=Image.open(pkg/'art/generated-v1.png').convert('RGBA');cut=im.height*3//4 + output=[];crops=[] + for f in range(frames): + cell=(f*im.width//frames,0,(f+1)*im.width//frames,cut);part=im.crop(cell) + box=part.getchannel('A').point(lambda a:255 if a>=128 else 0).getbbox();assert box + # Preserve meaningful alpha, plus margin; all discarded pixels are alpha<16. + allbox=part.getchannel('A').point(lambda a:255 if a>=16 else 0).getbbox() + crop=(max(0,allbox[0]-2),max(0,allbox[1]-2),min(part.width,allbox[2]+2),min(part.height,allbox[3]+2)) + part=part.crop(crop);size=(logical[0]*4,logical[1]*4);ratio=min((size[0]-24)/part.width,(size[1]-24)/part.height) + fit=part.resize((round(part.width*ratio),round(part.height*ratio)),Image.Resampling.LANCZOS);hd=Image.new('RGBA',size);hd.alpha_composite(fit,((size[0]-fit.width)//2,(size[1]-fit.height)//2));output.append(hd) + crops.append({'frame':f,'cell':cell,'alpha16_crop':crop,'source_occupied_bounds':box,'fit_size':fit.size}) + hd=Image.new('RGBA',(logical[0]*4*frames,logical[1]*4));sd=Image.new('RGBA',(logical[0]*frames,logical[1])) + for f,frame in enumerate(output):hd.paste(frame,(f*logical[0]*4,0));sd.paste(frame.resize(logical,Image.Resampling.BOX),(f*logical[0],0)) + hd.save(pkg/'art/unit-hd.png');sd.save(pkg/'art/unit-sd.png') + part=im.crop((0,cut,im.width,im.height));box=part.getchannel('A').point(lambda a:255 if a>=16 else 0).getbbox();assert box;part=part.crop(box) + shd=Image.new('RGBA',(24,48));ratio=min(20/part.width,44/part.height);fit=part.resize((round(part.width*ratio),round(part.height*ratio)),Image.Resampling.LANCZOS);shd.alpha_composite(fit,((24-fit.width)//2,(48-fit.height)//2));shd.save(pkg/'art/projectile-hd.png');shd.resize((6,12),Image.Resampling.BOX).save(pkg/'art/projectile-sd.png') + files={} + for name in ['unit-sd','unit-hd','projectile-sd','projectile-hd']: + path=pkg/'art'/f'{name}.png';x=Image.open(path);files[str(path.relative_to(pkg))]={'size':x.size,'sha256':sha(path)} + audio={name:pcm(pkg,name,duration,n*1000+i) for i,(name,duration) in enumerate([('warning',.32),('phase',.55),('shot',.25),('death',1.25)])} + put(pkg/'audio-recipe.json',{'generator':'build_finale_assets.py deterministic chirp/noise PCM synthesis; no recordings','files':audio}) + put(pkg/'art-qa.json',{'pipeline':'Complete meaningful-alpha cell crop with proportional fit; transparent centered padding; BOX SD reduction; no repaint','logical_size':logical,'frames':frames,'hd_scale':4,'origin':[0,0],'crops':crops,'projectile_crop_in_lower_cell':box,'files':files,'phase_alignment':'Common centered logical canvas; collision bounds identical for every displayed phase'}) + provenance(pkg,'boss',n) + id=pkg.name;title='Dreadnought' if n==7 else 'Leviathan';hp=280 if n==7 else 360 + content={'weapons':[{'id':id+':shell','name':title+' cannon shell','damage':3 if n==7 else 4,'speed':3,'cooldown':84,'behavior':'straight','target':'all','art':{'png':'art/projectile-sd.png','hd_png':'art/projectile-hd.png','logical_width':6,'logical_height':12}}], 'enemies':[{'id':id+':unit','name':title,'health':hp,'speed':0,'reward':5000 if n==7 else 9000,'ground':False,'boss':True,'cooldown':10000,'art':{'png':'art/unit-sd.png','hd_png':'art/unit-hd.png','logical_width':logical[0],'logical_height':logical[1],'frames':frames},'script':'scripts/ai.rhai'}], 'sounds':[{'id':id+':'+name,'name':title+' '+name,'file':info['file'],'volume':90 if name=='warning' else 110,'pan':127,'pitch':128,'priority':3 if name in ['death','phase'] else 2} for name,info in audio.items()]} + put(pkg/'content.json',content) + (pkg/'mod.toml').write_text(f'id = "{id}"\nname = "Iron Coast II: {title} Boss"\nversion = "1.0.0"\napi_version = 1\ndescription = "Distinct persistent {title} carrier with telegraphed phase attacks, SD/HD artwork and original synthesized PCM sounds."\ncontent = "content.json"\nscripts = ["scripts/ai.rhai"]\n') +def mission(n): + pkg=ROOT/f'iron_coast_stage2_mission_{n}';selected=2 if n==8 else 1;source=Image.open(pkg/f'art/generated-v{selected}.png').convert('RGB');hd=source.resize((1152,1536),Image.Resampling.LANCZOS) + # Ordinary palette0..239 only: reserved252/253 may never be remapped by art. + raw=PALETTE.read_bytes();colors=[(min(v,63)<<2)|(min(v,63)>>4) for v in raw];pal=Image.new('P',(1,1));pal.putpalette(colors[:720]+colors[:3]*16) + sd=source.resize((288,384),Image.Resampling.LANCZOS).quantize(palette=pal,dither=Image.Dither.NONE).convert('RGB') + for mode,master,scale in [('sd',sd,1),('hd',hd,4)]: + for reflect in [False,True]: + img=ImageOps.flip(master) if reflect else master;joined=Image.new('RGB',img.size) + for row in range(12): + for col in range(9): + k=int(reflect)*108+row*9+col;tile=img.crop((col*32*scale,row*32*scale,(col+1)*32*scale,(row+1)*32*scale));tile.save(pkg/f'art/tile_{k:03}_{mode}.png');joined.paste(tile,(col*32*scale,row*32*scale)) + assert joined.tobytes()==img.tobytes() + assert master.crop((0,master.height-1,master.width,master.height)).tobytes()==ImageOps.flip(master).crop((0,0,master.width,1)).tobytes() + master.save(pkg/f'art/terrain-preview-{mode}.png') + # Briefing is a genuinely authored map overview, proportional fit/crop; no + # duplicated static live entities or replacement text in artwork. + brief=ImageOps.fit(source,(1280,800),Image.Resampling.LANCZOS,centering=(.5,.5));brief.save(pkg/'art/briefing-hd.png');brief.resize((320,200),Image.Resampling.LANCZOS).quantize(palette=pal,dither=Image.Dither.NONE).convert('RGB').save(pkg/'art/briefing-sd.png') + audio={name:pcm(pkg,name,seconds,n*10000+i) for i,(name,seconds) in enumerate([('approach',1.1),('escalation',.9),('boss_alarm',1.2),('victory',1.6)])} + put(pkg/'audio-recipe.json',{'generator':'build_finale_assets.py deterministic note-envelope PCM synthesis; no recordings','files':audio}) + # Varied real native enemy entries keep original Catalog behavior and paths. + classics=['base:enemy_0_73','base:enemy_0_74','base:enemy_0_23','base:enemy_0_24','base:enemy_0_95','base:enemy_0_96'] + spawns=[] + for k,tick in enumerate(range(100,2400 if n==7 else 2700,125)): + spawns.append({'tick':tick,'enemy':classics[k%len(classics)],'x':[40,210,112,230,72,176][k%6],'y':-32}) + # Interceptor formations provide additional air pressure, with timed rests. + for k,tick in enumerate([330,740,1120,1510,1890,2210] if n==7 else [360,800,1210,1590,2030,2500]): + spawns.append({'tick':tick,'enemy':'iron_coast_stage2_interceptor:unit','x':[52,210,90,190][k%4],'y':-24}) + siege=[(260,32),(610,216),(1100,80),(1710,168)] if n==7 else [(280,32),(700,216),(1180,80),(1730,168),(2210,128)] + skimmer=[(460,64),(1370,192),(2140,128)] if n==7 else [(490,64),(960,192),(1510,112),(2400,224)] + for enemy,entries in [('siege',siege),('skimmer',skimmer)]: + spawns.extend({'tick':tick,'enemy':f'iron_coast_stage2_{enemy}:unit','x':x,'y':-32} for tick,x in entries) + boss_tick=2500 if n==7 else 2850;spawns.append({'tick':boss_tick,'enemy':f'iron_coast_stage2_boss_{n}:unit','x':88,'y':-112 if n==8 else -88});spawns.sort(key=lambda x:x['tick']) + id=pkg.name;title='Siege of the Iron Fleet' if n==7 else 'Black Tide' + content={'sounds':[{'id':id+':'+name,'name':title+' '+name,'file':info['file'],'volume':90 if name!='boss_alarm' else 105,'pan':127,'pitch':128,'priority':3 if name in ['boss_alarm','victory'] else 2} for name,info in audio.items()], 'missions':[{'id':id+f':mission_0{n}','name':f'Iron Coast II {n} — {title}','duration':3800,'auto_complete':False,'columns':9,'music_track':'iron_coast_stage2_music:finale','spawns':spawns,'tiles':[{'art':{'png':f'art/tile_{k:03}_sd.png','hd_png':f'art/tile_{k:03}_hd.png','logical_width':32,'logical_height':32}} for k in range(216)],'layout':list(range(216))*16,'art':{'png':'art/briefing-sd.png','hd_png':'art/briefing-hd.png','logical_width':320,'logical_height':200},'script':'scripts/mission.rhai'}]} + put(pkg/'content.json',content) + deps=['iron_coast_stage2_interceptor','iron_coast_stage2_siege','iron_coast_stage2_skimmer',f'iron_coast_stage2_boss_{n}','iron_coast_stage2_music'] + (pkg/'mod.toml').write_text(f'id = "{id}"\nname = "Iron Coast II {n}: {title}"\nversion = "1.0.0"\napi_version = 1\ndescription = "{title}: native classic waves, persistent naval defense objectives and a phased final carrier. Starter-gun viable, inventory safe, joined SD/HD terrain and original PCM cues."\ncontent = "content.json"\nscripts = ["scripts/mission.rhai"]\n\n[dependencies]\n'+''.join(f'{d} = "^1.0"\n' for d in deps)) + put(pkg/'art-qa.json',{'selected_raw':f'art/generated-v{selected}.png','selected_raw_sha256':sha(pkg/f'art/generated-v{selected}.png'),'logical_tile':[32,32],'hd_tile':[128,128],'columns':9,'rows':24,'layout_period_repetitions':16,'layout_total_rows':384,'logical_scroll_coverage':12288,'joined_palette_then_split':True,'mirrored_loop_boundary_exact':True,'reassembly_pixel_exact':True,'logical_collision_unchanged_by_hd':True,'palette_sha256':sha(PALETTE),'palette_classes':'ordinary0..239 only, alpha opaque; runtime mods never claim reserved original palette classes','briefing':'centered proportional overview crop of the genuine joined map; no extra entity artwork','files':{str(p.relative_to(pkg)):sha(p) for p in sorted((pkg/'art').glob('*-*.png'))}}) + provenance(pkg,'mission',n) +for n in [7,8]:boss(n);mission(n) +print('Four finale packages: matching art, seam-safe terrain, PCM and content generated') diff --git a/mods/iron_coast_stage2_mission_8/content.json b/mods/iron_coast_stage2_mission_8/content.json new file mode 100644 index 00000000..35775c4f --- /dev/null +++ b/mods/iron_coast_stage2_mission_8/content.json @@ -0,0 +1,5469 @@ +{ + "sounds": [ + { + "id": "iron_coast_stage2_mission_8:approach", + "name": "Black Tide approach", + "file": "audio/approach.wav", + "volume": 90, + "pan": 127, + "pitch": 128, + "priority": 2 + }, + { + "id": "iron_coast_stage2_mission_8:escalation", + "name": "Black Tide escalation", + "file": "audio/escalation.wav", + "volume": 90, + "pan": 127, + "pitch": 128, + "priority": 2 + }, + { + "id": "iron_coast_stage2_mission_8:boss_alarm", + "name": "Black Tide boss_alarm", + "file": "audio/boss_alarm.wav", + "volume": 105, + "pan": 127, + "pitch": 128, + "priority": 3 + }, + { + "id": "iron_coast_stage2_mission_8:victory", + "name": "Black Tide victory", + "file": "audio/victory.wav", + "volume": 90, + "pan": 127, + "pitch": 128, + "priority": 3 + } + ], + "missions": [ + { + "id": "iron_coast_stage2_mission_8:mission_08", + "name": "Iron Coast II 8 \u2014 Black Tide", + "duration": 3800, + "auto_complete": false, + "columns": 9, + "music_track": "iron_coast_stage2_music:finale", + "spawns": [ + { + "tick": 100, + "enemy": "base:enemy_0_73", + "x": 40, + "y": -32 + }, + { + "tick": 225, + "enemy": "base:enemy_0_74", + "x": 210, + "y": -32 + }, + { + "tick": 280, + "enemy": "iron_coast_stage2_siege:unit", + "x": 32, + "y": -32 + }, + { + "tick": 350, + "enemy": "base:enemy_0_23", + "x": 112, + "y": -32 + }, + { + "tick": 360, + "enemy": "iron_coast_stage2_interceptor:unit", + "x": 52, + "y": -24 + }, + { + "tick": 475, + "enemy": "base:enemy_0_24", + "x": 230, + "y": -32 + }, + { + "tick": 490, + "enemy": "iron_coast_stage2_skimmer:unit", + "x": 64, + "y": -32 + }, + { + "tick": 600, + "enemy": "base:enemy_0_95", + "x": 72, + "y": -32 + }, + { + "tick": 700, + "enemy": "iron_coast_stage2_siege:unit", + "x": 216, + "y": -32 + }, + { + "tick": 725, + "enemy": "base:enemy_0_96", + "x": 176, + "y": -32 + }, + { + "tick": 800, + "enemy": "iron_coast_stage2_interceptor:unit", + "x": 210, + "y": -24 + }, + { + "tick": 850, + "enemy": "base:enemy_0_73", + "x": 40, + "y": -32 + }, + { + "tick": 960, + "enemy": "iron_coast_stage2_skimmer:unit", + "x": 192, + "y": -32 + }, + { + "tick": 975, + "enemy": "base:enemy_0_74", + "x": 210, + "y": -32 + }, + { + "tick": 1100, + "enemy": "base:enemy_0_23", + "x": 112, + "y": -32 + }, + { + "tick": 1180, + "enemy": "iron_coast_stage2_siege:unit", + "x": 80, + "y": -32 + }, + { + "tick": 1210, + "enemy": "iron_coast_stage2_interceptor:unit", + "x": 90, + "y": -24 + }, + { + "tick": 1225, + "enemy": "base:enemy_0_24", + "x": 230, + "y": -32 + }, + { + "tick": 1350, + "enemy": "base:enemy_0_95", + "x": 72, + "y": -32 + }, + { + "tick": 1475, + "enemy": "base:enemy_0_96", + "x": 176, + "y": -32 + }, + { + "tick": 1510, + "enemy": "iron_coast_stage2_skimmer:unit", + "x": 112, + "y": -32 + }, + { + "tick": 1590, + "enemy": "iron_coast_stage2_interceptor:unit", + "x": 190, + "y": -24 + }, + { + "tick": 1600, + "enemy": "base:enemy_0_73", + "x": 40, + "y": -32 + }, + { + "tick": 1725, + "enemy": "base:enemy_0_74", + "x": 210, + "y": -32 + }, + { + "tick": 1730, + "enemy": "iron_coast_stage2_siege:unit", + "x": 168, + "y": -32 + }, + { + "tick": 1850, + "enemy": "base:enemy_0_23", + "x": 112, + "y": -32 + }, + { + "tick": 1975, + "enemy": "base:enemy_0_24", + "x": 230, + "y": -32 + }, + { + "tick": 2030, + "enemy": "iron_coast_stage2_interceptor:unit", + "x": 52, + "y": -24 + }, + { + "tick": 2100, + "enemy": "base:enemy_0_95", + "x": 72, + "y": -32 + }, + { + "tick": 2210, + "enemy": "iron_coast_stage2_siege:unit", + "x": 128, + "y": -32 + }, + { + "tick": 2225, + "enemy": "base:enemy_0_96", + "x": 176, + "y": -32 + }, + { + "tick": 2350, + "enemy": "base:enemy_0_73", + "x": 40, + "y": -32 + }, + { + "tick": 2400, + "enemy": "iron_coast_stage2_skimmer:unit", + "x": 224, + "y": -32 + }, + { + "tick": 2475, + "enemy": "base:enemy_0_74", + "x": 210, + "y": -32 + }, + { + "tick": 2500, + "enemy": "iron_coast_stage2_interceptor:unit", + "x": 210, + "y": -24 + }, + { + "tick": 2600, + "enemy": "base:enemy_0_23", + "x": 112, + "y": -32 + }, + { + "tick": 2850, + "enemy": "iron_coast_stage2_boss_8:unit", + "x": 88, + "y": -112 + } + ], + "tiles": [ + { + "art": { + "png": "art/tile_000_sd.png", + "hd_png": "art/tile_000_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_001_sd.png", + "hd_png": "art/tile_001_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_002_sd.png", + "hd_png": "art/tile_002_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_003_sd.png", + "hd_png": "art/tile_003_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_004_sd.png", + "hd_png": "art/tile_004_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_005_sd.png", + "hd_png": "art/tile_005_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_006_sd.png", + "hd_png": "art/tile_006_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_007_sd.png", + "hd_png": "art/tile_007_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_008_sd.png", + "hd_png": "art/tile_008_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_009_sd.png", + "hd_png": "art/tile_009_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_010_sd.png", + "hd_png": "art/tile_010_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_011_sd.png", + "hd_png": "art/tile_011_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_012_sd.png", + "hd_png": "art/tile_012_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_013_sd.png", + "hd_png": "art/tile_013_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_014_sd.png", + "hd_png": "art/tile_014_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_015_sd.png", + "hd_png": "art/tile_015_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_016_sd.png", + "hd_png": "art/tile_016_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_017_sd.png", + "hd_png": "art/tile_017_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_018_sd.png", + "hd_png": "art/tile_018_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_019_sd.png", + "hd_png": "art/tile_019_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_020_sd.png", + "hd_png": "art/tile_020_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_021_sd.png", + "hd_png": "art/tile_021_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_022_sd.png", + "hd_png": "art/tile_022_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_023_sd.png", + "hd_png": "art/tile_023_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_024_sd.png", + "hd_png": "art/tile_024_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_025_sd.png", + "hd_png": "art/tile_025_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_026_sd.png", + "hd_png": "art/tile_026_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_027_sd.png", + "hd_png": "art/tile_027_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_028_sd.png", + "hd_png": "art/tile_028_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_029_sd.png", + "hd_png": "art/tile_029_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_030_sd.png", + "hd_png": "art/tile_030_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_031_sd.png", + "hd_png": "art/tile_031_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_032_sd.png", + "hd_png": "art/tile_032_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_033_sd.png", + "hd_png": "art/tile_033_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_034_sd.png", + "hd_png": "art/tile_034_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_035_sd.png", + "hd_png": "art/tile_035_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_036_sd.png", + "hd_png": "art/tile_036_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_037_sd.png", + "hd_png": "art/tile_037_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_038_sd.png", + "hd_png": "art/tile_038_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_039_sd.png", + "hd_png": "art/tile_039_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_040_sd.png", + "hd_png": "art/tile_040_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_041_sd.png", + "hd_png": "art/tile_041_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_042_sd.png", + "hd_png": "art/tile_042_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_043_sd.png", + "hd_png": "art/tile_043_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_044_sd.png", + "hd_png": "art/tile_044_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_045_sd.png", + "hd_png": "art/tile_045_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_046_sd.png", + "hd_png": "art/tile_046_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_047_sd.png", + "hd_png": "art/tile_047_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_048_sd.png", + "hd_png": "art/tile_048_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_049_sd.png", + "hd_png": "art/tile_049_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_050_sd.png", + "hd_png": "art/tile_050_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_051_sd.png", + "hd_png": "art/tile_051_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_052_sd.png", + "hd_png": "art/tile_052_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_053_sd.png", + "hd_png": "art/tile_053_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_054_sd.png", + "hd_png": "art/tile_054_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_055_sd.png", + "hd_png": "art/tile_055_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_056_sd.png", + "hd_png": "art/tile_056_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_057_sd.png", + "hd_png": "art/tile_057_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_058_sd.png", + "hd_png": "art/tile_058_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_059_sd.png", + "hd_png": "art/tile_059_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_060_sd.png", + "hd_png": "art/tile_060_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_061_sd.png", + "hd_png": "art/tile_061_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_062_sd.png", + "hd_png": "art/tile_062_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_063_sd.png", + "hd_png": "art/tile_063_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_064_sd.png", + "hd_png": "art/tile_064_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_065_sd.png", + "hd_png": "art/tile_065_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_066_sd.png", + "hd_png": "art/tile_066_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_067_sd.png", + "hd_png": "art/tile_067_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_068_sd.png", + "hd_png": "art/tile_068_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_069_sd.png", + "hd_png": "art/tile_069_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_070_sd.png", + "hd_png": "art/tile_070_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_071_sd.png", + "hd_png": "art/tile_071_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_072_sd.png", + "hd_png": "art/tile_072_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_073_sd.png", + "hd_png": "art/tile_073_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_074_sd.png", + "hd_png": "art/tile_074_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_075_sd.png", + "hd_png": "art/tile_075_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_076_sd.png", + "hd_png": "art/tile_076_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_077_sd.png", + "hd_png": "art/tile_077_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_078_sd.png", + "hd_png": "art/tile_078_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_079_sd.png", + "hd_png": "art/tile_079_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_080_sd.png", + "hd_png": "art/tile_080_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_081_sd.png", + "hd_png": "art/tile_081_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_082_sd.png", + "hd_png": "art/tile_082_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_083_sd.png", + "hd_png": "art/tile_083_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_084_sd.png", + "hd_png": "art/tile_084_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_085_sd.png", + "hd_png": "art/tile_085_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_086_sd.png", + "hd_png": "art/tile_086_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_087_sd.png", + "hd_png": "art/tile_087_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_088_sd.png", + "hd_png": "art/tile_088_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_089_sd.png", + "hd_png": "art/tile_089_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_090_sd.png", + "hd_png": "art/tile_090_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_091_sd.png", + "hd_png": "art/tile_091_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_092_sd.png", + "hd_png": "art/tile_092_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_093_sd.png", + "hd_png": "art/tile_093_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_094_sd.png", + "hd_png": "art/tile_094_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_095_sd.png", + "hd_png": "art/tile_095_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_096_sd.png", + "hd_png": "art/tile_096_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_097_sd.png", + "hd_png": "art/tile_097_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_098_sd.png", + "hd_png": "art/tile_098_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_099_sd.png", + "hd_png": "art/tile_099_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_100_sd.png", + "hd_png": "art/tile_100_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_101_sd.png", + "hd_png": "art/tile_101_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_102_sd.png", + "hd_png": "art/tile_102_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_103_sd.png", + "hd_png": "art/tile_103_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_104_sd.png", + "hd_png": "art/tile_104_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_105_sd.png", + "hd_png": "art/tile_105_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_106_sd.png", + "hd_png": "art/tile_106_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_107_sd.png", + "hd_png": "art/tile_107_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_108_sd.png", + "hd_png": "art/tile_108_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_109_sd.png", + "hd_png": "art/tile_109_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_110_sd.png", + "hd_png": "art/tile_110_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_111_sd.png", + "hd_png": "art/tile_111_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_112_sd.png", + "hd_png": "art/tile_112_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_113_sd.png", + "hd_png": "art/tile_113_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_114_sd.png", + "hd_png": "art/tile_114_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_115_sd.png", + "hd_png": "art/tile_115_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_116_sd.png", + "hd_png": "art/tile_116_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_117_sd.png", + "hd_png": "art/tile_117_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_118_sd.png", + "hd_png": "art/tile_118_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_119_sd.png", + "hd_png": "art/tile_119_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_120_sd.png", + "hd_png": "art/tile_120_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_121_sd.png", + "hd_png": "art/tile_121_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_122_sd.png", + "hd_png": "art/tile_122_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_123_sd.png", + "hd_png": "art/tile_123_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_124_sd.png", + "hd_png": "art/tile_124_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_125_sd.png", + "hd_png": "art/tile_125_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_126_sd.png", + "hd_png": "art/tile_126_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_127_sd.png", + "hd_png": "art/tile_127_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_128_sd.png", + "hd_png": "art/tile_128_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_129_sd.png", + "hd_png": "art/tile_129_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_130_sd.png", + "hd_png": "art/tile_130_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_131_sd.png", + "hd_png": "art/tile_131_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_132_sd.png", + "hd_png": "art/tile_132_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_133_sd.png", + "hd_png": "art/tile_133_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_134_sd.png", + "hd_png": "art/tile_134_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_135_sd.png", + "hd_png": "art/tile_135_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_136_sd.png", + "hd_png": "art/tile_136_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_137_sd.png", + "hd_png": "art/tile_137_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_138_sd.png", + "hd_png": "art/tile_138_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_139_sd.png", + "hd_png": "art/tile_139_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_140_sd.png", + "hd_png": "art/tile_140_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_141_sd.png", + "hd_png": "art/tile_141_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_142_sd.png", + "hd_png": "art/tile_142_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_143_sd.png", + "hd_png": "art/tile_143_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_144_sd.png", + "hd_png": "art/tile_144_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_145_sd.png", + "hd_png": "art/tile_145_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_146_sd.png", + "hd_png": "art/tile_146_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_147_sd.png", + "hd_png": "art/tile_147_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_148_sd.png", + "hd_png": "art/tile_148_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_149_sd.png", + "hd_png": "art/tile_149_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_150_sd.png", + "hd_png": "art/tile_150_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_151_sd.png", + "hd_png": "art/tile_151_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_152_sd.png", + "hd_png": "art/tile_152_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_153_sd.png", + "hd_png": "art/tile_153_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_154_sd.png", + "hd_png": "art/tile_154_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_155_sd.png", + "hd_png": "art/tile_155_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_156_sd.png", + "hd_png": "art/tile_156_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_157_sd.png", + "hd_png": "art/tile_157_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_158_sd.png", + "hd_png": "art/tile_158_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_159_sd.png", + "hd_png": "art/tile_159_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_160_sd.png", + "hd_png": "art/tile_160_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_161_sd.png", + "hd_png": "art/tile_161_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_162_sd.png", + "hd_png": "art/tile_162_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_163_sd.png", + "hd_png": "art/tile_163_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_164_sd.png", + "hd_png": "art/tile_164_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_165_sd.png", + "hd_png": "art/tile_165_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_166_sd.png", + "hd_png": "art/tile_166_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_167_sd.png", + "hd_png": "art/tile_167_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_168_sd.png", + "hd_png": "art/tile_168_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_169_sd.png", + "hd_png": "art/tile_169_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_170_sd.png", + "hd_png": "art/tile_170_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_171_sd.png", + "hd_png": "art/tile_171_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_172_sd.png", + "hd_png": "art/tile_172_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_173_sd.png", + "hd_png": "art/tile_173_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_174_sd.png", + "hd_png": "art/tile_174_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_175_sd.png", + "hd_png": "art/tile_175_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_176_sd.png", + "hd_png": "art/tile_176_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_177_sd.png", + "hd_png": "art/tile_177_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_178_sd.png", + "hd_png": "art/tile_178_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_179_sd.png", + "hd_png": "art/tile_179_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_180_sd.png", + "hd_png": "art/tile_180_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_181_sd.png", + "hd_png": "art/tile_181_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_182_sd.png", + "hd_png": "art/tile_182_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_183_sd.png", + "hd_png": "art/tile_183_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_184_sd.png", + "hd_png": "art/tile_184_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_185_sd.png", + "hd_png": "art/tile_185_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_186_sd.png", + "hd_png": "art/tile_186_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_187_sd.png", + "hd_png": "art/tile_187_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_188_sd.png", + "hd_png": "art/tile_188_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_189_sd.png", + "hd_png": "art/tile_189_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_190_sd.png", + "hd_png": "art/tile_190_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_191_sd.png", + "hd_png": "art/tile_191_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_192_sd.png", + "hd_png": "art/tile_192_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_193_sd.png", + "hd_png": "art/tile_193_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_194_sd.png", + "hd_png": "art/tile_194_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_195_sd.png", + "hd_png": "art/tile_195_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_196_sd.png", + "hd_png": "art/tile_196_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_197_sd.png", + "hd_png": "art/tile_197_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_198_sd.png", + "hd_png": "art/tile_198_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_199_sd.png", + "hd_png": "art/tile_199_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_200_sd.png", + "hd_png": "art/tile_200_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_201_sd.png", + "hd_png": "art/tile_201_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_202_sd.png", + "hd_png": "art/tile_202_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_203_sd.png", + "hd_png": "art/tile_203_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_204_sd.png", + "hd_png": "art/tile_204_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_205_sd.png", + "hd_png": "art/tile_205_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_206_sd.png", + "hd_png": "art/tile_206_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_207_sd.png", + "hd_png": "art/tile_207_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_208_sd.png", + "hd_png": "art/tile_208_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_209_sd.png", + "hd_png": "art/tile_209_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_210_sd.png", + "hd_png": "art/tile_210_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_211_sd.png", + "hd_png": "art/tile_211_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_212_sd.png", + "hd_png": "art/tile_212_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_213_sd.png", + "hd_png": "art/tile_213_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_214_sd.png", + "hd_png": "art/tile_214_hd.png", + "logical_width": 32, + "logical_height": 32 + } + }, + { + "art": { + "png": "art/tile_215_sd.png", + "hd_png": "art/tile_215_hd.png", + "logical_width": 32, + "logical_height": 32 + } + } + ], + "layout": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215 + ], + "art": { + "png": "art/briefing-sd.png", + "hd_png": "art/briefing-hd.png", + "logical_width": 320, + "logical_height": 200 + }, + "script": "scripts/mission.rhai" + } + ] +} diff --git a/mods/iron_coast_stage2_mission_8/mod.toml b/mods/iron_coast_stage2_mission_8/mod.toml new file mode 100644 index 00000000..ea74f2fc --- /dev/null +++ b/mods/iron_coast_stage2_mission_8/mod.toml @@ -0,0 +1,14 @@ +id = "iron_coast_stage2_mission_8" +name = "Iron Coast II 8: Black Tide" +version = "1.0.0" +api_version = 1 +description = "Black Tide: native classic waves, persistent naval defense objectives and a phased final carrier. Starter-gun viable, inventory safe, joined SD/HD terrain and original PCM cues." +content = "content.json" +scripts = ["scripts/mission.rhai"] + +[dependencies] +iron_coast_stage2_interceptor = "^1.0" +iron_coast_stage2_siege = "^1.0" +iron_coast_stage2_skimmer = "^1.0" +iron_coast_stage2_boss_8 = "^1.0" +iron_coast_stage2_music = "^1.0" diff --git a/mods/iron_coast_stage2_mission_8/scripts/mission.rhai b/mods/iron_coast_stage2_mission_8/scripts/mission.rhai new file mode 100644 index 00000000..c9eebc01 --- /dev/null +++ b/mods/iron_coast_stage2_mission_8/scripts/mission.rhai @@ -0,0 +1,50 @@ +// All state resets on a new sortie. No temporary gear is granted or consumed. +fn on_mission_start(event,state,random) { + #{commands:[#{op:"objective",key:"iron_coast_stage2_mission_8:phase",value:1}, + #{op:"objective",key:"iron_coast_stage2_mission_8:required_siege",value:5},#{op:"objective",key:"iron_coast_stage2_mission_8:required_skimmers",value:4}, + #{op:"objective",key:"iron_coast_stage2_mission_8:debrief",value:0},#{op:"objective",key:"iron_coast_stage2_mission_8:complete",value:0}, + #{op:"objective",key:"iron_coast_stage2_siege:defeated",value:0},#{op:"objective",key:"iron_coast_stage2_skimmer:defeated",value:0}, + #{op:"objective",key:"iron_coast_stage2_boss_8:defeated",value:0},#{op:"objective",key:"iron_coast_stage2_boss_8:phase",value:1}, + #{op:"play_sound",sound:"iron_coast_stage2_mission_8:approach"},#{op:"shield",amount:15}], + state:#{second:false,third:false,boss:false,complete:false}} +} +fn on_tick(event,state,random) { + let commands=[]; + // Required naval targets continue their authored lateral movement, but cannot + // scroll away before the player destroys them. Native classic waves are not + // moved, cloned or overridden by this mission script. + for unit in event.entities { + if unit.definition=="iron_coast_stage2_siege:unit" || unit.definition=="iron_coast_stage2_skimmer:unit" { + let y=if unit.definition=="iron_coast_stage2_siege:unit" {48} else {80}; + if unit.y>=y { + let x=if unit.x<16 {16} else if unit.x>240 {240} else {unit.x}; + commands.push(#{op:"move",entity:unit.entity,x:x,y:y}); + } + } + } + if !state.second && event.tick>=900 { + state.second=true; + commands.push(#{op:"objective",key:"iron_coast_stage2_mission_8:phase",value:2});commands.push(#{op:"play_sound",sound:"iron_coast_stage2_mission_8:escalation"}); + commands.push(#{op:"shield",amount:15}); + } + if !state.third && event.tick>=1800 { + state.third=true; + commands.push(#{op:"objective",key:"iron_coast_stage2_mission_8:phase",value:3});commands.push(#{op:"play_sound",sound:"iron_coast_stage2_mission_8:escalation"}); + commands.push(#{op:"shield",amount:15}); + } + if !state.boss && event.tick>=2850 { + state.boss=true; + commands.push(#{op:"objective",key:"iron_coast_stage2_mission_8:phase",value:4});commands.push(#{op:"play_sound",sound:"iron_coast_stage2_mission_8:boss_alarm"}); + commands.push(#{op:"shield",amount:20}); + } + let siege=if event.objectives.contains("iron_coast_stage2_siege:defeated") {event.objectives["iron_coast_stage2_siege:defeated"]} else {0}; + let skimmers=if event.objectives.contains("iron_coast_stage2_skimmer:defeated") {event.objectives["iron_coast_stage2_skimmer:defeated"]} else {0}; + let bosses=if event.objectives.contains("iron_coast_stage2_boss_8:defeated") {event.objectives["iron_coast_stage2_boss_8:defeated"]} else {0}; + if !state.complete && state.boss && siege>=5 && skimmers>=4 && bosses>=1 { + state.complete=true; + commands.push(#{op:"objective",key:"iron_coast_stage2_mission_8:phase",value:5});commands.push(#{op:"objective",key:"iron_coast_stage2_mission_8:debrief",value:1});commands.push(#{op:"objective",key:"iron_coast_stage2_mission_8:complete",value:1}); + commands.push(#{op:"credits",amount:55000});commands.push(#{op:"play_sound",sound:"iron_coast_stage2_mission_8:victory"});commands.push(#{op:"complete"}); + } + #{commands:commands,state:state} +} +fn on_mission_end(event,state,random) { #{commands:[],state:state} } diff --git a/mods/iron_coast_stage2_mission_8/validation-summary.json b/mods/iron_coast_stage2_mission_8/validation-summary.json new file mode 100644 index 00000000..7cf30cd0 --- /dev/null +++ b/mods/iron_coast_stage2_mission_8/validation-summary.json @@ -0,0 +1,476 @@ +{ + "status": "Author production acceptance passed; independent campaign/SD-HD Host review handled separately", + "package": "iron_coast_stage2_mission_8", + "version": "1.0.0", + "api_version": 1, + "actual_original_catalog": true, + "starter_fire_only": true, + "normal_movement_limit_pixels_per_tick": 4, + "near_shot_sidesteps": { + "hostile_y": [ + 136, + 188 + ], + "horizontal_distance_from_player_center": 24 + }, + "runs": [ + { + "boss_only": false, + "classic_ids": [ + "base:enemy_0_23", + "base:enemy_0_24", + "base:enemy_0_73", + "base:enemy_0_74", + "base:enemy_0_95", + "base:enemy_0_96" + ], + "credits": 85110, + "difficulty": 0, + "digest": "da54bffacf1365e1fe184672eae9e65d7ff6646acf9658ddcfdc8f1660e22438", + "initial_credits": 10000, + "initial_shield": 75, + "inventory_preserved": true, + "inventory_slots": 2, + "maximum_live_enemies": 3, + "mission": 8, + "native_movement_ids": [ + "base:enemy_0_23", + "base:enemy_0_24", + "base:enemy_0_73", + "base:enemy_0_74", + "base:enemy_0_95", + "base:enemy_0_96" + ], + "objectives": { + "iron_coast_stage2_boss_8:defeated": 1, + "iron_coast_stage2_boss_8:phase": 3, + "iron_coast_stage2_boss_8:safe_lane": 1, + "iron_coast_stage2_interceptor:defeated": 6, + "iron_coast_stage2_mission_8:complete": 1, + "iron_coast_stage2_mission_8:debrief": 1, + "iron_coast_stage2_mission_8:phase": 5, + "iron_coast_stage2_mission_8:required_siege": 5, + "iron_coast_stage2_mission_8:required_skimmers": 4, + "iron_coast_stage2_siege:defeated": 5, + "iron_coast_stage2_skimmer:defeated": 4 + }, + "outcome": "Complete", + "phase_frames": [ + 0, + 1, + 2 + ], + "rewards_once": true, + "shield": 86, + "sound_ids": [ + "iron_coast_stage2_boss_8:death", + "iron_coast_stage2_boss_8:phase", + "iron_coast_stage2_boss_8:warning", + "iron_coast_stage2_interceptor:death", + "iron_coast_stage2_interceptor:shot", + "iron_coast_stage2_mission_8:approach", + "iron_coast_stage2_mission_8:boss_alarm", + "iron_coast_stage2_mission_8:escalation", + "iron_coast_stage2_mission_8:victory", + "iron_coast_stage2_siege:death", + "iron_coast_stage2_siege:shot", + "iron_coast_stage2_siege:warning", + "iron_coast_stage2_skimmer:death", + "iron_coast_stage2_skimmer:shot", + "iron_coast_stage2_skimmer:warning" + ], + "tick": 3026 + }, + { + "boss_only": false, + "classic_ids": [ + "base:enemy_0_23", + "base:enemy_0_24", + "base:enemy_0_73", + "base:enemy_0_74", + "base:enemy_0_95", + "base:enemy_0_96" + ], + "credits": 85110, + "difficulty": 1, + "digest": "78ec97ed470e5b642d5ebeed2eaffac6a2fa7e7a8dc4d4e6288708fde0039cf3", + "initial_credits": 10000, + "initial_shield": 75, + "inventory_preserved": true, + "inventory_slots": 2, + "maximum_live_enemies": 3, + "mission": 8, + "native_movement_ids": [ + "base:enemy_0_23", + "base:enemy_0_24", + "base:enemy_0_73", + "base:enemy_0_74", + "base:enemy_0_95", + "base:enemy_0_96" + ], + "objectives": { + "iron_coast_stage2_boss_8:defeated": 1, + "iron_coast_stage2_boss_8:phase": 3, + "iron_coast_stage2_boss_8:safe_lane": 1, + "iron_coast_stage2_interceptor:defeated": 6, + "iron_coast_stage2_mission_8:complete": 1, + "iron_coast_stage2_mission_8:debrief": 1, + "iron_coast_stage2_mission_8:phase": 5, + "iron_coast_stage2_mission_8:required_siege": 5, + "iron_coast_stage2_mission_8:required_skimmers": 4, + "iron_coast_stage2_siege:defeated": 5, + "iron_coast_stage2_skimmer:defeated": 4 + }, + "outcome": "Complete", + "phase_frames": [ + 0, + 1, + 2 + ], + "rewards_once": true, + "shield": 32, + "sound_ids": [ + "iron_coast_stage2_boss_8:death", + "iron_coast_stage2_boss_8:phase", + "iron_coast_stage2_boss_8:warning", + "iron_coast_stage2_interceptor:death", + "iron_coast_stage2_interceptor:shot", + "iron_coast_stage2_mission_8:approach", + "iron_coast_stage2_mission_8:boss_alarm", + "iron_coast_stage2_mission_8:escalation", + "iron_coast_stage2_mission_8:victory", + "iron_coast_stage2_siege:death", + "iron_coast_stage2_siege:shot", + "iron_coast_stage2_siege:warning", + "iron_coast_stage2_skimmer:death", + "iron_coast_stage2_skimmer:shot", + "iron_coast_stage2_skimmer:warning" + ], + "tick": 3026 + }, + { + "boss_only": false, + "classic_ids": [ + "base:enemy_0_23", + "base:enemy_0_24", + "base:enemy_0_73", + "base:enemy_0_74", + "base:enemy_0_95", + "base:enemy_0_96" + ], + "credits": 85110, + "difficulty": 2, + "digest": "04632cbdcce3f5195eff1e815fbe28a23af201ae902d4c4ac5634c92ea1df5cb", + "initial_credits": 10000, + "initial_shield": 75, + "inventory_preserved": true, + "inventory_slots": 2, + "maximum_live_enemies": 3, + "mission": 8, + "native_movement_ids": [ + "base:enemy_0_23", + "base:enemy_0_24", + "base:enemy_0_73", + "base:enemy_0_74", + "base:enemy_0_95", + "base:enemy_0_96" + ], + "objectives": { + "iron_coast_stage2_boss_8:defeated": 1, + "iron_coast_stage2_boss_8:phase": 3, + "iron_coast_stage2_boss_8:safe_lane": 2, + "iron_coast_stage2_interceptor:defeated": 6, + "iron_coast_stage2_mission_8:complete": 1, + "iron_coast_stage2_mission_8:debrief": 1, + "iron_coast_stage2_mission_8:phase": 5, + "iron_coast_stage2_mission_8:required_siege": 5, + "iron_coast_stage2_mission_8:required_skimmers": 4, + "iron_coast_stage2_siege:defeated": 5, + "iron_coast_stage2_skimmer:defeated": 4 + }, + "outcome": "Complete", + "phase_frames": [ + 0, + 1, + 2 + ], + "rewards_once": true, + "shield": 32, + "sound_ids": [ + "iron_coast_stage2_boss_8:death", + "iron_coast_stage2_boss_8:phase", + "iron_coast_stage2_boss_8:shot", + "iron_coast_stage2_boss_8:warning", + "iron_coast_stage2_interceptor:death", + "iron_coast_stage2_interceptor:shot", + "iron_coast_stage2_mission_8:approach", + "iron_coast_stage2_mission_8:boss_alarm", + "iron_coast_stage2_mission_8:escalation", + "iron_coast_stage2_mission_8:victory", + "iron_coast_stage2_siege:death", + "iron_coast_stage2_siege:shot", + "iron_coast_stage2_siege:warning", + "iron_coast_stage2_skimmer:death", + "iron_coast_stage2_skimmer:shot", + "iron_coast_stage2_skimmer:warning" + ], + "tick": 3206 + }, + { + "boss_only": false, + "classic_ids": [ + "base:enemy_0_23", + "base:enemy_0_24", + "base:enemy_0_73", + "base:enemy_0_74", + "base:enemy_0_95", + "base:enemy_0_96" + ], + "credits": 85110, + "difficulty": 3, + "digest": "d63bc837853e5c3fe422cfaeb2f694fd4e10a987934cf0578368c4c89d93c906", + "initial_credits": 10000, + "initial_shield": 75, + "inventory_preserved": true, + "inventory_slots": 2, + "maximum_live_enemies": 3, + "mission": 8, + "native_movement_ids": [ + "base:enemy_0_23", + "base:enemy_0_24", + "base:enemy_0_73", + "base:enemy_0_74", + "base:enemy_0_95", + "base:enemy_0_96" + ], + "objectives": { + "iron_coast_stage2_boss_8:defeated": 1, + "iron_coast_stage2_boss_8:phase": 3, + "iron_coast_stage2_boss_8:safe_lane": 2, + "iron_coast_stage2_interceptor:defeated": 6, + "iron_coast_stage2_mission_8:complete": 1, + "iron_coast_stage2_mission_8:debrief": 1, + "iron_coast_stage2_mission_8:phase": 5, + "iron_coast_stage2_mission_8:required_siege": 5, + "iron_coast_stage2_mission_8:required_skimmers": 4, + "iron_coast_stage2_siege:defeated": 5, + "iron_coast_stage2_skimmer:defeated": 4 + }, + "outcome": "Complete", + "phase_frames": [ + 0, + 1, + 2 + ], + "rewards_once": true, + "shield": 32, + "sound_ids": [ + "iron_coast_stage2_boss_8:death", + "iron_coast_stage2_boss_8:phase", + "iron_coast_stage2_boss_8:shot", + "iron_coast_stage2_boss_8:warning", + "iron_coast_stage2_interceptor:death", + "iron_coast_stage2_interceptor:shot", + "iron_coast_stage2_mission_8:approach", + "iron_coast_stage2_mission_8:boss_alarm", + "iron_coast_stage2_mission_8:escalation", + "iron_coast_stage2_mission_8:victory", + "iron_coast_stage2_siege:death", + "iron_coast_stage2_siege:shot", + "iron_coast_stage2_siege:warning", + "iron_coast_stage2_skimmer:death", + "iron_coast_stage2_skimmer:shot", + "iron_coast_stage2_skimmer:warning" + ], + "tick": 3206 + }, + { + "boss_only": false, + "classic_ids": [ + "base:enemy_0_23", + "base:enemy_0_24", + "base:enemy_0_73", + "base:enemy_0_74", + "base:enemy_0_95", + "base:enemy_0_96" + ], + "credits": 75110, + "difficulty": 2, + "digest": "5d92f6fbed995207b84786c6295396e3b1eef129ed1e75b2a568e8a6392fbb50", + "initial_credits": 0, + "initial_shield": 100, + "inventory_preserved": true, + "inventory_slots": 2, + "maximum_live_enemies": 3, + "mission": 8, + "native_movement_ids": [ + "base:enemy_0_23", + "base:enemy_0_24", + "base:enemy_0_73", + "base:enemy_0_74", + "base:enemy_0_95", + "base:enemy_0_96" + ], + "objectives": { + "iron_coast_stage2_boss_8:defeated": 1, + "iron_coast_stage2_boss_8:phase": 3, + "iron_coast_stage2_boss_8:safe_lane": 2, + "iron_coast_stage2_interceptor:defeated": 6, + "iron_coast_stage2_mission_8:complete": 1, + "iron_coast_stage2_mission_8:debrief": 1, + "iron_coast_stage2_mission_8:phase": 5, + "iron_coast_stage2_mission_8:required_siege": 5, + "iron_coast_stage2_mission_8:required_skimmers": 4, + "iron_coast_stage2_siege:defeated": 5, + "iron_coast_stage2_skimmer:defeated": 4 + }, + "outcome": "Complete", + "phase_frames": [ + 0, + 1, + 2 + ], + "rewards_once": true, + "shield": 42, + "sound_ids": [ + "iron_coast_stage2_boss_8:death", + "iron_coast_stage2_boss_8:phase", + "iron_coast_stage2_boss_8:shot", + "iron_coast_stage2_boss_8:warning", + "iron_coast_stage2_interceptor:death", + "iron_coast_stage2_interceptor:shot", + "iron_coast_stage2_mission_8:approach", + "iron_coast_stage2_mission_8:boss_alarm", + "iron_coast_stage2_mission_8:escalation", + "iron_coast_stage2_mission_8:victory", + "iron_coast_stage2_siege:death", + "iron_coast_stage2_siege:shot", + "iron_coast_stage2_siege:warning", + "iron_coast_stage2_skimmer:death", + "iron_coast_stage2_skimmer:shot", + "iron_coast_stage2_skimmer:warning" + ], + "tick": 3206 + }, + { + "boss_only": false, + "classic_ids": [ + "base:enemy_0_23", + "base:enemy_0_24", + "base:enemy_0_73", + "base:enemy_0_74", + "base:enemy_0_95", + "base:enemy_0_96" + ], + "credits": 85110, + "difficulty": 2, + "digest": "422032d669a860371d0a82cf1b6e47ea19ae3786cef6382b3e09bc19e2cf8ca2", + "initial_credits": 10000, + "initial_shield": 75, + "inventory_preserved": true, + "inventory_slots": 20, + "maximum_live_enemies": 3, + "mission": 8, + "native_movement_ids": [ + "base:enemy_0_23", + "base:enemy_0_24", + "base:enemy_0_73", + "base:enemy_0_74", + "base:enemy_0_95", + "base:enemy_0_96" + ], + "objectives": { + "iron_coast_stage2_boss_8:defeated": 1, + "iron_coast_stage2_boss_8:phase": 3, + "iron_coast_stage2_boss_8:safe_lane": 2, + "iron_coast_stage2_interceptor:defeated": 6, + "iron_coast_stage2_mission_8:complete": 1, + "iron_coast_stage2_mission_8:debrief": 1, + "iron_coast_stage2_mission_8:phase": 5, + "iron_coast_stage2_mission_8:required_siege": 5, + "iron_coast_stage2_mission_8:required_skimmers": 4, + "iron_coast_stage2_siege:defeated": 5, + "iron_coast_stage2_skimmer:defeated": 4 + }, + "outcome": "Complete", + "phase_frames": [ + 0, + 1, + 2 + ], + "rewards_once": true, + "shield": 32, + "sound_ids": [ + "iron_coast_stage2_boss_8:death", + "iron_coast_stage2_boss_8:phase", + "iron_coast_stage2_boss_8:shot", + "iron_coast_stage2_boss_8:warning", + "iron_coast_stage2_interceptor:death", + "iron_coast_stage2_interceptor:shot", + "iron_coast_stage2_mission_8:approach", + "iron_coast_stage2_mission_8:boss_alarm", + "iron_coast_stage2_mission_8:escalation", + "iron_coast_stage2_mission_8:victory", + "iron_coast_stage2_siege:death", + "iron_coast_stage2_siege:shot", + "iron_coast_stage2_siege:warning", + "iron_coast_stage2_skimmer:death", + "iron_coast_stage2_skimmer:shot", + "iron_coast_stage2_skimmer:warning" + ], + "tick": 3206 + } + ], + "actual_production_mixer": [ + { + "actual_mixer_peak": 4864, + "actual_mixer_rms": 1835.7426224827923, + "muted_exact_zero": true, + "sound": "iron_coast_stage2_mission_8:approach" + }, + { + "actual_mixer_peak": 5760, + "actual_mixer_rms": 2242.4113306884624, + "muted_exact_zero": true, + "sound": "iron_coast_stage2_mission_8:boss_alarm" + }, + { + "actual_mixer_peak": 4864, + "actual_mixer_rms": 1660.8207320478632, + "muted_exact_zero": true, + "sound": "iron_coast_stage2_mission_8:escalation" + }, + { + "actual_mixer_peak": 4864, + "actual_mixer_rms": 2214.1028124276436, + "muted_exact_zero": true, + "sound": "iron_coast_stage2_mission_8:victory" + } + ], + "actual_mixer_cues_unclipped": true, + "actual_mute_exact_zero": true, + "per_entity_phase_isolation": true, + "actual_world_repeated_spawn_step_lethal_with_retained_state": true, + "death_and_rewards_once": true, + "PNG_source_and_output_dimensions_checked": true, + "external_proof_hashes": { + "validation-results.json": "d063d101d9e1d5cf1cb94240caba3ddef04b5183def5b6625ebe32d92951b28d", + "boss-validation-results.json": "ef20464533b00c35f63c1add0d3149dc9da341ec580f3221e389a62230143e0a", + "actual-audio-proof.json": "293e8f37a5e0ae776d6b0369207dc80f2e38b52c0c903de412bba9b4fbfc60d4", + "actual-mixer-all-cues.wav": "af00e983a61e1c26e1504a818fa524b31528fa8f44211cc6969bbc0f6e430124", + "asset-validation.json": "7a30c3aaf365a8ac16c97c1b519d93ca39f1723c96b1fac5f93fa88f7757a1f7", + "boss-art-contact.png": "444de75e4c171ddac84e2ae6f3f206e749e1fdc3a59d406aa4c66f7678519aa7", + "terrain-briefing-contact.png": "254895a2296d6972f9fa4132e21d95979b149be960600507633f44847398eb3b" + }, + "reference_visibility_limits": "Art contact sheets are author visual inspection. Sound proof uses actual mixer without a liveSDL occurrence claim. Root/independent Host screenshots bind final gameplay presentation separately.", + "full_inventory_preserved": true, + "physical_reserve_capacity_checked": true, + "mandatory_reachable_after_4050_ticks": true, + "elapsed_duration_never_wins": true, + "every_step_deterministic_replay": true, + "serialized_script_state_continuation_at_every_boss_phase": true, + "restart_reset": true, + "failed_sortie_preserves_gear": true, + "mission_complete_and_debrief_explicit": true, + "layout_scroll_pixels": 12288 +} diff --git a/mods/iron_coast_stage2_mission_8/validation/Cargo.lock b/mods/iron_coast_stage2_mission_8/validation/Cargo.lock new file mode 100644 index 00000000..d43c417e --- /dev/null +++ b/mods/iron_coast_stage2_mission_8/validation/Cargo.lock @@ -0,0 +1,821 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "const-random", + "getrandom 0.3.4", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "anyhow" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "bitflags" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "bytemuck" +version = "1.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95832e849adfb21180ccb6826a99da14e5d266ae5c2e668e1602cf234f153797" + +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + +[[package]] +name = "cfg-if" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600" + +[[package]] +name = "const-random" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" +dependencies = [ + "const-random-macro", +] + +[[package]] +name = "const-random-macro" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" +dependencies = [ + "getrandom 0.2.17", + "once_cell", + "tiny-keccak", +] + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01a7799fd6b852db0e61728dde9a204c423b44d689dbd432522543614b490e78" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "dyn-clone" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "fdeflate" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "flate2" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e634e2e0ebac1ee034020da1ca582e17ffe4e0f5e985823721e168928136dcb" +dependencies = [ + "crc32fast", + "miniz_oxide 0.9.1", + "zlib-rs", +] + +[[package]] +name = "futures-core" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" + +[[package]] +name = "futures-task" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" + +[[package]] +name = "futures-util" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "image" +version = "0.25.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85ab80394333c02fe689eaf900ab500fbd0c2213da414687ebf995a65d5a6104" +dependencies = [ + "bytemuck", + "byteorder-lite", + "moxcms", + "num-traits", + "png", +] + +[[package]] +name = "indexmap" +version = "2.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "iron-coast-stage2-finale-validation" +version = "1.0.0" +dependencies = [ + "raptor-replica", + "serde_json", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "js-sys" +version = "0.3.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7883d941dae510fb2d978fc3fe018c71c9e2892fd38854de3e8b92c2e5ad9cc5" +dependencies = [ + "cfg-if", + "futures-util", + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.190" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce5d3ddc6d3fa000eb1536d85e147bfe31aacaba692ed6a876f95cb7c855be78" + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "miniz_oxide" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b63fbc4a50860e98e7b2aa7804ded1db5cbc3aff9193adaff57a6931bf7c4b4c" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "moxcms" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb85c154ba489f01b25c0d36ae69a87e4a1c73a72631fc6c0eb6dde34a73e44b" +dependencies = [ + "num-traits", + "pxfm", +] + +[[package]] +name = "no-std-compat" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c" +dependencies = [ + "spin", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "png" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61" +dependencies = [ + "bitflags", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide 0.8.9", +] + +[[package]] +name = "portable-atomic" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "pxfm" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d55d956fa96f5ec02be2e13af0e20391a5aa83d6a074e3ad368959d0fab299ea" + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "raptor-replica" +version = "0.1.0" +dependencies = [ + "anyhow", + "image", + "rhai", + "schemars", + "semver", + "serde", + "serde_json", + "sha2", + "toml", +] + +[[package]] +name = "rhai" +version = "1.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0334639972c0ea5a3fd366aa36116754a11431b619fec3ed559b3f73bcbcebf5" +dependencies = [ + "ahash", + "bitflags", + "no-std-compat", + "num-traits", + "once_cell", + "rhai_codegen", + "serde", + "smallvec", + "smartstring", + "thin-vec", + "web-time", +] + +[[package]] +name = "rhai_codegen" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cd3a7535e50bf36857e7be7bec276d334e8c2dfa469c2201226fd01638ea5ca" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "rustversion" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" + +[[package]] +name = "schemars" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615" +dependencies = [ + "dyn-clone", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e265784ad618884abaea0600a9adf15393368d840e0222d101a072f3f7534d" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 2.0.119", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" +dependencies = [ + "serde", + "serde_core", +] + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.7", +] + +[[package]] +name = "serde_derive_internals" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "serde_json" +version = "1.0.152" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1741ab7a6cc54a03a89b5d563ed60075c277d9e3cfa73ad0c1f23f23974703c6" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_spanned" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +dependencies = [ + "serde", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "simd-adler32" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b3dc8af474f516a851ff4bd12db780f948b9250ad37211e4eec0bccea54e01b" +dependencies = [ + "serde", +] + +[[package]] +name = "smartstring" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29" +dependencies = [ + "autocfg", + "static_assertions", + "version_check", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "syn" +version = "2.0.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "3.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d62a2e0561533f2ca2561d0cf27fd9fedb640a1bf2616ff5d5c80d99017faadc" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thin-vec" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6a4b9ba8738cb4a4f399d37e266becfd475e75eb73425b87a05a2f2039ba63e" + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "toml" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "toml_write", + "winnow", +] + +[[package]] +name = "toml_write" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" + +[[package]] +name = "typenum" +version = "1.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" + +[[package]] +name = "unicode-ident" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasip2" +version = "1.0.4+wasi-0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.129" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb54f33acc68fd454578d9820b0bde1a1a3d17aa17bb7b6595806d02886d409" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.129" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e29d0c35b16e224a7eeb5cd2d25e3e1968fbd65604117b44d3b789d00ee8535" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.129" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f501a8bc3719dba86ef8ae4728879c08001bea749eb1333ac5b91e040e2a6b7" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 3.0.7", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.129" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23f0c9c52aa7cd7d77769a4cfe2a9adb1b331f489a41d912ce14513d5ab995c6" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winnow" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" +dependencies = [ + "memchr", +] + +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + +[[package]] +name = "zerocopy" +version = "0.8.62" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86502bf56ac7c77571a32e2647bb2a15894565e981fb2a48d7bde2d91c965a9d" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.62" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5457206954b06561e2608c7e19cf58b1926586d999c246eebe4502f7e2039d1a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "zlib-rs" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b268e58e7c693d7c271f93ffc4ba3b380412554231c85bf61ca7af91042a4112" + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/mods/iron_coast_stage2_mission_8/validation/Cargo.toml b/mods/iron_coast_stage2_mission_8/validation/Cargo.toml new file mode 100644 index 00000000..ebc366d7 --- /dev/null +++ b/mods/iron_coast_stage2_mission_8/validation/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "iron-coast-stage2-finale-validation" +version = "1.0.0" +edition = "2024" +publish = false + +[dependencies] +raptor-replica = { path = "../../..", default-features = false } +serde_json = "1" diff --git a/mods/iron_coast_stage2_mission_8/validation/src/main.rs b/mods/iron_coast_stage2_mission_8/validation/src/main.rs new file mode 100644 index 00000000..43078764 --- /dev/null +++ b/mods/iron_coast_stage2_mission_8/validation/src/main.rs @@ -0,0 +1,618 @@ +use raptor_replica::{ + assets::Catalog, + content::{ContentPack, Registry}, + modding::{self, ActiveMods, Command}, + persistence::Pilot, + simulation::{Input, Outcome, World}, +}; +use serde_json::{Value, json}; +use std::{ + collections::{BTreeMap, BTreeSet}, + fs, + path::PathBuf, +}; +fn root() -> PathBuf { + PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("../../..") + .canonicalize() + .unwrap() +} +fn active(n: u32, boss_only: bool) -> ActiveMods { + let catalog = Catalog::open(root().join("data")).unwrap(); + let mut base = Registry::base(&catalog).unwrap(); + let mut items = vec![]; + for i in 0..20 { + items.push(json!({"id":format!("fixture:filler_{i}"),"name":"Neutral saved gear","price":0,"max_count":1})); + } + let mut pack: ContentPack = serde_json::from_value(json!({"items":items})).unwrap(); + if boss_only { + pack.weapons.push(serde_json::from_value(json!({"id":"fixture:instant","name":"Regression-only stationary lethal projectile","damage":10000,"speed":0,"cooldown":100,"target":"all","behavior":"straight"})).unwrap()); + pack.missions.push(serde_json::from_value(json!({"id":"fixture:boss","name":"Controlled carrier encounter","duration":4000,"auto_complete":false,"spawns":[{"tick":1,"enemy":format!("iron_coast_stage2_boss_{n}:unit"),"x":88,"y":if n==7{-88}else{-112}}]})).unwrap()); + } + base.apply(pack, "fixture").unwrap(); + let discovery = modding::discover(&root().join("mods")); + let enabled = if boss_only { + vec![format!("iron_coast_stage2_boss_{n}")] + } else { + vec![ + format!("iron_coast_stage2_mission_{n}"), + format!("iron_coast_stage2_boss_{n}"), + "iron_coast_stage2_interceptor".into(), + "iron_coast_stage2_siege".into(), + "iron_coast_stage2_skimmer".into(), + "iron_coast_stage2_music".into(), + ] + }; + ActiveMods::build(&base, &discovery, &enabled, Some(&catalog)).unwrap() +} +fn pilot(shield: u32, credits: u32, difficulty: u32, full: bool) -> Pilot { + let mut p = Pilot { + credits, + difficulty, + ..Pilot::default() + }; + p.inventory.insert("base:energy".into(), shield); + if full { + for i in 0..20 { + if p.inventory_slots() >= 20 { + break; + } + p.inventory + .insert(format!("fixture:filler_{i}").as_str().into(), 1); + } + } + p +} +fn input(w: &World) -> Input { + let desired = w + .enemies + .iter() + .filter(|e| e.health > 0 && e.y >= 0) + .max_by_key(|e| e.y) + .map(|e| e.x + e.width / 2 - 16) + .unwrap_or(128); + let center = w.player.x + 16; + let threat = w + .projectiles + .iter() + .filter(|p| p.hostile && p.y >= 136 && p.y <= 188 && (p.x + 4 - center).abs() < 24) + .max_by_key(|p| p.y); + let aim = if let Some(p) = threat { + if p.x + 4 < center { + w.player.x + 36 + } else { + w.player.x - 36 + } + } else { + desired + }; + Input { + fire: true, + absolute: Some([ + (w.player.x + (aim - w.player.x).clamp(-4, 4)).clamp(0, 256), + 160, + ]), + ..Input::default() + } +} + +fn run(a: &mut ActiveMods, n: u32, p: &Pilot, boss_only: bool) -> Value { + a.scripts.restore(Default::default()); + let id = if boss_only { + "fixture:boss".into() + } else { + format!("iron_coast_stage2_mission_{n}:mission_0{n}") + }; + let mut w = World::new(&id.as_str().into(), p, &a.registry).unwrap(); + let mut peak = 0; + let mut frames = BTreeSet::new(); + let mut classics = BTreeSet::new(); + let mut positions = BTreeMap::new(); + let mut moving = BTreeSet::new(); + let boss = format!("iron_coast_stage2_boss_{n}:unit"); + let death = format!("iron_coast_stage2_boss_{n}:defeated"); + let mut sounds = BTreeSet::new(); + for _ in 0..5200 { + w.step(input(&w), &a.registry, &mut a.scripts).unwrap(); + peak = peak.max(w.enemies.len()); + for e in &w.enemies { + if e.definition.0 == boss { + frames.insert(e.art_frame); + assert!(e.pinned_art_frame.is_some()); + } + if e.definition.0.starts_with("base:enemy_") { + assert!(a.registry.enemies[&e.definition].legacy.is_some()); + classics.insert(e.definition.0.clone()); + let k = (e.definition.0.clone(), e.entity); + if let Some(old) = positions.insert(k, (e.x, e.y)) { + if old != (e.x, e.y) { + moving.insert(e.definition.0.clone()); + } + } + } + } + for id in &w.mod_sounds { + sounds.insert(id.0.clone()); + } + if boss_only && w.objectives.get(&death).copied() == Some(1) { + break; + } + if w.outcome != Outcome::Playing { + break; + } + } + if boss_only { + assert_eq!( + w.objectives.get(&death).copied(), + Some(1), + "boss{n} failed: tick{} shield{} {:?}", + w.tick, + w.player.shield, + w.outcome + ); + assert_eq!(w.outcome, Outcome::Playing); + } else { + assert_eq!( + w.outcome, + Outcome::Complete, + "mission{n} failed: tick{} shield{} {:?}", + w.tick, + w.player.shield, + w.objectives + ); + assert_eq!(w.objectives[&death], 1); + assert_eq!( + w.objectives[&format!("iron_coast_stage2_mission_{n}:complete")], + 1 + ); + assert_eq!( + w.objectives[&format!("iron_coast_stage2_mission_{n}:debrief")], + 1 + ); + assert_eq!( + w.objectives["iron_coast_stage2_siege:defeated"], + if n == 7 { 4 } else { 5 } + ); + assert_eq!( + w.objectives["iron_coast_stage2_skimmer:defeated"], + if n == 7 { 3 } else { 4 } + ); + assert!(classics.len() >= 4 && moving.len() >= 4); + } + assert_eq!( + frames.len(), + if n == 7 { 2 } else { 3 }, + "all carrier phases must appear: {frames:?}" + ); + // Gameplay shield charge may change; equipment identities/counts stay intact. + for (id, count) in &p.inventory { + if id.0 != "base:energy" { + assert_eq!(w.player.inventory.get(id), Some(count)); + } + } + assert_eq!(w.player.inventory.len(), p.inventory.len()); + assert_eq!(w.player.super_shield_reserves, p.super_shield_reserves); + let credits = w.player.credits; + for _ in 0..4 { + w.step(Input::default(), &a.registry, &mut a.scripts) + .unwrap(); + } + assert_eq!(w.player.credits, credits); + assert_eq!(w.objectives[&death], 1); + json!({"mission":n,"boss_only":boss_only,"difficulty":p.difficulty,"initial_shield":p.inventory[&"base:energy".into()],"initial_credits":p.credits,"inventory_slots":p.inventory_slots(),"tick":w.tick-4,"outcome":format!("{:?}",w.outcome),"shield":w.player.shield,"credits":credits,"maximum_live_enemies":peak,"phase_frames":frames,"classic_ids":classics,"native_movement_ids":moving,"objectives":w.objectives,"sound_ids":sounds,"digest":w.digest(),"inventory_preserved":true,"rewards_once":true}) +} +fn reachable(a: &mut ActiveMods, n: u32) { + a.scripts.restore(Default::default()); + let mut p = pilot(100, 0, 0, false); + p.inventory.insert("base:super_shield".into(), 100); + p.super_shield_reserves = vec![100; 17]; + let mut w = World::new( + &format!("iron_coast_stage2_mission_{n}:mission_0{n}") + .as_str() + .into(), + &p, + &a.registry, + ) + .unwrap(); + for _ in 0..4050 { + w.step( + Input { + absolute: Some([260, 160]), + ..Input::default() + }, + &a.registry, + &mut a.scripts, + ) + .unwrap(); + if w.outcome != Outcome::Playing { + break; + } + } + assert_eq!( + w.outcome, + Outcome::Playing, + "elapsed duration may not grant victory" + ); + assert_eq!( + w.enemies + .iter() + .filter(|e| e.definition.0 == "iron_coast_stage2_siege:unit") + .count(), + if n == 7 { 4 } else { 5 } + ); + assert_eq!( + w.enemies + .iter() + .filter(|e| e.definition.0 == "iron_coast_stage2_skimmer:unit") + .count(), + if n == 7 { 3 } else { 4 } + ); + assert_eq!( + w.enemies + .iter() + .filter(|e| e.definition.0 == format!("iron_coast_stage2_boss_{n}:unit")) + .count(), + 1 + ); + assert!( + w.enemies + .iter() + .filter(|e| !e.definition.0.starts_with("base:")) + .all(|e| e.y <= 80 && e.x >= 0 && e.x + e.width <= 288) + ); +} +fn replay(a: &mut ActiveMods, n: u32) { + let p = pilot(75, 10000, 2, true); + a.scripts.restore(Default::default()); + let mut w = World::new( + &format!("iron_coast_stage2_mission_{n}:mission_0{n}") + .as_str() + .into(), + &p, + &a.registry, + ) + .unwrap(); + let mut inputs = vec![]; + let mut digests = vec![]; + let mut continuation = vec![]; + let mut phases = BTreeSet::new(); + for i in 0..5200 { + let ctl = input(&w); + inputs.push(ctl); + w.step(ctl, &a.registry, &mut a.scripts).unwrap(); + digests.push(w.digest()); + if let Some(enemy) = w + .enemies + .iter() + .find(|e| e.definition.0 == format!("iron_coast_stage2_boss_{n}:unit")) + { + if phases.insert(enemy.art_frame) { + continuation.push(( + i, + w.clone(), + serde_json::to_vec(&a.scripts.checkpoints()).unwrap(), + )); + } + } + if w.outcome != Outcome::Playing { + break; + } + } + assert_eq!(w.outcome, Outcome::Complete); + let expected = w.digest(); + a.scripts.restore(Default::default()); + let mut second = World::new(&w.mission, &p, &a.registry).unwrap(); + for (i, ctl) in inputs.iter().enumerate() { + second.step(*ctl, &a.registry, &mut a.scripts).unwrap(); + assert_eq!(second.digest(), digests[i]); + } + assert_eq!(second.digest(), expected); + assert_eq!(continuation.len(), if n == 7 { 2 } else { 3 }); + for (index, mut resumed, state) in continuation { + a.scripts.restore(serde_json::from_slice(&state).unwrap()); + for ctl in &inputs[index + 1..] { + resumed.step(*ctl, &a.registry, &mut a.scripts).unwrap(); + } + assert_eq!(resumed.digest(), expected); + } + // Keep the previous script state deliberately: spawn/start callbacks reset it. + let mut restarted = World::new(&w.mission, &p, &a.registry).unwrap(); + restarted + .step(Input::default(), &a.registry, &mut a.scripts) + .unwrap(); + assert_eq!( + restarted.objectives[&format!("iron_coast_stage2_boss_{n}:defeated")], + 0 + ); + assert_eq!(restarted.objectives["iron_coast_stage2_siege:defeated"], 0); + assert_eq!( + restarted.objectives[&format!("iron_coast_stage2_mission_{n}:debrief")], + 0 + ); + restarted + .apply_commands( + &[Command::Damage { + entity: 0, + amount: 100000, + }], + &a.registry, + ) + .unwrap(); + restarted + .step(Input::default(), &a.registry, &mut a.scripts) + .unwrap(); + assert_eq!(restarted.outcome, Outcome::Failed); + assert_eq!( + restarted.objectives[&format!("iron_coast_stage2_mission_{n}:complete")], + 0 + ); + for (id, count) in &p.inventory { + if id.0 != "base:energy" { + assert_eq!(restarted.player.inventory.get(id), Some(count)); + } + } +} +fn carrier_callbacks(a: &mut ActiveMods, n: u32) { + a.scripts.restore(Default::default()); + let owner = format!("iron_coast_stage2_boss_{n}"); + let script = "scripts/ai.rhai"; + let statekey = format!("{owner}/{script}"); + let id = format!("{owner}:unit"); + let hp = if n == 7 { 280 } else { 360 }; + let y = if n == 7 { 16 } else { 4 }; + let ev = |entity: u64, health: i32, count: i32| json!({"entity":entity,"tick":3000,"x":88,"y":y,"health":health,"entities":[{"entity":1,"health":hp,"definition":id},{"entity":2,"health":hp,"definition":id}],"objectives":{format!("{owner}:defeated"):count}}); + a.scripts.begin_tick(); + a.scripts + .invoke(&owner, script, "on_spawn", &ev(1, hp, 0), 3) + .unwrap(); + a.scripts + .invoke(&owner, script, "on_spawn", &ev(2, hp, 0), 3) + .unwrap(); + for age in 1..=if n == 7 { 84 } else { 96 } { + a.scripts.begin_tick(); + let cmds = a + .scripts + .invoke(&owner, script, "on_tick", &ev(1, hp, 0), 3) + .unwrap(); + let fire = cmds + .iter() + .filter(|c| matches!(c, Command::Projectile { .. })) + .count(); + assert_eq!( + fire, + if age == if n == 7 { 84 } else { 96 } { + if n == 7 { 3 } else { 4 } + } else { + 0 + } + ); + assert!(cmds.iter().all(|c| !matches!( + c, + Command::Effect { .. } | Command::Damage { .. } | Command::Complete + ))); + } + assert_eq!(a.scripts.states[&statekey]["units"]["1"]["volley"], 1); + assert_eq!(a.scripts.states[&statekey]["units"]["2"]["volley"], 0); + a.scripts.begin_tick(); + let cmds = a + .scripts + .invoke(&owner, script, "on_tick", &ev(1, hp / 3, 0), 3) + .unwrap(); + let phase = if n == 7 { 1 } else { 2 }; + assert!( + cmds.iter() + .any(|c| matches!(c,Command::Animation{entity:1,frame:Some(f)} if *f==phase)) + ); + let checkpoint = a.scripts.checkpoints(); + let bytes = serde_json::to_vec(&checkpoint).unwrap(); + a.scripts.restore(serde_json::from_slice(&bytes).unwrap()); + assert_eq!(a.scripts.states[&statekey]["units"]["1"]["phase"], phase); + a.scripts.begin_tick(); + let cmds = a + .scripts + .invoke(&owner, script, "on_death", &ev(1, 0, 0), 3) + .unwrap(); + assert!( + cmds.iter().any( + |c| matches!(c,Command::Objective{key,value:1} if key==&format!("{owner}:defeated")) + ) + ); + assert!(a.scripts.states[&statekey]["units"].get("1").is_none()); + assert!(a.scripts.states[&statekey]["units"].get("2").is_some()); + a.scripts.begin_tick(); + assert!( + a.scripts + .invoke(&owner, script, "on_death", &ev(1, 0, 1), 3) + .unwrap() + .is_empty() + ); + // A killed-before-spawn entity still counts a real death and never fires. + a.scripts.begin_tick(); + let mut immediate = ev(3, 0, 1); + immediate["entities"] = json!([]); + let cmds = a + .scripts + .invoke(&owner, script, "on_death", &immediate, 3) + .unwrap(); + assert!( + cmds.iter() + .any(|c| matches!(c, Command::Objective { value: 2, .. })) + ); + assert!( + a.scripts + .invoke(&owner, script, "on_spawn", &immediate, 3) + .unwrap() + .is_empty() + ); + // Spawn prunes abandoned prior-world cursors while retaining current peers. + a.scripts.begin_tick(); + let mut newworld = ev(4, hp, 0); + newworld["entities"] = json!([{"entity":4,"health":hp,"definition":id}]); + a.scripts + .invoke(&owner, script, "on_spawn", &newworld, 3) + .unwrap(); + assert_eq!( + a.scripts.states[&statekey]["units"] + .as_object() + .unwrap() + .len(), + 1 + ); +} +fn repeated_early_kill(n: u32) { + let mut a = active(n, true); + for _ in 0..2 { + let p = pilot(75, 10000, 2, false); + let mut w = World::new(&"fixture:boss".into(), &p, &a.registry).unwrap(); + w.apply_commands( + &[Command::Projectile { + weapon: "fixture:instant".into(), + x: 144, + y: -20, + vx: 0, + vy: 0, + hostile: false, + }], + &a.registry, + ) + .unwrap(); + for _ in 0..3 { + w.step(Input::default(), &a.registry, &mut a.scripts) + .unwrap(); + } + assert_eq!( + w.objectives[&format!("iron_coast_stage2_boss_{n}:defeated")], + 1 + ); + assert_eq!( + w.player.credits, + p.credits + if n == 7 { 5000 } else { 9000 } + ); + assert!(w.enemies.is_empty()); + w.step(Input::default(), &a.registry, &mut a.scripts) + .unwrap(); + assert_eq!( + w.objectives[&format!("iron_coast_stage2_boss_{n}:defeated")], + 1 + ); + } +} +fn audio_proof() { + use raptor_replica::{ + audio::Mixer, + sound::{SoundBank, encode_capture}, + }; + let catalog = Catalog::open(root().join("data")).unwrap(); + let genmidi = catalog.named("GENMIDI_OP2").unwrap(); + let rate = 32000; + let mut all = vec![]; + let mut rows = vec![]; + let mut composite_capture = None; + for n in [7, 8] { + let mut registry = Registry::default(); + for kind in ["boss", "mission"] { + let owner = format!("iron_coast_stage2_{kind}_{n}"); + let package = root().join("mods").join(&owner); + let pack: ContentPack = + serde_json::from_slice(&fs::read(package.join("content.json")).unwrap()).unwrap(); + registry + .apply( + ContentPack { + sounds: pack.sounds, + ..ContentPack::default() + }, + &owner, + ) + .unwrap(); + registry.asset_roots.insert(owner, package); + } + registry.validate().unwrap(); + for (id, _) in registry.sounds.iter().filter(|(id, _)| { + id.0.starts_with(&format!("iron_coast_stage2_boss_{n}:")) + || id.0.starts_with(&format!("iron_coast_stage2_mission_{n}:")) + }) { + let mut bank = SoundBank::default(); + let mut mixer = Mixer::new(rate, &genmidi).unwrap(); + mixer.music_volume = 0; + mixer.start_capture(2).unwrap(); + bank.queue_mod(®istry, &mut mixer, id).unwrap(); + let mut pcm = vec![0; rate as usize * 2 * 2]; + mixer.mix(&mut pcm); + let capture = mixer.take_capture().unwrap(); + assert_eq!(capture.samples, pcm); + if composite_capture.is_none() { + composite_capture = Some(capture); + } + let peak = pcm.iter().map(|s| i32::from(*s).abs()).max().unwrap(); + let rms = + (pcm.iter().map(|s| f64::from(*s).powi(2)).sum::() / pcm.len() as f64).sqrt(); + assert!(peak > 100 && peak < 32767 && rms > 20.0); + let mut mute = Mixer::new(rate, &genmidi).unwrap(); + mute.fx_volume = 0; + mute.music_volume = 0; + bank.queue_mod(®istry, &mut mute, id).unwrap(); + let mut silent = vec![1; rate as usize * 2]; + mute.mix(&mut silent); + assert!(silent.iter().all(|s| *s == 0)); + rows.push(json!({"sound":id.0,"actual_mixer_peak":peak,"actual_mixer_rms":rms,"muted_exact_zero":true})); + all.extend(pcm); + } + } + let dir = root() + .parent() + .unwrap() + .join(".reference/iron-coast-stage2-finale"); + fs::write(dir.join("actual-mixer-all-cues.wav"), { + let mut c = composite_capture.unwrap(); + c.samples = all; + encode_capture(&c).unwrap() + }) + .unwrap(); + fs::write(dir.join("actual-audio-proof.json"),serde_json::to_string_pretty(&json!({"sound_count":rows.len(),"mixer":"Production SoundBank::queue_mod + original digital Mixer, genuineGENMIDI table,32kHzstereo PCM","rows":rows,"live_sdl_claim":false})).unwrap()+"\n").unwrap(); + println!("Actual production mixer accepted all16 non-silent cues and exact FX mute"); +} +fn main() { + if std::env::args().any(|a| a == "--audio-only") { + audio_proof(); + return; + } + if std::env::args().any(|a| a == "--list-classics") { + let a = active(7, true); + for n in [23, 24, 73, 74, 95, 96] { + let id = format!("base:enemy_0_{n}"); + println!( + "{}", + serde_json::to_string_pretty(&a.registry.enemies[&id.as_str().into()]).unwrap() + ); + } + return; + } + let boss_only = std::env::args().any(|x| x == "--boss-only"); + let mut rows = vec![]; + for n in [7, 8] { + repeated_early_kill(n); + let mut a = active(n, boss_only); + carrier_callbacks(&mut a, n); + for d in 0..=3 { + let p = pilot(75, 10000, d, false); + rows.push(run(&mut a, n, &p, boss_only)); + } + if !boss_only { + rows.push(run(&mut a, n, &pilot(100, 0, 2, false), false)); + rows.push(run(&mut a, n, &pilot(75, 10000, 2, true), false)); + reachable(&mut a, n); + replay(&mut a, n); + } + } + let v = json!({"proof":"Actual original Catalog/native enemies, production World/Rhai, shipped PNG/WAV/MUS content; ordinary mouse movement capped 4px per tick, near-shot sidesteps at y136..188 and starter guns only","boss_only":boss_only,"runs":rows,"full_inventory":!boss_only,"mandatory_reachable_after4050_ticks":!boss_only,"auto_complete_disabled":!boss_only,"deterministic_every_step_replay":!boss_only,"boss_script_state_continuation":!boss_only,"restart_resets":!boss_only,"failure_preserves_equipment":!boss_only}); + let path = std::env::var_os("FINALE_REPORT") + .map(PathBuf::from) + .unwrap_or_else(|| { + root() + .parent() + .unwrap() + .join(".reference/iron-coast-stage2-finale/validation-results.json") + }); + fs::write(path, serde_json::to_string_pretty(&v).unwrap() + "\n").unwrap(); + println!("{}", serde_json::to_string_pretty(&v).unwrap()); +} diff --git a/mods/iron_coast_stage2_music/README.md b/mods/iron_coast_stage2_music/README.md new file mode 100644 index 00000000..466f3e93 --- /dev/null +++ b/mods/iron_coast_stage2_music/README.md @@ -0,0 +1,62 @@ +# Iron Coast II: Black Tide — Original Soundtrack + +Three original FM action themes for Iron Coast II, played by RustRaptor's +checked MUS decoder and classic GENMIDI/OPL3 music bus. This independent API 1 +package has no dependencies and does not override original music. Missions +that require it select the appropriate stable ID through `music_track`. + +| Track ID | Theme | Tempo | Score length | +| --- | --- | --- | --- | +| `iron_coast_stage2_music:assault` | **Rivetline Assault**: syncopated harbor machinery, distorted power chords and a driving D-minor guitar lead | 144 BPM | 56 bars / 93.329 s | +| `iron_coast_stage2_music:pursuit` | **Undertow Pursuit**: fast F-sharp-minor chase, angular square-wave calls, muted guitar and a quieter FM-bell fog passage | 168 BPM | 64 bars / 91.429 s | +| `iron_coast_stage2_music:finale` | **Black Tide Rising**: C-minor brass beacon motif, chromatic danger variation, open-water bridge and intensified final assault | 126 BPM | 56 bars / 106.671 s | + +Each has its own motifs, harmony, instruments, percussion and six-section +arrangement. Closing four-bar phrases return from the dominant to the opening +tonic. Explicit note releases and a final all-notes-off prevent carried notes. +The native 70 Hz service clock starts the first downbeat one quantum after +playback begins; following loop periods use the score's clock length. +Oscillator phases and release envelopes remain native. These are musical +loops, not sample-identical PCM splices. See [provenance](provenance.json) for +bar boundaries, channels, instrument declarations and exact score hashes. + +Enable the package in **Mods**, or let an Iron Coast II mission enable its +dependency automatically. It adds no shop item, consumable, control or artwork. +The game's **Music** setting controls these tracks; **Effects** retains its +separate bus. Original menus and cinematics continue to select their own music. +The full local preview WAVs are QA outputs outside the package; they are not +registered digital effects and therefore do not use the 30-second WAV-effect +limit. + +## Reproduction and verification + +All note sequences and arrangements were authored for this project by Codex. +No proprietary melody, source-game score, MIDI or recording was copied. The +Stage 1 composer was consulted for the existing MUS serialization convention. +FM playback uses the game's separately installed original instrument bank. +No external audio model, SoundFont or sample recording is needed. + +From `RustRaptor/`: + +```sh +python3 mods/iron_coast_stage2_music/build_music.py +python3 mods/iron_coast_stage2_music/validate_music.py +cargo run --locked --release --no-default-features -- \ + --mods mods --validate-mods iron_coast_stage2_music +cargo test --locked --no-default-features --test music +``` + +The standard-library-only Python composer regenerates all three MUS files and +provenance byte for byte. The native Rust QA helper validates independent +activation, exact header ranges, actual event counts and percussion preloads, +unmatched notes, original-bank dual-voice requirements, end markers, loop +continuation, Music mute, one-play tail decay, every rendered second and +clipping at both default and maximum Music volume. It creates full previews, +eight-second loop-boundary previews and an exact library/instrument/source +hash report in `../.reference/iron-coast-stage2-music/`. Use `--data PATH` or +`--output PATH` for another local catalog/output folder. It does not write +pilot files, settings or selected mods. + +Validation is objective inspection of the native PCM output, not a claim of +human listening or subjective playtest approval. Package verification results +and reproduction hashes are recorded in [validation.json](validation.json). diff --git a/mods/iron_coast_stage2_music/build_music.py b/mods/iron_coast_stage2_music/build_music.py new file mode 100644 index 00000000..47a7e292 --- /dev/null +++ b/mods/iron_coast_stage2_music/build_music.py @@ -0,0 +1,323 @@ +#!/usr/bin/env python3 +"""Compose three original Iron Coast II scores directly into checked MUS. + +All motifs and arrangements below are authored for this package. No original +game score, MIDI file, audio recording, external library or randomness is read. +The native Rust MUS service clock is 70 Hz; exact rational timing keeps rounded +boundaries consistent across long phrases. Run with Python 3 from any folder. +""" + +from collections import defaultdict +from fractions import Fraction +import hashlib +import json +from pathlib import Path +import struct + + +ROOT = Path(__file__).resolve().parent +CLOCK = 70 + + +class Score: + def __init__(self, key, title, bpm, bars, programs, tonality, sections): + self.key, self.title, self.bpm, self.bars = key, title, bpm, bars + self.programs, self.tonality, self.sections = programs, tonality, sections + self.events = defaultdict(list) + self.end = self.tick(Fraction(bars * 4)) + self.drums = set() + self.note_count = 0 + # Rhythm/bass have space for the melodic line; all five FM roles are + # original-bank programs, not an external SoundFont or recorded sample. + self.volumes = {0: 84, 1: 68, 2: 83, 3: 54, 4: 40, 15: 83} + # The original OPL driver uses three pan positions; values >=96 are + # the opposite side from <=48. Keep melodic counterlines apart from + # the rhythm guitar, with bass/lead/pads/drums centered. + self.pans = {0: 64, 1: 38, 2: 64, 3: 102, 4: 64, 15: 64} + for channel, program in programs.items(): + self.emit(0, 0, 0x40 | channel, [0, program]) + for channel, volume in self.volumes.items(): + self.emit(0, 0, 0x40 | channel, [3, volume]) + self.emit(0, 0, 0x40 | channel, [4, self.pans[channel]]) + + def tick(self, beat): + value = Fraction(beat) * CLOCK * 60 / self.bpm + return (2 * value.numerator + value.denominator) // (2 * value.denominator) + + def emit(self, tick, priority, descriptor, payload): + assert 0 <= tick <= self.end + self.events[tick].append((priority, bytes([descriptor]) + bytes(payload))) + + def note(self, channel, pitch, bar, step, length, velocity): + if pitch is None: + return + assert 0 <= pitch <= 127 and 0 < velocity <= 127 and length > 0 + beat = Fraction(bar * 4) + Fraction(step) / 4 + start = self.tick(beat) + stop = min(self.tick(beat + Fraction(length) / 4), self.end - 2) + assert stop > start + self.emit(start, 2, 0x10 | channel, [pitch | 0x80, velocity]) + self.emit(stop, 1, channel, [pitch]) + self.note_count += 1 + if channel == 15: + self.drums.add(pitch) + + def phrase(self, channel, notes, bar, velocity=91): + for slot, pitch in enumerate(notes): + if pitch is not None: + length = Fraction(3, 2) if slot < 7 and notes[slot + 1] is not None else 3 + self.note(channel, pitch, bar, slot * 2, min(length, 15 - slot * 2), + velocity if slot in [0, 4] else velocity - 11) + + def power(self, root, bar, slots, length=1, velocity=80): + for step in slots: + self.note(1, root + 12, bar, step, length, velocity) + self.note(1, root + 19, bar, step, length, velocity - 13) + + def pad(self, root, bar, length=15, velocity=48): + self.note(4, root + 24, bar, 0, length, velocity) + self.note(4, root + 31, bar, 0, length, velocity - 10) + + def kit(self, bar, style, crash=False, fill=False): + hat_steps = range(0, 16, 2) if style == "open" else range(16) + for step in hat_steps: + key = 46 if style == "ride" and step == 14 else 42 + self.note(15, key, bar, step, Fraction(2, 3), + 58 if step % 4 == 0 else 37 if step % 2 else 47) + kicks = [0, 8] if style == "open" else [0, 3, 8, 11] if style == "chase" else [0, 6, 8, 14] + for step in kicks: + self.note(15, 36, bar, step, 1, 108 if step in [0, 8] else 84) + for step in [4, 12]: + self.note(15, 38, bar, step, 1, 101 if style != "open" else 87) + if crash: + self.note(15, 49, bar, 0, 3, 84) + if fill: + for step, pitch in [(12, 47), (13, 45), (14, 43), (15, 41)]: + self.note(15, pitch, bar, step, Fraction(3, 4), 76 + (step % 2) * 7) + + @staticmethod + def delay(value): + chunks = [value & 127] + value >>= 7 + while value: + chunks.append(value & 127) + value >>= 7 + return bytes(piece | (128 if i < len(chunks) - 1 else 0) + for i, piece in enumerate(reversed(chunks))) + + def write(self): + # Every scored voice is released before the next downbeat. The cadence + # resolves to the starting tonic; this is a musical loop, not a pasted + # PCM splice. The game's FM release envelopes remain in the native bus. + for channel in self.volumes: + self.emit(self.end - 1, 3, 0x30 | channel, [11]) + self.emit(self.end, 4, 0x60, []) + times = sorted(self.events) + stream = bytearray() + pressed = set() + maximum = 0 + for index, tick in enumerate(times): + group = sorted(self.events[tick], key=lambda item: item[0]) + for position, (_, raw) in enumerate(group): + kind, channel = raw[0] >> 4, raw[0] & 15 + if kind == 1: + voice = (channel, raw[1] & 127) + assert voice not in pressed, f"Overlapping same pitch: {voice}, tick {tick}" + pressed.add(voice) + elif kind == 0: + pressed.remove((channel, raw[1])) + maximum = max(maximum, len(pressed)) + descriptor = raw[0] | (128 if position == len(group) - 1 and tick < self.end else 0) + stream.extend(bytes([descriptor]) + raw[1:]) + if tick < self.end: + stream.extend(self.delay(times[index + 1] - tick)) + assert not pressed + # MUS instrument declarations use 100 + GM percussion key. The Rust + # synthesizer's internal GENMIDI percussion index is a separate value. + instruments = sorted(set(self.programs.values()) | {100 + key for key in self.drums}) + start = 16 + 2 * len(instruments) + assert len(stream) <= 65535 + score = b"MUS\x1a" + struct.pack("<6H", len(stream), start, len(self.programs), 0, + len(instruments), 0) + score += struct.pack("<" + "H" * len(instruments), *instruments) + stream + path = ROOT / "music" / f"{self.key}.mus" + path.parent.mkdir(exist_ok=True) + path.write_bytes(score) + return { + "id": f"iron_coast_stage2_music:{self.key}", "title": self.title, + "file": f"music/{self.key}.mus", "tempo_bpm": self.bpm, "meter": "4/4", + "bars": self.bars, "duration_ticks": self.end, + "duration_seconds": self.end / CLOCK, "tonality": self.tonality, + "sections": self.sections, "programs": self.programs, + "percussion_keys": sorted(self.drums), "instrument_preload_table": instruments, + "events": sum(len(group) for group in self.events.values()), + "notes": self.note_count, "max_events_per_tick": max(map(len, self.events.values())), + "max_simultaneous_notes": maximum, "bytes": len(score), + "sha256": hashlib.sha256(score).hexdigest(), "dangling_notes": 0, + } + + +def section(name, first, bars): + return {"name": name, "first_bar": first, "bars": bars} + + +def assault(): + s = Score("assault", "Rivetline Assault", 144, 56, + {0: 34, 1: 30, 2: 29, 3: 81, 4: 48}, + "D minor, B-flat/F contrast, A-major dominant and D tonic return", + [section("Ignition", 0, 4), section("Rivetline", 4, 16), + section("Container crosswind", 20, 12), section("Drydock bridge", 32, 8), + section("Harbor assault", 40, 12), section("Home bearing", 52, 4)]) + a = [[74, None, 79, 77, 74, 81, 77, 72], + [74, 77, None, 81, 84, 81, 79, 77], + [72, None, 75, 77, 79, None, 77, 75], + [73, 76, 81, 79, 76, None, 73, None]] + b = [[77, 81, 84, 81, 79, 77, None, 74], + [79, None, 84, 86, 84, 81, 79, 77], + [76, 79, 84, None, 82, 79, 76, None], + [73, 76, 79, 81, 79, 76, 73, None]] + closing = [[79, 82, 81, 79, 77, None, 74, 77], + [76, 79, 84, 82, 79, 76, 74, None], + [73, 76, 81, 79, 76, 73, None, None], + [74, None, 77, 74, None, None, 74, None]] + for bar in range(s.bars): + intro, bridge, ending = bar < 4, 32 <= bar < 40, bar >= 52 + root = ([43, 36, 33, 38][bar - 52] if ending else + [43, 34, 36, 33][bar % 4] if bridge else + [34, 41, 36, 33][bar % 4] if 20 <= bar < 32 else [38, 38, 34, 33][bar % 4]) + for step, interval in [(0, 0), (2, 0), (5, 7), (8, 0), (10, 12), (13, 7)]: + if not bridge or step in [0, 8]: + s.note(0, root + interval, bar, step, 2 if bridge else Fraction(3, 2), + 100 if step in [0, 8] else 83) + s.power(root, bar, [0, 8] if intro or bridge else [0, 3, 4, 6, 8, 11, 12, 14], + 3 if bridge else 1, 80 if not intro else 69) + if bridge or bar % 4 == 0: + s.pad(root, bar, velocity=60 if bridge else 44) + if ending: + s.phrase(2, closing[bar - 52], bar, 94) + elif not intro and not bridge: + s.phrase(2, b[bar % 4] if 20 <= bar < 32 else a[bar % 4], bar, 95) + if bridge: + for step, interval in [(0, 24), (4, 31), (8, 36), (12, 31)]: + s.note(3, root + interval, bar, step, 3, 75) + elif 40 <= bar < 52 and bar % 4 == 3: + for step, pitch in [(10, 81), (12, 79), (14, 77)]: + s.note(3, pitch, bar, step, 1, 66) + s.kit(bar, "open" if intro or bridge else "drive", + crash=bar in [4, 20, 32, 40, 52], fill=bar % 8 == 7) + return s + + +def pursuit(): + s = Score("pursuit", "Undertow Pursuit", 168, 64, + {0: 33, 1: 28, 2: 80, 3: 10, 4: 50}, + "F-sharp minor, D/E rising chase and C-sharp-major return", + [section("Wake signal", 0, 4), section("Undertow", 4, 16), + section("Crosscurrent", 20, 16), section("Fog channel", 36, 8), + section("Raider wake", 44, 16), section("Bearing reset", 60, 4)]) + a = [[78, 85, 81, 83, 80, 78, 76, 81], + [83, None, 85, 88, 86, 85, 81, 80], + [81, 86, 85, 81, 80, 83, None, 80], + [77, 80, 85, None, 83, 80, 77, None]] + b = [[81, 85, 88, 86, 85, None, 81, 78], + [80, 83, 88, 90, 88, 83, 80, None], + [78, 81, 85, 88, 86, 85, 83, 81], + [77, None, 80, 85, 83, 80, 77, None]] + closing = [[81, 85, 86, 85, 81, 78, 76, None], + [80, 83, 88, 86, 83, 80, 78, None], + [77, 80, 85, 83, 80, 77, None, None], + [78, None, 85, 81, 78, None, 78, None]] + for bar in range(s.bars): + intro, fog, ending = bar < 4, 36 <= bar < 44, bar >= 60 + root = ([38, 40, 37, 42][bar - 60] if ending else + [42, 42, 38, 37][bar % 4] if fog else + [38, 40, 42, 37][bar % 4] if 20 <= bar < 36 else [42, 38, 40, 37][bar % 4]) + for step, interval in [(0, 0), (3, 7), (4, 0), (6, 12), (8, 0), (11, 7), (12, 0), (14, 7)]: + if not fog or step in [0, 4, 8, 12]: + s.note(0, root + interval, bar, step, 1 if not fog else 2, 94 if step % 4 == 0 else 79) + s.power(root, bar, [0, 6, 8, 14] if not fog else [0, 8], 1, 71) + if bar % 4 == 0: + s.pad(root, bar, 11, 44) + if ending: + s.phrase(2, closing[bar - 60], bar, 88) + elif not intro and not fog: + s.phrase(2, b[bar % 4] if 20 <= bar < 36 else a[bar % 4], bar, 90) + if fog or bar % 4 == 2: + # A short FM bell calls across the muted chase rhythm. This part is + # pitched music, not a repeating digital nautical sound effect. + for step, interval in [(1, 24), (5, 31), (9, 36), (13, 31)]: + s.note(3, root + interval, bar, step, 2, 63 if fog else 49) + s.kit(bar, "open" if fog else "chase", crash=bar in [4, 20, 36, 44, 60], + fill=bar in [3, 19, 35, 43, 51, 59]) + return s + + +def finale(): + s = Score("finale", "Black Tide Rising", 126, 56, + {0: 38, 1: 30, 2: 61, 3: 81, 4: 48}, + "C minor heroic/danger motif, A-flat/E-flat contrast and G-major dominant", + [section("Black horizon", 0, 4), section("Beacon motif", 4, 12), + section("Danger current", 16, 12), section("Eye of the tide", 28, 8), + section("The last breakwater", 36, 16), section("Beacon return", 52, 4)]) + hero = [[72, None, 79, 75, 74, None, 77, 75], + [80, 79, None, 75, 77, 80, 79, None], + [75, 79, 82, 79, 77, 75, 74, None], + [71, 74, 79, 77, 74, 71, 72, None]] + danger = [[72, 75, 74, 71, 72, 79, 78, 77], + [77, 80, 79, 75, 74, None, 77, 75], + [74, 77, 80, 77, 75, 74, 71, None], + [71, 74, 79, 82, 80, 79, 74, None]] + closing = [[80, 79, 75, None, 77, 75, 72, None], + [75, 79, 82, 79, 77, 75, 74, None], + [71, 74, 79, 77, 74, 71, None, None], + [72, None, 79, 75, 72, None, 72, None]] + for bar in range(s.bars): + intro, eye, rise, ending = bar < 4, 28 <= bar < 36, 36 <= bar < 52, bar >= 52 + root = ([32, 39, 31, 36][bar - 52] if ending else + [36, 41, 38, 31][bar % 4] if eye or 16 <= bar < 28 else [36, 32, 39, 31][bar % 4]) + bass_slots = [0, 8] if intro or eye else [0, 4, 6, 8, 12, 14] + for step in bass_slots: + s.note(0, root + (7 if step in [6, 14] else 0), bar, step, + 5 if eye else 2, 104 if step in [0, 8] else 86) + s.power(root, bar, [0, 8] if intro or eye else [0, 2, 6, 8, 10, 14], + 5 if eye else 1, 81) + if intro or eye or bar % 4 == 0: + s.pad(root, bar, 15, 61 if eye else 51) + if ending: + s.phrase(2, closing[bar - 52], bar, 91) + elif intro: + for step, pitch in [(0, 60), (8, 67 if bar % 2 == 0 else 63)]: + s.note(2, pitch, bar, step, 6, 78) + elif not eye: + s.phrase(2, danger[bar % 4] if 16 <= bar < 28 else hero[bar % 4], bar, + 98 if rise else 87) + if eye: + for step, interval in [(0, 24), (4, 27), (8, 31), (12, 36)]: + s.note(3, root + interval, bar, step, 3, 71) + elif rise and bar % 4 == 3: + for step, pitch in [(8, 79), (10, 77), (12, 74), (14, 71)]: + s.note(3, pitch, bar, step, 1, 65) + s.kit(bar, "open" if intro or eye else "ride" if rise else "drive", + crash=bar in [0, 4, 16, 28, 36, 44, 52], fill=bar % 8 == 7) + return s + + +def main(): + tracks = [score.write() for score in [assault(), pursuit(), finale()]] + report = { + "title": "Iron Coast II: Black Tide — Original Soundtrack", + "authorship": "Original note sequences, harmony, arrangement and deterministic composer authored by Codex for this project.", + "service_clock_hz": CLOCK, "recipe": "build_music.py", + "recipe_sha256": hashlib.sha256(Path(__file__).read_bytes()).hexdigest(), + "percussion_preload_encoding": "100 + GM percussion key (MUS convention)", + "source_policy": "No proprietary/original-game melody, MIDI, recording or generated audio model is used. Stage1 recipe read only for MUS serialization contract.", + "rendering": "Native Rust MusScore decoder and Mixer, using separately installed original GENMIDI FM instruments.", + "loop_design": "Four-bar dominant-to-tonic returns, explicit per-note releases and all-notes-off at final service tick; next score downbeat starts on the same tonic. FM waveform phases are native, not a sample-exact PCM splice.", + "tracks": tracks, + } + (ROOT / "provenance.json").write_text(json.dumps(report, indent=2) + "\n") + print(json.dumps(report, indent=2)) + + +if __name__ == "__main__": + main() diff --git a/mods/iron_coast_stage2_music/content.json b/mods/iron_coast_stage2_music/content.json new file mode 100644 index 00000000..6061589f --- /dev/null +++ b/mods/iron_coast_stage2_music/content.json @@ -0,0 +1,7 @@ +{ + "music": [ + {"id":"iron_coast_stage2_music:assault","name":"Rivetline Assault","file":"music/assault.mus","looping":true}, + {"id":"iron_coast_stage2_music:pursuit","name":"Undertow Pursuit","file":"music/pursuit.mus","looping":true}, + {"id":"iron_coast_stage2_music:finale","name":"Black Tide Rising","file":"music/finale.mus","looping":true} + ] +} diff --git a/mods/iron_coast_stage2_music/mod.toml b/mods/iron_coast_stage2_music/mod.toml new file mode 100644 index 00000000..90cc9301 --- /dev/null +++ b/mods/iron_coast_stage2_music/mod.toml @@ -0,0 +1,6 @@ +id = "iron_coast_stage2_music" +name = "Iron Coast II: Black Tide — Original Soundtrack" +version = "1.0.0" +api_version = 1 +description = "Three original looping FM action themes: mechanical harbor assault, a tense nautical pursuit and a dramatic Black Tide finale. Plays through the classic Rust GENMIDI music bus." +content = "content.json" diff --git a/mods/iron_coast_stage2_music/music/assault.mus b/mods/iron_coast_stage2_music/music/assault.mus new file mode 100644 index 00000000..542fe0ce Binary files /dev/null and b/mods/iron_coast_stage2_music/music/assault.mus differ diff --git a/mods/iron_coast_stage2_music/music/finale.mus b/mods/iron_coast_stage2_music/music/finale.mus new file mode 100644 index 00000000..2c537473 Binary files /dev/null and b/mods/iron_coast_stage2_music/music/finale.mus differ diff --git a/mods/iron_coast_stage2_music/music/pursuit.mus b/mods/iron_coast_stage2_music/music/pursuit.mus new file mode 100644 index 00000000..732389b3 Binary files /dev/null and b/mods/iron_coast_stage2_music/music/pursuit.mus differ diff --git a/mods/iron_coast_stage2_music/provenance.json b/mods/iron_coast_stage2_music/provenance.json new file mode 100644 index 00000000..4b3469af --- /dev/null +++ b/mods/iron_coast_stage2_music/provenance.json @@ -0,0 +1,261 @@ +{ + "title": "Iron Coast II: Black Tide \u2014 Original Soundtrack", + "authorship": "Original note sequences, harmony, arrangement and deterministic composer authored by Codex for this project.", + "service_clock_hz": 70, + "recipe": "build_music.py", + "recipe_sha256": "7fc846417f7993b9236b06228bbeba78f6158905f548d0387b8f30c5b1166063", + "percussion_preload_encoding": "100 + GM percussion key (MUS convention)", + "source_policy": "No proprietary/original-game melody, MIDI, recording or generated audio model is used. Stage1 recipe read only for MUS serialization contract.", + "rendering": "Native Rust MusScore decoder and Mixer, using separately installed original GENMIDI FM instruments.", + "loop_design": "Four-bar dominant-to-tonic returns, explicit per-note releases and all-notes-off at final service tick; next score downbeat starts on the same tonic. FM waveform phases are native, not a sample-exact PCM splice.", + "tracks": [ + { + "id": "iron_coast_stage2_music:assault", + "title": "Rivetline Assault", + "file": "music/assault.mus", + "tempo_bpm": 144, + "meter": "4/4", + "bars": 56, + "duration_ticks": 6533, + "duration_seconds": 93.32857142857142, + "tonality": "D minor, B-flat/F contrast, A-major dominant and D tonic return", + "sections": [ + { + "name": "Ignition", + "first_bar": 0, + "bars": 4 + }, + { + "name": "Rivetline", + "first_bar": 4, + "bars": 16 + }, + { + "name": "Container crosswind", + "first_bar": 20, + "bars": 12 + }, + { + "name": "Drydock bridge", + "first_bar": 32, + "bars": 8 + }, + { + "name": "Harbor assault", + "first_bar": 40, + "bars": 12 + }, + { + "name": "Home bearing", + "first_bar": 52, + "bars": 4 + } + ], + "programs": { + "0": 34, + "1": 30, + "2": 29, + "3": 81, + "4": 48 + }, + "percussion_keys": [ + 36, + 38, + 41, + 42, + 43, + 45, + 47, + 49 + ], + "instrument_preload_table": [ + 29, + 30, + 34, + 48, + 81, + 136, + 138, + 141, + 142, + 143, + 145, + 147, + 149 + ], + "events": 5162, + "notes": 2569, + "max_events_per_tick": 24, + "max_simultaneous_notes": 9, + "bytes": 15039, + "sha256": "cff88d3276e90b957d6df92f636101cb148e56d6a9684ff8319d90f7421463b4", + "dangling_notes": 0 + }, + { + "id": "iron_coast_stage2_music:pursuit", + "title": "Undertow Pursuit", + "file": "music/pursuit.mus", + "tempo_bpm": 168, + "meter": "4/4", + "bars": 64, + "duration_ticks": 6400, + "duration_seconds": 91.42857142857143, + "tonality": "F-sharp minor, D/E rising chase and C-sharp-major return", + "sections": [ + { + "name": "Wake signal", + "first_bar": 0, + "bars": 4 + }, + { + "name": "Undertow", + "first_bar": 4, + "bars": 16 + }, + { + "name": "Crosscurrent", + "first_bar": 20, + "bars": 16 + }, + { + "name": "Fog channel", + "first_bar": 36, + "bars": 8 + }, + { + "name": "Raider wake", + "first_bar": 44, + "bars": 16 + }, + { + "name": "Bearing reset", + "first_bar": 60, + "bars": 4 + } + ], + "programs": { + "0": 33, + "1": 28, + "2": 80, + "3": 10, + "4": 50 + }, + "percussion_keys": [ + 36, + 38, + 41, + 42, + 43, + 45, + 47, + 49 + ], + "instrument_preload_table": [ + 10, + 28, + 33, + 50, + 80, + 136, + 138, + 141, + 142, + 143, + 145, + 147, + 149 + ], + "events": 5620, + "notes": 2798, + "max_events_per_tick": 24, + "max_simultaneous_notes": 9, + "bytes": 16369, + "sha256": "454f2f4478d67d17c669f7c79fae3106b0f1e1753855e81885befe9d046c064d", + "dangling_notes": 0 + }, + { + "id": "iron_coast_stage2_music:finale", + "title": "Black Tide Rising", + "file": "music/finale.mus", + "tempo_bpm": 126, + "meter": "4/4", + "bars": 56, + "duration_ticks": 7467, + "duration_seconds": 106.67142857142858, + "tonality": "C minor heroic/danger motif, A-flat/E-flat contrast and G-major dominant", + "sections": [ + { + "name": "Black horizon", + "first_bar": 0, + "bars": 4 + }, + { + "name": "Beacon motif", + "first_bar": 4, + "bars": 12 + }, + { + "name": "Danger current", + "first_bar": 16, + "bars": 12 + }, + { + "name": "Eye of the tide", + "first_bar": 28, + "bars": 8 + }, + { + "name": "The last breakwater", + "first_bar": 36, + "bars": 16 + }, + { + "name": "Beacon return", + "first_bar": 52, + "bars": 4 + } + ], + "programs": { + "0": 38, + "1": 30, + "2": 61, + "3": 81, + "4": 48 + }, + "percussion_keys": [ + 36, + 38, + 41, + 42, + 43, + 45, + 46, + 47, + 49 + ], + "instrument_preload_table": [ + 30, + 38, + 48, + 61, + 81, + 136, + 138, + 141, + 142, + 143, + 145, + 146, + 147, + 149 + ], + "events": 4836, + "notes": 2406, + "max_events_per_tick": 26, + "max_simultaneous_notes": 9, + "bytes": 14065, + "sha256": "75f7bb28e0fd3e3e1632b81651dde44a63e2220174576412923a4f67a8dc46d1", + "dangling_notes": 0 + } + ] +} diff --git a/mods/iron_coast_stage2_music/validate_music.py b/mods/iron_coast_stage2_music/validate_music.py new file mode 100644 index 00000000..8ba34a30 --- /dev/null +++ b/mods/iron_coast_stage2_music/validate_music.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python3 +"""Reproduce native FM QA/previews outside this mod without changing selected mods. + +Run `python3 mods/iron_coast_stage2_music/validate_music.py` from RustRaptor or +any directory. Requires the local Rust compiler and original GENMIDI catalog. +Only generated QA/binaries go to the chosen output directory (ignored default). +""" +import argparse +import hashlib +import json +from pathlib import Path +import subprocess + + +PACKAGE = Path(__file__).resolve().parent +REPO = PACKAGE.parents[1] + + +def digest(path): + return hashlib.sha256(path.read_bytes()).hexdigest() + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("--data", type=Path, default=REPO / "data") + parser.add_argument("--output", type=Path, default=REPO.parent / ".reference/iron-coast-stage2-music") + parser.add_argument("--skip-build", action="store_true", + help="Reuse a previously recorded Cargo artifact pair in --output; require unchanged bytes") + args = parser.parse_args() + data, output = args.data.resolve(), args.output.resolve() + if output == PACKAGE or PACKAGE in output.parents: + parser.error("WAV previews/QA must remain outside the hashed mod package") + output.mkdir(parents=True, exist_ok=True) + pair_file = output / "cargo-artifact-library-pair.json" + if not args.skip_build: + build = subprocess.run(["cargo", "build", "--locked", "--release", "--no-default-features", "--lib", + "--message-format=json", "--manifest-path", str(REPO / "Cargo.toml")], + check=True, text=True, stdout=subprocess.PIPE) + records = [json.loads(line) for line in build.stdout.splitlines() if line.strip()] + artifacts = {} + for name in ["raptor_replica", "serde_json"]: + matches = {Path(filename).resolve() + for record in records if record.get("reason") == "compiler-artifact" + and record.get("target", {}).get("name") == name + and "lib" in record.get("target", {}).get("kind", []) + for filename in record.get("filenames", []) if filename.endswith(".rlib")} + if len(matches) != 1: + parser.error(f"Cargo must report exactly one active {name} library; found {sorted(matches)}") + artifact = matches.pop() + artifacts[name] = {"path": str(artifact), "sha256": digest(artifact)} + pair = {"selection": "Exact active compiler-artifact filenames from Cargo JSON; no mtime inference", + "profile": "release", "features": "no-default-features", "artifacts": artifacts} + pair_file.write_text(json.dumps(pair, indent=2) + "\n") + else: + if not pair_file.is_file(): + parser.error("--skip-build requires a prior successful Cargo artifact pair in --output") + pair = json.loads(pair_file.read_text()) + for name, artifact in pair["artifacts"].items(): + if not Path(artifact["path"]).is_file() or digest(Path(artifact["path"])) != artifact["sha256"]: + parser.error(f"Recorded {name} artifact changed; rerun without --skip-build") + library = Path(pair["artifacts"]["raptor_replica"]["path"]) + dependencies = REPO / "target/release/deps" + serde = Path(pair["artifacts"]["serde_json"]["path"]) + # Copy exact library snapshots to the ignored QA folder before rustc so + # simultaneous engine builds cannot replace the direct --extern files. + stable_library, stable_serde = output / "libraptor_replica.rlib", output / "libserde_json.rlib" + stable_library.write_bytes(library.read_bytes()); stable_serde.write_bytes(serde.read_bytes()) + assert digest(stable_library) == pair["artifacts"]["raptor_replica"]["sha256"] + assert digest(stable_serde) == pair["artifacts"]["serde_json"]["sha256"] + binary = output / "validate-music" + subprocess.run(["rustc", "--edition=2024", "-O", str(PACKAGE / "validate_music.rs"), + "--extern", f"raptor_replica={stable_library}", "--extern", f"serde_json={stable_serde}", + "-L", f"dependency={dependencies}", "-o", str(binary)], check=True) + subprocess.run([str(binary), str(data), str(REPO / "mods"), str(output)], check=True) + provenance = json.loads((PACKAGE / "provenance.json").read_text()) + report = json.loads((output / "native-validation.json").read_text()) + for native, authored in zip(report["tracks"], provenance["tracks"]): + for name in ["duration_ticks", "notes", "events"]: + assert native[name] == authored[name], (native["track"], name) + native["score_sha256"] = digest(PACKAGE / authored["file"]) + assert native["score_sha256"] == authored["sha256"] + native["preview_sha256"] = digest(Path(native["preview"])) + native["loop_boundary_sha256"] = digest(Path(native["loop_boundary_preview"])) + native["sections"] = [{**section, + "start_seconds": section["first_bar"] * 240 / authored["tempo_bpm"], + "duration_seconds": section["bars"] * 240 / authored["tempo_bpm"]} + for section in authored["sections"]] + report["native_library_sha256"] = digest(stable_library) + report["cargo_artifact_library_pair"] = pair + report["native_sources"] = {str(path.relative_to(REPO)): digest(path) + for path in [REPO / "src/audio.rs", REPO / "src/audio/opl3.rs", REPO / "src/sound.rs"]} + report["validator_recipe_sha256"] = digest(PACKAGE / "validate_music.py") + report["validator_rust_sha256"] = digest(PACKAGE / "validate_music.rs") + report["genmidi_sha256"] = digest(data / "misc/GENMIDI_OP2") + (output / "native-validation.json").write_text(json.dumps(report, indent=2) + "\n") + print(f"Native QA and all six WAV previews: {output}") + + +if __name__ == "__main__": + main() diff --git a/mods/iron_coast_stage2_music/validate_music.rs b/mods/iron_coast_stage2_music/validate_music.rs new file mode 100644 index 00000000..b7b067a5 --- /dev/null +++ b/mods/iron_coast_stage2_music/validate_music.rs @@ -0,0 +1,278 @@ +//! Native score/audio QA; built by validate_music.py against this game's library. +use raptor_replica::{ + assets::Catalog, + audio::{Mixer, MusScore, MusicEvent}, + content::Registry, + modding::{self, ActiveMods}, + sound, +}; +use serde_json::{Value, json}; +use std::{ + collections::{BTreeMap, BTreeSet}, + fs, + path::Path, +}; + +const RATE: u32 = 22_050; + +fn rms(samples: &[i16]) -> f64 { + (samples.iter().map(|&v| (v as f64).powi(2)).sum::() / samples.len() as f64).sqrt() +} +fn render(bank: &[u8], score: &MusScore, frames: usize, looping: bool, volume: u8) -> Vec { + let mut mixer = Mixer::new(RATE, bank).expect("native FM bank"); + mixer.music_volume = volume; + mixer.play(score.clone(), looping); + let mut pcm = vec![0; frames * 2]; + mixer.mix(&mut pcm); + pcm +} +fn wav(path: &Path, pcm: &[i16]) { + let size = (pcm.len() * 2) as u32; + let mut data = Vec::with_capacity(44 + size as usize); + data.extend(b"RIFF"); + data.extend((36 + size).to_le_bytes()); + data.extend(b"WAVEfmt "); + data.extend(16u32.to_le_bytes()); + data.extend(1u16.to_le_bytes()); + data.extend(2u16.to_le_bytes()); + data.extend(RATE.to_le_bytes()); + data.extend((RATE * 4).to_le_bytes()); + data.extend(4u16.to_le_bytes()); + data.extend(16u16.to_le_bytes()); + data.extend(b"data"); + data.extend(size.to_le_bytes()); + for sample in pcm { + data.extend(sample.to_le_bytes()); + } + fs::write(path, data).expect("write WAV preview outside mod"); +} +fn metrics(pcm: &[i16]) -> Value { + json!({ + "rms": rms(pcm), + "peak": pcm.iter().map(|v| (*v as i32).abs()).max().unwrap(), + "clipped_samples": pcm.iter().filter(|&&v| v == i16::MIN || v == i16::MAX).count(), + "nonzero_samples": pcm.iter().filter(|&&v| v != 0).count(), + "dc_mean": pcm.iter().map(|&v| v as f64).sum::() / pcm.len() as f64, + }) +} +fn inspect(key: &str, package: &Path, output: &Path, bank: &[u8]) -> Value { + let bytes = fs::read(package.join(format!("music/{key}.mus"))).expect("score file"); + let u16_at = |i| u16::from_le_bytes([bytes[i], bytes[i + 1]]) as usize; + let (length, start, channels, secondary, count, reserved) = ( + u16_at(4), + u16_at(6), + u16_at(8), + u16_at(10), + u16_at(12), + u16_at(14), + ); + assert_eq!(&bytes[..4], b"MUS\x1a"); + assert_eq!(start, 16 + count * 2); + assert_eq!(start + length, bytes.len()); + assert_eq!(channels, 5); + assert_eq!(secondary, 0); + assert_eq!(reserved, 0); + let declared = (0..count) + .map(|i| u16_at(16 + i * 2)) + .collect::>(); + assert_eq!(declared.len(), count, "duplicate instrument preload"); + let score = sound::decode_music(&bytes).expect("checked mod MUS decoder"); + let ticks = score.groups.last().expect("groups").0; + assert!( + (5_600..=9_100).contains(&ticks), + "requested 80–130 sec duration" + ); + let mut program = [0usize; 16]; + let mut used = BTreeSet::new(); + let mut channels_used = BTreeSet::new(); + let mut percussion = BTreeSet::new(); + let mut pressed = BTreeMap::new(); + let mut max_notes = 0usize; + let mut max_opl_voices = 0usize; + let mut notes = 0usize; + let mut per_channel_notes = [0usize; 16]; + let mut end_events = 0usize; + let mut same_tick_events = BTreeMap::new(); + let mut events = 0usize; + let mut final_note_off = 0u32; + for (tick, group) in &score.groups { + *same_tick_events.entry(*tick).or_insert(0usize) += group.len(); + events += group.len(); + for event in group { + match *event { + MusicEvent::Control(c, 0, p) => { + assert!(c < 5); + program[c as usize] = p as usize; + used.insert(p as usize); + } + MusicEvent::On(c, key, velocity) => { + assert!(c < 5 || c == 15); + assert!(velocity > 0); + let instrument = if c == 15 { + assert!((35..=81).contains(&key)); + percussion.insert(key); + used.insert(100 + key as usize); + 128 + (key - 35) as usize + } else { + program[c as usize] + }; + let offset = 8 + instrument * 36; + let flags = u16::from_le_bytes([bank[offset], bank[offset + 1]]); + let voices = if flags & 4 != 0 { 2 } else { 1 }; + assert!( + pressed.insert((c, key), voices).is_none(), + "overlapping same pitch" + ); + channels_used.insert(c); + notes += 1; + per_channel_notes[c as usize] += 1; + } + MusicEvent::Off(c, key) => { + assert!(pressed.remove(&(c, key)).is_some(), "unmatched release"); + final_note_off = *tick; + } + MusicEvent::System(c, 11) => { + assert!( + !pressed.keys().any(|&(channel, _)| channel == c), + "forced release hides dangling note" + ); + } + MusicEvent::End => { + assert_eq!(*tick, ticks); + end_events += 1; + } + MusicEvent::OnInherited(..) => panic!("recipe must have explicit velocity"), + _ => {} + } + max_notes = max_notes.max(pressed.len()); + max_opl_voices = max_opl_voices.max(pressed.values().sum()); + } + } + assert!(pressed.is_empty()); + assert_eq!(end_events, 1); + assert_eq!( + used, declared, + "preload declaration must match programs and 100 + drum key" + ); + assert_eq!(channels_used, BTreeSet::from([0, 1, 2, 3, 4, 15])); + assert!(max_opl_voices <= 18, "arrangement requires voice stealing"); + assert!(final_note_off < ticks - 1); + + // The native bus services tick 0 after the first 70 Hz quantum. The loop + // restarts after ticks + 1 quanta, then preserves synth oscillator phase. + let loop_frame = ((ticks as u64 + 1) * RATE as u64).div_ceil(70) as usize; + let frames = loop_frame + RATE as usize * 8; + let preview = render(bank, &score, frames, true, 85); + let full_volume = render(bank, &score, frames, true, 127); + let single = render(bank, &score, frames, false, 85); + let default_metrics = metrics(&preview); + let full_metrics = metrics(&full_volume); + assert_eq!(default_metrics["clipped_samples"], 0); + assert_eq!(full_metrics["clipped_samples"], 0); + assert!(default_metrics["peak"].as_i64().unwrap() > 1_000); + let second_rms = preview + .chunks_exact(RATE as usize * 2) + .map(rms) + .collect::>(); + assert!( + second_rms.iter().all(|&v| v > 10.), + "unexpected silent second" + ); + let tail = (frames - RATE as usize * 2) * 2; + let single_tail_rms = rms(&single[tail..]); + let loop_tail_rms = rms(&preview[tail..]); + assert!( + single_tail_rms < loop_tail_rms / 20., + "one-play tail does not decay" + ); + let muted = render(bank, &score, RATE as usize, true, 0); + assert!(muted.iter().all(|&v| v == 0), "native Music volume mute"); + let preview_file = output.join(format!("{key}-preview.wav")); + wav(&preview_file, &preview); + let boundary_start = loop_frame.saturating_sub(RATE as usize * 4); + let boundary_end = loop_frame + RATE as usize * 4; + let boundary_file = output.join(format!("{key}-loop-boundary.wav")); + wav( + &boundary_file, + &preview[boundary_start * 2..boundary_end * 2], + ); + let sample_delta = (0..2) + .map(|channel| { + (preview[loop_frame * 2 + channel] as i32 + - preview[(loop_frame - 1) * 2 + channel] as i32) + .abs() + }) + .max() + .unwrap(); + let nearby_max_delta = preview[(loop_frame - 100) * 2..(loop_frame + 100) * 2] + .windows(3) + .map(|v| (v[2] as i32 - v[0] as i32).abs()) + .max() + .unwrap(); + assert!(sample_delta <= nearby_max_delta); + json!({ + "track": key, "duration_ticks": ticks, "duration_seconds": ticks as f64 / 70., + "score_bytes": bytes.len(), "score_start": start, "score_stream_bytes": length, + "primary_channels": channels, "secondary_channels": secondary, + "events": events, "notes": notes, "groups": score.groups.len(), + "maximum_events_per_tick": same_tick_events.values().max(), + "maximum_pressed_notes": max_notes, "maximum_required_opl_voices": max_opl_voices, + "per_channel_note_counts": per_channel_notes, "percussion_keys": percussion, + "declared_instruments": declared, "unmatched_or_dangling_notes": 0, + "end_events": end_events, "last_note_release_tick": final_note_off, + "sample_rate": RATE, "rendered_frames": frames, "rendered_seconds": frames as f64 / RATE as f64, + "native_loop_restart_frame": loop_frame, "native_loop_restart_seconds": loop_frame as f64 / RATE as f64, + "default_volume_85": default_metrics, "maximum_volume_127": full_metrics, + "per_second_rms": second_rms, "one_play_tail_rms": single_tail_rms, + "looping_tail_rms": loop_tail_rms, "music_mute_exact_zero": true, + "boundary_sample_delta": sample_delta, "nearby_maximum_sample_delta": nearby_max_delta, + "boundary_first_half_rms": rms(&preview[boundary_start * 2..loop_frame * 2]), + "boundary_second_half_rms": rms(&preview[loop_frame * 2..boundary_end * 2]), + "preview": preview_file, "loop_boundary_preview": boundary_file, + "waveform_splice_identical": false, + }) +} +fn main() { + let args = std::env::args().collect::>(); + assert_eq!(args.len(), 4, "validate_music DATA_DIR MODS_DIR OUTPUT_DIR"); + let catalog = Catalog::open(Path::new(&args[1])).expect("local catalog"); + let mods = Path::new(&args[2]); + let output = Path::new(&args[3]); + fs::create_dir_all(output).unwrap(); + let package = mods.join("iron_coast_stage2_music"); + let active = ActiveMods::build( + &Registry::default(), + &modding::discover(mods), + &["iron_coast_stage2_music".to_owned()], + Some(&catalog), + ) + .expect("independent activation"); + assert_eq!(active.pins.len(), 1); + assert_eq!(active.registry.music.len(), 3); + let bank = catalog + .named("GENMIDI_OP2") + .expect("local original FM instruments"); + let tracks = ["assault", "pursuit", "finale"].map(|key| inspect(key, &package, output, &bank)); + let report = json!({"renderer": "Rust checked mod MUS decoder and native GENMIDI/OPL3 Mixer", + "independent_activation": true, "pins": active.pins, "tracks": tracks, + "preview_storage": "Ignored local QA; full previews are not digital sound definitions", + "audition_method": "Objective native PCM inspection, no claim of human listening", + "percussion_preload_convention": "100 + GM key; bank playback index separately 128 + key - 35", + "loop_limit": "Intentional musical cadence; native envelope/oscillator phase means no sample-exact splice"}); + fs::write( + output.join("native-validation.json"), + serde_json::to_vec_pretty(&report).unwrap(), + ) + .unwrap(); + for track in report["tracks"].as_array().unwrap() { + println!( + "{}: {} ticks, {} notes, {} FM voices max, peak85={} peak127={}, clipped=0, loop/mute/release checks passed", + track["track"], + track["duration_ticks"], + track["notes"], + track["maximum_required_opl_voices"], + track["default_volume_85"]["peak"], + track["maximum_volume_127"]["peak"] + ); + } +} diff --git a/mods/iron_coast_stage2_music/validation.json b/mods/iron_coast_stage2_music/validation.json new file mode 100644 index 00000000..8caceb90 --- /dev/null +++ b/mods/iron_coast_stage2_music/validation.json @@ -0,0 +1,323 @@ +{ + "package": "iron_coast_stage2_music", + "api_version": 1, + "version": "1.0.0", + "result": "passed", + "deterministic_composer_regeneration": "byte-identical MUS and provenance after repeated generation", + "portable_music_api_tests": { + "passed": 7, + "failed": 0, + "command": "cargo test --locked --no-default-features --manifest-path RustRaptor/Cargo.toml --test music" + }, + "independent_activation": true, + "native_checked_decoder": true, + "native_library_sha256": "3525beac85a8e592f5db81358901ae8f321460f106f3929246ff6af832deeb24", + "native_sources": { + "src/audio.rs": "dcf352dcc16e383de389648d9fc288f682e7c2bfc92277db6ee76e198e3ad054", + "src/audio/opl3.rs": "e875db410274e3b4e725e68f160862782baa768c993c132f3c09976da683b396", + "src/sound.rs": "aff6779b85f9f4f4bc30a15ad75ec6fdd61d42895639700f4842870636e73c4b" + }, + "original_instrument_bank_sha256": "fdc93c076bf44207299e61ec1bbcfafca421454bfa99dd14fa4e5dcada1547b9", + "validator_rust_sha256": "14868b5e7c43c01c9dfe8e0b0868ae4f2940620bf85c3874e083cdd7bca0dcd8", + "validator_recipe_sha256": "590720e80870f7f4f968b92880a84d6b4f8822e1ce05e0a7e4ed1d5d8c248a88", + "native_pcm_inspection": { + "sample_rate": 22050, + "channels": 2, + "pcm_bits": 16, + "clipped_samples_all_tracks_at_volume_85_and_127": 0, + "all_complete_seconds_audible": true, + "music_mute_exact_zero": true, + "single_play_tails_decay": true, + "percussion_declarations": "verified against used programs and 100 + GM percussion key", + "same_pitch_overlap_unmatched_or_dangling_notes": 0, + "opl_capacity": 18, + "listen_method": "Objective PCM, header, clock, note and instrument-bank inspection; no claim of human listening", + "limitations": [ + "Native instrument waveforms have small nonzero DC means; no custom filtering or driver changes were applied.", + "Loops intentionally close a musical cadence; native envelopes and oscillator phases do not make sample-identical PCM splices.", + "Art/SD/HD review does not apply: this package contains only scores and reproduction/validation sources.", + "Full and boundary WAVs are ignored local QA outputs, not registered digital effects or required package assets." + ] + }, + "preview_reproduction": "python3 mods/iron_coast_stage2_music/validate_music.py", + "local_evidence": "../.reference/iron-coast-stage2-music/native-validation.json", + "tracks": [ + { + "id": "iron_coast_stage2_music:assault", + "score_sha256": "cff88d3276e90b957d6df92f636101cb148e56d6a9684ff8319d90f7421463b4", + "duration_ticks": 6533, + "duration_seconds": 93.32857142857142, + "events": 5162, + "notes": 2569, + "maximum_events_per_tick": 24, + "maximum_required_opl_voices": 12, + "default_volume_85": { + "clipped_samples": 0, + "dc_mean": 69.18367231865963, + "nonzero_samples": 4455116, + "peak": 2994, + "rms": 415.0117284494293 + }, + "maximum_volume_127": { + "clipped_samples": 0, + "dc_mean": 96.13358885890602, + "nonzero_samples": 4458171, + "peak": 5695, + "rms": 683.7804926027605 + }, + "loop_boundary_sample_delta": 16, + "nearby_maximum_sample_delta": 913, + "one_play_tail_rms": 4.223457869078616, + "looping_tail_rms": 384.95123487435717, + "section_pcm_inspection": [ + { + "section": "Ignition", + "seconds": 6.667, + "rms": 351.242, + "dc_mean": 32.702, + "ac_rms": 349.716, + "left_rms": 348.113, + "right_rms": 354.343 + }, + { + "section": "Rivetline", + "seconds": 26.667, + "rms": 432.098, + "dc_mean": 56.845, + "ac_rms": 428.343, + "left_rms": 416.462, + "right_rms": 447.188 + }, + { + "section": "Container crosswind", + "seconds": 20.0, + "rms": 430.109, + "dc_mean": 60.882, + "ac_rms": 425.779, + "left_rms": 413.407, + "right_rms": 446.187 + }, + { + "section": "Drydock bridge", + "seconds": 13.333, + "rms": 388.74, + "dc_mean": 158.121, + "ac_rms": 355.129, + "left_rms": 422.695, + "right_rms": 351.52 + }, + { + "section": "Harbor assault", + "seconds": 20.0, + "rms": 429.783, + "dc_mean": 58.143, + "ac_rms": 425.832, + "left_rms": 415.234, + "right_rms": 443.855 + }, + { + "section": "Home bearing", + "seconds": 6.667, + "rms": 425.064, + "dc_mean": 66.546, + "ac_rms": 419.822, + "left_rms": 407.324, + "right_rms": 442.092 + } + ], + "minimum_complete_second_ac_rms": 299.8780249693171 + }, + { + "id": "iron_coast_stage2_music:pursuit", + "score_sha256": "454f2f4478d67d17c669f7c79fae3106b0f1e1753855e81885befe9d046c064d", + "duration_ticks": 6400, + "duration_seconds": 91.42857142857143, + "events": 5620, + "notes": 2798, + "maximum_events_per_tick": 24, + "maximum_required_opl_voices": 10, + "default_volume_85": { + "clipped_samples": 0, + "dc_mean": 298.56022351285964, + "nonzero_samples": 4369524, + "peak": 3380, + "rms": 596.498760715444 + }, + "maximum_volume_127": { + "clipped_samples": 0, + "dc_mean": 329.3054494086099, + "nonzero_samples": 4375231, + "peak": 5924, + "rms": 851.5674189129206 + }, + "loop_boundary_sample_delta": 4, + "nearby_maximum_sample_delta": 867, + "one_play_tail_rms": 3.2440683704010826, + "looping_tail_rms": 634.3466454271086, + "section_pcm_inspection": [ + { + "section": "Wake signal", + "seconds": 5.714, + "rms": 425.53, + "dc_mean": 42.941, + "ac_rms": 423.358, + "left_rms": 415.611, + "right_rms": 435.223 + }, + { + "section": "Undertow", + "seconds": 22.857, + "rms": 636.14, + "dc_mean": 375.349, + "ac_rms": 513.602, + "left_rms": 630.761, + "right_rms": 641.474 + }, + { + "section": "Crosscurrent", + "seconds": 22.857, + "rms": 646.284, + "dc_mean": 379.254, + "ac_rms": 523.306, + "left_rms": 641.119, + "right_rms": 651.408 + }, + { + "section": "Fog channel", + "seconds": 11.429, + "rms": 420.534, + "dc_mean": 32.688, + "ac_rms": 419.261, + "left_rms": 417.203, + "right_rms": 423.838 + }, + { + "section": "Raider wake", + "seconds": 22.857, + "rms": 640.104, + "dc_mean": 377.461, + "ac_rms": 516.969, + "left_rms": 634.875, + "right_rms": 645.292 + }, + { + "section": "Bearing reset", + "seconds": 5.714, + "rms": 627.901, + "dc_mean": 358.595, + "ac_rms": 515.431, + "left_rms": 622.267, + "right_rms": 633.484 + } + ], + "minimum_complete_second_ac_rms": 357.95592768692705 + }, + { + "id": "iron_coast_stage2_music:finale", + "score_sha256": "75f7bb28e0fd3e3e1632b81651dde44a63e2220174576412923a4f67a8dc46d1", + "duration_ticks": 7467, + "duration_seconds": 106.67142857142858, + "events": 4836, + "notes": 2406, + "maximum_events_per_tick": 26, + "maximum_required_opl_voices": 12, + "default_volume_85": { + "clipped_samples": 0, + "dc_mean": -246.0077532208698, + "nonzero_samples": 5040764, + "peak": 3199, + "rms": 562.450135416922 + }, + "maximum_volume_127": { + "clipped_samples": 0, + "dc_mean": -220.1935161458704, + "nonzero_samples": 5043075, + "peak": 5190, + "rms": 751.9019131880304 + }, + "loop_boundary_sample_delta": 5, + "nearby_maximum_sample_delta": 1694, + "one_play_tail_rms": 4.714550257127835, + "looping_tail_rms": 446.96381073480205, + "section_pcm_inspection": [ + { + "section": "Black horizon", + "seconds": 7.619, + "rms": 445.51, + "dc_mean": -178.859, + "ac_rms": 408.03, + "left_rms": 451.911, + "right_rms": 439.015 + }, + { + "section": "Beacon motif", + "seconds": 22.857, + "rms": 590.669, + "dc_mean": -295.959, + "ac_rms": 511.173, + "left_rms": 601.045, + "right_rms": 580.108 + }, + { + "section": "Danger current", + "seconds": 22.857, + "rms": 578.671, + "dc_mean": -294.397, + "ac_rms": 498.187, + "left_rms": 589.383, + "right_rms": 567.757 + }, + { + "section": "Eye of the tide", + "seconds": 15.238, + "rms": 394.546, + "dc_mean": 37.955, + "ac_rms": 392.716, + "left_rms": 405.907, + "right_rms": 382.848 + }, + { + "section": "The last breakwater", + "seconds": 30.476, + "rms": 634.283, + "dc_mean": -330.425, + "ac_rms": 541.418, + "left_rms": 644.539, + "right_rms": 623.857 + }, + { + "section": "Beacon return", + "seconds": 7.619, + "rms": 609.635, + "dc_mean": -309.531, + "ac_rms": 525.21, + "left_rms": 619.585, + "right_rms": 599.52 + } + ], + "minimum_complete_second_ac_rms": 344.61837692343346 + } + ], + "real_catalog_cli": { + "passed": true, + "validated_packages": 1, + "overrides": 0, + "command": "cargo run --locked --release --no-default-features --manifest-path RustRaptor/Cargo.toml -- --data RustRaptor/data --mods RustRaptor/mods --validate-mods iron_coast_stage2_music" + }, + "reproduction_library_selection": { + "method": "Exact active Cargo --message-format=json compiler-artifact filenames", + "artifacts": { + "raptor_replica": { + "path": "/home/quintine/Projects/RaptorReplica/RustRaptor/target/release/libraptor_replica.rlib", + "sha256": "3525beac85a8e592f5db81358901ae8f321460f106f3929246ff6af832deeb24" + }, + "serde_json": { + "path": "/home/quintine/Projects/RaptorReplica/RustRaptor/target/release/deps/libserde_json-89b5c242431768d3.rlib", + "sha256": "ba61a9b6a7f97c994c6fdb2ab5e50915a5d6b456664f31709fd05306d56e48bd" + } + }, + "shared_desktop_build_mtime_failure_fixed": true, + "rerendered_previews_byte_identical_to_original_native_proof": true, + "all_three_score_bytes_unchanged": true + } +} diff --git a/mods/iron_coast_stage2_siege/ART_PROVENANCE.md b/mods/iron_coast_stage2_siege/ART_PROVENANCE.md new file mode 100644 index 00000000..13a0572c --- /dev/null +++ b/mods/iron_coast_stage2_siege/ART_PROVENANCE.md @@ -0,0 +1,15 @@ +# Bastion Crawler artwork and audio provenance + +The two `art/*-generated-v1.png` files are unchanged outputs of the built-in image generator. Their exact built-in paths, output hints, generation job/lease IDs, original bytes SHA-256 and saved prompt paths are recorded in `provenance-unit-v1.json` and `provenance-projectile-v1.json`. They were generated as transparent new enemy/artwork designs; the originals were style references, not replacement sprite authority. No decoded original reference image is distributed inside this mod. + +The authentic catalog style references were viewed before generation: the enemy reference is asset `200c8`, and the projectile reference is `101d6`. Their decoded reference SHA-256 values are retained in the provenance records. Original gray metal, compact top-down silhouette, restrained highlights and readable small logical canvases informed these new designs. The exact palette used for local renderer review is recorded in the external validation handoff. + +`prepare_art.rs` is the complete reproducible preparation recipe. It crops only completely transparent outer margins (every input pixel with alpha at least one remains within the recorded crop), preserves the occupied aspect ratio, fits and centers the artwork inside the declared logical canvas with padding, and creates an 8× HD canvas using premultiplied-alpha Lanczos3. SD uses the same floor-nearest sample positions as the renderer at logical size, retaining bright projectile cores and matching the SD/HD silhouette placement at 1×. The production PNG loader performs its normal alpha threshold and original-palette conversion; this package does not change that policy. Native details necessarily simplify at SD and the smallest indexed HD sizes. + +`art-qa.json` records every raw/SD/HD hash, dimensions, crop, occupied fit, offsets, logical origin `[0,0]`, single-frame count and alpha-threshold bounds. No opaque edge touches the sprite canvas. HD and SD canvases have exactly the same aspect and logical placement. Generated masters remain untouched; only derived artwork is prepared. + +To reproduce preparation, compile `prepare_art.rs` against the project's locked `image`, `serde_json` and `sha2` crates, then pass this mod folder to the resulting executable. The checked local compiler arguments are retained in the external development validation record. This helper writes only derived PNGs and `art-qa.json` in the supplied mod. + +`generate_audio.py` creates original effects with seeded chirps and filtered noise using the Python standard library. It uses no original recordings, external audio service or nondeterministic noise source. Run `python3 generate_audio.py` from this mod folder to reproduce the three WAVs and their recipe. All are mono 22050 Hz 16-bit PCM, with short attack/release envelopes and normalized peaks below clipping. Exact seeds, lengths, peak/RMS and SHA-256 values are in `audio-recipe.json`. + +Local visual review covers the unchanged raw outputs, both prepared modes and all indexed renderer outputs at scales 1–4. These diagnostic galleries do not claim live whole-mission rendering. SoundBank/Mixer tests confirm that all effects decode, queue and produce nonzero unclipped output; they do not measure a user's speakers. diff --git a/mods/iron_coast_stage2_siege/README.md b/mods/iron_coast_stage2_siege/README.md new file mode 100644 index 00000000..cdb9f235 --- /dev/null +++ b/mods/iron_coast_stage2_siege/README.md @@ -0,0 +1,34 @@ +# Iron Coast II: Bastion Crawler + +An independent enemy package for API version 1. Enable **Iron Coast II: Bastion Crawler** in the game's Mods menu. Enabling a mission that requires it also enables this package through the dependency manager. Enabling this enemy alone registers its content; a mission or another mod must spawn it. There are no dependencies or overrides. + +## Behavior + +- Enemy ID: `iron_coast_stage2_siege:unit`; ground target, logical canvas 32×32, health 48, reward 220 credits. +- Armored convoy tank. It advances one pixel per tick and occasionally drifts sideways. At health 24 or lower it loses its sideways drift and its second cannon shell. +- A ten-tick warning precedes two aimed 3-damage shells at speed 3. Subsequent warnings are 87 engine ticks apart (about 3.7 seconds). Damaged crawlers fire one shell. +- `:gun` is a scripted firing controller; `:projectile` is the distinct hostile projectile definition. These weapons are enemy content, unavailable in the shop; no player equipment or credits are granted. +- `:shot`, `:warning` and `:death` are synthesized local WAV cues. Needlewing's warning is supplied for authors but is not played by its ordinary AI. + +The original forward guns can hit these enemies. Air-only weapons cannot hit ground enemies, and ground-only weapons cannot hit the Needlewing. Collision dimensions are identical in SD and HD; artwork has transparent padding and one aligned frame per sprite. Normal units leave the playfield if not killed. A mission may hold a required target inside the screen while retaining its lateral movement. + +## Mission integration + +Spawn `iron_coast_stage2_siege:unit` through normal mission definitions or the documented `spawn` command. Actual deaths increment the objective `iron_coast_stage2_siege:defeated` once. Escapes and despawns do not increment it. The engine awards the configured reward and creates normal death feedback; this script adds its local death cue. Objective keys and content IDs are namespaced so all three shared enemy packages coexist. + +Firing is rejected for dead or invisible units and after they pass the player. Bursts are finite; scripts never spawn enemies, grant equipment, deal direct damage, or complete a mission. Per-entity movement clocks and burst state are serializable and use only supplied deterministic RNG. Up to 128 live units receive custom AI, with periodic pruning and a bounded 128-entry death guard. Excess units retain basic engine movement and do not gain extra attacks. The diagnostics counters saturate at one billion. Missions should use much smaller readable waves. + +No new controls are introduced. Fire and weapon selection remain the normal game controls. All prices are inapplicable because the package adds enemies, not purchasable items. + +## Assets and validation + +Both artwork modes, unchanged generated masters, prompts, derivation recipe and all sound recipes are included. See [artwork provenance](ART_PROVENANCE.md), [art checks](art-qa.json), [audio recipe](audio-recipe.json) and [validation record](validation/acceptance.json). Decoded original style references and local review screenshots are deliberately kept outside this package. + +From the RustRaptor folder: + +```sh +cargo test --locked --no-default-features --test stage2_enemies +cargo run --locked --no-default-features -- --data data --mods mods --validate-mods iron_coast_stage2_siege +``` + +Tests exercise actual World callbacks, finite volleys and telegraphs, ground/air filtering, damage behavior, escapes, real death rewards and counters, reused entity IDs, bounded state, full save/RNG continuation and independent/combined activation. Shipped PNG geometry and all nine effects are also checked through the real SoundBank/Mixer. Local catalog validation and indexed SD/HD scale 1–4 galleries are recorded separately. These controlled checks do not establish full campaign balance or a live SDL scene; the mission packages have their own route tests. diff --git a/mods/iron_coast_stage2_siege/art-qa.json b/mods/iron_coast_stage2_siege/art-qa.json new file mode 100644 index 00000000..27695aee --- /dev/null +++ b/mods/iron_coast_stage2_siege/art-qa.json @@ -0,0 +1,105 @@ +{ + "all_occupied_input_alpha_retained_in_crop": true, + "frames": [ + { + "crop_all_alpha_ge_1": [ + 0, + 37, + 1224, + 1230 + ], + "frames": 1, + "hd_alpha128_bounds": [ + 50, + 54, + 211, + 200 + ], + "hd_canvas": [ + 256, + 256 + ], + "hd_sha256": "9fe5a2b6754952f7e26cb59de52de8518465f1ee3aa03add89e421121dbe80a9", + "kind": "unit", + "logical_canvas": [ + 32, + 32 + ], + "logical_origin": [ + 0, + 0 + ], + "occupied_fit": [ + 224, + 218 + ], + "offset_hd": [ + 16, + 19 + ], + "raw_dimensions": [ + 1254, + 1254 + ], + "raw_sha256": "549b42781c0dda763c0f1f7be2a7890403d31a2369e3c90653c97122616dd81a", + "sd_alpha128_bounds": [ + 7, + 7, + 27, + 25 + ], + "sd_sha256": "09087ebf54d35b2b18fa08dc713fef7f753232f49ae0068902bbe11f3e0f6933" + }, + { + "crop_all_alpha_ge_1": [ + 103, + 39, + 1176, + 1133 + ], + "frames": 1, + "hd_alpha128_bounds": [ + 25, + 19, + 37, + 47 + ], + "hd_canvas": [ + 64, + 64 + ], + "hd_sha256": "499f421139817f4a08b40fba5af7d0eb8ab0cb45d569c0d30c41e27f869b29a2", + "kind": "projectile", + "logical_canvas": [ + 8, + 8 + ], + "logical_origin": [ + 0, + 0 + ], + "occupied_fit": [ + 47, + 48 + ], + "offset_hd": [ + 8, + 8 + ], + "raw_dimensions": [ + 1254, + 1254 + ], + "raw_sha256": "13350afdc0fd4bb020413f947959c9ee0ead42add29ff68f2df236962d78439b", + "sd_alpha128_bounds": [ + 4, + 3, + 5, + 6 + ], + "sd_sha256": "9a288b63300997374de9a1a160b7e671cb2112e90e81de6be3eb52ee03770019" + } + ], + "method": "prepare_art.rs: unchanged genuine alpha master, crop only transparent margin, aspect-preserving centered fit, premultiplied-alpha Lanczos3 HD8x and renderer-aligned floor-nearest SD; original images are style references only", + "source_unchanged": true +} \ No newline at end of file diff --git a/mods/iron_coast_stage2_siege/art/projectile-generated-v1.png b/mods/iron_coast_stage2_siege/art/projectile-generated-v1.png new file mode 100644 index 00000000..80bf5445 Binary files /dev/null and b/mods/iron_coast_stage2_siege/art/projectile-generated-v1.png differ diff --git a/mods/iron_coast_stage2_siege/art/projectile-hd.png b/mods/iron_coast_stage2_siege/art/projectile-hd.png new file mode 100644 index 00000000..48eb808e Binary files /dev/null and b/mods/iron_coast_stage2_siege/art/projectile-hd.png differ diff --git a/mods/iron_coast_stage2_siege/art/projectile-sd.png b/mods/iron_coast_stage2_siege/art/projectile-sd.png new file mode 100644 index 00000000..441f7044 Binary files /dev/null and b/mods/iron_coast_stage2_siege/art/projectile-sd.png differ diff --git a/mods/iron_coast_stage2_siege/art/unit-generated-v1.png b/mods/iron_coast_stage2_siege/art/unit-generated-v1.png new file mode 100644 index 00000000..87a8fca5 Binary files /dev/null and b/mods/iron_coast_stage2_siege/art/unit-generated-v1.png differ diff --git a/mods/iron_coast_stage2_siege/art/unit-hd.png b/mods/iron_coast_stage2_siege/art/unit-hd.png new file mode 100644 index 00000000..131a4822 Binary files /dev/null and b/mods/iron_coast_stage2_siege/art/unit-hd.png differ diff --git a/mods/iron_coast_stage2_siege/art/unit-sd.png b/mods/iron_coast_stage2_siege/art/unit-sd.png new file mode 100644 index 00000000..23e42296 Binary files /dev/null and b/mods/iron_coast_stage2_siege/art/unit-sd.png differ diff --git a/mods/iron_coast_stage2_siege/audio-recipe.json b/mods/iron_coast_stage2_siege/audio-recipe.json new file mode 100644 index 00000000..bbe9c652 --- /dev/null +++ b/mods/iron_coast_stage2_siege/audio-recipe.json @@ -0,0 +1,38 @@ +{ + "generator": "generate_audio.py standard Python seeded chirp/filtered noise; no original recordings", + "files": [ + { + "file": "audio/shot.wav", + "seed": 8200, + "duration_seconds": 0.19002267573696144, + "samples": 4190, + "format": "mono PCM16 little endian", + "sample_rate": 22050, + "peak": 20316, + "rms": 0.09185327584402317, + "sha256": "104c5b1080cf0e2d2562b1e81add4ca2b356d47bedf23eed3a0e766ddb09e209" + }, + { + "file": "audio/warning.wav", + "seed": 8201, + "duration_seconds": 0.26, + "samples": 5733, + "format": "mono PCM16 little endian", + "sample_rate": 22050, + "peak": 13107, + "rms": 0.12782127881204097, + "sha256": "02ccd8177ec95592fcee098ed8f469d262abc281be344b781fa47798022ec0c1" + }, + { + "file": "audio/death.wav", + "seed": 8202, + "duration_seconds": 0.72, + "samples": 15876, + "format": "mono PCM16 little endian", + "sample_rate": 22050, + "peak": 24248, + "rms": 0.11268966219350272, + "sha256": "2058b2cc0707aef88ee02ee8c6a6182d074c8b96eda52a8fe4e0c9c6f9a7fce7" + } + ] +} diff --git a/mods/iron_coast_stage2_siege/audio/death.wav b/mods/iron_coast_stage2_siege/audio/death.wav new file mode 100644 index 00000000..26154256 Binary files /dev/null and b/mods/iron_coast_stage2_siege/audio/death.wav differ diff --git a/mods/iron_coast_stage2_siege/audio/shot.wav b/mods/iron_coast_stage2_siege/audio/shot.wav new file mode 100644 index 00000000..b961fd09 Binary files /dev/null and b/mods/iron_coast_stage2_siege/audio/shot.wav differ diff --git a/mods/iron_coast_stage2_siege/audio/warning.wav b/mods/iron_coast_stage2_siege/audio/warning.wav new file mode 100644 index 00000000..9800505b Binary files /dev/null and b/mods/iron_coast_stage2_siege/audio/warning.wav differ diff --git a/mods/iron_coast_stage2_siege/content.json b/mods/iron_coast_stage2_siege/content.json new file mode 100644 index 00000000..144a09d6 --- /dev/null +++ b/mods/iron_coast_stage2_siege/content.json @@ -0,0 +1,74 @@ +{ + "weapons": [ + { + "id": "iron_coast_stage2_siege:gun", + "name": "Bastion Crawler firing controller", + "damage": 1, + "speed": 0, + "cooldown": 86, + "behavior": "scripted", + "target": "all", + "script": "scripts/gun.rhai" + }, + { + "id": "iron_coast_stage2_siege:projectile", + "name": "Bastion Crawler shell", + "damage": 3, + "speed": 3, + "cooldown": 86, + "behavior": "straight", + "target": "all", + "art": { + "png": "art/projectile-sd.png", + "hd_png": "art/projectile-hd.png", + "logical_width": 8, + "logical_height": 8, + "frames": 1 + } + } + ], + "enemies": [ + { + "id": "iron_coast_stage2_siege:unit", + "name": "Bastion Crawler", + "health": 48, + "speed": 1, + "reward": 220, + "ground": true, + "boss": false, + "cooldown": 86, + "weapon": "iron_coast_stage2_siege:gun", + "art": { + "png": "art/unit-sd.png", + "hd_png": "art/unit-hd.png", + "logical_width": 32, + "logical_height": 32, + "frames": 1 + }, + "script": "scripts/ai.rhai" + } + ], + "sounds": [ + { + "id": "iron_coast_stage2_siege:shot", + "name": "Bastion Crawler shot", + "file": "audio/shot.wav", + "volume": 80, + "priority": 2 + }, + { + "id": "iron_coast_stage2_siege:warning", + "name": "Bastion Crawler warning", + "file": "audio/warning.wav", + "volume": 62, + "priority": 2 + }, + { + "id": "iron_coast_stage2_siege:death", + "name": "Bastion Crawler death", + "file": "audio/death.wav", + "volume": 96, + "priority": 3 + } + ] +} diff --git a/mods/iron_coast_stage2_siege/contract.json b/mods/iron_coast_stage2_siege/contract.json new file mode 100644 index 00000000..f59b0dc7 --- /dev/null +++ b/mods/iron_coast_stage2_siege/contract.json @@ -0,0 +1,20 @@ +{ + "id": "iron_coast_stage2_siege", + "name": "Bastion Crawler", + "logical_size": [ + 32, + 32 + ], + "ground": true, + "health": 48, + "reward": 220, + "gun_cooldown": 86, + "actual_engine_firing_period": 87, + "projectile_damage": 3, + "projectile_speed": 3, + "burst": 2, + "warning_ticks": 10, + "objective": "iron_coast_stage2_siege:defeated", + "maximum_live_script_units": 128, + "maximum_retained_death_guards": 128 +} diff --git a/mods/iron_coast_stage2_siege/generate_audio.py b/mods/iron_coast_stage2_siege/generate_audio.py new file mode 100644 index 00000000..21dd6bd0 --- /dev/null +++ b/mods/iron_coast_stage2_siege/generate_audio.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 +"""Reproduce authored mono PCM effects using seeded chirps and filtered noise.""" +from pathlib import Path +import random,math,struct,wave,json,hashlib +root=Path(__file__).resolve().parent +role=root.name.split('_')[-1];index=['interceptor','siege','skimmer'].index(role) +rate=22050;files=[] +for name,duration in [('shot',[.095,.19,.14][index]),('warning',[.12,.26,.19][index]),('death',[.46,.72,.56][index])]: + seed=8100+index*100+['shot','warning','death'].index(name);rng=random.Random(seed);count=round(rate*duration);values=[];phase=0.0;low=0.0 + for i in range(count): + t=i/rate;u=i/max(count-1,1);noise=rng.uniform(-1,1);low=.9*low+.1*noise + if name=='shot': + start=[1600,440,1000][index];end=[460,90,280][index];phase+=2*math.pi*(end+(start-end)*(1-u)**2)/rate + value=[.64,.45,.57][index]*math.sin(phase)+[.10,.34,.18][index]*noise+.14*math.sin(1.93*phase);env=math.exp(-[5.8,6.5,5.3][index]*u) + elif name=='warning': + phase+=2*math.pi*([670,310,540][index]+[390,240,420][index]*u)/rate;value=.7*math.sin(phase)+.1*math.sin(2*phase);env=math.sin(math.pi*u)**1.4*(.65+.35*math.sin(2*math.pi*[13,9,16][index]*t)) + else: + phase+=2*math.pi*([130,85,110][index]*(1-u)+24)/rate;value=.55*low+.27*noise+.24*math.sin(phase);env=math.exp(-[5.5,4.7,5.1][index]*u) + env*=min(1,t/.003)*min(1,(count-1-i)/(rate*.006));values.append(value*max(env,0)) + peak=max(abs(v)for v in values);amp=.4 if name=='warning'else(.62 if name=='shot'else.74);samples=[round(v/peak*amp*32767)for v in values];path=root/'audio'/f'{name}.wav' + with wave.open(str(path),'wb')as out:out.setnchannels(1);out.setsampwidth(2);out.setframerate(rate);out.writeframes(struct.pack('<'+'h'*count,*samples)) + files.append({'file':str(path.relative_to(root)),'seed':seed,'duration_seconds':count/rate,'samples':count,'format':'mono PCM16 little endian','sample_rate':rate,'peak':max(abs(v)for v in samples),'rms':math.sqrt(sum(v*v for v in samples)/count)/32767,'sha256':hashlib.sha256(path.read_bytes()).hexdigest()}) +(root/'audio-recipe.json').write_text(json.dumps({'generator':'generate_audio.py standard Python seeded chirp/filtered noise; no original recordings','files':files},indent=2)+'\n') +print(root.name,'3 valid PCM WAV cues reproduced') diff --git a/mods/iron_coast_stage2_siege/mod.toml b/mods/iron_coast_stage2_siege/mod.toml new file mode 100644 index 00000000..42c3d12f --- /dev/null +++ b/mods/iron_coast_stage2_siege/mod.toml @@ -0,0 +1,7 @@ +id = "iron_coast_stage2_siege" +name = "Iron Coast II: Bastion Crawler" +version = "1.0.0" +api_version = 1 +description = "Independent Stage 2 siege: Bastion Crawler. Scripted movement, readable volleys, SD/HD sprites and synthesized sounds." +content = "content.json" +scripts = ["scripts/ai.rhai", "scripts/gun.rhai"] diff --git a/mods/iron_coast_stage2_siege/prepare_art.rs b/mods/iron_coast_stage2_siege/prepare_art.rs new file mode 100644 index 00000000..e68cc49c --- /dev/null +++ b/mods/iron_coast_stage2_siege/prepare_art.rs @@ -0,0 +1,127 @@ +//! Derive aligned SD/HD canvases from unchanged built-in generated PNG masters. +//! The PNG master is never modified. Only wholly transparent margins are trimmed; +//! every occupied input alpha pixel remains inside the recorded source crop. +use image::{ + imageops::{self, FilterType}, + Rgba, RgbaImage, +}; +use serde_json::json; +use sha2::{Digest, Sha256}; +use std::{fs, path::Path}; +fn sha(p: &Path) -> String { + format!("{:x}", Sha256::digest(fs::read(p).unwrap())) +} +fn bounds(im: &RgbaImage, threshold: u8) -> (u32, u32, u32, u32) { + let (mut x0, mut y0, mut x1, mut y1) = (im.width(), im.height(), 0, 0); + for (x, y, p) in im.enumerate_pixels() { + if p[3] >= threshold { + x0 = x0.min(x); + y0 = y0.min(y); + x1 = x1.max(x + 1); + y1 = y1.max(y + 1); + } + } + assert!(x1 > x0 && y1 > y0, "empty sprite"); + (x0, y0, x1, y1) +} +fn filtered(im: &RgbaImage, w: u32, h: u32, filter: FilterType) -> RgbaImage { + // Resample premultiplied alpha to keep opaque dark interior recesses while + // preventing invisible RGB from becoming a dark fringe at the sprite edge. + let mut premul = im.clone(); + for p in premul.pixels_mut() { + for c in 0..3 { + p[c] = ((p[c] as u32 * p[3] as u32 + 127) / 255) as u8; + } + } + let mut out = imageops::resize(&premul, w, h, filter); + for p in out.pixels_mut() { + if p[3] == 0 { + *p = Rgba([0, 0, 0, 0]); + } else { + for c in 0..3 { + p[c] = ((p[c] as u32 * 255 + p[3] as u32 / 2) / p[3] as u32).min(255) as u8; + } + } + } + out +} +fn main() { + let arg = std::env::args().nth(1).expect("pass the mod directory"); + let root = Path::new(&arg); + let contract: serde_json::Value = + serde_json::from_slice(&fs::read(root.join("contract.json")).unwrap()).unwrap(); + let mut reports = Vec::new(); + for kind in ["unit", "projectile"] { + let (lw, lh) = if kind == "unit" { + ( + contract["logical_size"][0].as_u64().unwrap() as u32, + contract["logical_size"][1].as_u64().unwrap() as u32, + ) + } else { + (8, 8) + }; + let source_path = root.join(format!("art/{kind}-generated-v1.png")); + let original_sha = sha(&source_path); + let raw = image::open(&source_path).unwrap().into_rgba8(); + assert!( + raw.pixels().any(|p| p[3] == 0), + "generated source needs genuine transparent background" + ); + assert!( + raw.pixels().any(|p| p[3] == 255), + "generated source needs occupied opaque artwork" + ); + let (x0, y0, x1, y1) = bounds(&raw, 1); + let occupied = imageops::crop_imm(&raw, x0, y0, x1 - x0, y1 - y0).to_image(); + let scale = 8; + let pad = if kind == "unit" { 2 } else { 1 }; + let (limit_w, limit_h) = ((lw - pad * 2) * scale, (lh - pad * 2) * scale); + let (ow, oh) = occupied.dimensions(); + let (w, h) = if limit_w as u64 * oh as u64 <= limit_h as u64 * ow as u64 { + ( + limit_w, + ((oh as u64 * limit_w as u64 + ow as u64 / 2) / ow as u64) as u32, + ) + } else { + ( + ((ow as u64 * limit_h as u64 + oh as u64 / 2) / oh as u64) as u32, + limit_h, + ) + }; + let fitted = filtered(&occupied, w, h, FilterType::Lanczos3); + let mut hd = RgbaImage::new(lw * scale, lh * scale); + let offset = ((hd.width() - w) / 2, (hd.height() - h) / 2); + imageops::overlay(&mut hd, &fitted, offset.0 as i64, offset.1 as i64); + // Match the renderer's indexed HD-to-logical sample positions exactly. + // This retains the bright projectile core and aligns both modes at 1x. + let mut sd = RgbaImage::new(lw, lh); + for y in 0..lh { + for x in 0..lw { + sd.put_pixel(x, y, *hd.get_pixel(x * scale, y * scale)); + } + } + let sdb = bounds(&sd, 128); + let hdb = bounds(&hd, 128); + assert!( + sdb.0 >= 1 && sdb.1 >= 1 && sdb.2 < lw && sdb.3 < lh, + "SD clipped {kind}" + ); + assert!( + hdb.0 >= 1 && hdb.1 >= 1 && hdb.2 < hd.width() && hdb.3 < hd.height(), + "HD clipped {kind}" + ); + let sdpath = root.join(format!("art/{kind}-sd.png")); + let hdpath = root.join(format!("art/{kind}-hd.png")); + sd.save(&sdpath).unwrap(); + hd.save(&hdpath).unwrap(); + assert_eq!(sha(&source_path), original_sha); + reports.push(json!({"kind":kind,"raw_sha256":original_sha,"raw_dimensions":[raw.width(),raw.height()],"crop_all_alpha_ge_1":[x0,y0,x1,y1],"logical_canvas":[lw,lh],"hd_canvas":[hd.width(),hd.height()],"occupied_fit":[w,h],"offset_hd":[offset.0,offset.1],"sd_alpha128_bounds":[sdb.0,sdb.1,sdb.2,sdb.3],"hd_alpha128_bounds":[hdb.0,hdb.1,hdb.2,hdb.3],"logical_origin":[0,0],"frames":1,"sd_sha256":sha(&sdpath),"hd_sha256":sha(&hdpath)})); + } + let report = json!({"method":"prepare_art.rs: unchanged genuine alpha master, crop only transparent margin, aspect-preserving centered fit, premultiplied-alpha Lanczos3 HD8x and renderer-aligned floor-nearest SD; original images are style references only","source_unchanged":true,"all_occupied_input_alpha_retained_in_crop":true,"frames":reports}); + fs::write( + root.join("art-qa.json"), + serde_json::to_vec_pretty(&report).unwrap(), + ) + .unwrap(); + println!("Prepared aligned SD/HD art: {}", root.display()); +} diff --git a/mods/iron_coast_stage2_siege/prompts/projectile-v1.txt b/mods/iron_coast_stage2_siege/prompts/projectile-v1.txt new file mode 100644 index 00000000..ef29ebfb --- /dev/null +++ b/mods/iron_coast_stage2_siege/prompts/projectile-v1.txt @@ -0,0 +1,5 @@ +Use case: stylized-concept +Asset type: one transparent original-palette Raptor-style hostile projectile sprite. +Input image1: authentic original8x8 Raptor bullet, palette/readability reference only. +Subject: one small heavy orange/brass tank shell pointing DOWN, compact blunt glowing-orange head with a dark metallic cylindrical sabot casing; no large aura. A new projectile for Bastion Crawler, readable in an8x8logical game canvas. +Style: crisp overhead arcade game sprite detail, warm/muted metal accents matching classic Raptor, isolated single projectile. One centered frame on real transparent square canvas with at least15% transparent safe margins. Whole visible. DOWN orientation. Opaque dark interior; genuine alpha outside. No background, labels, smoke, muzzle explosion, fireworks, trail beyond sprite, giant bloom, contact sheet or extra projectiles. diff --git a/mods/iron_coast_stage2_siege/prompts/unit-v1.txt b/mods/iron_coast_stage2_siege/prompts/unit-v1.txt new file mode 100644 index 00000000..67169d76 --- /dev/null +++ b/mods/iron_coast_stage2_siege/prompts/unit-v1.txt @@ -0,0 +1,6 @@ +Use case: stylized-concept +Asset type: one transparent top-down sprite for the new Raptor-style enemy mod Bastion Crawler. +Input image1: authentic original Raptor sprite, STYLE AND CAMERA REFERENCE ONLY; create the requested new enemy, not a duplicate. +Subject: A broad low olive/brown armored tank convoy crawler, facing DOWN, with two dark chunky continuous tracks, a squat square steel central turret and a short downward gun barrel. Distinct blocky armored silhouette, modest cyan sight window and restrained warm gunport. Readable at32x32. No ground slab, shadows outside hull, smoke or glow. +Style: faithful classic Raptor military arcade shooter remastered into crisp richly hand-painted HD sprite detail: small bevels, muted original palette, clear original-scale silhouette, upper-left metallic lighting, strictly orthographic overhead. +Canvas: one fully isolated sprite on REAL alpha-transparent background, centered with at least10% completely transparent safe space on every side; no text, watermark, backdrop, contact sheet or other sprites. Whole object visible. Logical canvas 32x32, source orientation down-screen. Native occupied black/dark recesses remain opaque; only space outside object transparent. One frame only. Aim for a square source canvas; do not imply extra content or effects outside the craft. Clean silhouette and clean alpha. Avoid photographic camera perspective, oblique views, neon saturation, large glows, generic modern vector icon style. diff --git a/mods/iron_coast_stage2_siege/provenance-projectile-v1.json b/mods/iron_coast_stage2_siege/provenance-projectile-v1.json new file mode 100644 index 00000000..9e0ca5d9 --- /dev/null +++ b/mods/iron_coast_stage2_siege/provenance-projectile-v1.json @@ -0,0 +1,15 @@ +{ + "output_hint": "Generated images are saved to /home/quintine/.codex/generated_images/01a129a5-9f83-7611-a949-ec6a80b026d4 as /home/quintine/.codex/generated_images/01a129a5-9f83-7611-a949-ec6a80b026d4/exec-cde205f6-51fe-4aa7-b7aa-fa041747ce83.png by default.\nIf you need to use a generated image at another path, copy it and leave the original in place unless the user explicitly asks you to delete it.\nThe generated image is already displayed to the user. There is no need to render it in the final response as a Markdown image or file link.", + "lease": "f44f3e58-0028-49b6-89fb-e051ee66a702", + "job": "stage2-bastion-projectile-v1", + "builtin_path": "/home/quintine/.codex/generated_images/01a129a5-9f83-7611-a949-ec6a80b026d4/exec-cde205f6-51fe-4aa7-b7aa-fa041747ce83.png", + "raw_sha256": "13350afdc0fd4bb020413f947959c9ee0ead42add29ff68f2df236962d78439b", + "mode": "built-in imagegen", + "raw_unchanged": true, + "prompt": "prompts/projectile-v1.txt", + "original_style_reference_asset": "101d6", + "original_reference_copies_shipped": false, + "external_style_reference_png_sha256": "090d5cd708457f92c04253328ac47413f2cc53b6f83546df92c816d3debbcbcc", + "original_style_reference_payload_sha256": "73dfa9a1f1313b1b9bbd71c3f3e2086ffb0440d5a298d98cbb4de407a9faaf2b", + "original_palette_payload_sha256": "1cf6adb926d1dee1888b3e3d33b51a7049b3e5eb5f90a3067ef71c8970547204" +} diff --git a/mods/iron_coast_stage2_siege/provenance-unit-v1.json b/mods/iron_coast_stage2_siege/provenance-unit-v1.json new file mode 100644 index 00000000..e94b5488 --- /dev/null +++ b/mods/iron_coast_stage2_siege/provenance-unit-v1.json @@ -0,0 +1,15 @@ +{ + "output_hint": "Generated images are saved to /home/quintine/.codex/generated_images/01a129a5-9f83-7611-a949-ec6a80b026d4 as /home/quintine/.codex/generated_images/01a129a5-9f83-7611-a949-ec6a80b026d4/exec-00314c50-e45e-4bc7-838c-3fda448cf222.png by default.\nIf you need to use a generated image at another path, copy it and leave the original in place unless the user explicitly asks you to delete it.\nThe generated image is already displayed to the user. There is no need to render it in the final response as a Markdown image or file link.", + "lease": "f7d79f71-2850-4cf4-b972-eb35b4837696", + "job": "stage2-bastion-unit-v1", + "builtin_path": "/home/quintine/.codex/generated_images/01a129a5-9f83-7611-a949-ec6a80b026d4/exec-00314c50-e45e-4bc7-838c-3fda448cf222.png", + "raw_sha256": "549b42781c0dda763c0f1f7be2a7890403d31a2369e3c90653c97122616dd81a", + "mode": "built-in imagegen", + "raw_unchanged": true, + "prompt": "prompts/unit-v1.txt", + "original_style_reference_asset": "200c8", + "original_reference_copies_shipped": false, + "external_style_reference_png_sha256": "d087d71fcfd105a3e03a62d7fa0f539d9c814eb6887170370f34201c45905879", + "original_style_reference_payload_sha256": "75b4d81b2aef8e32cd129a1cd0f1012ef1e3cc3860651b0ae8bf09da9ab0dfde", + "original_palette_payload_sha256": "1cf6adb926d1dee1888b3e3d33b51a7049b3e5eb5f90a3067ef71c8970547204" +} diff --git a/mods/iron_coast_stage2_siege/scripts/ai.rhai b/mods/iron_coast_stage2_siege/scripts/ai.rhai new file mode 100644 index 00000000..955991fe --- /dev/null +++ b/mods/iron_coast_stage2_siege/scripts/ai.rhai @@ -0,0 +1,124 @@ +// Integer-only per-entity clocks. No spawns, equipment grants or direct damage. +// The engine owns collision, one kill reward, projectile retirement and explosions. +fn alive(event) { + for unit in event.entities { + if unit.entity == event.entity && unit.health > 0 { return true; } + } + false +} +// Firing events use muzzle coordinates; visibility must use the real canvas. +fn ready_to_fire(event) { + for unit in event.entities { + if unit.entity == event.entity { + return unit.health > 0 && unit.x >= 0 && unit.x + unit.width <= 320 && unit.y >= 0 && unit.y + unit.height <= 180 && unit.y + unit.height < event.player.y - 8; + } + } + false +} +fn fresh(random) { #{clock:0, sign: if random[0] % 2 == 0 {1} else {-1}, remaining:0, wait:0, aim_x:0, aim_y:3} } +fn ready(state) { + if !state.contains("units") { state.units = #{}; } + if !state.contains("dead") { state.dead = #{}; } + if !state.contains("dead_order") { state.dead_order = []; } + state +} +fn tidy(event, state) { + state = ready(state); + let retained = #{}; + for unit in event.entities { + let key = unit.entity.to_string(); + if unit.definition == "iron_coast_stage2_siege:unit" && unit.health > 0 && state.units.contains(key) && retained.len() < 128 { + retained[key] = state.units[key]; + } + } + state.units = retained; + state +} +fn counter(state, key) { + if !state.contains(key) {return 1;} + if state[key] >= 1000000000 {return 1000000000;} + state[key] + 1 +} +fn clamp_speed(value) { if value < -3 {-3} else if value > 3 {3} else {value} } +fn aimed(event) { + let dx = event.player.x + 16 - event.x; + let dy = event.player.y + 16 - event.y; + let ax = if dx < 0 {-dx} else {dx}; + let ay = if dy < 0 {-dy} else {dy}; + let norm = if ax > ay {ax} else {ay}; + if norm == 0 {return [0,3];} + let vy = dy * 3 / norm; + [clamp_speed(dx * 3 / norm), if vy < 1 {1} else {vy}] +} +fn on_spawn(event, state, random) { + state = tidy(event,state); + let key = event.entity.to_string(); + // Entity IDs restart with each mission. Clear the old lifecycle guard even + // when a spawn was already killed before queued callbacks are dispatched. + state.dead.remove(key); + let keep = []; + for old in state.dead_order { if old != key {keep.push(old);} } + state.dead_order = keep; + if !alive(event) {return #{commands:[],state:state};} + if state.units.len() >= 128 {return #{commands:[],state:state};} + let unit = fresh(random); + state.units[key] = unit; + #{commands:[#{op:"velocity",entity:event.entity,vx:0,vy:1}],state:state} +} +fn on_fire(event, state, random) { + state = ready(state); + if !ready_to_fire(event) || event.x < 0 || event.x >= 320 || event.y < 32 || event.y > 180 || event.y >= event.player.y - 8 { + return #{commands:[],state:state}; + } + let key = event.entity.to_string(); + if !state.units.contains(key) {return #{commands:[],state:state};} + let unit = state.units[key]; + let aim = aimed(event); + unit.remaining = 2; unit.wait = 10; + unit.aim_x = aim[0]; unit.aim_y = aim[1]; + state.units[key] = unit; + #{commands:[#{op:"play_sound",sound:"iron_coast_stage2_siege:warning"}],state:state} +} +fn on_tick(event, state, random) { + state = ready(state); + // Stagger periodic pruning to keep dense waves within the shared script budget. + if (event.tick + event.entity) % 32 == 0 { state = tidy(event,state); } + if event.health <= 0 || !alive(event) {return #{commands:[],state:state};} + let key = event.entity.to_string(); + if !state.units.contains(key) {return #{commands:[],state:state};} + let unit = state.units[key]; + unit.clock = (unit.clock + 1) % 96; + let sideways = if unit.clock >= 64 && unit.clock < 80 && event.health > 24 {unit.sign} else {0}; + let down = 1; + if event.x <= 8 {sideways = 1;} + if event.x >= 320 - 32 - 8 {sideways = -1;} + let commands = [#{op:"velocity",entity:event.entity,vx:sideways,vy:down}]; + // Never fire from an invisible/dead unit, or backwards at a player it passed. + if event.x < 0 || event.x + 32 > 320 || event.y < 0 || event.y + 32 > 180 || event.y + 32 >= event.player.y - 8 { + unit.remaining = 0; + } + if unit.wait > 0 {unit.wait -= 1;} + if unit.remaining > 0 && unit.wait == 0 { + let shells = if event.health <= 24 {1} else {2}; + for side in 0..shells {let offset=if side==0 {-1} else {1};commands.push(#{op:"projectile",weapon:"iron_coast_stage2_siege:projectile",x:event.x+12+offset*5,y:event.y+30,vx:clamp_speed(unit.aim_x+offset),vy:unit.aim_y,hostile:true});} + unit.remaining=0; + commands.push(#{op:"play_sound",sound:"iron_coast_stage2_siege:shot"}); + state.shots = counter(state,"shots"); + } + state.units[key] = unit; + #{commands:commands,state:state} +} +fn on_hit(event, state, random) { + state.hits = counter(state,"hits"); + #{commands:[],state:state} +} +fn on_death(event, state, random) { + state = tidy(event,state); + let key = event.entity.to_string(); + if alive(event) || state.dead.contains(key) {return #{commands:[],state:state};} + if state.dead_order.len() >= 128 {let oldest=state.dead_order.remove(0);state.dead.remove(oldest);} + state.dead[key] = true; state.dead_order.push(key); state.units.remove(key); + state.destroyed = counter(state,"destroyed"); + let defeated = if event.objectives.contains("iron_coast_stage2_siege:defeated") {event.objectives["iron_coast_stage2_siege:defeated"] + 1} else {1}; + #{commands:[#{op:"objective",key:"iron_coast_stage2_siege:defeated",value:defeated},#{op:"play_sound",sound:"iron_coast_stage2_siege:death"}],state:state} +} diff --git a/mods/iron_coast_stage2_siege/scripts/gun.rhai b/mods/iron_coast_stage2_siege/scripts/gun.rhai new file mode 100644 index 00000000..a5f05834 --- /dev/null +++ b/mods/iron_coast_stage2_siege/scripts/gun.rhai @@ -0,0 +1,3 @@ +// The engine supplies the firing cooldown. This wrapper deliberately emits +// no default projectile: the enemy AI schedules its own bounded burst. +fn on_fire(event, state, random) { #{commands: [], state: state} } diff --git a/mods/iron_coast_stage2_siege/validation/acceptance.json b/mods/iron_coast_stage2_siege/validation/acceptance.json new file mode 100644 index 00000000..ffd231d0 --- /dev/null +++ b/mods/iron_coast_stage2_siege/validation/acceptance.json @@ -0,0 +1,49 @@ +{ + "api_version": 1, + "owned_package": "iron_coast_stage2_siege", + "portable_actual_world_tests": { + "command": "cargo test --locked --no-default-features --test stage2_enemies -- --nocapture", + "passed": 9, + "failed": 0, + "test_log_sha256": "1ceb868b5dcb07efd054f529a5356069c1837dd45f27f536886124782256d862", + "coverage": [ + "independent and Stage1 coexistence activation", + "exact engine cooldown/finite burst/warning ticks", + "distinct bounded movement and escape without reward", + "actual ground/air collision filtering and damaged crawler shell loss", + "actual death rewards/objectives once and reused IDs after queued early kills", + "full serialized World plus Rhai state and RNG deterministic continuation", + "260 deaths per package with bounded128 history/live state", + "shipped PNG dimensions/padding/unchanged source SHA and all9SoundBank/Mixer nonzero unclipped effects", + "no invisible/passed-unit warning/projectile from muzzle-coordinate event" + ] + }, + "shipped_assets": { + "SD_HD_PNGs": 4, + "unchanged_generated_masters": 2, + "WAV_effects": 3, + "alpha_and_alignment": "checked; equal logical canvas/aspect;one frame;origin0,0;opaque content leaves padding" + }, + "local_visual_review": { + "actual_palette_outputs": 16, + "modes": [ + "SD", + "HD" + ], + "scales": [ + 1, + 2, + 3, + 4 + ], + "reserved_animated_palette_indices": 0, + "scope": "Actual art_sprite_variant plus identical desktop scaling branch, full diagnostic gallery visually inspected; not a live SDL Host scene. Fine HD details simplify in SD. Full raw masters inspected earlier; unedited generator bytes and exact hashes retained." + }, + "real_catalog_validation": "Included assets and scripts passed real-catalog activation; final whole-folder pins and CLI reruns are recorded outside package in .reference/stage2-enemies/final-handoff.json to avoid recursive content hashes.", + "limits": [ + "No whole-campaign balance or live SDL scene claim by this package owner; mission owners and independent reviewer validate integration.", + "Ordinary targets may escape; required mission targets must be held by mission logic.", + "Custom AI state is capped128 per package; dense enemy spawning remains a mission-author balance responsibility.", + "No platform source or launcher changes." + ] +} diff --git a/mods/iron_coast_stage2_skimmer/ART_PROVENANCE.md b/mods/iron_coast_stage2_skimmer/ART_PROVENANCE.md new file mode 100644 index 00000000..53fb5836 --- /dev/null +++ b/mods/iron_coast_stage2_skimmer/ART_PROVENANCE.md @@ -0,0 +1,15 @@ +# Wakeknife artwork and audio provenance + +The two `art/*-generated-v1.png` files are unchanged outputs of the built-in image generator. Their exact built-in paths, output hints, generation job/lease IDs, original bytes SHA-256 and saved prompt paths are recorded in `provenance-unit-v1.json` and `provenance-projectile-v1.json`. They were generated as transparent new enemy/artwork designs; the originals were style references, not replacement sprite authority. No decoded original reference image is distributed inside this mod. + +The authentic catalog style references were viewed before generation: the enemy reference is asset `10334`, and the projectile reference is `101d6`. Their decoded reference SHA-256 values are retained in the provenance records. Original gray metal, compact top-down silhouette, restrained highlights and readable small logical canvases informed these new designs. The exact palette used for local renderer review is recorded in the external validation handoff. + +`prepare_art.rs` is the complete reproducible preparation recipe. It crops only completely transparent outer margins (every input pixel with alpha at least one remains within the recorded crop), preserves the occupied aspect ratio, fits and centers the artwork inside the declared logical canvas with padding, and creates an 8× HD canvas using premultiplied-alpha Lanczos3. SD uses the same floor-nearest sample positions as the renderer at logical size, retaining bright projectile cores and matching the SD/HD silhouette placement at 1×. The production PNG loader performs its normal alpha threshold and original-palette conversion; this package does not change that policy. Native details necessarily simplify at SD and the smallest indexed HD sizes. + +`art-qa.json` records every raw/SD/HD hash, dimensions, crop, occupied fit, offsets, logical origin `[0,0]`, single-frame count and alpha-threshold bounds. No opaque edge touches the sprite canvas. HD and SD canvases have exactly the same aspect and logical placement. Generated masters remain untouched; only derived artwork is prepared. + +To reproduce preparation, compile `prepare_art.rs` against the project's locked `image`, `serde_json` and `sha2` crates, then pass this mod folder to the resulting executable. The checked local compiler arguments are retained in the external development validation record. This helper writes only derived PNGs and `art-qa.json` in the supplied mod. + +`generate_audio.py` creates original effects with seeded chirps and filtered noise using the Python standard library. It uses no original recordings, external audio service or nondeterministic noise source. Run `python3 generate_audio.py` from this mod folder to reproduce the three WAVs and their recipe. All are mono 22050 Hz 16-bit PCM, with short attack/release envelopes and normalized peaks below clipping. Exact seeds, lengths, peak/RMS and SHA-256 values are in `audio-recipe.json`. + +Local visual review covers the unchanged raw outputs, both prepared modes and all indexed renderer outputs at scales 1–4. These diagnostic galleries do not claim live whole-mission rendering. SoundBank/Mixer tests confirm that all effects decode, queue and produce nonzero unclipped output; they do not measure a user's speakers. diff --git a/mods/iron_coast_stage2_skimmer/README.md b/mods/iron_coast_stage2_skimmer/README.md new file mode 100644 index 00000000..04fa7fdd --- /dev/null +++ b/mods/iron_coast_stage2_skimmer/README.md @@ -0,0 +1,34 @@ +# Iron Coast II: Wakeknife + +An independent enemy package for API version 1. Enable **Iron Coast II: Wakeknife** in the game's Mods menu. Enabling a mission that requires it also enables this package through the dependency manager. Enabling this enemy alone registers its content; a mission or another mod must spawn it. There are no dependencies or overrides. + +## Behavior + +- Enemy ID: `iron_coast_stage2_skimmer:unit`; ground target, logical canvas 32×24, health 26, reward 140 credits. +- Naval hovercraft with side flotation pods. It advances one pixel per tick while weaving left, pausing, weaving right and pausing. +- A six-tick warning precedes a pair of 2-damage wake shells at speed 3. Their lateral velocities differ by two, forming a narrow fan. Subsequent warnings are 82 engine ticks apart (about 3.5 seconds). +- `:gun` is a scripted firing controller; `:projectile` is the distinct hostile projectile definition. These weapons are enemy content, unavailable in the shop; no player equipment or credits are granted. +- `:shot`, `:warning` and `:death` are synthesized local WAV cues. Needlewing's warning is supplied for authors but is not played by its ordinary AI. + +The original forward guns can hit these enemies. Air-only weapons cannot hit ground enemies, and ground-only weapons cannot hit the Needlewing. Collision dimensions are identical in SD and HD; artwork has transparent padding and one aligned frame per sprite. Normal units leave the playfield if not killed. A mission may hold a required target inside the screen while retaining its lateral movement. + +## Mission integration + +Spawn `iron_coast_stage2_skimmer:unit` through normal mission definitions or the documented `spawn` command. Actual deaths increment the objective `iron_coast_stage2_skimmer:defeated` once. Escapes and despawns do not increment it. The engine awards the configured reward and creates normal death feedback; this script adds its local death cue. Objective keys and content IDs are namespaced so all three shared enemy packages coexist. + +Firing is rejected for dead or invisible units and after they pass the player. Bursts are finite; scripts never spawn enemies, grant equipment, deal direct damage, or complete a mission. Per-entity movement clocks and burst state are serializable and use only supplied deterministic RNG. Up to 128 live units receive custom AI, with periodic pruning and a bounded 128-entry death guard. Excess units retain basic engine movement and do not gain extra attacks. The diagnostics counters saturate at one billion. Missions should use much smaller readable waves. + +No new controls are introduced. Fire and weapon selection remain the normal game controls. All prices are inapplicable because the package adds enemies, not purchasable items. + +## Assets and validation + +Both artwork modes, unchanged generated masters, prompts, derivation recipe and all sound recipes are included. See [artwork provenance](ART_PROVENANCE.md), [art checks](art-qa.json), [audio recipe](audio-recipe.json) and [validation record](validation/acceptance.json). Decoded original style references and local review screenshots are deliberately kept outside this package. + +From the RustRaptor folder: + +```sh +cargo test --locked --no-default-features --test stage2_enemies +cargo run --locked --no-default-features -- --data data --mods mods --validate-mods iron_coast_stage2_skimmer +``` + +Tests exercise actual World callbacks, finite volleys and telegraphs, ground/air filtering, damage behavior, escapes, real death rewards and counters, reused entity IDs, bounded state, full save/RNG continuation and independent/combined activation. Shipped PNG geometry and all nine effects are also checked through the real SoundBank/Mixer. Local catalog validation and indexed SD/HD scale 1–4 galleries are recorded separately. These controlled checks do not establish full campaign balance or a live SDL scene; the mission packages have their own route tests. diff --git a/mods/iron_coast_stage2_skimmer/art-qa.json b/mods/iron_coast_stage2_skimmer/art-qa.json new file mode 100644 index 00000000..b5eb6b49 --- /dev/null +++ b/mods/iron_coast_stage2_skimmer/art-qa.json @@ -0,0 +1,105 @@ +{ + "all_occupied_input_alpha_retained_in_crop": true, + "frames": [ + { + "crop_all_alpha_ge_1": [ + 65, + 53, + 1127, + 1138 + ], + "frames": 1, + "hd_alpha128_bounds": [ + 69, + 47, + 195, + 155 + ], + "hd_canvas": [ + 256, + 192 + ], + "hd_sha256": "dc576e5db25f453aa05ab26b3ca24b3b2d574b4db772627f4ac8d567f1525e1b", + "kind": "unit", + "logical_canvas": [ + 32, + 24 + ], + "logical_origin": [ + 0, + 0 + ], + "occupied_fit": [ + 157, + 160 + ], + "offset_hd": [ + 49, + 16 + ], + "raw_dimensions": [ + 1254, + 1254 + ], + "raw_sha256": "a8cb21f2e7edc1d876f37b17415d30d6dd27f02357e668201766644fe9b51b9d", + "sd_alpha128_bounds": [ + 9, + 6, + 25, + 20 + ], + "sd_sha256": "317f3f76bc21ae68ce34e7ce0b15365cbaf8b2641092521e9bf1f041b72bbfbb" + }, + { + "crop_all_alpha_ge_1": [ + 202, + 300, + 1053, + 957 + ], + "frames": 1, + "hd_alpha128_bounds": [ + 23, + 13, + 41, + 50 + ], + "hd_canvas": [ + 64, + 64 + ], + "hd_sha256": "d526e0658e85eaf99a45329903492e483bb0af8b3e0f1ef2de04e910bcfa18b3", + "kind": "projectile", + "logical_canvas": [ + 8, + 8 + ], + "logical_origin": [ + 0, + 0 + ], + "occupied_fit": [ + 48, + 37 + ], + "offset_hd": [ + 8, + 13 + ], + "raw_dimensions": [ + 1254, + 1254 + ], + "raw_sha256": "821512bc8865198fb005f8638448882f4282da040a997915ede17ea0136eb5b1", + "sd_alpha128_bounds": [ + 3, + 2, + 6, + 7 + ], + "sd_sha256": "3c966ec3f8d54a2e5e1468f01f8881681127fa434605b0d9264c937deee44162" + } + ], + "method": "prepare_art.rs: unchanged genuine alpha master, crop only transparent margin, aspect-preserving centered fit, premultiplied-alpha Lanczos3 HD8x and renderer-aligned floor-nearest SD; original images are style references only", + "source_unchanged": true +} \ No newline at end of file diff --git a/mods/iron_coast_stage2_skimmer/art/projectile-generated-v1.png b/mods/iron_coast_stage2_skimmer/art/projectile-generated-v1.png new file mode 100644 index 00000000..c6ef88d9 Binary files /dev/null and b/mods/iron_coast_stage2_skimmer/art/projectile-generated-v1.png differ diff --git a/mods/iron_coast_stage2_skimmer/art/projectile-hd.png b/mods/iron_coast_stage2_skimmer/art/projectile-hd.png new file mode 100644 index 00000000..48dca72c Binary files /dev/null and b/mods/iron_coast_stage2_skimmer/art/projectile-hd.png differ diff --git a/mods/iron_coast_stage2_skimmer/art/projectile-sd.png b/mods/iron_coast_stage2_skimmer/art/projectile-sd.png new file mode 100644 index 00000000..243efbe1 Binary files /dev/null and b/mods/iron_coast_stage2_skimmer/art/projectile-sd.png differ diff --git a/mods/iron_coast_stage2_skimmer/art/unit-generated-v1.png b/mods/iron_coast_stage2_skimmer/art/unit-generated-v1.png new file mode 100644 index 00000000..48d31346 Binary files /dev/null and b/mods/iron_coast_stage2_skimmer/art/unit-generated-v1.png differ diff --git a/mods/iron_coast_stage2_skimmer/art/unit-hd.png b/mods/iron_coast_stage2_skimmer/art/unit-hd.png new file mode 100644 index 00000000..aecbbdfe Binary files /dev/null and b/mods/iron_coast_stage2_skimmer/art/unit-hd.png differ diff --git a/mods/iron_coast_stage2_skimmer/art/unit-sd.png b/mods/iron_coast_stage2_skimmer/art/unit-sd.png new file mode 100644 index 00000000..8a52bbc5 Binary files /dev/null and b/mods/iron_coast_stage2_skimmer/art/unit-sd.png differ diff --git a/mods/iron_coast_stage2_skimmer/audio-recipe.json b/mods/iron_coast_stage2_skimmer/audio-recipe.json new file mode 100644 index 00000000..c2046445 --- /dev/null +++ b/mods/iron_coast_stage2_skimmer/audio-recipe.json @@ -0,0 +1,38 @@ +{ + "generator": "generate_audio.py standard Python seeded chirp/filtered noise; no original recordings", + "files": [ + { + "file": "audio/shot.wav", + "seed": 8300, + "duration_seconds": 0.14, + "samples": 3087, + "format": "mono PCM16 little endian", + "sample_rate": 22050, + "peak": 20316, + "rms": 0.10664457043373429, + "sha256": "24739207f5328b933b3313ae7aeb85b1735f595794be4357f9de1c05f4535840" + }, + { + "file": "audio/warning.wav", + "seed": 8301, + "duration_seconds": 0.19002267573696144, + "samples": 4190, + "format": "mono PCM16 little endian", + "sample_rate": 22050, + "peak": 13107, + "rms": 0.13314642240991556, + "sha256": "76c6c0237ac100aca9eb08b55c1646a295f14dd343d19b714d0e4b81b9ba90a7" + }, + { + "file": "audio/death.wav", + "seed": 8302, + "duration_seconds": 0.56, + "samples": 12348, + "format": "mono PCM16 little endian", + "sample_rate": 22050, + "peak": 24248, + "rms": 0.11432585809234382, + "sha256": "de494506026ee9a5ec56c5fb090cdc9ce34f2d3dad2a114488fd34c886ae6ef5" + } + ] +} diff --git a/mods/iron_coast_stage2_skimmer/audio/death.wav b/mods/iron_coast_stage2_skimmer/audio/death.wav new file mode 100644 index 00000000..8cef12b4 Binary files /dev/null and b/mods/iron_coast_stage2_skimmer/audio/death.wav differ diff --git a/mods/iron_coast_stage2_skimmer/audio/shot.wav b/mods/iron_coast_stage2_skimmer/audio/shot.wav new file mode 100644 index 00000000..719a1a14 Binary files /dev/null and b/mods/iron_coast_stage2_skimmer/audio/shot.wav differ diff --git a/mods/iron_coast_stage2_skimmer/audio/warning.wav b/mods/iron_coast_stage2_skimmer/audio/warning.wav new file mode 100644 index 00000000..5463fdb2 Binary files /dev/null and b/mods/iron_coast_stage2_skimmer/audio/warning.wav differ diff --git a/mods/iron_coast_stage2_skimmer/content.json b/mods/iron_coast_stage2_skimmer/content.json new file mode 100644 index 00000000..4ad01395 --- /dev/null +++ b/mods/iron_coast_stage2_skimmer/content.json @@ -0,0 +1,74 @@ +{ + "weapons": [ + { + "id": "iron_coast_stage2_skimmer:gun", + "name": "Wakeknife firing controller", + "damage": 1, + "speed": 0, + "cooldown": 81, + "behavior": "scripted", + "target": "all", + "script": "scripts/gun.rhai" + }, + { + "id": "iron_coast_stage2_skimmer:projectile", + "name": "Wakeknife shell", + "damage": 2, + "speed": 3, + "cooldown": 81, + "behavior": "straight", + "target": "all", + "art": { + "png": "art/projectile-sd.png", + "hd_png": "art/projectile-hd.png", + "logical_width": 8, + "logical_height": 8, + "frames": 1 + } + } + ], + "enemies": [ + { + "id": "iron_coast_stage2_skimmer:unit", + "name": "Wakeknife", + "health": 26, + "speed": 1, + "reward": 140, + "ground": true, + "boss": false, + "cooldown": 81, + "weapon": "iron_coast_stage2_skimmer:gun", + "art": { + "png": "art/unit-sd.png", + "hd_png": "art/unit-hd.png", + "logical_width": 32, + "logical_height": 24, + "frames": 1 + }, + "script": "scripts/ai.rhai" + } + ], + "sounds": [ + { + "id": "iron_coast_stage2_skimmer:shot", + "name": "Wakeknife shot", + "file": "audio/shot.wav", + "volume": 80, + "priority": 2 + }, + { + "id": "iron_coast_stage2_skimmer:warning", + "name": "Wakeknife warning", + "file": "audio/warning.wav", + "volume": 62, + "priority": 2 + }, + { + "id": "iron_coast_stage2_skimmer:death", + "name": "Wakeknife death", + "file": "audio/death.wav", + "volume": 96, + "priority": 3 + } + ] +} diff --git a/mods/iron_coast_stage2_skimmer/contract.json b/mods/iron_coast_stage2_skimmer/contract.json new file mode 100644 index 00000000..bb2ffa55 --- /dev/null +++ b/mods/iron_coast_stage2_skimmer/contract.json @@ -0,0 +1,20 @@ +{ + "id": "iron_coast_stage2_skimmer", + "name": "Wakeknife", + "logical_size": [ + 32, + 24 + ], + "ground": true, + "health": 26, + "reward": 140, + "gun_cooldown": 81, + "actual_engine_firing_period": 82, + "projectile_damage": 2, + "projectile_speed": 3, + "burst": 2, + "warning_ticks": 6, + "objective": "iron_coast_stage2_skimmer:defeated", + "maximum_live_script_units": 128, + "maximum_retained_death_guards": 128 +} diff --git a/mods/iron_coast_stage2_skimmer/generate_audio.py b/mods/iron_coast_stage2_skimmer/generate_audio.py new file mode 100644 index 00000000..21dd6bd0 --- /dev/null +++ b/mods/iron_coast_stage2_skimmer/generate_audio.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 +"""Reproduce authored mono PCM effects using seeded chirps and filtered noise.""" +from pathlib import Path +import random,math,struct,wave,json,hashlib +root=Path(__file__).resolve().parent +role=root.name.split('_')[-1];index=['interceptor','siege','skimmer'].index(role) +rate=22050;files=[] +for name,duration in [('shot',[.095,.19,.14][index]),('warning',[.12,.26,.19][index]),('death',[.46,.72,.56][index])]: + seed=8100+index*100+['shot','warning','death'].index(name);rng=random.Random(seed);count=round(rate*duration);values=[];phase=0.0;low=0.0 + for i in range(count): + t=i/rate;u=i/max(count-1,1);noise=rng.uniform(-1,1);low=.9*low+.1*noise + if name=='shot': + start=[1600,440,1000][index];end=[460,90,280][index];phase+=2*math.pi*(end+(start-end)*(1-u)**2)/rate + value=[.64,.45,.57][index]*math.sin(phase)+[.10,.34,.18][index]*noise+.14*math.sin(1.93*phase);env=math.exp(-[5.8,6.5,5.3][index]*u) + elif name=='warning': + phase+=2*math.pi*([670,310,540][index]+[390,240,420][index]*u)/rate;value=.7*math.sin(phase)+.1*math.sin(2*phase);env=math.sin(math.pi*u)**1.4*(.65+.35*math.sin(2*math.pi*[13,9,16][index]*t)) + else: + phase+=2*math.pi*([130,85,110][index]*(1-u)+24)/rate;value=.55*low+.27*noise+.24*math.sin(phase);env=math.exp(-[5.5,4.7,5.1][index]*u) + env*=min(1,t/.003)*min(1,(count-1-i)/(rate*.006));values.append(value*max(env,0)) + peak=max(abs(v)for v in values);amp=.4 if name=='warning'else(.62 if name=='shot'else.74);samples=[round(v/peak*amp*32767)for v in values];path=root/'audio'/f'{name}.wav' + with wave.open(str(path),'wb')as out:out.setnchannels(1);out.setsampwidth(2);out.setframerate(rate);out.writeframes(struct.pack('<'+'h'*count,*samples)) + files.append({'file':str(path.relative_to(root)),'seed':seed,'duration_seconds':count/rate,'samples':count,'format':'mono PCM16 little endian','sample_rate':rate,'peak':max(abs(v)for v in samples),'rms':math.sqrt(sum(v*v for v in samples)/count)/32767,'sha256':hashlib.sha256(path.read_bytes()).hexdigest()}) +(root/'audio-recipe.json').write_text(json.dumps({'generator':'generate_audio.py standard Python seeded chirp/filtered noise; no original recordings','files':files},indent=2)+'\n') +print(root.name,'3 valid PCM WAV cues reproduced') diff --git a/mods/iron_coast_stage2_skimmer/mod.toml b/mods/iron_coast_stage2_skimmer/mod.toml new file mode 100644 index 00000000..af6e6111 --- /dev/null +++ b/mods/iron_coast_stage2_skimmer/mod.toml @@ -0,0 +1,7 @@ +id = "iron_coast_stage2_skimmer" +name = "Iron Coast II: Wakeknife" +version = "1.0.0" +api_version = 1 +description = "Independent Stage 2 skimmer: Wakeknife. Scripted movement, readable volleys, SD/HD sprites and synthesized sounds." +content = "content.json" +scripts = ["scripts/ai.rhai", "scripts/gun.rhai"] diff --git a/mods/iron_coast_stage2_skimmer/prepare_art.rs b/mods/iron_coast_stage2_skimmer/prepare_art.rs new file mode 100644 index 00000000..e68cc49c --- /dev/null +++ b/mods/iron_coast_stage2_skimmer/prepare_art.rs @@ -0,0 +1,127 @@ +//! Derive aligned SD/HD canvases from unchanged built-in generated PNG masters. +//! The PNG master is never modified. Only wholly transparent margins are trimmed; +//! every occupied input alpha pixel remains inside the recorded source crop. +use image::{ + imageops::{self, FilterType}, + Rgba, RgbaImage, +}; +use serde_json::json; +use sha2::{Digest, Sha256}; +use std::{fs, path::Path}; +fn sha(p: &Path) -> String { + format!("{:x}", Sha256::digest(fs::read(p).unwrap())) +} +fn bounds(im: &RgbaImage, threshold: u8) -> (u32, u32, u32, u32) { + let (mut x0, mut y0, mut x1, mut y1) = (im.width(), im.height(), 0, 0); + for (x, y, p) in im.enumerate_pixels() { + if p[3] >= threshold { + x0 = x0.min(x); + y0 = y0.min(y); + x1 = x1.max(x + 1); + y1 = y1.max(y + 1); + } + } + assert!(x1 > x0 && y1 > y0, "empty sprite"); + (x0, y0, x1, y1) +} +fn filtered(im: &RgbaImage, w: u32, h: u32, filter: FilterType) -> RgbaImage { + // Resample premultiplied alpha to keep opaque dark interior recesses while + // preventing invisible RGB from becoming a dark fringe at the sprite edge. + let mut premul = im.clone(); + for p in premul.pixels_mut() { + for c in 0..3 { + p[c] = ((p[c] as u32 * p[3] as u32 + 127) / 255) as u8; + } + } + let mut out = imageops::resize(&premul, w, h, filter); + for p in out.pixels_mut() { + if p[3] == 0 { + *p = Rgba([0, 0, 0, 0]); + } else { + for c in 0..3 { + p[c] = ((p[c] as u32 * 255 + p[3] as u32 / 2) / p[3] as u32).min(255) as u8; + } + } + } + out +} +fn main() { + let arg = std::env::args().nth(1).expect("pass the mod directory"); + let root = Path::new(&arg); + let contract: serde_json::Value = + serde_json::from_slice(&fs::read(root.join("contract.json")).unwrap()).unwrap(); + let mut reports = Vec::new(); + for kind in ["unit", "projectile"] { + let (lw, lh) = if kind == "unit" { + ( + contract["logical_size"][0].as_u64().unwrap() as u32, + contract["logical_size"][1].as_u64().unwrap() as u32, + ) + } else { + (8, 8) + }; + let source_path = root.join(format!("art/{kind}-generated-v1.png")); + let original_sha = sha(&source_path); + let raw = image::open(&source_path).unwrap().into_rgba8(); + assert!( + raw.pixels().any(|p| p[3] == 0), + "generated source needs genuine transparent background" + ); + assert!( + raw.pixels().any(|p| p[3] == 255), + "generated source needs occupied opaque artwork" + ); + let (x0, y0, x1, y1) = bounds(&raw, 1); + let occupied = imageops::crop_imm(&raw, x0, y0, x1 - x0, y1 - y0).to_image(); + let scale = 8; + let pad = if kind == "unit" { 2 } else { 1 }; + let (limit_w, limit_h) = ((lw - pad * 2) * scale, (lh - pad * 2) * scale); + let (ow, oh) = occupied.dimensions(); + let (w, h) = if limit_w as u64 * oh as u64 <= limit_h as u64 * ow as u64 { + ( + limit_w, + ((oh as u64 * limit_w as u64 + ow as u64 / 2) / ow as u64) as u32, + ) + } else { + ( + ((ow as u64 * limit_h as u64 + oh as u64 / 2) / oh as u64) as u32, + limit_h, + ) + }; + let fitted = filtered(&occupied, w, h, FilterType::Lanczos3); + let mut hd = RgbaImage::new(lw * scale, lh * scale); + let offset = ((hd.width() - w) / 2, (hd.height() - h) / 2); + imageops::overlay(&mut hd, &fitted, offset.0 as i64, offset.1 as i64); + // Match the renderer's indexed HD-to-logical sample positions exactly. + // This retains the bright projectile core and aligns both modes at 1x. + let mut sd = RgbaImage::new(lw, lh); + for y in 0..lh { + for x in 0..lw { + sd.put_pixel(x, y, *hd.get_pixel(x * scale, y * scale)); + } + } + let sdb = bounds(&sd, 128); + let hdb = bounds(&hd, 128); + assert!( + sdb.0 >= 1 && sdb.1 >= 1 && sdb.2 < lw && sdb.3 < lh, + "SD clipped {kind}" + ); + assert!( + hdb.0 >= 1 && hdb.1 >= 1 && hdb.2 < hd.width() && hdb.3 < hd.height(), + "HD clipped {kind}" + ); + let sdpath = root.join(format!("art/{kind}-sd.png")); + let hdpath = root.join(format!("art/{kind}-hd.png")); + sd.save(&sdpath).unwrap(); + hd.save(&hdpath).unwrap(); + assert_eq!(sha(&source_path), original_sha); + reports.push(json!({"kind":kind,"raw_sha256":original_sha,"raw_dimensions":[raw.width(),raw.height()],"crop_all_alpha_ge_1":[x0,y0,x1,y1],"logical_canvas":[lw,lh],"hd_canvas":[hd.width(),hd.height()],"occupied_fit":[w,h],"offset_hd":[offset.0,offset.1],"sd_alpha128_bounds":[sdb.0,sdb.1,sdb.2,sdb.3],"hd_alpha128_bounds":[hdb.0,hdb.1,hdb.2,hdb.3],"logical_origin":[0,0],"frames":1,"sd_sha256":sha(&sdpath),"hd_sha256":sha(&hdpath)})); + } + let report = json!({"method":"prepare_art.rs: unchanged genuine alpha master, crop only transparent margin, aspect-preserving centered fit, premultiplied-alpha Lanczos3 HD8x and renderer-aligned floor-nearest SD; original images are style references only","source_unchanged":true,"all_occupied_input_alpha_retained_in_crop":true,"frames":reports}); + fs::write( + root.join("art-qa.json"), + serde_json::to_vec_pretty(&report).unwrap(), + ) + .unwrap(); + println!("Prepared aligned SD/HD art: {}", root.display()); +} diff --git a/mods/iron_coast_stage2_skimmer/prompts/projectile-v1.txt b/mods/iron_coast_stage2_skimmer/prompts/projectile-v1.txt new file mode 100644 index 00000000..5ab0f308 --- /dev/null +++ b/mods/iron_coast_stage2_skimmer/prompts/projectile-v1.txt @@ -0,0 +1,5 @@ +Use case: stylized-concept +Asset type: one transparent original-palette Raptor-style hostile projectile sprite. +Input image1: authentic original8x8 Raptor bullet, palette/readability reference only. +Subject: one compact teal-white wake-themed plasma dart pointing DOWN, a narrow white-hot core inside a restrained muted cyan crescent-edged capsule; clean readable silhouette, no sprawling glow. A new projectile for Wakeknife, readable in an8x8logical game canvas. +Style: crisp overhead arcade game sprite detail, warm/muted metal accents matching classic Raptor, isolated single projectile. One centered frame on real transparent square canvas with at least15% transparent safe margins. Whole visible. DOWN orientation. Opaque dark interior; genuine alpha outside. No background, labels, smoke, muzzle explosion, fireworks, trail beyond sprite, giant bloom, contact sheet or extra projectiles. diff --git a/mods/iron_coast_stage2_skimmer/prompts/unit-v1.txt b/mods/iron_coast_stage2_skimmer/prompts/unit-v1.txt new file mode 100644 index 00000000..f88e4dbe --- /dev/null +++ b/mods/iron_coast_stage2_skimmer/prompts/unit-v1.txt @@ -0,0 +1,6 @@ +Use case: stylized-concept +Asset type: one transparent top-down sprite for the new Raptor-style enemy mod Wakeknife. +Input image1: authentic original Raptor sprite, STYLE AND CAMERA REFERENCE ONLY; create the requested new enemy, not a duplicate. +Subject: A squat low naval hovercraft facing DOWN, two angular gunmetal flotation side pods and a pointed central pale steel bow. Narrow muted teal deck stripe, copper ports and a dark skirt, with a wide low boat silhouette at32x24. Wake-theme side channels integrated into hull, no painted wake outside hull, no water, floating debris, smoke or glow. +Style: faithful classic Raptor military arcade shooter remastered into crisp richly hand-painted HD sprite detail: small bevels, muted original palette, clear original-scale silhouette, upper-left metallic lighting, strictly orthographic overhead. +Canvas: one fully isolated sprite on REAL alpha-transparent background, centered with at least10% completely transparent safe space on every side; no text, watermark, backdrop, contact sheet or other sprites. Whole object visible. Logical canvas 32x24, source orientation down-screen. Native occupied black/dark recesses remain opaque; only space outside object transparent. One frame only. Aim for a square source canvas; do not imply extra content or effects outside the craft. Clean silhouette and clean alpha. Avoid photographic camera perspective, oblique views, neon saturation, large glows, generic modern vector icon style. diff --git a/mods/iron_coast_stage2_skimmer/provenance-projectile-v1.json b/mods/iron_coast_stage2_skimmer/provenance-projectile-v1.json new file mode 100644 index 00000000..5004060c --- /dev/null +++ b/mods/iron_coast_stage2_skimmer/provenance-projectile-v1.json @@ -0,0 +1,15 @@ +{ + "output_hint": "Generated images are saved to /home/quintine/.codex/generated_images/01a129a5-9f83-7611-a949-ec6a80b026d4 as /home/quintine/.codex/generated_images/01a129a5-9f83-7611-a949-ec6a80b026d4/exec-30de6b07-e100-4f0c-879f-85da4b11ee30.png by default.\nIf you need to use a generated image at another path, copy it and leave the original in place unless the user explicitly asks you to delete it.\nThe generated image is already displayed to the user. There is no need to render it in the final response as a Markdown image or file link.", + "lease": "46c9d118-6f84-4d1d-91d7-d9e91f677e74", + "job": "stage2-wakeknife-projectile-v1", + "builtin_path": "/home/quintine/.codex/generated_images/01a129a5-9f83-7611-a949-ec6a80b026d4/exec-30de6b07-e100-4f0c-879f-85da4b11ee30.png", + "raw_sha256": "821512bc8865198fb005f8638448882f4282da040a997915ede17ea0136eb5b1", + "mode": "built-in imagegen", + "raw_unchanged": true, + "prompt": "prompts/projectile-v1.txt", + "original_style_reference_asset": "101d6", + "original_reference_copies_shipped": false, + "external_style_reference_png_sha256": "090d5cd708457f92c04253328ac47413f2cc53b6f83546df92c816d3debbcbcc", + "original_style_reference_payload_sha256": "73dfa9a1f1313b1b9bbd71c3f3e2086ffb0440d5a298d98cbb4de407a9faaf2b", + "original_palette_payload_sha256": "1cf6adb926d1dee1888b3e3d33b51a7049b3e5eb5f90a3067ef71c8970547204" +} diff --git a/mods/iron_coast_stage2_skimmer/provenance-unit-v1.json b/mods/iron_coast_stage2_skimmer/provenance-unit-v1.json new file mode 100644 index 00000000..aa8c5f82 --- /dev/null +++ b/mods/iron_coast_stage2_skimmer/provenance-unit-v1.json @@ -0,0 +1,15 @@ +{ + "output_hint": "Generated images are saved to /home/quintine/.codex/generated_images/01a129a5-9f83-7611-a949-ec6a80b026d4 as /home/quintine/.codex/generated_images/01a129a5-9f83-7611-a949-ec6a80b026d4/exec-f49611a8-d556-47ab-a1ee-979567826e8c.png by default.\nIf you need to use a generated image at another path, copy it and leave the original in place unless the user explicitly asks you to delete it.\nThe generated image is already displayed to the user. There is no need to render it in the final response as a Markdown image or file link.", + "lease": "dc268c50-02b4-405b-af5c-e7ebe5894386", + "job": "stage2-wakeknife-unit-v1", + "builtin_path": "/home/quintine/.codex/generated_images/01a129a5-9f83-7611-a949-ec6a80b026d4/exec-f49611a8-d556-47ab-a1ee-979567826e8c.png", + "raw_sha256": "a8cb21f2e7edc1d876f37b17415d30d6dd27f02357e668201766644fe9b51b9d", + "mode": "built-in imagegen", + "raw_unchanged": true, + "prompt": "prompts/unit-v1.txt", + "original_style_reference_asset": "10334", + "original_reference_copies_shipped": false, + "external_style_reference_png_sha256": "81d2769507112e1d370aafac149b690cfc0f90094408044fd6409db816a70f75", + "original_style_reference_payload_sha256": "4c1a0672ab5ce3e26f8382f97bb0bb7a8cc7c8e727ac43cf4a3467f361433bc4", + "original_palette_payload_sha256": "1cf6adb926d1dee1888b3e3d33b51a7049b3e5eb5f90a3067ef71c8970547204" +} diff --git a/mods/iron_coast_stage2_skimmer/scripts/ai.rhai b/mods/iron_coast_stage2_skimmer/scripts/ai.rhai new file mode 100644 index 00000000..556f59a4 --- /dev/null +++ b/mods/iron_coast_stage2_skimmer/scripts/ai.rhai @@ -0,0 +1,125 @@ +// Integer-only per-entity clocks. No spawns, equipment grants or direct damage. +// The engine owns collision, one kill reward, projectile retirement and explosions. +fn alive(event) { + for unit in event.entities { + if unit.entity == event.entity && unit.health > 0 { return true; } + } + false +} +// Firing events use muzzle coordinates; visibility must use the real canvas. +fn ready_to_fire(event) { + for unit in event.entities { + if unit.entity == event.entity { + return unit.health > 0 && unit.x >= 0 && unit.x + unit.width <= 320 && unit.y >= 0 && unit.y + unit.height <= 180 && unit.y + unit.height < event.player.y - 8; + } + } + false +} +fn fresh(random) { #{clock:0, sign: if random[0] % 2 == 0 {1} else {-1}, remaining:0, wait:0, aim_x:0, aim_y:3} } +fn ready(state) { + if !state.contains("units") { state.units = #{}; } + if !state.contains("dead") { state.dead = #{}; } + if !state.contains("dead_order") { state.dead_order = []; } + state +} +fn tidy(event, state) { + state = ready(state); + let retained = #{}; + for unit in event.entities { + let key = unit.entity.to_string(); + if unit.definition == "iron_coast_stage2_skimmer:unit" && unit.health > 0 && state.units.contains(key) && retained.len() < 128 { + retained[key] = state.units[key]; + } + } + state.units = retained; + state +} +fn counter(state, key) { + if !state.contains(key) {return 1;} + if state[key] >= 1000000000 {return 1000000000;} + state[key] + 1 +} +fn clamp_speed(value) { if value < -3 {-3} else if value > 3 {3} else {value} } +fn aimed(event) { + let dx = event.player.x + 16 - event.x; + let dy = event.player.y + 16 - event.y; + let ax = if dx < 0 {-dx} else {dx}; + let ay = if dy < 0 {-dy} else {dy}; + let norm = if ax > ay {ax} else {ay}; + if norm == 0 {return [0,3];} + let vy = dy * 3 / norm; + [clamp_speed(dx * 3 / norm), if vy < 1 {1} else {vy}] +} +fn on_spawn(event, state, random) { + state = tidy(event,state); + let key = event.entity.to_string(); + // Entity IDs restart with each mission. Clear the old lifecycle guard even + // when a spawn was already killed before queued callbacks are dispatched. + state.dead.remove(key); + let keep = []; + for old in state.dead_order { if old != key {keep.push(old);} } + state.dead_order = keep; + if !alive(event) {return #{commands:[],state:state};} + if state.units.len() >= 128 {return #{commands:[],state:state};} + let unit = fresh(random); + state.units[key] = unit; + #{commands:[#{op:"velocity",entity:event.entity,vx:unit.sign,vy:1}],state:state} +} +fn on_fire(event, state, random) { + state = ready(state); + if !ready_to_fire(event) || event.x < 0 || event.x >= 320 || event.y < 24 || event.y > 180 || event.y >= event.player.y - 8 { + return #{commands:[],state:state}; + } + let key = event.entity.to_string(); + if !state.units.contains(key) {return #{commands:[],state:state};} + let unit = state.units[key]; + let aim = aimed(event); + unit.remaining = 2; unit.wait = 6; + unit.aim_x = aim[0]; unit.aim_y = aim[1]; + state.units[key] = unit; + #{commands:[#{op:"play_sound",sound:"iron_coast_stage2_skimmer:warning"}],state:state} +} +fn on_tick(event, state, random) { + state = ready(state); + // Stagger periodic pruning to keep dense waves within the shared script budget. + if (event.tick + event.entity) % 32 == 0 { state = tidy(event,state); } + if event.health <= 0 || !alive(event) {return #{commands:[],state:state};} + let key = event.entity.to_string(); + if !state.units.contains(key) {return #{commands:[],state:state};} + let unit = state.units[key]; + unit.clock = (unit.clock + 1) % 96; + let phase = (unit.clock / 18) % 4; + let weave = [1,0,-1,0]; + let sideways = weave[phase] * unit.sign; + let down = 1; + if event.x <= 8 {sideways = 1;} + if event.x >= 320 - 32 - 8 {sideways = -1;} + let commands = [#{op:"velocity",entity:event.entity,vx:sideways,vy:down}]; + // Never fire from an invisible/dead unit, or backwards at a player it passed. + if event.x < 0 || event.x + 32 > 320 || event.y < 0 || event.y + 24 > 180 || event.y + 24 >= event.player.y - 8 { + unit.remaining = 0; + } + if unit.wait > 0 {unit.wait -= 1;} + if unit.remaining > 0 && unit.wait == 0 { + for side in [-1,1] {commands.push(#{op:"projectile",weapon:"iron_coast_stage2_skimmer:projectile",x:event.x+12+side*6,y:event.y+22,vx:clamp_speed(unit.aim_x+side),vy:unit.aim_y,hostile:true});} + unit.remaining=0; + commands.push(#{op:"play_sound",sound:"iron_coast_stage2_skimmer:shot"}); + state.shots = counter(state,"shots"); + } + state.units[key] = unit; + #{commands:commands,state:state} +} +fn on_hit(event, state, random) { + state.hits = counter(state,"hits"); + #{commands:[],state:state} +} +fn on_death(event, state, random) { + state = tidy(event,state); + let key = event.entity.to_string(); + if alive(event) || state.dead.contains(key) {return #{commands:[],state:state};} + if state.dead_order.len() >= 128 {let oldest=state.dead_order.remove(0);state.dead.remove(oldest);} + state.dead[key] = true; state.dead_order.push(key); state.units.remove(key); + state.destroyed = counter(state,"destroyed"); + let defeated = if event.objectives.contains("iron_coast_stage2_skimmer:defeated") {event.objectives["iron_coast_stage2_skimmer:defeated"] + 1} else {1}; + #{commands:[#{op:"objective",key:"iron_coast_stage2_skimmer:defeated",value:defeated},#{op:"play_sound",sound:"iron_coast_stage2_skimmer:death"}],state:state} +} diff --git a/mods/iron_coast_stage2_skimmer/scripts/gun.rhai b/mods/iron_coast_stage2_skimmer/scripts/gun.rhai new file mode 100644 index 00000000..a5f05834 --- /dev/null +++ b/mods/iron_coast_stage2_skimmer/scripts/gun.rhai @@ -0,0 +1,3 @@ +// The engine supplies the firing cooldown. This wrapper deliberately emits +// no default projectile: the enemy AI schedules its own bounded burst. +fn on_fire(event, state, random) { #{commands: [], state: state} } diff --git a/mods/iron_coast_stage2_skimmer/validation/acceptance.json b/mods/iron_coast_stage2_skimmer/validation/acceptance.json new file mode 100644 index 00000000..58378ce3 --- /dev/null +++ b/mods/iron_coast_stage2_skimmer/validation/acceptance.json @@ -0,0 +1,49 @@ +{ + "api_version": 1, + "owned_package": "iron_coast_stage2_skimmer", + "portable_actual_world_tests": { + "command": "cargo test --locked --no-default-features --test stage2_enemies -- --nocapture", + "passed": 9, + "failed": 0, + "test_log_sha256": "1ceb868b5dcb07efd054f529a5356069c1837dd45f27f536886124782256d862", + "coverage": [ + "independent and Stage1 coexistence activation", + "exact engine cooldown/finite burst/warning ticks", + "distinct bounded movement and escape without reward", + "actual ground/air collision filtering and damaged crawler shell loss", + "actual death rewards/objectives once and reused IDs after queued early kills", + "full serialized World plus Rhai state and RNG deterministic continuation", + "260 deaths per package with bounded128 history/live state", + "shipped PNG dimensions/padding/unchanged source SHA and all9SoundBank/Mixer nonzero unclipped effects", + "no invisible/passed-unit warning/projectile from muzzle-coordinate event" + ] + }, + "shipped_assets": { + "SD_HD_PNGs": 4, + "unchanged_generated_masters": 2, + "WAV_effects": 3, + "alpha_and_alignment": "checked; equal logical canvas/aspect;one frame;origin0,0;opaque content leaves padding" + }, + "local_visual_review": { + "actual_palette_outputs": 16, + "modes": [ + "SD", + "HD" + ], + "scales": [ + 1, + 2, + 3, + 4 + ], + "reserved_animated_palette_indices": 0, + "scope": "Actual art_sprite_variant plus identical desktop scaling branch, full diagnostic gallery visually inspected; not a live SDL Host scene. Fine HD details simplify in SD. Full raw masters inspected earlier; unedited generator bytes and exact hashes retained." + }, + "real_catalog_validation": "Included assets and scripts passed real-catalog activation; final whole-folder pins and CLI reruns are recorded outside package in .reference/stage2-enemies/final-handoff.json to avoid recursive content hashes.", + "limits": [ + "No whole-campaign balance or live SDL scene claim by this package owner; mission owners and independent reviewer validate integration.", + "Ordinary targets may escape; required mission targets must be held by mission logic.", + "Custom AI state is capped128 per package; dense enemy spawning remains a mission-author balance responsibility.", + "No platform source or launcher changes." + ] +} diff --git a/src/desktop.rs b/src/desktop.rs index ff8cf6fb..b5ed20c8 100644 --- a/src/desktop.rs +++ b/src/desktop.rs @@ -8018,7 +8018,43 @@ mod tests { capture(&mut host, &format!("{namespace}-details")); } host.go(Screen::Missions); - capture(&mut host, "mission-selection"); + for (n, name) in [(1, "nightbreak"), (8, "black-tide")] { + let id: ContentId = format!("iron_coast_stage2_mission_{n}:mission_{n:02}") + .as_str() + .into(); + host.selected = host + .missions() + .iter() + .position(|candidate| candidate == &id) + .unwrap(); + capture(&mut host, &format!("mission-selection-{name}")); + } + host.pending = enabled.clone(); + host.go(Screen::Mods); + let ordered_rows = host.mod_ids(); + host.selected = ordered_rows + .iter() + .position(|id| id == "iron_coast_stage2_campaign") + .unwrap() + + 2; + let campaign_row = host.selected; + capture(&mut host, "stage2-mod-manager"); + host.open_diagnostics(); + capture(&mut host, "stage2-dependency-details"); + host.back().unwrap(); + assert!(host.screen == Screen::Mods); + assert_eq!(host.selected, campaign_row); + host.activate().unwrap(); + assert!(host.screen == Screen::ConfirmDisable); + assert_eq!(host.selected, 1, "Cancel must be the default choice"); + assert_eq!(host.pending_disable.as_ref().unwrap().removed.len(), 23); + capture(&mut host, "stage2-disable-confirmation-first"); + host.selected = host.rows().len() - 1; + capture(&mut host, "stage2-disable-confirmation-last"); + host.back().unwrap(); + assert!(host.screen == Screen::Mods); + assert_eq!(host.pending, enabled); + assert_eq!(host.mod_ids(), ordered_rows); assert!(!host.paths.data.exists()); println!("Stage2 artwork preview captures: {}", output.display()); } diff --git a/tests/iron_coast_stage2.rs b/tests/iron_coast_stage2.rs new file mode 100644 index 00000000..8d2fe1d0 --- /dev/null +++ b/tests/iron_coast_stage2.rs @@ -0,0 +1,540 @@ +//! Portable assembly/progression checks use synthetic resources; the ignored +//! playable route requires the original game catalog. +use raptor_replica::{ + assets::Catalog, + content::{ContentPack, Registry}, + mod_selection, + modding::{self, ActiveMods, Manifest}, + persistence::Pilot, + simulation::{Input, Outcome, World}, +}; +use serde_json::{Value, json}; +use std::{ + collections::BTreeSet, + fs, + path::{Path, PathBuf}, + sync::OnceLock, +}; + +const CAMPAIGN: &str = "iron_coast_stage2_campaign"; +const MISSIONS: [&str; 8] = [ + "iron_coast_stage2_mission_1:mission_01", + "iron_coast_stage2_mission_2:mission_02", + "iron_coast_stage2_mission_3:mission_03", + "iron_coast_stage2_mission_4:mission_04", + "iron_coast_stage2_mission_5:mission_05", + "iron_coast_stage2_mission_6:mission_06", + "iron_coast_stage2_mission_7:mission_07", + "iron_coast_stage2_mission_8:mission_08", +]; + +fn fixture_resources(value: &Value, root: &Path, original: &Path) { + match value { + Value::Object(object) => { + if let (Some(width), Some(height)) = ( + object.get("logical_width").and_then(Value::as_u64), + object.get("logical_height").and_then(Value::as_u64), + ) { + let frames = object.get("frames").and_then(Value::as_u64).unwrap_or(1); + // Use the minimum valid HD resolution in portable tests. Actual + // generated 4x artwork is validated separately by the CLI. + for (key, scale) in [("png", 1), ("hd_png", 2)] { + if let Some(file) = object.get(key).and_then(Value::as_str) { + let path = root.join(file); + fs::create_dir_all(path.parent().unwrap()).unwrap(); + image::RgbaImage::from_pixel( + (width * frames * scale) as u32, + (height * scale) as u32, + image::Rgba([80, 96, 104, 255]), + ) + .save(path) + .unwrap(); + } + } + } + if let Some(file) = object.get("file").and_then(Value::as_str) { + let path = root.join(file); + fs::create_dir_all(path.parent().unwrap()).unwrap(); + if Path::new(file) + .extension() + .is_some_and(|extension| extension.eq_ignore_ascii_case("mus")) + { + // The new soundtrack is original mod content, independent + // of the game catalog, so its bounded score can be tested. + fs::copy(original.join(file), path).unwrap(); + } else { + let mut wav = Vec::new(); + wav.extend_from_slice(b"RIFF"); + wav.extend_from_slice(&100_u32.to_le_bytes()); + wav.extend_from_slice(b"WAVEfmt "); + wav.extend_from_slice(&16_u32.to_le_bytes()); + wav.extend_from_slice(&1_u16.to_le_bytes()); + wav.extend_from_slice(&1_u16.to_le_bytes()); + wav.extend_from_slice(&22050_u32.to_le_bytes()); + wav.extend_from_slice(&44100_u32.to_le_bytes()); + wav.extend_from_slice(&2_u16.to_le_bytes()); + wav.extend_from_slice(&16_u16.to_le_bytes()); + wav.extend_from_slice(b"data"); + wav.extend_from_slice(&64_u32.to_le_bytes()); + wav.extend_from_slice(&[0; 64]); + fs::write(path, wav).unwrap(); + } + } + for child in object.values() { + fixture_resources(child, root, original); + } + } + Value::Array(values) => { + for child in values { + fixture_resources(child, root, original); + } + } + _ => {} + } +} + +fn fixture_directory() -> &'static Path { + static FIXTURE: OnceLock = OnceLock::new(); + FIXTURE + .get_or_init(|| { + let temporary = tempfile::tempdir().unwrap(); + let source = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("mods"); + let mut visited = BTreeSet::new(); + let mut packages = vec![CAMPAIGN.to_string()]; + while let Some(id) = packages.pop() { + if !visited.insert(id.clone()) { + continue; + } + let original = source.join(&id); + let root = temporary.path().join(&id); + fs::create_dir_all(&root).unwrap(); + let manifest_data = fs::read(original.join("mod.toml")).unwrap(); + let manifest: Manifest = + toml::from_str(std::str::from_utf8(&manifest_data).unwrap()).unwrap(); + packages.extend(manifest.dependencies.keys().cloned()); + fs::write(root.join("mod.toml"), manifest_data).unwrap(); + let content = fs::read(original.join(&manifest.content)).unwrap(); + let value: Value = serde_json::from_slice(&content).unwrap(); + fs::write(root.join(&manifest.content), content).unwrap(); + for script in manifest.scripts { + let path = root.join(&script); + fs::create_dir_all(path.parent().unwrap()).unwrap(); + fs::copy(original.join(script), path).unwrap(); + } + fixture_resources(&value, &root, &original); + } + temporary + }) + .path() +} + +fn base() -> Registry { + let mut registry = Registry::default(); + let mut value = json!({ + "weapons":[{"id":"base:projectile_forward_guns","name":"Forward Guns","damage":1,"speed":8,"cooldown":2,"behavior":"straight","target":"all","legacy":0,"art":{"asset":42,"logical_width":4,"logical_height":8,"frames":4}}], + "items":[ + {"id":"base:forward_guns","name":"Forward Guns","price":0,"max_count":1,"weapon":"base:projectile_forward_guns","legacy":0}, + {"id":"base:energy","name":"Shield","price":10000,"initial_count":25,"max_count":100,"legacy":16}, + {"id":"base:super_shield","name":"Super Shield","price":78500,"initial_count":100,"max_count":100,"legacy":15} + ], + "missions":[{"id":"base:sector_1_wave_1","name":"Base fixture","duration":1000}] + }); + for n in 0..18 { + value["items"].as_array_mut().unwrap().push(json!({"id":format!("base:fixture_item_{n}"),"name":"Synthetic equipment","price":0,"max_count":1})); + } + let pack: ContentPack = serde_json::from_value(value).unwrap(); + registry.apply(pack, "base").unwrap(); + registry.validate().unwrap(); + registry +} + +fn discovery() -> modding::Discovery { + let discovery = modding::discover(fixture_directory()); + assert!(discovery.errors.is_empty(), "{:?}", discovery.errors); + discovery +} + +/// Native IDs are present only to validate the portable dependency graph and +/// first-step inventory grants. These placeholders supply no native behavior. +/// The playable campaign test below uses the original catalog, not this base. +fn structural_base(discovery: &modding::Discovery) -> Registry { + let mut registry = base(); + let mut native = BTreeSet::new(); + for package in discovery.mods.values() { + let pack: ContentPack = serde_json::from_slice( + &fs::read(package.root.join(&package.manifest.content)).unwrap(), + ) + .unwrap(); + for mission in pack.missions { + for spawn in mission.spawns { + if spawn.enemy.0.starts_with("base:enemy_") { + native.insert(spawn.enemy); + } + } + } + } + let enemies = native + .into_iter() + .map(|id| { + json!({ + "id":id, + "name":"Structural native-ID placeholder; no gameplay acceptance", + "health":1, + "speed":0 + }) + }) + .collect::>(); + registry + .apply( + serde_json::from_value(json!({"enemies":enemies})).unwrap(), + "base", + ) + .unwrap(); + registry.validate().unwrap(); + registry +} + +fn active() -> ActiveMods { + let discovery = discovery(); + let enabled = mod_selection::plan_enable(&discovery, &[], CAMPAIGN).unwrap(); + ActiveMods::build(&structural_base(&discovery), &discovery, &enabled, None).unwrap() +} + +fn active_original() -> ActiveMods { + let data = std::env::var_os("RAPTOR_TEST_DATA") + .map(PathBuf::from) + .unwrap_or_else(|| PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("data")); + let catalog = Catalog::open(data).unwrap(); + let registry = Registry::base(&catalog).unwrap(); + let discovery = modding::discover(&PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("mods")); + assert!(discovery.errors.is_empty(), "{:?}", discovery.errors); + let enabled = mod_selection::plan_enable(&discovery, &[], CAMPAIGN).unwrap(); + ActiveMods::build(®istry, &discovery, &enabled, Some(&catalog)).unwrap() +} + +#[test] +fn stage2_selects_complete_dependencies_and_prunes_unused_packages() { + let discovery = discovery(); + let enabled = mod_selection::plan_enable(&discovery, &[], CAMPAIGN).unwrap(); + assert_eq!(enabled.len(), 23); + let positions = enabled + .iter() + .enumerate() + .map(|(n, id)| (id.clone(), n)) + .collect::>(); + for id in &enabled { + for dependency in discovery.mods[id].manifest.dependencies.keys() { + assert!( + positions[dependency] < positions[id], + "{dependency} must precede {id}" + ); + } + } + let active = active(); + let campaign = &active.registry.campaigns[&"iron_coast_stage2_campaign:campaign".into()]; + assert_eq!( + campaign + .missions + .iter() + .map(|id| id.0.as_str()) + .collect::>(), + MISSIONS + ); + assert!(active.registry.overrides.is_empty()); + let disabled = mod_selection::plan_disable(&discovery, &enabled, CAMPAIGN); + assert!(disabled.enabled.is_empty()); + for n in 1..=8 { + let mission = format!("iron_coast_stage2_mission_{n}"); + let standalone = mod_selection::plan_enable(&discovery, &[], &mission).unwrap(); + assert!( + standalone + .iter() + .all(|id| !id.starts_with("iron_coast_stage2_mission_") || id == &mission) + ); + assert!(!standalone.contains(&CAMPAIGN.into())); + assert!(!standalone.contains(&"iron_coast_railburst".into())); + assert!(!standalone.contains(&"iron_coast_depth_charge".into())); + ActiveMods::build(&structural_base(&discovery), &discovery, &standalone, None).unwrap(); + } +} + +#[test] +fn eight_distinct_objective_missions_have_native_waves_and_own_bosses() { + let active = active(); + let mut names = BTreeSet::new(); + for (n, id) in MISSIONS.iter().enumerate() { + let mission = &active.registry.missions[&(*id).into()]; + assert!(names.insert(&mission.name)); + assert!(!mission.auto_complete); + assert!(mission.script.is_some()); + assert!( + mission.layout.len() / mission.columns as usize * 32 + >= mission.duration as usize + 2000, + "{id} runs out of terrain during a delayed objective fight" + ); + assert!( + mission + .spawns + .iter() + .any(|spawn| spawn.enemy.0.starts_with("base:enemy_")) + ); + let bosses = mission + .spawns + .iter() + .filter(|spawn| active.registry.enemies[&spawn.enemy].boss) + .collect::>(); + assert!(!bosses.is_empty()); + let boss = format!("iron_coast_stage2_boss_{}:unit", n + 1); + assert!(bosses.iter().all(|spawn| spawn.enemy.0 == boss)); + assert!(bosses.iter().all(|spawn| spawn.tick < mission.duration)); + assert!( + bosses.iter().all(|spawn| spawn.difficulty == 0), + "{id} omits its required boss on easy difficulties" + ); + assert!( + mission + .music_track + .as_ref() + .unwrap() + .0 + .starts_with("iron_coast_stage2_music:") + ); + } +} + +#[test] +fn progression_pins_state_and_optional_equipment_round_trip_without_overrides() { + let active = active(); + let temporary = tempfile::tempdir().unwrap(); + let path = temporary.path().join("stage2-pilot.json"); + let mut pilot = Pilot::default(); + pilot.mission = MISSIONS[0].into(); + pilot.mods = active.pins.clone(); + pilot + .inventory + .insert("iron_coast_railburst:equipment".into(), 1); + pilot.script_state.insert( + "iron_coast_stage2_interceptor/scripts/ai.rhai".into(), + json!({"shots":17}), + ); + pilot.script_rng.insert( + "iron_coast_stage2_interceptor/scripts/ai.rhai".into(), + raptor_replica::simulation::LegacyRng::new(12345), + ); + for (n, id) in MISSIONS.iter().enumerate() { + assert_eq!(pilot.mission.0, *id); + pilot.complete_mission(&active.registry).unwrap(); + assert_eq!(pilot.completed.len(), n + 1); + assert_eq!(pilot.mission.0, MISSIONS[(n + 1).min(7)]); + pilot.save(&path).unwrap(); + let recovered = Pilot::load(&path, &active.registry, &active.pins).unwrap(); + assert_eq!( + serde_json::to_value(&pilot).unwrap(), + serde_json::to_value(&recovered).unwrap() + ); + pilot = recovered; + } + pilot.complete_mission(&active.registry).unwrap(); + assert_eq!(pilot.completed.len(), 8); +} + +#[test] +fn stage2_never_replaces_owned_equipment_or_breaks_full_inventories() { + let mut active = active(); + for mission in MISSIONS { + for reserves in [0, 4] { + let mut pilot = Pilot::default(); + pilot.mission = mission.into(); + pilot + .inventory + .insert("iron_coast_railburst:equipment".into(), 1); + pilot + .inventory + .insert("iron_coast_depth_charge:equipment".into(), 1); + if reserves > 0 { + pilot.inventory.insert("base:super_shield".into(), 100); + pilot.super_shield_reserves = vec![100; reserves]; + } + for n in 0..18 { + if pilot.inventory_slots() == 20 { + break; + } + pilot + .inventory + .insert(format!("base:fixture_item_{n}").as_str().into(), 1); + } + pilot.validate(&active.registry, &[]).unwrap(); + assert_eq!(pilot.inventory_slots(), 20); + let mut world = World::new(&pilot.mission, &pilot, &active.registry).unwrap(); + world + .step(Input::default(), &active.registry, &mut active.scripts) + .unwrap(); + assert_eq!(world.player.inventory, pilot.inventory, "{mission}"); + assert_eq!( + world.player.super_shield_reserves, + pilot.super_shield_reserves + ); + } + } +} + +fn route_input(world: &World, registry: &Registry) -> Input { + let namespace = world.mission.0.split_once(':').unwrap().0; + let target = world + .enemies + .iter() + .filter(|enemy| enemy.health > 0 && enemy.y >= 0 && enemy.y < 145) + .min_by_key(|enemy| { + let definition = ®istry.enemies[&enemy.definition]; + let priority = if enemy.definition.0.starts_with(&format!("{namespace}:")) { + 0 + } else if definition.boss { + 1 + } else if definition.ground { + 2 + } else { + 3 + }; + (priority, enemy.entity) + }); + let goal = target + .map(|enemy| enemy.x + enemy.width / 2 - 16) + .unwrap_or(144) + .clamp(5, 282); + let aimed = world.player.x + (goal - world.player.x).clamp(-4, 4); + // Ordinary four-pixel mouse steps evade imminent projectile lanes. This + // controller changes input only; enemies, health and damage stay real. + let score = |x: i32| { + let mut danger = 0_i32; + for shot in world + .projectiles + .iter() + .filter(|shot| shot.hostile && shot.y >= 100 && shot.y <= 196) + { + let dy = (shot.y - shot.py).max(shot.vy); + if dy <= 0 { + continue; + } + let ticks = ((160 - shot.y) / dy).clamp(0, 8); + let predicted = shot.x + (shot.x - shot.px) * ticks; + danger += (24 - (x + 16 - predicted).abs()).max(0) * (10 - ticks); + } + danger * 1000 + (goal - x).abs() + }; + let x = [ + aimed, + (world.player.x - 4).max(5), + (world.player.x + 4).min(282), + ] + .into_iter() + .min_by_key(|x| score(*x)) + .unwrap(); + Input { + fire: true, + absolute: Some([x, 160]), + ..Input::default() + } +} + +#[test] +#[ignore = "requires original catalog; full real eight-sortie gameplay and pilot continuation"] +fn starter_ship_completes_all_eight_missions_with_paid_repairs_and_finale_replay() { + let mut active = active_original(); + let temporary = tempfile::tempdir().unwrap(); + let path = temporary.path().join("route.json"); + let mut pilot = Pilot::default(); + pilot.name = "Black Tide Acceptance".into(); + pilot.credits = 10_000; + pilot.inventory.insert("base:energy".into(), 75); + pilot.difficulty = std::env::var("RAPTOR_STAGE2_DIFFICULTY") + .map(|value| value.parse().unwrap()) + .unwrap_or(2); + assert!(pilot.difficulty <= 3); + pilot.mission = MISSIONS[0].into(); + pilot.mods = active.pins.clone(); + let mut reports = Vec::new(); + let mut paid_refills = 0; + for (n, mission) in MISSIONS + .iter() + .chain(std::iter::once(&MISSIONS[7])) + .enumerate() + { + assert_eq!(pilot.mission.0, *mission); + while pilot.inventory[&"base:energy".into()] < 90 && pilot.credits >= 10_000 { + pilot.buy(&"base:energy".into(), &active.registry).unwrap(); + paid_refills += 1; + } + let start_shield = pilot.inventory[&"base:energy".into()]; + let start_credits = pilot.credits; + let mut world = World::new(&pilot.mission, &pilot, &active.registry).unwrap(); + let mut native_motion = BTreeSet::new(); + let mut seen_bosses = BTreeSet::new(); + let limit = active.registry.missions[&pilot.mission].duration + 1800; + while world.tick < limit && world.outcome == Outcome::Playing { + let input = route_input(&world, &active.registry); + world + .step(input, &active.registry, &mut active.scripts) + .unwrap(); + for enemy in &world.enemies { + let definition = &active.registry.enemies[&enemy.definition]; + if definition.boss { + seen_bosses.insert(enemy.definition.clone()); + } + if enemy.definition.0.starts_with("base:enemy_") + && (enemy.x != enemy.sx || enemy.y != enemy.sy) + { + assert!(definition.legacy.is_some()); + native_motion.insert(enemy.definition.clone()); + } + } + } + assert_eq!( + world.outcome, + Outcome::Complete, + "{mission}: tick={},shield={},objectives={:?}", + world.tick, + world.player.shield, + world.objectives + ); + assert!(world.player.shield > 0); + assert!( + !native_motion.is_empty(), + "{mission} did not show classic native movement" + ); + assert!(!seen_bosses.is_empty()); + let namespace = mission.split_once(':').unwrap().0; + assert_eq!(world.objectives[&format!("{namespace}:complete")], 1); + assert_eq!(world.objectives[&format!("{namespace}:debrief")], 1); + let credits = world.player.credits; + world + .step(Input::default(), &active.registry, &mut active.scripts) + .unwrap(); + assert_eq!(world.player.credits, credits, "{mission} paid twice"); + eprintln!( + "{mission}: complete {} ticks, shields {start_shield}-> {}, credits {}", + world.tick, world.player.shield, world.player.credits + ); + reports.push(json!({"mission":mission,"replay":n==8,"ticks":world.tick,"start_shield":start_shield,"shield":world.player.shield,"start_credits":start_credits,"credits":credits,"native_motion":native_motion,"objectives":world.objectives,"digest":world.digest()})); + pilot = world.pilot(&pilot); + pilot.merge_runtime_snapshot(&active.pins, &active.scripts.states, &active.scripts.rng); + pilot.complete_mission(&active.registry).unwrap(); + assert_eq!(pilot.completed.len(), (n + 1).min(8)); + pilot.save(&path).unwrap(); + let recovered = Pilot::load(&path, &active.registry, &active.pins).unwrap(); + assert_eq!( + serde_json::to_value(&pilot).unwrap(), + serde_json::to_value(&recovered).unwrap() + ); + active + .scripts + .restore((recovered.script_state.clone(), recovered.script_rng.clone())); + pilot = recovered; + } + if let Ok(path) = std::env::var("RAPTOR_STAGE2_REPORT") { + let path = PathBuf::from(path); + if let Some(parent) = path.parent() { + fs::create_dir_all(parent).unwrap(); + } + fs::write(path,serde_json::to_vec_pretty(&json!({"original_catalog":true,"difficulty":pilot.difficulty,"pins":active.pins,"paid_refills":paid_refills,"reports":reports})).unwrap()).unwrap(); + } +} diff --git a/tests/iron_coast_stage2_weapons.rs b/tests/iron_coast_stage2_weapons.rs new file mode 100644 index 00000000..47a26d90 --- /dev/null +++ b/tests/iron_coast_stage2_weapons.rs @@ -0,0 +1,625 @@ +//! API-level tests use synthetic artwork/audio; the ignored balance run uses +//! the installed original catalog and actual public mod packages. +use raptor_replica::{ + assets::Catalog, + content::{ContentId, ContentPack, Registry}, + modding::{self, ActiveMods}, + persistence::Pilot, + simulation::{EffectKind, Input, Outcome, World}, +}; +use serde_json::{Value, json}; +use std::{fs, path::Path}; + +const PACKAGES: [&str; 2] = ["iron_coast_railburst", "iron_coast_depth_charge"]; +const HEALTH: i32 = 100_000; + +fn range(registry: &mut Registry) { + let definitions: ContentPack = serde_json::from_value(json!({ + "missions": [{"id":"stage2range:range","name":"Controlled range","duration":10000,"auto_complete":false}], + "enemies": [ + {"id":"stage2range:air","name":"Air fixture","health":HEALTH,"speed":0}, + {"id":"stage2range:ground","name":"Ground fixture","health":HEALTH,"speed":0,"ground":true,"script":"ground.rhai"} + ] + })).unwrap(); + registry.apply(definitions, "stage2range").unwrap(); +} + +fn attach_range_script(active: &mut ActiveMods) { + active + .scripts + .add( + "stage2range", + "ground.rhai", + r#" + // Cancel terrain scroll after collision processing, without changing weapons. + fn on_tick(event,state,random) { + #{commands:[#{op:"move",entity:event.entity,x:event.x,y:event.y-1}],state:state} + } + "#, + ) + .unwrap(); +} + +fn synthetic_install(root: &Path, id: &str) { + let source = Path::new(env!("CARGO_MANIFEST_DIR")).join("mods").join(id); + let target = root.join(id); + for directory in ["scripts", "art", "audio"] { + fs::create_dir_all(target.join(directory)).unwrap(); + } + for file in ["mod.toml", "content.json", "scripts/weapon.rhai"] { + fs::copy(source.join(file), target.join(file)).unwrap(); + } + let content: Value = + serde_json::from_slice(&fs::read(target.join("content.json")).unwrap()).unwrap(); + for entry in content["weapons"] + .as_array() + .unwrap() + .iter() + .chain(content["items"].as_array().unwrap()) + { + let art = &entry["art"]; + for (property, scale) in [("png", 1), ("hd_png", 4)] { + image::RgbaImage::from_pixel( + art["logical_width"].as_u64().unwrap() as u32 * scale, + art["logical_height"].as_u64().unwrap() as u32 * scale, + image::Rgba([80, 100, 120, 255]), + ) + .save(target.join(art[property].as_str().unwrap())) + .unwrap(); + } + } + let mut wav = b"RIFF".to_vec(); + wav.extend(164u32.to_le_bytes()); + wav.extend(b"WAVEfmt "); + wav.extend(16u32.to_le_bytes()); + wav.extend(1u16.to_le_bytes()); + wav.extend(1u16.to_le_bytes()); + wav.extend(11025u32.to_le_bytes()); + wav.extend(22050u32.to_le_bytes()); + wav.extend(2u16.to_le_bytes()); + wav.extend(16u16.to_le_bytes()); + wav.extend(b"data"); + wav.extend(128u32.to_le_bytes()); + wav.extend([0; 128]); + for sound in content["sounds"].as_array().unwrap() { + fs::write(target.join(sound["file"].as_str().unwrap()), &wav).unwrap(); + } +} + +fn activate(ids: &[&str]) -> (tempfile::TempDir, ActiveMods) { + let root = tempfile::tempdir().unwrap(); + for id in ids { + synthetic_install(root.path(), id); + } + let discovery = modding::discover(root.path()); + assert!(discovery.errors.is_empty(), "{:?}", discovery.errors); + let mut base = Registry::default(); + base.apply( + serde_json::from_value( + json!({"items":[{"id":"base:energy","name":"Shield","price":100,"max_count":100}]}), + ) + .unwrap(), + "base", + ) + .unwrap(); + let mut active = ActiveMods::build( + &base, + &discovery, + &ids.iter().map(|s| s.to_string()).collect::>(), + None, + ) + .unwrap(); + range(&mut active.registry); + attach_range_script(&mut active); + (root, active) +} + +fn world(item: &str, registry: &Registry) -> World { + let id = ContentId::from(item); + let pilot = Pilot { + mission: "stage2range:range".into(), + difficulty: 2, + inventory: [(id.clone(), 1), ("base:energy".into(), 100)] + .into_iter() + .collect(), + selected: registry.items[&id].special.then_some(id), + ..Pilot::default() + }; + World::new(&pilot.mission, &pilot, registry).unwrap() +} + +fn step(world: &mut World, active: &mut ActiveMods, fire: bool) { + world + .step( + Input { + fire, + ..Input::default() + }, + &active.registry, + &mut active.scripts, + ) + .unwrap(); +} + +fn spawn(world: &mut World, active: &ActiveMods, targets: &[(&str, i32, i32)]) -> Vec { + targets + .iter() + .map(|(kind, x, y)| { + world + .spawn( + &format!("stage2range:{kind}").as_str().into(), + *x, + *y, + &active.registry, + ) + .unwrap() + }) + .collect() +} + +fn damage(world: &World, entities: &[u64]) -> Vec { + entities + .iter() + .map(|id| { + HEALTH + - world + .enemies + .iter() + .find(|e| e.entity == *id) + .unwrap() + .health + }) + .collect() +} + +#[test] +fn independent_activation_coexistence_and_real_shop_resale() { + for ids in [vec![PACKAGES[0]], vec![PACKAGES[1]], PACKAGES.to_vec()] { + let (_root, active) = activate(&ids); + assert_eq!(active.pins.len(), ids.len()); + assert!(active.registry.overrides.is_empty()); + for id in ids { + let item: ContentId = format!("{id}:equipment").as_str().into(); + let definition = &active.registry.items[&item]; + assert!(definition.special && !definition.consumable); + assert!(definition.description.contains("Selectable")); + let mut pilot = Pilot { + credits: definition.price, + inventory: Default::default(), + ..Pilot::default() + }; + pilot.buy(&item, &active.registry).unwrap(); + assert_eq!(pilot.credits, 0); + assert_eq!(pilot.inventory[&item], 1); + assert!(pilot.buy(&item, &active.registry).is_err()); + pilot.selected = Some(item.clone()); + pilot.sell(&item, &active.registry).unwrap(); + assert_eq!(pilot.credits, definition.price / 2); + assert!(!pilot.inventory.contains_key(&item)); + assert!(pilot.selected.is_none()); + } + } +} + +#[test] +fn railburst_contact_penetrates_only_three_aligned_targets_with_falling_damage() { + let (_root, mut active) = activate(&[PACKAGES[0]]); + let mut world = world("iron_coast_railburst:equipment", &active.registry); + let ids = spawn( + &mut world, + &active, + &[ + ("air", 144, 104), + ("ground", 144, 64), + ("air", 144, 24), + ("air", 144, 0), + ("air", 200, 64), + ], + ); + step(&mut world, &mut active, true); + assert!( + world.effects.is_empty(), + "no muzzle explosion before real contact" + ); + for _ in 0..3 { + step(&mut world, &mut active, false); + } + assert_eq!(damage(&world, &ids), [42, 32, 22, 0, 0]); + assert_eq!( + active.scripts.states["iron_coast_railburst/scripts/weapon.rhai"]["hits"], + 3 + ); + assert!(world.effects.iter().any(|e| e.kind == EffectKind::SmallAir)); + assert!( + world + .effects + .iter() + .any(|e| e.kind == EffectKind::SmallGround) + ); + assert_eq!( + world.player.inventory[&"iron_coast_railburst:equipment".into()], + 1 + ); +} + +#[test] +fn depth_charge_has_contact_only_ground_splash_falloff_radius_and_neighbor_cap() { + let (_root, mut active) = activate(&[PACKAGES[1]]); + let mut world = world("iron_coast_depth_charge:equipment", &active.registry); + let ids = spawn( + &mut world, + &active, + &[ + ("ground", 144, 96), + ("ground", 154, 96), + ("ground", 169, 96), + ("ground", 179, 96), + ("ground", 180, 96), + ("ground", 181, 96), + ("air", 144, 96), + ], + ); + step(&mut world, &mut active, true); + assert!(world.effects.is_empty()); + for _ in 0..8 { + step(&mut world, &mut active, false); + } + assert_eq!(damage(&world, &ids), [72, 36, 20, 20, 0, 0, 0]); + assert_eq!(world.effects.len(), 1); + assert_eq!(world.effects[0].kind, EffectKind::GroundBlast); + assert!(world.effects[0].ground); + assert_eq!( + active.scripts.states["iron_coast_depth_charge/scripts/weapon.rhai"]["hits"], + 4 + ); +} + +#[test] +fn unselected_idle_and_missed_shots_do_not_inflict_damage_or_make_explosions() { + let (_root, mut active) = activate(&PACKAGES); + for id in PACKAGES { + active + .scripts + .restore((Default::default(), Default::default())); + let mut world = world(&format!("{id}:equipment"), &active.registry); + world.player.inventory.insert( + format!( + "{}:equipment", + if id == PACKAGES[0] { + PACKAGES[1] + } else { + PACKAGES[0] + } + ) + .as_str() + .into(), + 1, + ); + let ids = spawn( + &mut world, + &active, + &[("air", 220, 80), ("ground", 220, 80)], + ); + for _ in 0..60 { + step(&mut world, &mut active, false); + } + assert!(active.scripts.states.keys().all(|s| !s.starts_with(id))); + step(&mut world, &mut active, true); + for _ in 0..35 { + step(&mut world, &mut active, false); + } + assert_eq!(damage(&world, &ids), [0, 0]); + assert!(world.effects.is_empty()); + let other = if id == PACKAGES[0] { + PACKAGES[1] + } else { + PACKAGES[0] + }; + assert!( + !active + .scripts + .states + .contains_key(&format!("{other}/scripts/weapon.rhai")) + ); + } +} + +#[test] +fn saved_script_state_and_rng_resume_identically_and_failed_callbacks_roll_back() { + for id in PACKAGES { + let (_root, mut active) = activate(&[id]); + let mut original = world(&format!("{id}:equipment"), &active.registry); + spawn( + &mut original, + &active, + &[("ground", 144, 96), ("ground", 154, 96), ("air", 144, 64)], + ); + for _ in 0..75 { + step(&mut original, &mut active, true); + } + let mut resumed = original.clone(); + let (_other, mut replay) = activate(&[id]); + let serialized = serde_json::to_vec(&active.scripts.checkpoints()).unwrap(); + replay + .scripts + .restore(serde_json::from_slice(&serialized).unwrap()); + for _ in 0..100 { + step(&mut original, &mut active, true); + step(&mut resumed, &mut replay, true); + } + assert_eq!(original.digest(), resumed.digest()); + assert_eq!( + serde_json::to_value(active.scripts.checkpoints()).unwrap(), + serde_json::to_value(replay.scripts.checkpoints()).unwrap() + ); + active.scripts.add(id,"scripts/weapon.rhai",r#"fn on_fire(event,state,random){#{commands:[#{op:"credits",amount:500},#{op:"damage",entity:999999999,amount:1}],state:#{counter:random[0]}}}"#).unwrap(); + let mut bad = world(&format!("{id}:equipment"), &active.registry); + let before = bad.digest(); + let scripts = serde_json::to_value(active.scripts.checkpoints()).unwrap(); + let error = bad + .step( + Input { + fire: true, + ..Input::default() + }, + &active.registry, + &mut active.scripts, + ) + .unwrap_err(); + assert!(error.to_string().contains("target")); + assert_eq!(before, bad.digest()); + assert_eq!( + scripts, + serde_json::to_value(active.scripts.checkpoints()).unwrap() + ); + } +} + +#[test] +fn cadence_is_explicit_and_equipment_is_reusable() { + for (id, cooldown, shots) in [(PACKAGES[0], 22, 4), (PACKAGES[1], 48, 2)] { + let (_root, mut active) = activate(&[id]); + let mut world = world(&format!("{id}:equipment"), &active.registry); + for _ in 0..70 { + step(&mut world, &mut active, true); + } + assert_eq!( + active.registry.weapons[&format!("{id}:projectile").as_str().into()].cooldown, + cooldown + ); + assert_eq!( + active.scripts.states[&format!("{id}/scripts/weapon.rhai")]["shots"], + shots + ); + assert_eq!( + world.player.inventory[&format!("{id}:equipment").as_str().into()], + 1 + ); + assert_eq!(world.player.shield, 100); + } +} + +#[test] +fn lethal_primary_contacts_still_trigger_finite_secondary_damage() { + for id in PACKAGES { + let (_root, mut active) = activate(&[id]); + let mut world = world(&format!("{id}:equipment"), &active.registry); + let targets = if id == PACKAGES[0] { + vec![ + ("ground", 144, 104), + ("air", 144, 64), + ("ground", 144, 24), + ("air", 220, 64), + ] + } else { + vec![ + ("ground", 144, 96), + ("ground", 154, 96), + ("air", 144, 96), + ("ground", 220, 96), + ] + }; + let entities = spawn(&mut world, &active, &targets); + world.enemies[0].health = 1; + step(&mut world, &mut active, true); + for _ in 0..15 { + step(&mut world, &mut active, false); + } + assert!( + !world.enemies.iter().any(|e| e.entity == entities[0]), + "lethal primary retires normally" + ); + assert_eq!( + world + .enemies + .iter() + .find(|e| e.entity == entities[1]) + .unwrap() + .health, + HEALTH - if id == PACKAGES[0] { 32 } else { 36 } + ); + assert_eq!( + world + .enemies + .iter() + .find(|e| e.entity == *entities.last().unwrap()) + .unwrap() + .health, + HEALTH + ); + } +} + +#[test] +fn full_inventory_rejects_purchase_without_changing_owned_equipment() { + let (_root, active) = activate(&PACKAGES); + for id in PACKAGES { + let mut pilot = Pilot { + credits: 2_000_000, + inventory: (0..20) + .map(|n| (ContentId::new(format!("unavailable:slot{n}")).unwrap(), 1)) + .collect(), + ..Pilot::default() + }; + let before = serde_json::to_value(&pilot).unwrap(); + assert!( + pilot + .buy(&format!("{id}:equipment").as_str().into(), &active.registry) + .is_err() + ); + assert_eq!(before, serde_json::to_value(&pilot).unwrap()); + } +} + +#[test] +fn disabling_and_reenabling_keeps_saved_equipment_mod_pins_and_script_state() { + let (_root, mut active) = activate(&PACKAGES); + let mut flight = world("iron_coast_railburst:equipment", &active.registry); + step(&mut flight, &mut active, true); + let pilot = Pilot { + mission: "stage2range:range".into(), + inventory: [ + ("iron_coast_railburst:equipment".into(), 1), + ("iron_coast_depth_charge:equipment".into(), 1), + ("base:energy".into(), 100), + ] + .into_iter() + .collect(), + selected: Some("iron_coast_railburst:equipment".into()), + mods: active.pins.clone(), + script_state: active.scripts.states.clone(), + script_rng: active.scripts.rng.clone(), + ..Pilot::default() + }; + let save = tempfile::tempdir().unwrap(); + let path = save.path().join("pilot.json"); + pilot.save(&path).unwrap(); + let original = fs::read(&path).unwrap(); + let (_disabled, disabled) = activate(&[]); + let missing = Pilot::inspect_load(&path, &disabled.registry, &disabled.pins).unwrap(); + assert!(!missing.compatibility.is_compatible()); + assert_eq!( + serde_json::to_value(&missing.pilot).unwrap(), + serde_json::to_value(&pilot).unwrap() + ); + assert_eq!( + original, + fs::read(&path).unwrap(), + "read-only compatibility inspection must preserve the original save" + ); + let (_restored, reenabled) = activate(&PACKAGES); + let compatible = Pilot::inspect_load(&path, &reenabled.registry, &reenabled.pins).unwrap(); + assert!( + compatible.compatibility.is_compatible(), + "{:?}", + compatible.compatibility.messages() + ); + assert_eq!(compatible.pilot.inventory, pilot.inventory); + assert_eq!(compatible.pilot.script_state, pilot.script_state); + assert_eq!( + serde_json::to_value(compatible.pilot.script_rng).unwrap(), + serde_json::to_value(pilot.script_rng).unwrap() + ); +} + +#[test] +#[ignore = "requires installed original catalog and completed PNG/WAV mod packages"] +fn real_catalog_700_tick_balance_and_coexistence_report() { + let package = Path::new(env!("CARGO_MANIFEST_DIR")); + let catalog = Catalog::open( + std::env::var_os("RAPTOR_TEST_DATA") + .map(std::path::PathBuf::from) + .unwrap_or_else(|| package.join("data")), + ) + .unwrap(); + let base = Registry::base(&catalog).unwrap(); + let enabled = [PACKAGES[0], PACKAGES[1], "ion_lance", "lightning_cannon"].map(String::from); + // Freeze only the packages under observation, so unrelated authors can work + // while this slow original-data integration test scans and builds packages. + fn copy_tree(from: &Path, to: &Path) { + fs::create_dir_all(to).unwrap(); + for entry in fs::read_dir(from).unwrap() { + let entry = entry.unwrap(); + if entry.file_type().unwrap().is_dir() { + copy_tree(&entry.path(), &to.join(entry.file_name())); + } else { + fs::copy(entry.path(), to.join(entry.file_name())).unwrap(); + } + } + } + let frozen = tempfile::tempdir().unwrap(); + for id in &enabled { + copy_tree(&package.join("mods").join(id), &frozen.path().join(id)); + } + let discovery = modding::discover(frozen.path()); + let mut active = ActiveMods::build(&base, &discovery, &enabled, Some(&catalog)).unwrap(); + range(&mut active.registry); + attach_range_script(&mut active); + let scenes: Vec<(&str, Vec<(&str, i32, i32)>)> = vec![ + ("aligned_air", vec![("air", 144, 80)]), + ("aligned_ground", vec![("ground", 144, 80)]), + ("off_axis_air", vec![("air", 220, 80)]), + ("off_axis_ground", vec![("ground", 220, 80)]), + ( + "aligned_column", + vec![ + ("ground", 144, 104), + ("air", 144, 64), + ("ground", 144, 24), + ("air", 144, 0), + ], + ), + ( + "ground_cluster", + vec![ + ("ground", 144, 80), + ("ground", 154, 80), + ("ground", 169, 80), + ("ground", 179, 80), + ("ground", 181, 80), + ("air", 144, 80), + ], + ), + ]; + let mut rows = Vec::new(); + for item in [ + "iron_coast_railburst:equipment", + "iron_coast_depth_charge:equipment", + "ion_lance:equipment", + "lightning_cannon:equipment", + "base:forward_guns", + "base:death_ray", + "base:forward_laser", + ] { + for combo in [false, true] { + if combo && item.starts_with("base:") { + continue; + } + for (scene, targets) in &scenes { + active + .scripts + .restore((Default::default(), Default::default())); + let mut world = world(item, &active.registry); + world.player.selected = active.registry.items[&ContentId::from(item)] + .special + .then(|| item.into()); + if combo { + world.player.inventory.insert("base:forward_guns".into(), 1); + } + let entities = spawn(&mut world, &active, targets); + for _ in 0..700 { + step(&mut world, &mut active, true); + } + assert_eq!(world.outcome, Outcome::Playing); + assert_eq!(world.player.shield, 100); + let damage = damage(&world, &entities); + rows.push(json!({"item":item,"price":active.registry.items[&ContentId::from(item)].price,"scene":scene,"with_forward_guns":combo,"ticks":700,"seconds":30,"damage":damage,"group_dps":damage.iter().sum::() as f64/30.0})); + } + } + } + let report = json!({"fixture_health":HEALTH,"target_size":[32,32],"difficulty":2,"rate":"70/3 Hz","rows":rows}); + if let Some(path) = std::env::var_os("IRON_COAST_STAGE2_BALANCE_REPORT") { + fs::write(path, serde_json::to_vec_pretty(&report).unwrap()).unwrap(); + } + println!("{report}"); +} diff --git a/tests/stage2_enemies.rs b/tests/stage2_enemies.rs new file mode 100644 index 00000000..fe964d08 --- /dev/null +++ b/tests/stage2_enemies.rs @@ -0,0 +1,481 @@ +//! Three independent Stage 2 shared enemy packages; synthetic asset tests run everywhere. +use raptor_replica::{ + content::{ContentId, ContentPack, Registry}, + modding::{self, ActiveMods, Command}, + persistence::Pilot, + simulation::{Input, World}, +}; +use serde_json::json; +use std::{fs, path::Path}; +const IDS: [&str; 3] = [ + "iron_coast_stage2_interceptor", + "iron_coast_stage2_siege", + "iron_coast_stage2_skimmer", +]; +fn base() -> Registry { + let mut r = Registry::default(); + let p:ContentPack=serde_json::from_value(json!({"weapons":[ + {"id":"base:projectile_forward_guns","name":"Guns","damage":1,"speed":8,"cooldown":2,"behavior":"straight","target":"all"}, + {"id":"base:air_probe","name":"Air probe","damage":5,"speed":0,"cooldown":1,"behavior":"straight","target":"air"}, + {"id":"base:ground_probe","name":"Ground probe","damage":5,"speed":0,"cooldown":1,"behavior":"straight","target":"ground"}], + "items":[{"id":"base:forward_guns","name":"Guns","price":0,"weapon":"base:projectile_forward_guns"},{"id":"base:energy","name":"Shield","price":0,"max_count":100}], + "missions":[{"id":"base:sector_1_wave_1","name":"Synthetic shared enemies range","duration":10000,"auto_complete":false}]})).unwrap(); + r.apply(p, "base").unwrap(); + r.validate().unwrap(); + r +} +fn fixture(parent: &Path, id: &str) { + let source = Path::new(env!("CARGO_MANIFEST_DIR")).join("mods").join(id); + let dest = parent.join(id); + for sub in ["scripts", "art", "audio"] { + fs::create_dir_all(dest.join(sub)).unwrap(); + } + for file in ["mod.toml", "content.json", "scripts/ai.rhai"] { + fs::copy(source.join(file), dest.join(file)).unwrap(); + } + if source.join("scripts/gun.rhai").exists() { + fs::copy( + source.join("scripts/gun.rhai"), + dest.join("scripts/gun.rhai"), + ) + .unwrap(); + } + let content: ContentPack = + serde_json::from_slice(&fs::read(source.join("content.json")).unwrap()).unwrap(); + for a in content + .enemies + .iter() + .filter_map(|d| d.art.as_ref()) + .chain(content.weapons.iter().filter_map(|d| d.art.as_ref())) + { + for (path, scale) in [ + (a.png.as_ref().unwrap(), 1), + (a.hd_png.as_ref().unwrap(), 2), + ] { + let mut im = + image::RgbaImage::new(a.logical_width * a.frames * scale, a.logical_height * scale); + for frame in 0..a.frames { + for y in scale..(a.logical_height - 1) * scale { + for x in scale..(a.logical_width - 1) * scale { + im.put_pixel( + frame * a.logical_width * scale + x, + y, + image::Rgba([94, 105, 113, 255]), + ); + } + } + } + im.save(dest.join(path)).unwrap(); + } + } + let mut wav = b"RIFF".to_vec(); + wav.extend(40_u32.to_le_bytes()); + wav.extend(b"WAVEfmt "); + wav.extend(16_u32.to_le_bytes()); + wav.extend(1_u16.to_le_bytes()); + wav.extend(1_u16.to_le_bytes()); + wav.extend(22050_u32.to_le_bytes()); + wav.extend(44100_u32.to_le_bytes()); + wav.extend(2_u16.to_le_bytes()); + wav.extend(16_u16.to_le_bytes()); + wav.extend(b"data"); + wav.extend(4_u32.to_le_bytes()); + wav.extend([0; 4]); + for s in content.sounds { + fs::write(dest.join(s.file), &wav).unwrap(); + } +} +fn active(ids: &[&str]) -> (tempfile::TempDir, ActiveMods) { + let temp = tempfile::tempdir().unwrap(); + for id in ids { + fixture(temp.path(), id); + } + let discovery = modding::discover(temp.path()); + assert!(discovery.errors.is_empty(), "{:?}", discovery.errors); + let a = ActiveMods::build( + &base(), + &discovery, + &ids.iter().map(|s| s.to_string()).collect::>(), + None, + ) + .unwrap(); + (temp, a) +} +fn world(a: &ActiveMods) -> World { + let mut p = Pilot::default(); + p.credits = 0; + let mut w = World::new(&p.mission, &p, &a.registry).unwrap(); + w.player.shield = 100; + w +} +fn spawn(w: &mut World, a: &ActiveMods, id: &str, x: i32, y: i32) -> u64 { + w.spawn( + &ContentId::new(format!("{id}:unit")).unwrap(), + x, + y, + &a.registry, + ) + .unwrap() +} +#[test] +fn stage2_packages_activate_independently_and_coexist_with_stage1() { + for id in IDS { + let (_t, a) = active(&[id]); + assert_eq!(a.pins.len(), 1); + assert_eq!(a.registry.enemies.len(), 1); + assert_eq!(a.registry.sounds.len(), 3); + assert_eq!(a.registry.weapons.len(), 5); + assert!(a.registry.overrides.is_empty()); + } + let (_t, a) = active(&[ + IDS[0], + IDS[1], + IDS[2], + "iron_coast_scout", + "iron_coast_turret", + "iron_coast_boss", + ]); + assert_eq!(a.pins.len(), 6); + assert_eq!(a.registry.enemies.len(), 6); + assert!(a.registry.overrides.is_empty()); +} +#[test] +fn stage2_engine_cooldowns_produce_finite_bursts_and_warnings() { + for (idx, id) in IDS.iter().enumerate() { + let (_t, mut a) = active(&[*id]); + let mut w = world(&a); + w.player.x = 240; + spawn(&mut w, &a, id, 100, 0); + let mut shots = Vec::new(); + let mut warnings = Vec::new(); + for tick in 0..200 { + let e = &mut w.enemies[0]; + e.x = 100; + e.y = 0; + w.step(Input::default(), &a.registry, &mut a.scripts) + .unwrap(); + let new = w + .projectiles + .iter() + .filter(|p| p.age == 0) + .collect::>(); + if !new.is_empty() { + assert!(new.iter().all(|p| p.hostile + && p.weapon.0 == format!("{id}:projectile") + && p.vy >= 1 + && p.vx.abs() <= 3)); + shots.push((tick, new.len())); + } + if w.mod_sounds.iter().any(|s| s.0 == format!("{id}:warning")) { + warnings.push(tick); + } + assert_eq!(w.enemies.len(), 1, "AI must never spawn extra enemies"); + assert!(w.projectiles.len() < 32); + } + let expected = match idx { + 0 => vec![ + (1, 1), + (5, 1), + (9, 1), + (71, 1), + (75, 1), + (79, 1), + (141, 1), + (145, 1), + (149, 1), + ], + 1 => vec![(10, 2), (97, 2), (184, 2)], + _ => vec![(6, 2), (88, 2), (170, 2)], + }; + assert_eq!(shots, expected, "{id}"); + assert_eq!( + warnings, + match idx { + 0 => vec![], + 1 => vec![0, 87, 174], + _ => vec![0, 82, 164], + }, + "{id}" + ); + } +} +#[test] +fn stage2_movement_has_distinct_bounded_patterns_and_units_escape_without_rewards() { + for (idx, id) in IDS.iter().enumerate() { + let (_t, mut a) = active(&[*id]); + let mut w = world(&a); + w.player.x = 0; + spawn(&mut w, &a, id, 150, -24); + let mut left = false; + let mut right = false; + let mut stopped = false; + for _ in 0..400 { + w.step(Input::default(), &a.registry, &mut a.scripts) + .unwrap(); + if w.enemies.is_empty() { + break; + } + let e = &w.enemies[0]; + left |= e.vx < 0; + right |= e.vx > 0; + stopped |= e.vx == 0; + assert!(e.x >= 6 && e.x + e.width <= 314); + assert!((1..=2).contains(&e.vy)); + } + assert!(w.enemies.is_empty(), "{id} should leave naturally"); + assert_eq!(w.player.credits, 0); + assert!(!w.objectives.contains_key(&format!("{id}:defeated"))); + if idx != 1 { + assert!(left && right, "{id} must weave in both directions"); + } else { + assert!(stopped && (left || right)); + } + } +} +#[test] +fn stage2_air_ground_filtering_and_siege_damage_disable_second_shell() { + for (idx, id) in IDS.iter().enumerate() { + for ground in [false, true] { + let (_t, mut a) = active(&[*id]); + let mut w = world(&a); + spawn(&mut w, &a, id, 120, 40); + let initial = w.enemies[0].health; + w.apply_commands( + &[Command::Projectile { + weapon: if ground { + "base:ground_probe" + } else { + "base:air_probe" + } + .into(), + x: 128, + y: 48, + vx: 0, + vy: 0, + hostile: false, + }], + &a.registry, + ) + .unwrap(); + w.step(Input::default(), &a.registry, &mut a.scripts) + .unwrap(); + assert_eq!( + w.enemies[0].health, + initial - if ground == (idx != 0) { 5 } else { 0 }, + "{id} ground={ground}" + ); + } + } + let (_t, mut a) = active(&[IDS[1]]); + let mut w = world(&a); + spawn(&mut w, &a, IDS[1], 120, 0); + w.enemies[0].health = 24; + for tick in 0..=10 { + w.enemies[0].y = 0; + w.step(Input::default(), &a.registry, &mut a.scripts) + .unwrap(); + if tick == 10 { + assert_eq!(w.projectiles.iter().filter(|p| p.age == 0).count(), 1); + } + } +} +#[test] +fn stage2_deaths_reward_count_once_and_replayed_entity_ids_reset_guards() { + let (_t, mut a) = active(&IDS); + for _ in 0..3 { + let mut w = world(&a); + for (idx, id) in IDS.iter().enumerate() { + let entity = spawn(&mut w, &a, id, 24 + idx as i32 * 92, 0); + w.apply_commands( + &[Command::Damage { + entity, + amount: 100000, + }], + &a.registry, + ) + .unwrap(); + } + // on_spawn is queued before on_death even when every entity is already gone. + w.step(Input::default(), &a.registry, &mut a.scripts) + .unwrap(); + assert_eq!(w.player.credits, 460); + assert!(w.enemies.is_empty()); + for id in IDS { + assert_eq!(w.objectives.get(&format!("{id}:defeated")), Some(&1)); + assert!(w.mod_sounds.iter().any(|s| s.0 == format!("{id}:death"))); + } + w.step(Input::default(), &a.registry, &mut a.scripts) + .unwrap(); + assert_eq!(w.player.credits, 460); + assert!(w.mod_sounds.is_empty()); + } +} +#[test] +fn stage2_rng_and_full_world_state_continue_identically_after_serialization() { + let (_t, mut a) = active(&IDS); + let (_u, mut b) = active(&IDS); + let mut x = world(&a); + x.player.x = 0; + for (idx, id) in IDS.iter().enumerate() { + spawn(&mut x, &a, id, 60 + idx as i32 * 75, -24); + } + let mut y = x.clone(); + for _ in 0..93 { + x.step(Input::default(), &a.registry, &mut a.scripts) + .unwrap(); + y.step(Input::default(), &b.registry, &mut b.scripts) + .unwrap(); + assert_eq!(x.digest(), y.digest()); + assert_eq!(a.scripts.checkpoints(), b.scripts.checkpoints()); + } + y = serde_json::from_slice(&serde_json::to_vec(&x).unwrap()).unwrap(); + b.scripts.restore(a.scripts.checkpoints()); + for _ in 0..210 { + x.step(Input::default(), &a.registry, &mut a.scripts) + .unwrap(); + y.step(Input::default(), &b.registry, &mut b.scripts) + .unwrap(); + assert_eq!( + serde_json::to_value(&x).unwrap(), + serde_json::to_value(&y).unwrap() + ); + assert_eq!(a.scripts.checkpoints(), b.scripts.checkpoints()); + } +} +#[test] +fn stage2_death_history_and_escaped_unit_state_are_bounded() { + for id in IDS { + let (_t, mut a) = active(&[id]); + let mut w = world(&a); + for _ in 0..260 { + let entity = spawn(&mut w, &a, id, 100, 0); + w.apply_commands( + &[Command::Damage { + entity, + amount: 100000, + }], + &a.registry, + ) + .unwrap(); + w.step(Input::default(), &a.registry, &mut a.scripts) + .unwrap(); + } + assert_eq!(w.objectives.get(&format!("{id}:defeated")), Some(&260)); + let states = a.scripts.checkpoints().0; + let s = &states[&format!("{id}/scripts/ai.rhai")]; + assert!(s["dead"].as_object().unwrap().len() <= 128); + assert!(s["dead_order"].as_array().unwrap().len() <= 128); + assert!(s["units"].as_object().unwrap().is_empty()); + assert!(serde_json::to_vec(s).unwrap().len() < 16000); + } +} + +#[test] +fn stage2_shipped_art_is_aligned_and_every_sound_reaches_the_real_mixer() { + use raptor_replica::{audio::Mixer, sound::SoundBank}; + use sha2::{Digest, Sha256}; + let root = Path::new(env!("CARGO_MANIFEST_DIR")); + let mut registry = base(); + for id in IDS { + let dir = root.join("mods").join(id); + let pack: ContentPack = + serde_json::from_slice(&fs::read(dir.join("content.json")).unwrap()).unwrap(); + registry.apply(pack, id).unwrap(); + registry.asset_roots.insert(id.to_string(), dir.clone()); + let qa: serde_json::Value = + serde_json::from_slice(&fs::read(dir.join("art-qa.json")).unwrap()).unwrap(); + for frame in qa["frames"].as_array().unwrap() { + let kind = frame["kind"].as_str().unwrap(); + for (mode, scale) in [("sd", 1), ("hd", 8)] { + let bytes = fs::read(dir.join(format!("art/{kind}-{mode}.png"))).unwrap(); + let image = image::load_from_memory(&bytes).unwrap().into_rgba8(); + let (w, h) = image.dimensions(); + assert_eq!( + [w, h], + [ + frame["logical_canvas"][0].as_u64().unwrap() as u32 * scale, + frame["logical_canvas"][1].as_u64().unwrap() as u32 * scale + ] + ); + assert_eq!( + format!("{:x}", Sha256::digest(&bytes)), + frame[format!("{mode}_sha256")].as_str().unwrap() + ); + assert!(image.pixels().any(|p| p[3] >= 128)); + assert!(image.pixels().any(|p| p[3] == 0)); + for (x, y, p) in image.enumerate_pixels() { + if p[3] >= 128 { + assert!( + x > 0 && y > 0 && x + 1 < w && y + 1 < h, + "{id}:{kind}:{mode} clipped" + ); + } + } + } + let raw = fs::read(dir.join(format!("art/{kind}-generated-v1.png"))).unwrap(); + assert_eq!( + format!("{:x}", Sha256::digest(&raw)), + frame["raw_sha256"].as_str().unwrap() + ); + } + } + registry.validate().unwrap(); + let mut bank = SoundBank::default(); + let mut genmidi = b"#OPL_II#".to_vec(); + genmidi.resize(8 + 175 * 36, 0); + for id in IDS { + for cue in ["shot", "warning", "death"] { + let sound: ContentId = format!("{id}:{cue}").as_str().into(); + let sample = bank.mod_sample(®istry, &sound).unwrap(); + assert_eq!(sample.rate, 22050); + assert!(sample.data.len() >= 2000); + assert!(sample.data.iter().any(|s| *s != 128)); + let mut mixer = Mixer::new(44100, &genmidi).unwrap(); + bank.queue_mod(®istry, &mut mixer, &sound).unwrap(); + let mut output = vec![0i16; 44100 * 2]; + mixer.mix(&mut output); + assert!( + output.iter().any(|s| *s != 0), + "{sound} was silent at real queue/mix path" + ); + assert!( + output.iter().all(|s| *s != i16::MAX && *s != i16::MIN), + "{sound} clipped" + ); + } + } +} + +#[test] +fn stage2_invisible_or_passed_units_never_warn_or_fire_from_muzzle_coordinates() { + for (idx, id) in IDS.iter().enumerate() { + let width = if idx == 0 { 24 } else { 32 }; + for (x, y, player_y) in [ + (-8, 20, 170), + (320 - width + 4, 20, 170), + (100, -6, 170), + (100, 190, 170), + (100, 80, 80), + ] { + let (_t, mut a) = active(&[*id]); + let mut w = world(&a); + w.player.x = 0; + w.player.y = player_y; + spawn(&mut w, &a, id, x, y); + for _ in 0..16 { + w.enemies[0].x = x; + w.enemies[0].y = y; + w.step(Input::default(), &a.registry, &mut a.scripts) + .unwrap(); + assert!( + w.projectiles.is_empty(), + "{id} invisible/passed x{x},y{y} fired" + ); + assert!( + w.mod_sounds.is_empty(), + "{id} invisible/passed x{x},y{y} warned" + ); + } + } + } +}