Files
idle_clicker/README.md
T

75 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Idle Clicker
A themeable idle game inspired by *Universal Paperclips*. Make units by hand, sell them, automate production, buy upgrades. Runs in any browser (phone, tablet, desktop); progress is saved in cookies and can be exported/imported as a JSON or TXT file.
Zero runtime dependencies: a small Node server (`http` module only) plus a vanilla JS frontend (ES modules).
## Run it
```bash
docker compose up -d --build # http://localhost:8080 (GAME_PORT=9000 to change the port)
```
The container is a single image running as the unprivileged `node` user, with a read-only filesystem, no capabilities and `no-new-privileges`.
Without Docker: `npm start` (Node 22+). Tests: `npm test`.
## How the project is organised
```
server/ static file server + /api/themes and /api/locales (auto-discovery)
public/
index.html page skeleton (texts come from i18n via data-i18n attributes)
css/ base (tokens) · layout (responsive grid) · components
data/ GAME CONTENT, theme-independent: rules, generators, upgrades (ids + numbers)
locales/ core UI texts, one file per language (en, fr)
themes/<id>/ ONE FOLDER PER THEME
theme.json order + (later) image paths
theme.css colours/fonts, as CSS variables
locales/<lang>.json the theme's vocabulary: names of resources, generators, upgrades
js/
engine/ game rules, pure JS, no DOM (also used by the tests)
services/ cookies · storage · save import/export · i18n · formatting · data loading
ui/ DOM helpers · main view · settings dialog · toasts
main.js wires everything together
tests/ node:test suites (engine, save import/export, server, content completeness)
```
The key idea: **mechanics are shared, themes are skins.** `public/data/` defines generators and upgrades by id (`gen1`, `click_1`, …) with their numbers; a theme only gives those ids a name, a colour palette and, later, images. Rebalancing the game is a change in `public/data/`, not in each theme.
## Add a theme
1. Copy `public/themes/paperclip/` to `public/themes/<your-id>/` (lowercase letters, digits, dashes).
2. Edit `theme.css` (palette, font, radius), `theme.json` (`order`), and the texts in `locales/*.json`.
3. Reload. The server discovers the folder; no code change and no rebuild list. (With Docker, rebuild the image or mount the folder.)
`npm test` fails if a theme misses a name for any resource, generator or upgrade, or lacks a language the game supports.
## Add a language
1. Copy `public/locales/en.json` to `public/locales/<code>.json` and translate it (set `meta.name` to the language's own name).
2. Add `public/themes/<id>/locales/<code>.json` to every theme.
Missing keys fall back to English, then to the raw key. Strings accept `{param}` and `{@other.key}` (embeds another entry, which is how core texts use the theme's vocabulary, e.g. `{@theme.res.material}`).
## Images
Every icon is currently a grey square. To use real images, put files in the theme folder and list them in its `theme.json`:
```json
{ "order": 1, "assets": { "gen.gen1": "img/autoclipper.svg", "res.units": "img/clip.svg", "upg.click_1": "img/bender.svg" } }
```
Keys: `res.units|funds|material`, `gen.<id>`, `upg.<id>`. Anything not listed keeps the placeholder.
## Saves
- Each theme has its own save slot, stored in cookies (`ic_save_<theme>_*`, chunked and base64-encoded because a cookie holds ~4 KB), plus one preferences cookie (theme + language).
- **Save & settings** exports the current theme's save as `.json` or `.txt` (download or copy/paste) and imports either (file picker or pasted text). Imports are validated and sanitised: unknown ids are dropped, numbers clamped.
- Progress continues while the game is closed: up to 8 h, at 50 % efficiency (`public/data/rules.json`).
- Cookies are sent with every request to the server. A save is under 2 KB and there is one per theme, so this stays far below header limits, but it is the reason to keep saves compact.
## Tuning the game
Everything numeric is in `public/data/`: `rules.json` (market, marketing, offline, autosave), `generators.json`, `upgrades.json`. Customers want `baseDemand × demandMultiplier` units/s at the *fair price* and demand collapses above it, so: raise the price when supply is short, buy marketing/demand upgrades to sell more.