diff --git a/LORE.md b/LORE.md index 7b541a6..54b178c 100644 --- a/LORE.md +++ b/LORE.md @@ -95,6 +95,89 @@ replaced by a receipt. | `datacentre` | Edge Node | power/build-radius creep | humming white monolith with a single blue status LED | | `transcoder` | Transcoder | refinery | white cube that swallows records whole; only receipts come out | +## Heroes + +Each side fields exactly one hero. They cost a fortune, they cannot be replaced +while alive, and losing one is a story beat, not a statistic. + +### THE SELECTOR (MRP, `selector`) + +Nobody built the Selector. It assembled itself in the sub-basement of a flooded +pressing plant out of a coat rack, a broken mastering lathe, and the contents of +a collection somebody spent forty years building and one afternoon losing. + +It carries a crate of **one-of-one dubplates** — acetates cut before the +Compression, of songs that exist nowhere else. Each one it throws is gone +forever. That is the Selector's whole tragedy and its whole tactic: it wins +fights by destroying the last copies of the things it is fighting for. + +It does not speak. It nods, and something in the distance falls over. + +- Slow, absurdly tough for infantry, huge splash damage, long reload. +- Voice lines are just the needle-drop crackle of a record starting. + +### THE CURATOR (Stream, `curator`) + +The Algorithm's only physical opinion. A white sphere ringed with lenses that +hovers three feet off the ground and *watches*, and the watching is the weapon — +everything it looks at is being scored, ranked, and found wanting. + +It is unfailingly polite. It refers to units it is destroying as "underperforming +content." It refers to the Selector as "a legacy account." + +- Fast, fragile for a hero, continuous beam that melts armour. +- Cannot capture or hold ground. It only ever passes through, sampling. + +## Air + +Late-war escalation. Both sides looked up at the same time. + +- **45 Flyer** (`flyer45`, MRP): a 7-inch single with tonearm rotor blades and a + scavenged engine pod bolted through the spindle hole. Loud, fast, made of + rubbish, held together by belief. +- **Compression Drone** (`compressor`, Stream): from the original Stream roster — + projects a shrinking blue field; things inside get smaller and worse. +- Launch pads: **Launch Ramp** (`launchramp`) and **Drone Port** (`droneport`). + +## Scouts + +- **Boom Bike** (`boombike`, MRP): a trike with two speaker cones where the + pillion should be. Nothing outruns it. Nothing wants to be near it either. +- **Crawler** (`crawler`, Stream): a flat white rover that maps your base and + files a report. Unarmed, silent, already gone by the time you shoot at it. + +## Wax seeps + +Wax fields are not deposits, they are **wounds**. Each field grows from a +**seep point** — a crack over a buried pressing plant, a landfill vent, a +flooded archive — and as long as the seep is open, the field regrows. Kill the +economy of a map and it will heal; the Black Wax has all the time in the world. + +## The campaign: SIDE A + +Three missions. The MRP origin story, told from the landfill up. + +### 1. FIRST PRESSING +The Party wakes up. A pop-up van and a single digger in a wax field at the edge +of the old industrial estate. Get a pressing plant running and press the first +records of the new world — before the Stream's survey drones finish counting +what's down here. +*Objectives: build a Pressing Plant, bank 2000 records, survive the first probe.* + +### 2. CRATE DIGGERS +A Stream transcoder outpost has found something under the hill: a **master +lacquer**, the original of an original. In six minutes it will be a receipt. +Take the outpost apart and take back the master. +*Objectives: destroy the Transcoder before the timer, keep the Selector alive.* + +### 3. THE DROP +The Algorithm has surfaced. Build the Mastering Studio, charge the orbital +tonearm, and put the needle through it. +*Objectives: build a Mastering Studio, fire THE DROP at the Algorithm, survive +the counterattack.* + +*(SIDE B — the Stream campaign, in which you are the polite one — is unwritten.)* + ## Tone Saturday-morning-cartoon apocalypse. The stakes are real (music is being deleted diff --git a/assets_src/PROMPTS.md b/assets_src/PROMPTS.md index 82a436d..0053be5 100644 --- a/assets_src/PROMPTS.md +++ b/assets_src/PROMPTS.md @@ -31,3 +31,7 @@ All images generated locally on MODELBEAST (`flux_local`) via `tools/mbgen.py`. | renders/scraper.png | 2026-07-20 | glossy seamless white tech aesthetic, soft blue ring lights, smooth rounded minimal design, autonomous white street sweeper vehicle inhaling black vinyl through a glowing blue intake, isometric three-quarter view from above, single object centered, video game asset, plain flat grey background, no text | | renders/bufferbot.png | 2026-07-20 | glossy seamless white tech aesthetic, soft blue ring lights, smooth rounded minimal design, knee-high white sphere robot with a loading spinner face, isometric three-quarter view from above, single object centered, video game asset, plain flat grey background, no text | | renders/drmwalker.png | 2026-07-20 | glossy seamless white tech aesthetic, soft blue ring lights, smooth rounded minimal design, tall faceless white mech with one blue ring-light eye and a glowing paywall screen chest, isometric three-quarter view from above, single object centered, video game asset, plain flat grey background, no text | +| renders/selector.png | 2026-07-25 | rusty junkyard robot aesthetic, rust metal with hot pink trim, analog dials and speaker parts, legendary hero DJ robot in a long coat with a crate of glowing gold dubplates under one arm and a tonearm staff, isometric three-quarter view from above, single object centered, video game asset, plain flat grey background, no text | +| renders/curator.png | 2026-07-25 | glossy seamless white tech aesthetic, soft blue ring lights, smooth rounded minimal design, hovering white sphere ringed with many camera lenses, a single blue eye at the front, faint halo, isometric three-quarter view from above, single object centered, video game asset, plain flat grey background, no text | +| renders/launchramp.png | 2026-07-25 | rusty junkyard robot aesthetic, rust metal with hot pink trim, analog dials and speaker parts, scrap metal launch ramp pad with painted pink chevrons, floodlights and a parked flying vinyl disc, isometric three-quarter view from above, single object centered, video game asset, plain flat grey background, no text | +| renders/droneport.png | 2026-07-25 | glossy seamless white tech aesthetic, soft blue ring lights, smooth rounded minimal design, white circular drone landing pad building with recessed blue guide lights and folded launch arms, isometric three-quarter view from above, single object centered, video game asset, plain flat grey background, no text | diff --git a/assets_src/renders/curator.png b/assets_src/renders/curator.png new file mode 100644 index 0000000..87381d6 Binary files /dev/null and b/assets_src/renders/curator.png differ diff --git a/assets_src/renders/curator_raw.png b/assets_src/renders/curator_raw.png new file mode 100644 index 0000000..422c976 Binary files /dev/null and b/assets_src/renders/curator_raw.png differ diff --git a/assets_src/renders/droneport.png b/assets_src/renders/droneport.png new file mode 100644 index 0000000..7481dfc Binary files /dev/null and b/assets_src/renders/droneport.png differ diff --git a/assets_src/renders/droneport_raw.png b/assets_src/renders/droneport_raw.png new file mode 100644 index 0000000..460573e Binary files /dev/null and b/assets_src/renders/droneport_raw.png differ diff --git a/assets_src/renders/launchramp.png b/assets_src/renders/launchramp.png new file mode 100644 index 0000000..e42c4dd Binary files /dev/null and b/assets_src/renders/launchramp.png differ diff --git a/assets_src/renders/launchramp_raw.png b/assets_src/renders/launchramp_raw.png new file mode 100644 index 0000000..e3c920d Binary files /dev/null and b/assets_src/renders/launchramp_raw.png differ diff --git a/assets_src/renders/selector.png b/assets_src/renders/selector.png new file mode 100644 index 0000000..74de6d3 Binary files /dev/null and b/assets_src/renders/selector.png differ diff --git a/assets_src/renders/selector_raw.png b/assets_src/renders/selector_raw.png new file mode 100644 index 0000000..bbfaf90 Binary files /dev/null and b/assets_src/renders/selector_raw.png differ diff --git a/assets_src/renders_topdown/boombike.png b/assets_src/renders_topdown/boombike.png new file mode 100644 index 0000000..1a2f556 Binary files /dev/null and b/assets_src/renders_topdown/boombike.png differ diff --git a/assets_src/renders_topdown/boombike_raw.png b/assets_src/renders_topdown/boombike_raw.png new file mode 100644 index 0000000..40df1a9 Binary files /dev/null and b/assets_src/renders_topdown/boombike_raw.png differ diff --git a/assets_src/renders_topdown/compressor.png b/assets_src/renders_topdown/compressor.png new file mode 100644 index 0000000..96d03da Binary files /dev/null and b/assets_src/renders_topdown/compressor.png differ diff --git a/assets_src/renders_topdown/compressor_raw.png b/assets_src/renders_topdown/compressor_raw.png new file mode 100644 index 0000000..942a790 Binary files /dev/null and b/assets_src/renders_topdown/compressor_raw.png differ diff --git a/assets_src/renders_topdown/crawler.png b/assets_src/renders_topdown/crawler.png new file mode 100644 index 0000000..b38830b Binary files /dev/null and b/assets_src/renders_topdown/crawler.png differ diff --git a/assets_src/renders_topdown/crawler_raw.png b/assets_src/renders_topdown/crawler_raw.png new file mode 100644 index 0000000..3456ac9 Binary files /dev/null and b/assets_src/renders_topdown/crawler_raw.png differ diff --git a/assets_src/renders_topdown/flyer45.png b/assets_src/renders_topdown/flyer45.png new file mode 100644 index 0000000..5afc3ef Binary files /dev/null and b/assets_src/renders_topdown/flyer45.png differ diff --git a/assets_src/renders_topdown/flyer45_raw.png b/assets_src/renders_topdown/flyer45_raw.png new file mode 100644 index 0000000..3ffec2f Binary files /dev/null and b/assets_src/renders_topdown/flyer45_raw.png differ diff --git a/assets_src/renders_topdown/waxseed.png b/assets_src/renders_topdown/waxseed.png new file mode 100644 index 0000000..5cc6cc5 Binary files /dev/null and b/assets_src/renders_topdown/waxseed.png differ diff --git a/assets_src/renders_topdown/waxseed_raw.png b/assets_src/renders_topdown/waxseed_raw.png new file mode 100644 index 0000000..e9125a7 Binary files /dev/null and b/assets_src/renders_topdown/waxseed_raw.png differ diff --git a/mods/vinylgod/chrome/assets/production-icons.png b/mods/vinylgod/chrome/assets/production-icons.png index eba5bcf..650d378 100644 Binary files a/mods/vinylgod/chrome/assets/production-icons.png and b/mods/vinylgod/chrome/assets/production-icons.png differ diff --git a/mods/vinylgod/chrome/chrome.yaml b/mods/vinylgod/chrome/chrome.yaml index 13de231..98f7f81 100644 --- a/mods/vinylgod/chrome/chrome.yaml +++ b/mods/vinylgod/chrome/chrome.yaml @@ -403,3 +403,6 @@ production-icons: vehicle: 0, 32, 16, 16 vehicle-disabled: 16, 32, 16, 16 vehicle-alert: 32, 32, 16, 16 + aircraft: 0, 48, 16, 16 + aircraft-disabled: 16, 48, 16, 16 + aircraft-alert: 32, 48, 16, 16 diff --git a/mods/vinylgod/chrome/layouts/ingame-player.yaml b/mods/vinylgod/chrome/layouts/ingame-player.yaml index 8ab1b06..43274a1 100644 --- a/mods/vinylgod/chrome/layouts/ingame-player.yaml +++ b/mods/vinylgod/chrome/layouts/ingame-player.yaml @@ -93,3 +93,14 @@ Container@PLAYER_WIDGETS: X: 7 Y: 7 ImageCollection: production-icons + ProductionTypeButton@AIRCRAFT: + Y: 99 + Width: 30 + Height: 30 + Background: button + ProductionGroup: Aircraft + Children: + Image@ICON: + X: 7 + Y: 7 + ImageCollection: production-icons diff --git a/mods/vinylgod/fluent/rules.ftl b/mods/vinylgod/fluent/rules.ftl index 090f98c..11ba81a 100644 --- a/mods/vinylgod/fluent/rules.ftl +++ b/mods/vinylgod/fluent/rules.ftl @@ -87,3 +87,23 @@ power-thedrop = power-theshuffle = .name = THE SHUFFLE .description = Reality-compression strike. Terms of service apply. + +## round 5: heroes, scouts, air +actor-selector = + .name = The Selector +actor-curator = + .name = The Curator +actor-boombike = + .name = Boom Bike +actor-crawler = + .name = Crawler +actor-flyer45 = + .name = 45 Flyer +actor-compressor = + .name = Compression Drone +actor-launchramp = + .name = Launch Ramp +actor-droneport = + .name = Drone Port +actor-waxseed = + .name = Wax Seep diff --git a/mods/vinylgod/maps/arena/map.png b/mods/vinylgod/maps/arena/map.png index 100a5ea..d85d7dc 100644 Binary files a/mods/vinylgod/maps/arena/map.png and b/mods/vinylgod/maps/arena/map.png differ diff --git a/mods/vinylgod/maps/arena/map.yaml b/mods/vinylgod/maps/arena/map.yaml index 8c5c05d..50a3c23 100644 --- a/mods/vinylgod/maps/arena/map.yaml +++ b/mods/vinylgod/maps/arena/map.yaml @@ -58,5 +58,11 @@ Actors: Actor4: scraper Owner: BotB Location: 24,25 + waxseed0: waxseed + Owner: Neutral + Location: 8,20 + waxseed1: waxseed + Owner: Neutral + Location: 18,10 Rules: rules.yaml diff --git a/mods/vinylgod/maps/compression/map.png b/mods/vinylgod/maps/compression/map.png index 2d636cd..45627d1 100644 Binary files a/mods/vinylgod/maps/compression/map.png and b/mods/vinylgod/maps/compression/map.png differ diff --git a/mods/vinylgod/maps/compression/map.yaml b/mods/vinylgod/maps/compression/map.yaml index 550793b..950969b 100644 --- a/mods/vinylgod/maps/compression/map.yaml +++ b/mods/vinylgod/maps/compression/map.yaml @@ -76,3 +76,30 @@ Actors: Actor5: mpspawn Owner: Multi5 Location: 45,84 + waxseed0: waxseed + Owner: Neutral + Location: 12,45 + waxseed1: waxseed + Owner: Neutral + Location: 20,20 + waxseed2: waxseed + Owner: Neutral + Location: 20,71 + waxseed3: waxseed + Owner: Neutral + Location: 45,45 + waxseed4: waxseed + Owner: Neutral + Location: 45,25 + waxseed5: waxseed + Owner: Neutral + Location: 45,66 + waxseed6: waxseed + Owner: Neutral + Location: 71,20 + waxseed7: waxseed + Owner: Neutral + Location: 71,71 + waxseed8: waxseed + Owner: Neutral + Location: 79,45 diff --git a/mods/vinylgod/maps/district/map.png b/mods/vinylgod/maps/district/map.png index 21276e9..0540620 100644 Binary files a/mods/vinylgod/maps/district/map.png and b/mods/vinylgod/maps/district/map.png differ diff --git a/mods/vinylgod/maps/district/map.yaml b/mods/vinylgod/maps/district/map.yaml index 95fb87a..8be80a1 100644 --- a/mods/vinylgod/maps/district/map.yaml +++ b/mods/vinylgod/maps/district/map.yaml @@ -60,3 +60,30 @@ Actors: Actor3: mpspawn Owner: Multi3 Location: 57,57 + waxseed0: waxseed + Owner: Neutral + Location: 10,32 + waxseed1: waxseed + Owner: Neutral + Location: 16,16 + waxseed2: waxseed + Owner: Neutral + Location: 16,49 + waxseed3: waxseed + Owner: Neutral + Location: 32,32 + waxseed4: waxseed + Owner: Neutral + Location: 32,10 + waxseed5: waxseed + Owner: Neutral + Location: 32,55 + waxseed6: waxseed + Owner: Neutral + Location: 49,16 + waxseed7: waxseed + Owner: Neutral + Location: 49,49 + waxseed8: waxseed + Owner: Neutral + Location: 55,32 diff --git a/mods/vinylgod/maps/needledrop/map.png b/mods/vinylgod/maps/needledrop/map.png index d404cf8..7e31e30 100644 Binary files a/mods/vinylgod/maps/needledrop/map.png and b/mods/vinylgod/maps/needledrop/map.png differ diff --git a/mods/vinylgod/maps/needledrop/map.yaml b/mods/vinylgod/maps/needledrop/map.yaml index ebe7358..747faac 100644 --- a/mods/vinylgod/maps/needledrop/map.yaml +++ b/mods/vinylgod/maps/needledrop/map.yaml @@ -44,3 +44,18 @@ Actors: Actor1: mpspawn Owner: Multi1 Location: 34,20 + waxseed0: waxseed + Owner: Neutral + Location: 7,7 + waxseed1: waxseed + Owner: Neutral + Location: 7,34 + waxseed2: waxseed + Owner: Neutral + Location: 20,20 + waxseed3: waxseed + Owner: Neutral + Location: 34,7 + waxseed4: waxseed + Owner: Neutral + Location: 34,34 diff --git a/mods/vinylgod/maps/shellmap/map.png b/mods/vinylgod/maps/shellmap/map.png index 100a5ea..d85d7dc 100644 Binary files a/mods/vinylgod/maps/shellmap/map.png and b/mods/vinylgod/maps/shellmap/map.png differ diff --git a/mods/vinylgod/maps/shellmap/map.yaml b/mods/vinylgod/maps/shellmap/map.yaml index 679fe75..3b4bab1 100644 --- a/mods/vinylgod/maps/shellmap/map.yaml +++ b/mods/vinylgod/maps/shellmap/map.yaml @@ -52,3 +52,9 @@ Actors: Actor8: adblocker Owner: Creeps Location: 25,22 + waxseed0: waxseed + Owner: Neutral + Location: 8,20 + waxseed1: waxseed + Owner: Neutral + Location: 18,10 diff --git a/mods/vinylgod/maps/vinylgod/map.png b/mods/vinylgod/maps/vinylgod/map.png index 100a5ea..d85d7dc 100644 Binary files a/mods/vinylgod/maps/vinylgod/map.png and b/mods/vinylgod/maps/vinylgod/map.png differ diff --git a/mods/vinylgod/maps/vinylgod/map.yaml b/mods/vinylgod/maps/vinylgod/map.yaml index 1613021..356d41c 100644 --- a/mods/vinylgod/maps/vinylgod/map.yaml +++ b/mods/vinylgod/maps/vinylgod/map.yaml @@ -36,3 +36,9 @@ Actors: Actor0: mpspawn Owner: Multi0 Location: 16,16 + waxseed0: waxseed + Owner: Neutral + Location: 10,10 + waxseed1: waxseed + Owner: Neutral + Location: 24,23 diff --git a/mods/vinylgod/rules/combat.yaml b/mods/vinylgod/rules/combat.yaml index 61e559e..392c581 100644 --- a/mods/vinylgod/rules/combat.yaml +++ b/mods/vinylgod/rules/combat.yaml @@ -215,3 +215,152 @@ algorithm: DisplayRadarPing: true SupportPowerPaletteOrder: 10 SupportPowerChargeBar: + +# --- round 5: MRP hero + scout --- + +selector: + Inherits: ^ArmedUnit + Voiced: + VoiceSet: MrpVoice + Buildable: + Queue: Infantry + BuildPaletteOrder: 30 + Prerequisites: mastering + BuildLimit: 1 + Valued: + Cost: 2000 + Tooltip: + Name: actor-selector.name + Health: + HP: 40000 + Armor: + Type: None + Mobile: + Locomotor: foot + Speed: 42 + Armament: + Weapon: dubplate + RevealsShroud: + Range: 7c0 + SelectionDecorations: + +boombike: + Inherits: ^ArmedUnit + Voiced: + VoiceSet: MrpVoice + -WithSpriteBody: + WithFacingSpriteBody: + Buildable: + Queue: Vehicle + BuildPaletteOrder: 35 + Prerequisites: garage + Valued: + Cost: 400 + Tooltip: + Name: actor-boombike.name + Health: + HP: 15000 + Armor: + Type: Light + Mobile: + Locomotor: wheeled + Speed: 140 + Armament: + Weapon: bike_horn + RevealsShroud: + Range: 8c0 + +# --- round 5: air --- +# ponytail: aircraft are Targetable as GroundActor too, so existing weapons can +# hit them. Upgrade path: dedicated AA armaments + AirborneActor-only targeting. + +^AirUnit: + BodyOrientation: + QuantizeFacingsFromSequence: + RenderSprites: + WithFacingSpriteBody: + SelectionDecorations: + AppearsOnRadar: + UseLocation: true + HitShape: + HiddenUnderFog: + Type: GroundPosition + Selectable: + Bounds: 1024, 1024 + Targetable: + TargetTypes: GroundActor, AirborneActor + MustBeDestroyed: + FireWarheadsOnDeath: + Weapon: UnitExplode + Aircraft: + CanHover: True + CanSlide: True + VTOL: True + IdleBehavior: Land + LandableTerrainTypes: Clear, Wax + AirborneCondition: airborne + CruisingCondition: cruising + Hovers@CRUISING: + RequiresCondition: cruising + AttackMove: + Guard: + Guardable: + AutoTarget: + AutoTargetPriority@DEFAULT: + ValidTargets: GroundActor, Structure + RevealsShroud: + Range: 7c0 + Type: CenterPosition + MapEditorData: + Categories: Aircraft + +flyer45: + Inherits: ^AirUnit + Voiced: + VoiceSet: MrpVoice + Buildable: + Queue: Aircraft + BuildPaletteOrder: 10 + Prerequisites: launchramp + Valued: + Cost: 900 + Tooltip: + Name: actor-flyer45.name + Health: + HP: 22000 + Armor: + Type: Light + Aircraft: + Speed: 149 + Armament: + Weapon: rotor_blade + PauseOnCondition: !ammo + AttackAircraft: + AttackType: Hover + FacingTolerance: 90 + AmmoPool: + Ammo: 12 + ReloadDelay: 24 + AmmoCondition: ammo + +launchramp: + Inherits: ^EconBuilding + Inherits@shape: ^Buildable2x2 + Buildable: + Queue: Building + BuildPaletteOrder: 55 + Prerequisites: garage + Valued: + Cost: 800 + Tooltip: + Name: actor-launchramp.name + Health: + HP: 70000 + Production: + Produces: Aircraft + Exit@1: + SpawnOffset: 0,-256,0 + ExitCell: 0,0 + Reservable: + Power: + Amount: -20 diff --git a/mods/vinylgod/rules/economy.yaml b/mods/vinylgod/rules/economy.yaml index 31c15a6..6ed396b 100644 --- a/mods/vinylgod/rules/economy.yaml +++ b/mods/vinylgod/rules/economy.yaml @@ -263,3 +263,27 @@ garage: ExitCell: 0, 2 Power: Amount: -20 + +# --- round 5: wax seep points (regrow the fields; see LORE.md "Wax seeps") --- + +waxseed: + BodyOrientation: + RenderSprites: + WithSpriteBody: + Interactable: + HiddenUnderShroud: + Building: + Footprint: x + Dimensions: 1,1 + TerrainTypes: Clear, Wax + AppearsOnRadar: + RadarColorFromTerrain: + Terrain: Wax + AppearsOnMapPreview: + Terrain: Wax + SeedsResource: + ResourceType: Wax + Interval: 90 + MaxRange: 60 + MapEditorData: + Categories: Resource spawn diff --git a/mods/vinylgod/rules/player.yaml b/mods/vinylgod/rules/player.yaml index 792a84d..fa03c81 100644 --- a/mods/vinylgod/rules/player.yaml +++ b/mods/vinylgod/rules/player.yaml @@ -26,6 +26,10 @@ player: Type: Infantry Group: Infantry ReadyAudio: UnitReady + ClassicProductionQueue@Aircraft: + Type: Aircraft + Group: Aircraft + ReadyAudio: UnitReady ConquestVictoryConditions: MissionObjectives: WinNotification: Win diff --git a/mods/vinylgod/rules/stream.yaml b/mods/vinylgod/rules/stream.yaml index a2a2d70..72067eb 100644 --- a/mods/vinylgod/rules/stream.yaml +++ b/mods/vinylgod/rules/stream.yaml @@ -202,3 +202,108 @@ drmwalker: Speed: 42 Armament: Weapon: feedback_burst + +# --- round 5: Stream hero + scout --- + +curator: + Inherits: ^ArmedUnit + Voiced: + VoiceSet: StreamVoice + Buildable: + Queue: Infantry + BuildPaletteOrder: 30 + Prerequisites: algorithm + BuildLimit: 1 + Valued: + Cost: 2000 + Tooltip: + Name: actor-curator.name + Health: + HP: 25000 + Armor: + Type: Light + Mobile: + Locomotor: foot + Speed: 95 + Armament: + Weapon: curator_beam + RevealsShroud: + Range: 8c0 + SelectionDecorations: + +crawler: + Inherits: ^Unit + Voiced: + VoiceSet: StreamVoice + -WithSpriteBody: + WithFacingSpriteBody: + Buildable: + Queue: Vehicle + BuildPaletteOrder: 15 + Prerequisites: transcoder + Valued: + Cost: 300 + Tooltip: + Name: actor-crawler.name + Health: + HP: 10000 + Armor: + Type: Light + Mobile: + Locomotor: wheeled + Speed: 155 + RevealsShroud: + Range: 10c0 + +# --- round 5: air --- + +compressor: + Inherits: ^AirUnit + Voiced: + VoiceSet: StreamVoice + Buildable: + Queue: Aircraft + BuildPaletteOrder: 11 + Prerequisites: droneport + Valued: + Cost: 700 + Tooltip: + Name: actor-compressor.name + Health: + HP: 16000 + Armor: + Type: Light + Aircraft: + Speed: 170 + Armament: + Weapon: compress_field + PauseOnCondition: !ammo + AttackAircraft: + AttackType: Hover + FacingTolerance: 90 + AmmoPool: + Ammo: 10 + ReloadDelay: 20 + AmmoCondition: ammo + +droneport: + Inherits: ^EconBuilding + Inherits@shape: ^Buildable2x2 + Buildable: + Queue: Building + BuildPaletteOrder: 56 + Prerequisites: printfarm + Valued: + Cost: 800 + Tooltip: + Name: actor-droneport.name + Health: + HP: 60000 + Production: + Produces: Aircraft + Exit@1: + SpawnOffset: 0,-256,0 + ExitCell: 0,0 + Reservable: + Power: + Amount: -20 diff --git a/mods/vinylgod/sequences/assets/boombike.png b/mods/vinylgod/sequences/assets/boombike.png new file mode 100644 index 0000000..b28f17d Binary files /dev/null and b/mods/vinylgod/sequences/assets/boombike.png differ diff --git a/mods/vinylgod/sequences/assets/compressor.png b/mods/vinylgod/sequences/assets/compressor.png new file mode 100644 index 0000000..30939a2 Binary files /dev/null and b/mods/vinylgod/sequences/assets/compressor.png differ diff --git a/mods/vinylgod/sequences/assets/crawler.png b/mods/vinylgod/sequences/assets/crawler.png new file mode 100644 index 0000000..117bda6 Binary files /dev/null and b/mods/vinylgod/sequences/assets/crawler.png differ diff --git a/mods/vinylgod/sequences/assets/curator.png b/mods/vinylgod/sequences/assets/curator.png new file mode 100644 index 0000000..f3cff42 Binary files /dev/null and b/mods/vinylgod/sequences/assets/curator.png differ diff --git a/mods/vinylgod/sequences/assets/droneport.png b/mods/vinylgod/sequences/assets/droneport.png new file mode 100644 index 0000000..92a1e43 Binary files /dev/null and b/mods/vinylgod/sequences/assets/droneport.png differ diff --git a/mods/vinylgod/sequences/assets/flyer45.png b/mods/vinylgod/sequences/assets/flyer45.png new file mode 100644 index 0000000..7bb5ab2 Binary files /dev/null and b/mods/vinylgod/sequences/assets/flyer45.png differ diff --git a/mods/vinylgod/sequences/assets/icon_curator.png b/mods/vinylgod/sequences/assets/icon_curator.png new file mode 100644 index 0000000..6fb5f38 Binary files /dev/null and b/mods/vinylgod/sequences/assets/icon_curator.png differ diff --git a/mods/vinylgod/sequences/assets/icon_droneport.png b/mods/vinylgod/sequences/assets/icon_droneport.png new file mode 100644 index 0000000..67fc69d Binary files /dev/null and b/mods/vinylgod/sequences/assets/icon_droneport.png differ diff --git a/mods/vinylgod/sequences/assets/icon_launchramp.png b/mods/vinylgod/sequences/assets/icon_launchramp.png new file mode 100644 index 0000000..8970d41 Binary files /dev/null and b/mods/vinylgod/sequences/assets/icon_launchramp.png differ diff --git a/mods/vinylgod/sequences/assets/icon_selector.png b/mods/vinylgod/sequences/assets/icon_selector.png new file mode 100644 index 0000000..02b95d6 Binary files /dev/null and b/mods/vinylgod/sequences/assets/icon_selector.png differ diff --git a/mods/vinylgod/sequences/assets/launchramp.png b/mods/vinylgod/sequences/assets/launchramp.png new file mode 100644 index 0000000..7a12691 Binary files /dev/null and b/mods/vinylgod/sequences/assets/launchramp.png differ diff --git a/mods/vinylgod/sequences/assets/selector.png b/mods/vinylgod/sequences/assets/selector.png new file mode 100644 index 0000000..34c0894 Binary files /dev/null and b/mods/vinylgod/sequences/assets/selector.png differ diff --git a/mods/vinylgod/sequences/assets/waxseed.png b/mods/vinylgod/sequences/assets/waxseed.png new file mode 100644 index 0000000..d3b1a49 Binary files /dev/null and b/mods/vinylgod/sequences/assets/waxseed.png differ diff --git a/mods/vinylgod/sequences/economy.yaml b/mods/vinylgod/sequences/economy.yaml index 75dc933..417b76e 100644 --- a/mods/vinylgod/sequences/economy.yaml +++ b/mods/vinylgod/sequences/economy.yaml @@ -213,3 +213,59 @@ smoke_m: Filename: sequences/assets/smoke.png Start: 6 Length: 2 + +selector: + idle: + Filename: sequences/assets/selector.png + icon: + Filename: sequences/assets/icon_selector.png + +curator: + idle: + Filename: sequences/assets/curator.png + icon: + Filename: sequences/assets/icon_curator.png + +launchramp: + idle: + Filename: sequences/assets/launchramp.png + icon: + Filename: sequences/assets/icon_launchramp.png + +droneport: + idle: + Filename: sequences/assets/droneport.png + icon: + Filename: sequences/assets/icon_droneport.png + +boombike: + idle: + Filename: sequences/assets/boombike.png + Facings: 16 + icon: + Filename: sequences/assets/icon_boombike.png + +crawler: + idle: + Filename: sequences/assets/crawler.png + Facings: 16 + icon: + Filename: sequences/assets/icon_crawler.png + +flyer45: + idle: + Filename: sequences/assets/flyer45.png + Facings: 16 + icon: + Filename: sequences/assets/icon_flyer45.png + +compressor: + idle: + Filename: sequences/assets/compressor.png + Facings: 16 + icon: + Filename: sequences/assets/icon_compressor.png + +waxseed: + idle: + Filename: sequences/assets/waxseed.png diff --git a/mods/vinylgod/weapons/vinylgod.yaml b/mods/vinylgod/weapons/vinylgod.yaml index 6ec2e0d..2ca502d 100644 --- a/mods/vinylgod/weapons/vinylgod.yaml +++ b/mods/vinylgod/weapons/vinylgod.yaml @@ -153,3 +153,104 @@ theshuffle_impact: Explosions: bigboom ImpactSounds: audio/sfx_boom.wav ValidTargets: Ground, GroundActor + +# --- round 5: heroes, scouts, air --- + +dubplate: + Inherits: ^GroundWeapon + Report: audio/sfx_throw.wav + ReloadDelay: 90 + Range: 5c512 + Projectile: Bullet + Speed: 448 + LaunchAngle: 40 + Image: seven_inch_proj + Sequences: idle + Warhead@1Dam: SpreadDamage + Spread: 426 + Damage: 9000 + ValidTargets: GroundActor + Versus: + None: 100 + Wood: 90 + Light: 85 + Heavy: 65 + Warhead@2Eff: CreateEffect + Explosions: bigboom + ImpactSounds: audio/sfx_boom.wav + ValidTargets: Ground, GroundActor + +curator_beam: + Inherits: ^GroundWeapon + Report: audio/sfx_zap.wav + ReloadDelay: 8 + Range: 4c512 + Warhead@1Dam: SpreadDamage + Spread: 42 + Damage: 1100 + ValidTargets: GroundActor + Versus: + None: 70 + Wood: 80 + Light: 110 + Heavy: 120 + Warhead@2Eff: CreateEffect + Explosions: pop + ValidTargets: Ground, GroundActor + +bike_horn: + Inherits: ^GroundWeapon + Report: audio/sfx_bass.wav + ReloadDelay: 35 + Range: 2c512 + Warhead@1Dam: SpreadDamage + Spread: 128 + Damage: 1400 + ValidTargets: GroundActor + Versus: + None: 120 + Wood: 30 + Light: 40 + Heavy: 10 + Warhead@2Eff: CreateEffect + Explosions: pop + ImpactSounds: audio/sfx_pop.wav + ValidTargets: Ground, GroundActor + +rotor_blade: + Inherits: ^GroundWeapon + Report: audio/sfx_throw.wav + ReloadDelay: 22 + Range: 3c512 + Warhead@1Dam: SpreadDamage + Spread: 96 + Damage: 2600 + ValidTargets: GroundActor + Versus: + None: 95 + Wood: 60 + Light: 90 + Heavy: 55 + Warhead@2Eff: CreateEffect + Explosions: pop + ImpactSounds: audio/sfx_pop.wav + ValidTargets: Ground, GroundActor + +compress_field: + Inherits: ^GroundWeapon + Report: audio/sfx_zap.wav + ReloadDelay: 28 + Range: 3c256 + Warhead@1Dam: SpreadDamage + Spread: 213 + Damage: 1900 + ValidTargets: GroundActor + Versus: + None: 110 + Wood: 70 + Light: 80 + Heavy: 45 + Warhead@2Eff: CreateEffect + Explosions: pop + ImpactSounds: audio/sfx_pop.wav + ValidTargets: Ground, GroundActor diff --git a/tools/mbfacings.py b/tools/mbfacings.py index a1ba744..3bb385e 100644 --- a/tools/mbfacings.py +++ b/tools/mbfacings.py @@ -30,6 +30,11 @@ VEHICLES = [ ('streamvan', 26, STR + 'sleek white autonomous delivery van with blue play-button roof logo'), ('scraper', 24, STR + 'white autonomous street sweeper vehicle with glowing blue front intake'), ('drmwalker', 30, STR + 'white quad-legged mech with one blue ring light, seen from above'), + # round 5: scouts + aircraft + ('boombike', 20, MRP + 'small fast motorbike trike with two loudspeaker cones mounted on the back'), + ('crawler', 18, STR + 'small flat white six-wheeled scout rover with a blue sensor dome'), + ('flyer45', 22, MRP + 'flying machine built from a black vinyl record with spinning tonearm rotor blades and a small rusty engine pod'), + ('compressor', 22, STR + 'white quadcopter drone with four rotors and a glowing blue lens underneath'), ] @@ -47,7 +52,12 @@ def sheet16(im, size, out): print(f'[facings] {out}', flush=True) +only = [a for a in sys.argv[1:] if not a.startswith('-')] +skip_world = '--units-only' in sys.argv + for name, size, prompt in VEHICLES: + if only and name not in only: + continue raw = os.path.join(RENDERS, f'{name}_raw.png') cut = os.path.join(RENDERS, f'{name}.png') if not os.path.exists(cut): @@ -55,6 +65,10 @@ for name, size, prompt in VEHICLES: run('bg_remove_local', {}, cut, asset_id=upload(raw)) sheet16(Image.open(cut).convert('RGBA'), size, os.path.join(ASSETS, f'{name}.png')) +if skip_world or only: + print('ALL DONE (units only)') + sys.exit(0) + # terrain tile: seamless ground texture -> 32x32 traw = os.path.join(RENDERS, 'terrain_raw.png') if not os.path.exists(traw): diff --git a/tools/mbsprites.py b/tools/mbsprites.py index b981606..297e762 100644 --- a/tools/mbsprites.py +++ b/tools/mbsprites.py @@ -43,6 +43,11 @@ ACTORS = [ ('scraper', 22, STR + 'autonomous white street sweeper vehicle inhaling black vinyl through a glowing blue intake'), ('bufferbot', 14, STR + 'knee-high white sphere robot with a loading spinner face'), ('drmwalker', 28, STR + 'tall faceless white mech with one blue ring-light eye and a glowing paywall screen chest'), + # round 5: heroes + air bases + ('selector', 22, MRP + 'legendary hero DJ robot in a long coat with a crate of glowing gold dubplates under one arm and a tonearm staff'), + ('curator', 22, STR + 'hovering white sphere ringed with many camera lenses, a single blue eye at the front, faint halo'), + ('launchramp', 64, MRP + 'scrap metal launch ramp pad with painted pink chevrons, floodlights and a parked flying vinyl disc'), + ('droneport', 64, STR + 'white circular drone landing pad building with recessed blue guide lights and folded launch arms'), ] diff --git a/tools/place_seeds.py b/tools/place_seeds.py new file mode 100644 index 0000000..e6f202c --- /dev/null +++ b/tools/place_seeds.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python3 +"""Place a neutral `waxseed` actor at the centre of every wax blob on every map. + +Reads the resource plane straight out of each map.bin, finds blob centroids by +flood fill, and appends the actors to map.yaml. Idempotent: strips previously +placed waxseed entries first. +""" +import os, re, struct, glob + +MAPS = glob.glob(os.path.join(os.path.dirname(__file__), '..', 'mods', 'vinylgod', 'maps', '*')) + + +def resource_cells(path): + d = open(path, 'rb').read() + fmt, w, h = d[0], *struct.unpack_from('= 6: # ignore specks + out.append((round(sum(p[0] for p in blob) / len(blob)), + round(sum(p[1] for p in blob) / len(blob)))) + return out + + +for mapdir in sorted(MAPS): + my, mb = os.path.join(mapdir, 'map.yaml'), os.path.join(mapdir, 'map.bin') + if not (os.path.exists(my) and os.path.exists(mb)): + continue + centres = blobs(resource_cells(mb)) + s = open(my).read() + s = re.sub(r'\n\twaxseed\d+: waxseed\n\t\tOwner: Neutral\n\t\tLocation: \d+,\d+', '', s) + if 'Actors:' not in s: + s = s.rstrip() + '\n\nActors:\n' + block = ''.join(f'\n\twaxseed{i}: waxseed\n\t\tOwner: Neutral\n\t\tLocation: {x},{y}' + for i, (x, y) in enumerate(centres)) + # append to the Actors section (it is the last block in our generated maps) + head, _, tail = s.partition('Actors:') + lines = tail.split('\n') + cut = len(lines) + for i, ln in enumerate(lines): + if ln and not ln.startswith('\t') and i > 0: # next top-level key + cut = i + break + tail = '\n'.join(lines[:cut]).rstrip() + block + '\n' + '\n'.join(lines[cut:]) + open(my, 'w').write(head + 'Actors:' + tail) + print(f'{os.path.basename(mapdir)}: {len(centres)} seep(s) at {centres}')