Decree two: construction buildup anims, Boombox Crates, real faction flags, character portraits
* All 17 buildings now RISE out of the ground behind a pink scan line when built (tools/make_anims.py generates 7-frame make sequences; WithMakeAnimation on the building template). * Boombox Crates: neutral pickups spawn on a timer (max 4). 500 records usually, 1500 jackpot sometimes, bass_ring feedback trap rarely. Locomotors crush crates to collect, classic style. * Lobby faction flags are real now: MRP record, Stream play button, split '?'. * MC 8-TRACK and ASSISTANT portraits generated for briefings/press kit. * Balance ledger updated: first aura-era match went to Stream (runaway flag); full ledger M M M | S S | M | S — boundary variance, no knee-jerk tune. Smoke-tested PASS on arena and m01 with everything live. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ -198,8 +198,11 @@ faction, or it reads as clip-art soup. Fix the Blender camera rig once, reuse.
|
||||
Six instrumented arena matches so far: 3x MRP blowouts (structural AI bugs,
|
||||
fixed), 2x Stream blowouts (buff overshoot: scraper 18 / drmwalker 750),
|
||||
then 1x close 12-min MRP win with zero verdict flags after the half-step
|
||||
walk-back (scraper 16, drmwalker 820, bufferbot 5000 kept). The matchup now
|
||||
flips with small knob changes = we are near the boundary. Acceptance test for
|
||||
walk-back (scraper 16, drmwalker 820, bufferbot 5000 kept), then 1x Stream win
|
||||
(runaway-flagged) in the first aura-era match. Full ledger: M M M | S S | M | S.
|
||||
The matchup now flips match to match = near the boundary with real variance.
|
||||
If Stream trends ahead over a series, first knobs: In The Mix range 5c0->6c0
|
||||
or Low Latency 130->120. Acceptance test for
|
||||
any future balance change: a 5-match arena series via balance_report.py, not
|
||||
a single game. Human playtesting is the real referee from here.
|
||||
|
||||
|
||||
@ -35,3 +35,7 @@ All images generated locally on MODELBEAST (`flux_local`) via `tools/mbgen.py`.
|
||||
| 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 |
|
||||
| renders/boombox.png | 2026-07-26 | rusty boombox ghetto blaster with hot pink speaker cones and a cassette deck, tiny video game pickup crate sprite |
|
||||
| portrait_mc8track.png | 2026-07-26 | character portrait of MC 8-TRACK, warm friendly rusty robot radio announcer, cassette-deck chest, glowing pink CRT smile |
|
||||
| portrait_assistant.png | 2026-07-26 | character portrait of ASSISTANT, eerily polite seamless white smart-speaker robot, single calm blue ring light face |
|
||||
| keyart_raw.png | 2026-07-26 | wide cinematic key art, monster robot holding vinyl aloft on hill of smashed speakers, white obelisk city, vinyl sun |
|
||||
|
||||
BIN
assets_src/portrait_assistant.png
Normal file
|
After Width: | Height: | Size: 1.0 MiB |
BIN
assets_src/portrait_mc8track.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
assets_src/renders/boombox.png
Normal file
|
After Width: | Height: | Size: 638 KiB |
BIN
assets_src/renders/boombox_raw.png
Normal file
|
After Width: | Height: | Size: 562 KiB |
BIN
mods/vinylgod/chrome/assets/flags.png
Normal file
|
After Width: | Height: | Size: 524 B |
@ -117,12 +117,12 @@ strategic:
|
||||
player_owned: 160, 142, 22, 22
|
||||
|
||||
flags:
|
||||
Inherits: ^Glyphs
|
||||
Image: chrome/assets/flags.png
|
||||
Regions:
|
||||
vinylgod: 226, 241, 30, 15
|
||||
stream: 226, 241, 30, 15
|
||||
Random: 226, 241, 30, 15
|
||||
spectator: 226, 241, 30, 15
|
||||
vinylgod: 0, 0, 30, 15
|
||||
stream: 0, 16, 30, 15
|
||||
Random: 0, 32, 30, 15
|
||||
spectator: 0, 32, 30, 15
|
||||
|
||||
music:
|
||||
Inherits: ^Glyphs
|
||||
|
||||
@ -109,3 +109,5 @@ actor-waxseed =
|
||||
.name = Wax Seep
|
||||
actor-lacquer =
|
||||
.name = Master Lacquer
|
||||
actor-boombox =
|
||||
.name = Boombox Crate
|
||||
|
||||
@ -116,6 +116,7 @@ djgrunt:
|
||||
|
||||
^EconBuilding:
|
||||
Inherits: ^EconSprite
|
||||
WithMakeAnimation:
|
||||
ShakeOnDeath:
|
||||
Duration: 12
|
||||
Intensity: 2
|
||||
@ -328,3 +329,29 @@ lacquer:
|
||||
HP: 1000
|
||||
MapEditorData:
|
||||
Categories: Props
|
||||
|
||||
# neutral pickup: the Boombox Crate. Cash mostly, jackpot sometimes, feedback trap rarely.
|
||||
boombox:
|
||||
Interactable:
|
||||
HiddenUnderFog:
|
||||
BodyOrientation:
|
||||
QuantizeFacingsFromSequence:
|
||||
RenderSprites:
|
||||
Tooltip:
|
||||
Name: actor-boombox.name
|
||||
Crate:
|
||||
Duration: 6000
|
||||
TerrainTypes: Clear, Wax
|
||||
WithCrateBody:
|
||||
LandSequence: idle
|
||||
GiveCashCrateAction:
|
||||
Amount: 500
|
||||
SelectionShares: 20
|
||||
UseCashTick: true
|
||||
GiveCashCrateAction@jackpot:
|
||||
Amount: 1500
|
||||
SelectionShares: 5
|
||||
UseCashTick: true
|
||||
ExplodeCrateAction@trap:
|
||||
Weapon: bass_ring
|
||||
SelectionShares: 5
|
||||
|
||||
@ -50,12 +50,14 @@ world:
|
||||
PanelName: SKIRMISH_STATS
|
||||
Locomotor@WHEELED:
|
||||
Name: wheeled
|
||||
Crushes: crate
|
||||
TerrainSpeeds:
|
||||
Clear: 100
|
||||
Wax: 80
|
||||
Locomotor@FOOT:
|
||||
Name: foot
|
||||
SharesCell: true
|
||||
Crushes: crate
|
||||
TerrainSpeeds:
|
||||
Clear: 100
|
||||
Wax: 70
|
||||
@ -73,6 +75,10 @@ world:
|
||||
Sequences: wax01
|
||||
Name: resource-wax
|
||||
ResourceClaimLayer:
|
||||
CrateSpawner:
|
||||
Maximum: 4
|
||||
SpawnInterval: 3000
|
||||
CrateActors: boombox
|
||||
ScreenShaker:
|
||||
SmudgeLayer@SCORCH:
|
||||
Type: Scorch
|
||||
|
||||
BIN
mods/vinylgod/sequences/assets/adblocker_make.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
mods/vinylgod/sequences/assets/algorithm_make.png
Normal file
|
After Width: | Height: | Size: 8.5 KiB |
BIN
mods/vinylgod/sequences/assets/ampstack_make.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
mods/vinylgod/sequences/assets/boombox.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
mods/vinylgod/sequences/assets/datacentre_make.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
mods/vinylgod/sequences/assets/droneport_make.png
Normal file
|
After Width: | Height: | Size: 9.2 KiB |
BIN
mods/vinylgod/sequences/assets/garage_make.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
mods/vinylgod/sequences/assets/hornpit_make.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
mods/vinylgod/sequences/assets/launchramp_make.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
mods/vinylgod/sequences/assets/mastering_make.png
Normal file
|
After Width: | Height: | Size: 8.9 KiB |
BIN
mods/vinylgod/sequences/assets/merchtable_make.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
mods/vinylgod/sequences/assets/podfarm_make.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
mods/vinylgod/sequences/assets/popupshop_make.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
mods/vinylgod/sequences/assets/pressplant_make.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
mods/vinylgod/sequences/assets/printfarm_make.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
mods/vinylgod/sequences/assets/streamhub_make.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
mods/vinylgod/sequences/assets/transcoder_make.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
mods/vinylgod/sequences/assets/vault_make.png
Normal file
|
After Width: | Height: | Size: 4.5 KiB |
@ -27,6 +27,10 @@ djgrunt:
|
||||
Filename: sequences/assets/icon_djgrunt.png
|
||||
|
||||
popupshop:
|
||||
make:
|
||||
Filename: sequences/assets/popupshop_make.png
|
||||
Length: 7
|
||||
Tick: 70
|
||||
idle:
|
||||
Filename: sequences/assets/popupshop.png
|
||||
Length: 6
|
||||
@ -35,6 +39,10 @@ popupshop:
|
||||
Filename: sequences/assets/icon_popupshop.png
|
||||
|
||||
pressplant:
|
||||
make:
|
||||
Filename: sequences/assets/pressplant_make.png
|
||||
Length: 7
|
||||
Tick: 70
|
||||
idle:
|
||||
Filename: sequences/assets/pressplant.png
|
||||
Length: 6
|
||||
@ -43,6 +51,10 @@ pressplant:
|
||||
Filename: sequences/assets/icon_pressplant.png
|
||||
|
||||
ampstack:
|
||||
make:
|
||||
Filename: sequences/assets/ampstack_make.png
|
||||
Length: 7
|
||||
Tick: 70
|
||||
idle:
|
||||
Filename: sequences/assets/ampstack.png
|
||||
Length: 6
|
||||
@ -51,6 +63,10 @@ ampstack:
|
||||
Filename: sequences/assets/icon_ampstack.png
|
||||
|
||||
vault:
|
||||
make:
|
||||
Filename: sequences/assets/vault_make.png
|
||||
Length: 7
|
||||
Tick: 70
|
||||
idle:
|
||||
Filename: sequences/assets/vault.png
|
||||
Length: 6
|
||||
@ -59,6 +75,10 @@ vault:
|
||||
Filename: sequences/assets/icon_vault.png
|
||||
|
||||
merchtable:
|
||||
make:
|
||||
Filename: sequences/assets/merchtable_make.png
|
||||
Length: 7
|
||||
Tick: 70
|
||||
idle:
|
||||
Filename: sequences/assets/merchtable.png
|
||||
Length: 6
|
||||
@ -67,6 +87,10 @@ merchtable:
|
||||
Filename: sequences/assets/icon_merchtable.png
|
||||
|
||||
garage:
|
||||
make:
|
||||
Filename: sequences/assets/garage_make.png
|
||||
Length: 7
|
||||
Tick: 70
|
||||
idle:
|
||||
Filename: sequences/assets/garage.png
|
||||
Length: 6
|
||||
@ -102,6 +126,10 @@ roadie:
|
||||
Filename: sequences/assets/icon_roadie.png
|
||||
|
||||
mastering:
|
||||
make:
|
||||
Filename: sequences/assets/mastering_make.png
|
||||
Length: 7
|
||||
Tick: 70
|
||||
idle:
|
||||
Filename: sequences/assets/mastering.png
|
||||
Length: 6
|
||||
@ -117,6 +145,10 @@ streamvan:
|
||||
Filename: sequences/assets/icon_streamvan.png
|
||||
|
||||
streamhub:
|
||||
make:
|
||||
Filename: sequences/assets/streamhub_make.png
|
||||
Length: 7
|
||||
Tick: 70
|
||||
idle:
|
||||
Filename: sequences/assets/streamhub.png
|
||||
Length: 6
|
||||
@ -125,6 +157,10 @@ streamhub:
|
||||
Filename: sequences/assets/icon_streamhub.png
|
||||
|
||||
datacentre:
|
||||
make:
|
||||
Filename: sequences/assets/datacentre_make.png
|
||||
Length: 7
|
||||
Tick: 70
|
||||
idle:
|
||||
Filename: sequences/assets/datacentre.png
|
||||
Length: 6
|
||||
@ -133,6 +169,10 @@ datacentre:
|
||||
Filename: sequences/assets/icon_datacentre.png
|
||||
|
||||
transcoder:
|
||||
make:
|
||||
Filename: sequences/assets/transcoder_make.png
|
||||
Length: 7
|
||||
Tick: 70
|
||||
idle:
|
||||
Filename: sequences/assets/transcoder.png
|
||||
Length: 6
|
||||
@ -141,6 +181,10 @@ transcoder:
|
||||
Filename: sequences/assets/icon_transcoder.png
|
||||
|
||||
podfarm:
|
||||
make:
|
||||
Filename: sequences/assets/podfarm_make.png
|
||||
Length: 7
|
||||
Tick: 70
|
||||
idle:
|
||||
Filename: sequences/assets/podfarm.png
|
||||
Length: 6
|
||||
@ -149,6 +193,10 @@ podfarm:
|
||||
Filename: sequences/assets/icon_podfarm.png
|
||||
|
||||
printfarm:
|
||||
make:
|
||||
Filename: sequences/assets/printfarm_make.png
|
||||
Length: 7
|
||||
Tick: 70
|
||||
idle:
|
||||
Filename: sequences/assets/printfarm.png
|
||||
Length: 6
|
||||
@ -190,6 +238,10 @@ explosion:
|
||||
Length: 12
|
||||
|
||||
hornpit:
|
||||
make:
|
||||
Filename: sequences/assets/hornpit_make.png
|
||||
Length: 7
|
||||
Tick: 70
|
||||
idle:
|
||||
Filename: sequences/assets/hornpit.png
|
||||
Length: 6
|
||||
@ -198,6 +250,10 @@ hornpit:
|
||||
Filename: sequences/assets/icon_hornpit.png
|
||||
|
||||
adblocker:
|
||||
make:
|
||||
Filename: sequences/assets/adblocker_make.png
|
||||
Length: 7
|
||||
Tick: 70
|
||||
idle:
|
||||
Filename: sequences/assets/adblocker.png
|
||||
Length: 6
|
||||
@ -224,6 +280,10 @@ icon:
|
||||
Filename: sequences/assets/icon_theshuffle.png
|
||||
|
||||
algorithm:
|
||||
make:
|
||||
Filename: sequences/assets/algorithm_make.png
|
||||
Length: 7
|
||||
Tick: 70
|
||||
idle:
|
||||
Filename: sequences/assets/algorithm.png
|
||||
Length: 6
|
||||
@ -257,6 +317,10 @@ curator:
|
||||
Filename: sequences/assets/icon_curator.png
|
||||
|
||||
launchramp:
|
||||
make:
|
||||
Filename: sequences/assets/launchramp_make.png
|
||||
Length: 7
|
||||
Tick: 70
|
||||
idle:
|
||||
Filename: sequences/assets/launchramp.png
|
||||
Length: 6
|
||||
@ -265,6 +329,10 @@ launchramp:
|
||||
Filename: sequences/assets/icon_launchramp.png
|
||||
|
||||
droneport:
|
||||
make:
|
||||
Filename: sequences/assets/droneport_make.png
|
||||
Length: 7
|
||||
Tick: 70
|
||||
idle:
|
||||
Filename: sequences/assets/droneport.png
|
||||
Length: 6
|
||||
@ -327,3 +395,7 @@ auras:
|
||||
Filename: sequences/assets/aura_mix.png
|
||||
latency:
|
||||
Filename: sequences/assets/aura_latency.png
|
||||
|
||||
boombox:
|
||||
idle:
|
||||
Filename: sequences/assets/boombox.png
|
||||
|
||||
61
tools/make_anims.py
Normal file
@ -0,0 +1,61 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate construction 'make' animations for every building.
|
||||
|
||||
7 frames per building: the structure rises out of the ground behind a hot pink
|
||||
scan line, classic buildup feel without hand-drawn scaffolding. Source frames
|
||||
are the static frame-0 backups maintained by animate_sprites.py.
|
||||
|
||||
Writes <name>_make.png sheets and appends `make:` sequences.
|
||||
"""
|
||||
import os
|
||||
from PIL import Image, ImageDraw
|
||||
from PIL.PngImagePlugin import PngInfo
|
||||
|
||||
ROOT = os.path.join(os.path.dirname(__file__), '..')
|
||||
ASSETS = os.path.join(ROOT, 'mods', 'vinylgod', 'sequences', 'assets')
|
||||
BACKUP = os.path.join(ROOT, 'assets_src', 'static_frames')
|
||||
SEQ = os.path.join(ROOT, 'mods', 'vinylgod', 'sequences', 'economy.yaml')
|
||||
|
||||
FRAMES = 7
|
||||
PINK = (255, 45, 150, 255)
|
||||
|
||||
BUILDINGS = ['popupshop', 'pressplant', 'ampstack', 'vault', 'merchtable', 'garage',
|
||||
'mastering', 'hornpit', 'streamhub', 'datacentre', 'transcoder', 'podfarm',
|
||||
'printfarm', 'adblocker', 'algorithm', 'launchramp', 'droneport']
|
||||
|
||||
seq = open(SEQ).read()
|
||||
made = []
|
||||
for name in BUILDINGS:
|
||||
src = os.path.join(BACKUP, f'{name}.png')
|
||||
if not os.path.exists(src):
|
||||
continue
|
||||
base = Image.open(src).convert('RGBA')
|
||||
w, h = base.size
|
||||
sheet = Image.new('RGBA', (w * FRAMES, h), (0, 0, 0, 0))
|
||||
for i in range(FRAMES):
|
||||
t = (i + 1) / FRAMES
|
||||
reveal = int(h * t) # rows revealed, bottom-up
|
||||
rise = int((1 - t) * h * 0.25) # slight rise from the ground
|
||||
frame = Image.new('RGBA', (w, h), (0, 0, 0, 0))
|
||||
part = base.crop((0, h - reveal, w, h))
|
||||
frame.paste(part, (0, h - reveal + rise), part)
|
||||
d = ImageDraw.Draw(frame)
|
||||
if i < FRAMES - 1:
|
||||
y = h - reveal + rise
|
||||
if 0 <= y < h:
|
||||
d.line([0, y, w, y], fill=PINK, width=2)
|
||||
sheet.paste(frame, (i * w, 0))
|
||||
meta = PngInfo()
|
||||
meta.add_text('FrameSize', f'{w},{h}')
|
||||
sheet.save(os.path.join(ASSETS, f'{name}_make.png'), pnginfo=meta)
|
||||
|
||||
block = f'{name}:\n\tidle:'
|
||||
if block in seq and f'{name}:\n\tidle:' in seq and f'sequences/assets/{name}_make.png' not in seq:
|
||||
seq = seq.replace(f'{name}:\n\tidle:',
|
||||
f'{name}:\n\tmake:\n\t\tFilename: sequences/assets/{name}_make.png\n'
|
||||
f'\t\tLength: {FRAMES}\n\t\tTick: 70\n\tidle:', 1)
|
||||
made.append(name)
|
||||
print(f'make anim: {name}')
|
||||
|
||||
open(SEQ, 'w').write(seq)
|
||||
print(f'{len(made)} buildup animations written')
|
||||