Files

46 lines
4.5 KiB
Python

#!/usr/bin/env python3
"""Deterministically author original PNG/WAV/WASM package resources using stdlib."""
from pathlib import Path
import hashlib,json,struct,zlib,math,wave
ROOT=Path(__file__).resolve().parents[1]
def png(path,w,h,pixel):
def chunk(kind,data):return struct.pack('>I',len(data))+kind+data+struct.pack('>I',zlib.crc32(kind+data)&0xffffffff)
raw=b''.join(b'\x00'+b''.join(bytes(pixel(x,y)) for x in range(w)) for y in range(h))
path.write_bytes(b'\x89PNG\r\n\x1a\n'+chunk(b'IHDR',struct.pack('>IIBBBBB',w,h,8,2,0,0,0))+chunk(b'IDAT',zlib.compress(raw,9))+chunk(b'IEND',b''))
def js(path,obj):path.write_text(json.dumps(obj,indent=2)+'\n')
def manifest(path,ident,deps,caps,resources):
js(path/'manifest.json',{'schema':1,'id':ident,'version':'1.0.0','license':'MIT OR Apache-2.0',
'dependencies':[{'id':d,'version':'1.0.0'} for d in deps], 'capabilities':caps,
'resources':[{'path':p,'scope':scope,'role':role,'size':(path/p).stat().st_size,'sha256':hashlib.sha256((path/p).read_bytes()).hexdigest()}for p,scope,role in resources]})
base=ROOT/'packages/base'; trampoline=ROOT/'packages/trampoline'
for p in [base/'client',base/'common',trampoline/'client',trampoline/'common',trampoline/'server']:p.mkdir(parents=True,exist_ok=True)
# Pixel noise tile, generated by integer hash; intentionally original, no external art.
def grain(x,y):
v=((x*374761393+y*668265263)^((x+y*17)*1274126177))&0xffffffff
value=211+((v^(v>>13))%29);return[value,value,value]
png(base/'client/texture.png',64,64,grain)
js(base/'client/style.json',{'schema':1,'texture':'client/texture.png','texture_mode':'repeat-tint','pixel_size':64,'license':'MIT OR Apache-2.0'})
js(base/'common/definitions.json',{'schema':1,'catalog':'builtin-java-26.2','data_version':4903,'coordinates':'+Y up; block models in [0,1], entity models relative feet','vanilla_assets':False})
# Authored spring mat: dark frame, mint mesh, small crossing weave.
def mat(x,y):
if x<3 or y<3 or x>=29 or y>=29:return[53,78,73]
if x%4==0 or y%4==0:return[123,217,166]
return[75,153,118]
png(trampoline/'client/texture.png',32,32,mat)
js(trampoline/'client/style.json',{'schema':1,'block':'shacraft:trampoline','color':[97,205,151],'texture':'client/texture.png','effect':'bounce','sound':'client/bounce.wav','shader':'client/tint.glsl'})
(trampoline/'client/tint.glsl').write_text('// Original optional Shacraft material function. GLSL ES 3.00.\nvec3 shacraftBounceTint(vec3 color, float pulse) {\n return color * (1.0 + 0.12 * clamp(pulse, 0.0, 1.0));\n}\n')
with wave.open(str(trampoline/'client/bounce.wav'),'wb') as wav:
rate=22050;n=int(rate*.18);wav.setnchannels(1);wav.setsampwidth(2);wav.setframerate(rate)
wav.writeframes(b''.join(struct.pack('<h',int(10000*(1-i/n)**2*math.sin(2*math.pi*(260*i/rate+450*(i/rate)**2))))for i in range(n)))
js(trampoline/'common/definitions.json',{'schema':1,'blocks':[{'state':'shacraft:trampoline','color':[97,205,151],'collision':[{'min':[0,0,0],'max':[1,1,1]}],'behavior':{'server_hook':'on_jump'}}], 'client_effect':{'on_jump':'bounce'},'capability_contract':{'hook':'on_jump','parameters':[],'result':'f32','units':'blocks/second','fuel':10000,'memory_pages':1,'imports':[]}})
(trampoline/'server/trampoline.wat').write_text(';; Original executable server extension. No imports, memory, filesystem or network.\n(module (func (export "on_jump") (result f32) f32.const 10))\n')
# Binary encoding of the tiny WAT above, independently loaded/tested by server wasmi.
wasm=b'\x00asm\x01\x00\x00\x00'+bytes([1,5,1,0x60,0,1,0x7d])+bytes([3,2,1,0])+bytes([7,11,1,7])+b'on_jump'+bytes([0,0])+bytes([10,9,1,7,0,0x43])+struct.pack('<f',10.)+bytes([0x0b])
(trampoline/'server/trampoline.wasm').write_bytes(wasm)
manifest(base,'shacraft.base',[],['blocks.define','entities.define','client.texture','client.style'],[('common/definitions.json','common','definitions'),('client/texture.png','client','texture'),('client/style.json','client','client-style')])
manifest(trampoline,'shacraft.trampoline',['shacraft.base'],['blocks.define','client.texture','client.style','client.shader','client.sound','server.on_jump'],[('common/definitions.json','common','definitions'),('client/texture.png','client','texture'),('client/style.json','client','client-style'),('client/bounce.wav','client','sound'),('client/tint.glsl','client','shader'),('server/trampoline.wasm','server','wasm-on-jump'),('server/trampoline.wat','server','wasm-source')])
print('Original package assets and checksummed manifests generated.')