Add nerd glasses and the ...because he was bored... subtitle to the loading screen

This commit is contained in:
enne2
2026-10-11 02:08:20 +02:00
parent db2b57775c
commit e15deef84f
7 changed files with 133 additions and 53 deletions
+21 -12
View File
@@ -3,43 +3,52 @@
"file": "assets/branding/boot_splash.png",
"size": [
1024,
1185
1315
],
"mode": "P",
"palette_colors": 256,
"sha256": "4b4bab87b5038915d5a7493c6ee134cd654293036d093e71d210cbad6359bdb2"
"sha256": "715bd5f1dd3a651b1b5f6ee0560db232ddfdad676091f07ea34696787e27fbee"
},
"mascot_source": {
"file": "tools/branding/raw/agy_edit_20261010235510_0.jpg",
"sha256": "913184c2e2e3dd5357f7729988859c8e038e4561ba18af7cb60f12644f7f6994"
"file": "tools/branding/raw/agy_edit_20261011000309_0.jpg",
"sha256": "57bc1e46eb0876c02008038981c9b01a6bf4e02da78418de7b44f4fcbd93895e"
},
"generator": {
"tool": "agy_generate (Antigravity direct API)",
"model": "gemini-3.1-flash-image",
"date": "2026-10-11",
"prompt": "single cartoon zombie head-and-bust mascot, unsettling wide grin, thumbs up, 2D cartoon style with bold outlines, flat magenta chroma-key background, no text and no logo; then edited to a bald scalp with a sparse hair fringe on the sides only",
"prompt": "single cartoon zombie head-and-bust mascot, unsettling wide grin, thumbs up, 2D cartoon style with bold outlines, flat magenta chroma-key background, no text and no logo; then edited to a bald scalp with a sparse hair fringe on the sides only, then edited again to wear thick nerd glasses",
"terms_note": "generated from no third-party source material; the provider terms do not claim ownership of the output. The generator emits no real alpha channel, so the background is keyed out locally by this script."
},
"chroma_key": {
"background_rgb": [
246,
1,
237
244,
0,
233
],
"transparent_below": 55,
"opaque_above": 130
},
"title": {
"text": "MatGames",
"subtitle": "\"...because he was bored...\"",
"font": "tools/branding/fonts/VT323-Regular.ttf",
"license": "SIL Open Font License 1.1 (tools/branding/fonts/OFL.txt)"
},
"bottom_fade_px": 50,
"mascot_derived_from": [
"mascot_provenance": [
{
"file": "tools/branding/raw/agy_generate_20261010234423_0.jpg",
"sha256": "5929495ff606fbcdd74f52a37304f3b569315bcd1fc0fef812b5fd7689dc1396",
"edit": "AI edit (agy_edit): keep face, grin, thumbs up, shirt, pose and flat background; change the hair to a bald scalp with a sparse fringe on the sides only"
"sha256": "5929495ff606fbcdd74f52a37304f3b569315bcd1fc0fef812b5fd7689dc1396"
},
{
"file": "tools/branding/raw/agy_edit_20261010235510_0.jpg",
"sha256": "913184c2e2e3dd5357f7729988859c8e038e4561ba18af7cb60f12644f7f6994"
},
{
"file": "tools/branding/raw/agy_edit_20261011000309_0.jpg",
"sha256": "57bc1e46eb0876c02008038981c9b01a6bf4e02da78418de7b44f4fcbd93895e"
}
]
],
"bottom_padding_px": 30
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 529 KiB

@@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://b5pj4ipovpbo"
path="res://.godot/imported/agy_edit_20261011000309_0.jpg-c4ed4776ca2aca40794a7d66a2e8befc.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://tools/branding/raw/agy_edit_20261011000309_0.jpg"
dest_files=["res://.godot/imported/agy_edit_20261011000309_0.jpg-c4ed4776ca2aca40794a7d66a2e8befc.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
+39 -28
View File
@@ -14,14 +14,19 @@ from PIL import Image, ImageDraw, ImageFilter, ImageFont
parser = argparse.ArgumentParser()
parser.add_argument('raw', type=pathlib.Path, help='raw generated image (magenta background)')
parser.add_argument('--title', default='MatGames')
parser.add_argument('--subtitle', default='"...because he was bored..."',
help='second line under the title; empty string for none')
parser.add_argument('--subtitle-height', type=int, default=100)
parser.add_argument('--bottom-padding', type=int, default=30,
help='empty band under the text: the shell progress bar sits there')
parser.add_argument('--canvas', type=int, default=1024)
parser.add_argument('--title-height', type=int, default=190)
parser.add_argument('--bottom-fade', type=int, default=50,
help='soften the generator frame cut at the bottom of the bust')
parser.add_argument('--colors', type=int, default=256,
help='palette colors for the shipped PNG; 0 keeps 32-bit RGBA')
parser.add_argument('--generated-from', type=pathlib.Path, default=None,
help='pre-edit generation this file was derived from, for provenance')
parser.add_argument('--provenance', action='append', type=pathlib.Path, default=[],
help='earlier files of the generation/edit chain, in order; repeatable')
args = parser.parse_args()
args.raw = args.raw.resolve()
root = pathlib.Path(__file__).resolve().parents[1]
@@ -70,27 +75,34 @@ if args.bottom_fade > 0:
# ---------------------------------------------------------------- composition
canvas_width = args.canvas
title_area = args.title_height
title_area = args.title_height + (args.subtitle_height if args.subtitle else 0)
scale = (canvas_width - 2 * 40) / mascot.width
mascot = mascot.resize((round(mascot.width * scale), round(mascot.height * scale)), Image.LANCZOS)
height = mascot.height + title_area
height = mascot.height + title_area + args.bottom_padding
canvas = Image.new('RGBA', (canvas_width, height), (0, 0, 0, 0))
canvas.alpha_composite(mascot, ((canvas_width - mascot.width) // 2, 0))
font_size = int(title_area * 0.95)
font = ImageFont.truetype(str(font_path), font_size)
text = args.title
while font.getbbox(text)[2] - font.getbbox(text)[0] > canvas_width - 60 and font_size > 8:
font_size -= 2
font = ImageFont.truetype(str(font_path), font_size)
box = font.getbbox(text)
text_width = box[2] - box[0]
position = ((canvas_width - text_width) // 2 - box[0], mascot.height + (title_area - box[3]) // 2 - box[1])
glow = Image.new('RGBA', canvas.size, (0, 0, 0, 0))
ImageDraw.Draw(glow).text(position, text, font=font, fill=(255, 150, 20, 190))
glow = glow.filter(ImageFilter.GaussianBlur(9))
canvas.alpha_composite(glow)
ImageDraw.Draw(canvas).text(position, text, font=font, fill=(255, 196, 64, 255))
def _draw_line(text: str, block_top: int, block_height: int, size: int,
glow_color: tuple, text_color: tuple, blur: int) -> None:
font = ImageFont.truetype(str(font_path), size)
while font.getbbox(text)[2] - font.getbbox(text)[0] > canvas_width - 60 and size > 8:
size -= 2
font = ImageFont.truetype(str(font_path), size)
box = font.getbbox(text)
position = ((canvas_width - (box[2] - box[0])) // 2 - box[0],
block_top + (block_height - box[3]) // 2 - box[1])
glow = Image.new('RGBA', canvas.size, (0, 0, 0, 0))
ImageDraw.Draw(glow).text(position, text, font=font, fill=glow_color)
canvas.alpha_composite(glow.filter(ImageFilter.GaussianBlur(blur)))
ImageDraw.Draw(canvas).text(position, text, font=font, fill=text_color)
_draw_line(args.title, mascot.height, args.title_height, int(args.title_height * 0.95),
(255, 150, 20, 190), (255, 196, 64, 255), 9)
if args.subtitle:
_draw_line(args.subtitle, mascot.height + args.title_height, args.subtitle_height,
int(args.subtitle_height * 0.8), (255, 150, 20, 150), (255, 176, 58, 240), 6)
out = branding / 'boot_splash.png'
if args.colors > 0:
@@ -111,23 +123,22 @@ manifest.update({
'prompt': ('single cartoon zombie head-and-bust mascot, unsettling wide grin, thumbs up, '
'2D cartoon style with bold outlines, flat magenta chroma-key background, '
'no text and no logo; then edited to a bald scalp with a sparse hair fringe '
'on the sides only'),
'on the sides only, then edited again to wear thick nerd glasses'),
'terms_note': ('generated from no third-party source material; the provider terms do not claim '
'ownership of the output. The generator emits no real alpha channel, so the '
'background is keyed out locally by this script.'),
},
'chroma_key': {'background_rgb': list(background), 'transparent_below': T0, 'opaque_above': T1},
'title': {'text': args.title, 'font': 'tools/branding/fonts/VT323-Regular.ttf',
'title': {'text': args.title, 'subtitle': args.subtitle,
'font': 'tools/branding/fonts/VT323-Regular.ttf',
'license': 'SIL Open Font License 1.1 (tools/branding/fonts/OFL.txt)'},
'bottom_fade_px': args.bottom_fade,
'bottom_padding_px': args.bottom_padding,
})
if args.generated_from is not None:
chain = manifest.get('mascot_derived_from', [])
manifest['mascot_derived_from'] = chain + [{
'file': str(args.generated_from.resolve().relative_to(root)),
'sha256': hashlib.sha256(args.generated_from.read_bytes()).hexdigest(),
'edit': 'AI edit (agy_edit): keep face, grin, thumbs up, shirt, pose and flat background; '
'change the hair to a bald scalp with a sparse fringe on the sides only',
}]
chain = list(args.provenance) + [args.raw]
manifest['mascot_provenance'] = [
{'file': str(path.resolve().relative_to(root)),
'sha256': hashlib.sha256(path.read_bytes()).hexdigest()} for path in chain]
manifest.pop('mascot_derived_from', None)
(source_tools / 'manifest.json').write_text(json.dumps(manifest, indent=2) + '\n')
print(out, canvas.size, canvas.mode, 'mascot', mascot.size)