Deploy-base-aware asset URLs; live at partly.party/toastsim
Absolute '/assets/...' paths 404 under the /toastsim/ subpath (and the root /assets/ URL is another game's — returns 200 with wrong content, the classic partly.party trap). assetUrl() prefixes BASE_URL inside loadProp + the four direct loads (bench/backdrop textures, title art, judge portraits). Verified live: JS application/javascript, toaster.glb 4.5MB binary, title_art image/png, title screen renders. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
d5ed20cacb
commit
db31273fc9
@ -4,6 +4,13 @@ import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
|
||||
const loader = new GLTFLoader();
|
||||
const cache = new Map<string, Promise<THREE.Group>>();
|
||||
|
||||
/** Root-relative asset path → deploy-base-aware URL. Dev base is '/', the
|
||||
* partly.party deploy serves from /toastsim/ — absolute '/assets/...' paths
|
||||
* silently 404 (or worse, hit another game's files) under a subpath. */
|
||||
export function assetUrl(path: string): string {
|
||||
return import.meta.env.BASE_URL.replace(/\/$/, '') + path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a generated GLB and make it usable without touching the file.
|
||||
*
|
||||
@ -17,7 +24,7 @@ export function loadProp(url: string, size: number): Promise<THREE.Group> {
|
||||
const key = `${url}@${size}`;
|
||||
let p = cache.get(key);
|
||||
if (!p) {
|
||||
p = loader.loadAsync(url).then((gltf) => {
|
||||
p = loader.loadAsync(assetUrl(url)).then((gltf) => {
|
||||
const root = gltf.scene;
|
||||
const box = new THREE.Box3().setFromObject(root);
|
||||
const dim = box.getSize(new THREE.Vector3());
|
||||
|
||||
@ -6,6 +6,7 @@ import type { Verdict } from '../game/judging';
|
||||
import { judgeFace, verdictLines } from '../game/lines';
|
||||
import { TOOLS, type ToolId } from '../sim/cutlery';
|
||||
import { clear, el, Panel } from '../ui/hud';
|
||||
import { assetUrl } from './assets';
|
||||
|
||||
/**
|
||||
* The scorecard. This is the screen the game is actually about: every number
|
||||
@ -148,7 +149,7 @@ export class JudgeView implements View {
|
||||
const lines = verdictLines(verdict, order, TOOLS[tool].name, rand);
|
||||
for (const l of lines) el('p', undefined, this.linesEl, l);
|
||||
|
||||
this.faceEl.src = `/assets/img/judge_${judgeFace(verdict.grade)}.png`;
|
||||
this.faceEl.src = assetUrl(`/assets/img/judge_${judgeFace(verdict.grade)}.png`);
|
||||
this.stampEl.textContent = verdict.grade;
|
||||
this.stampEl.className = `judge-stamp grade-${verdict.grade}`;
|
||||
// re-trigger the stamp animation
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import * as THREE from 'three';
|
||||
import { assetUrl } from './assets';
|
||||
|
||||
export function roundedRect(w: number, h: number, r: number): THREE.Shape {
|
||||
const hw = w / 2;
|
||||
@ -169,7 +170,7 @@ export function makeBench(): THREE.Group {
|
||||
const g = new THREE.Group();
|
||||
const loader = new THREE.TextureLoader();
|
||||
|
||||
const wood = loader.load('/assets/img/bench_wood.png');
|
||||
const wood = loader.load(assetUrl('/assets/img/bench_wood.png'));
|
||||
wood.wrapS = wood.wrapT = THREE.RepeatWrapping;
|
||||
wood.repeat.set(4, 2);
|
||||
// The texture was generated as artwork, i.e. sRGB. Saying so is what keeps it
|
||||
@ -185,7 +186,7 @@ export function makeBench(): THREE.Group {
|
||||
g.add(top);
|
||||
|
||||
// Splashback: a blurred kitchen so the scene has a horizon instead of fog.
|
||||
const back = loader.load('/assets/img/kitchen_backdrop.png');
|
||||
const back = loader.load(assetUrl('/assets/img/kitchen_backdrop.png'));
|
||||
back.colorSpace = THREE.SRGBColorSpace;
|
||||
const wall = new THREE.Mesh(
|
||||
new THREE.PlaneGeometry(22, 8),
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { el, Panel } from './hud';
|
||||
import { assetUrl } from '../scenes/assets';
|
||||
|
||||
/** The front door. One button, one piece of art, one joke. */
|
||||
export class Title {
|
||||
@ -8,7 +9,7 @@ export class Title {
|
||||
this.panel = new Panel('title');
|
||||
const wrap = el('div', 'title-wrap', this.panel.root);
|
||||
const art = el('img', 'title-art', wrap);
|
||||
art.src = '/assets/img/title_art.png';
|
||||
art.src = assetUrl('/assets/img/title_art.png');
|
||||
art.alt = '';
|
||||
const txt = el('div', 'title-txt', wrap);
|
||||
el('h1', undefined, txt, 'TOASTSIM');
|
||||
|
||||
Loading…
Reference in New Issue
Block a user