Add rank, friends, fishing, and camp treasure with T2 studio models and skill presentation.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
"""Validate proposed battle skill contracts without touching the running game."""
|
||||
from __future__ import annotations
|
||||
import argparse
|
||||
import hashlib
|
||||
from decimal import Decimal,ROUND_CEILING
|
||||
import json
|
||||
from pathlib import Path,PurePosixPath
|
||||
@@ -79,21 +80,32 @@ def validate(plan,view,sound,gameplay,root=ROOT):
|
||||
if cue['kind']=='animation':
|
||||
mark=assets[cue['asset']]['releaseNormalized']
|
||||
require(abs(mark-release/(release+recovery))<=1/(release+recovery),'Animation release marker is not aligned: '+skill['id'])
|
||||
require(sound['status']=='planned_not_generated','SFX design manifest must not claim generated assets')
|
||||
require(sound['status'] in ('planned_not_generated','partially_generated','generated'),'Invalid SFX production status')
|
||||
require(1<=sound['maxInflight']<=4,'TangoFlux in-flight limit exceeds guide')
|
||||
require(sound['sourceFormat']==dict(container='wav',sampleRate=44100,channels=2),'TangoFlux source format mismatch')
|
||||
items=index(sound['items'],'SFX')
|
||||
generated=0
|
||||
for item in items.values():
|
||||
require(item['prompt'].isascii() and 0<len(item['prompt'])<=2000,'SFX prompt must be specific English within service limit')
|
||||
require(1<=item.get('duration',sound['defaults']['duration'])<=30,'TangoFlux duration must be 1..30 seconds')
|
||||
require(type(item['seed']) is int,'Reproducible SFX seed required')
|
||||
production=item.get('production')
|
||||
if production:
|
||||
output=root/production['output'];receipt=root/production['receipt']
|
||||
require(output.is_file() and receipt.is_file(),'Generated SFX output/receipt missing')
|
||||
require(hashlib.sha256(output.read_bytes()).hexdigest()==production['sha256'],'Generated SFX hash mismatch')
|
||||
rows=json.loads(receipt.read_text(encoding='utf-8'))['items']
|
||||
require(any(r['id']==item['id'] and r['outputSha256']==production['sha256'] and r['job']['status']=='succeeded' for r in rows),'Generated SFX receipt mismatch')
|
||||
generated+=1
|
||||
expected='planned_not_generated' if generated==0 else 'generated' if generated==len(items) else 'partially_generated'
|
||||
require(sound['status']==expected,'SFX production status does not match receipts')
|
||||
for asset in assets.values():
|
||||
if asset['type']=='sfx':require(PurePosixPath(asset['path']).stem in items,'SFX production recipe missing: '+asset['id'])
|
||||
return dict(status='design_contract_validated',runtimeIntegrated=False,generatedAudio=False,
|
||||
return dict(status='design_contract_validated',runtimeIntegrated=False,generatedAudio=generated==len(items),generatedSfxCount=generated,
|
||||
skills=len(skills),pets=len(gameplay['pets']),enemies=len(gameplay['enemies']),stages=len(gameplay['stages']),
|
||||
presentationProfiles=len(profiles),existingAssets=sum(a['status']=='existing' for a in assets.values()),
|
||||
plannedAssets=sum(a['status']=='planned' for a in assets.values()),sfxRecipes=len(items),
|
||||
note='Configuration and reference validation only; no combat runtime or audio generation executed')
|
||||
note='Design proposal validation only; formal runtime integration is validated separately by validate_skill_runtime.py')
|
||||
|
||||
def load(path):return json.loads(path.read_text(encoding='utf-8-sig'))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user