Spaces:
Running
Running
File size: 4,034 Bytes
2c94890 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | // Plotwren town layout: one fixed map, every plot has a fixed tier and a fixed price. Pure data, shared by the Worker and
// the browser (build copies it to web/town.js). No auctions, no takeovers, no resale: a plot is sold once at its tier price.
// © 2026 CyberMax. All rights reserved.
export const WORLD = { w: 1536, h: 1024, tile: 16 };
// Prices in US cents. Featured is an optional monthly upgrade for any sold plot.
export const TIERS = {
stall: { name: 'Market stall', price: 500, w: 32, h: 32, blurb: 'A pixel stall on Market Row with your logo, name and link.' },
shop: { name: 'Shop', price: 1900, w: 48, h: 48, blurb: 'A shop on Maker Street with a big sign, your logo and a one-line pitch.' },
billboard: { name: 'Billboard', price: 4900, w: 64, h: 48, blurb: 'A billboard on Launch Boulevard, the road everyone crosses.' },
landmark: { name: 'Landmark', price: 14900, w: 96, h: 96, blurb: 'One of four landmark towers on Plotwren Square, the centre of town.' },
};
export const FEATURED = { name: 'Featured', price: 900, interval: 'month', blurb: 'Pinned to the Featured strip, a glowing outline on the map and first in the directory. Cancel any time.' };
export const DISTRICTS = {
square: 'Plotwren Square',
boulevard: 'Launch Boulevard',
street: 'Maker Street',
market: 'Market Row',
yard: 'CyberMax Yard',
};
// Roads (world px rectangles) drawn by the renderer; plots never overlap them.
export const ROADS = [
{ x: 0, y: 448, w: 1536, h: 48 }, // Launch Boulevard (east-west)
{ x: 744, y: 0, w: 48, h: 1024 }, // North-south avenue
{ x: 64, y: 240, w: 640, h: 32 }, // Maker Street (west)
{ x: 832, y: 240, w: 640, h: 32 }, // Maker Street (east)
{ x: 64, y: 704, w: 640, h: 24 }, // Market Row lane (west)
{ x: 832, y: 704, w: 640, h: 24 }, // Market Row lane (east)
];
export const WATER = { x: 0, y: 960, w: 1536, h: 64 };
export const FOUNTAIN = { x: 744, y: 448, w: 48, h: 48 };
const pad = (n, l = 2) => String(n).padStart(l, '0');
function build() {
const plots = [];
const add = (id, tier, district, x, y) => plots.push({ id, tier, district, x, y, w: TIERS[tier].w, h: TIERS[tier].h });
// Plotwren Square: four landmarks around the fountain crossing.
add('L1', 'landmark', 'square', 636, 336); add('L2', 'landmark', 'square', 804, 336);
add('L3', 'landmark', 'square', 636, 508); add('L4', 'landmark', 'square', 804, 508);
// Launch Boulevard: 6 billboards each side of the square, north side of the road.
let b = 1;
for (let i = 0; i < 6; i++) add(`B${pad(b++)}`, 'billboard', 'boulevard', 72 + i * 92, 392);
for (let i = 0; i < 6; i++) add(`B${pad(b++)}`, 'billboard', 'boulevard', 912 + i * 92, 392);
// Maker Street: two rows of shops either side of each half of the street.
let s = 1;
for (const x0 of [72, 840]) {
for (let i = 0; i < 10; i++) add(`H${pad(s++)}`, 'shop', 'street', x0 + i * 62, 184);
for (let i = 0; i < 10; i++) add(`H${pad(s++)}`, 'shop', 'street', x0 + i * 62, 280);
}
// Market Row: stalls in two rows either side of each lane, south of the boulevard.
let m = 1;
for (const x0 of [72, 840]) {
for (const y of [664, 736, 776]) for (let i = 0; i < 16; i++) add(`M${pad(m++, 3)}`, 'stall', 'market', x0 + i * 39, y);
}
return plots;
}
// CyberMax Yard: the house plots, north-west corner, never for sale (CyberMax's own products, clearly labelled).
export const YARD = [
{ id: 'Y1', x: 72, y: 56, w: 64, h: 64 }, { id: 'Y2', x: 152, y: 56, w: 64, h: 64 }, { id: 'Y3', x: 232, y: 56, w: 64, h: 64 },
{ id: 'Y4', x: 312, y: 56, w: 64, h: 64 }, { id: 'Y5', x: 392, y: 56, w: 64, h: 64 }, { id: 'Y6', x: 472, y: 56, w: 64, h: 64 },
{ id: 'Y7', x: 552, y: 56, w: 64, h: 64 }, { id: 'Y8', x: 632, y: 56, w: 64, h: 64 },
];
export const PLOTS = build();
export const PLOT_BY_ID = Object.fromEntries(PLOTS.map((p) => [p.id, p]));
export const priceOf = (id) => TIERS[PLOT_BY_ID[id]?.tier]?.price ?? null;
export const usd = (cents) => `$${(cents / 100).toFixed(cents % 100 ? 2 : 0)}`;
|