Spaces:
Running
Running
Download town.js from CyberMax-tools/plotwren: direct link, hf CLI and curl.
- Browser
- Download file 4.03 kB
-
https://huggingface.co/spaces/CyberMax-tools/plotwren/resolve/main/town.js
- Command line
-
hf download hf://spaces/CyberMax-tools/plotwren/town.js
-
curl -L -o town.js https://huggingface.co/spaces/CyberMax-tools/plotwren/resolve/main/town.js
4.03 kB
| // 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)}`; | |