BeamNG.Earth
A 1:1 scale streamed Earth for BeamNG.drive: real elevation and satellite imagery, floating origin, LOD streaming from a companion server
翻譯準備中
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證正在載入完整 README。 以下為已儲存的摘錄。
A Mastermind variant played on a necklace of coloured beads instead of a row of pegs.
The secret is a cyclic sequence of bead colours (5 positions and up to 4 colours by default; both
configurable — see Settings below). Unlike classic Mastermind, you aren't choosing freely
from an unlimited palette: the necklace starts already full, holding the secret's own beads in
some scrambled (not correct) order. The puzzle is entirely about position, since the multiset of
colours is known and fixed from the start — every move just rearranges the same beads.檢視完整 README ↗A Mastermind variant played on a necklace of coloured beads instead of a row of pegs.
The secret is a cyclic sequence of bead colours (5 positions and up to 4 colours by default; both configurable — see Settings below). Unlike classic Mastermind, you aren't choosing freely from an unlimited palette: the necklace starts already full, holding the secret's own beads in some scrambled (not correct) order. The puzzle is entirely about position, since the multiset of colours is known and fixed from the start — every move just rearranges the same beads.
A guess is scored by trying every rotation of the guess against the secret and keeping whichever rotation gives the most exact matches (right colour, right position).
Variant note: this branch/version replaces the earlier "unlimited four-colour palette" version of Cyclomind, which is preserved as-is on the
classic-necklacebranch (and at that point inmain's history) in case it's worth wiring back in as a selectable mode later. An intermediate "bead box" version (drag beads in from a separate supply tray) also existed briefly before this pairwise-swap version replaced it.
Settings. The gear button (top-left) opens a panel for Positions (4-8) and Colours
(2-6, a maximum — each position still rolls independently among the available colours, so
a given secret may end up using fewer than the maximum). Applying starts a fresh game at the new
size. A Show colour numbers checkbox overlays each colour's 1-based number in small type at
the centre of its beads (makeColorNumberLabel(), with automatic light/dark text for contrast) as
a colour-blind-friendly aid; it takes effect immediately, without starting a new game. ALL_COLORS
in src/game.js holds 6 colours chosen for reasonable hue separation at every prefix
length (COLORS.slice(0, n)), not just the full set — each is the one that maximises its hue
distance from the colours before it. Bead radius is computed from the current position count
(beadRadiusFor(), driven by BEAD_GAP_FRACTION) rather than fixed, so beads stay sensibly sized
— filling the ring without touching — whether there are 4 positions or 8.
Shareable URL. The position count, colour count, and secret are encoded into the query string
(n, c, s) on every new game, so a puzzle can be bookmarked or shared as a link that reproduces
it exactly. The secret is a byte-XOR-obfuscated, base64url-encoded digit string (encodeSolution()
/ decodeSolution(), mask from solutionMaskByte()) — compact and not casually readable at a
glance, but deliberately not real security. Loading a URL with an s param starts that exact
puzzle instead of a random one; back/forward navigation (popstate) restores whichever puzzle was
current at that point in history.
Starting state. startGame() generates the secret, then builds a starting guess by shuffling
a copy of it (makeStartingGuess(), retrying if the shuffle happens to already solve it) and
scoring that immediately as Guess 0 — a free look at how close a random arrangement gets,
before the player does anything. The board shows it already in its scoring position (the winning
rotation), same as any submitted guess — matching the Guess 0 history tile exactly, since the
raw unrotated shuffle is never actually shown. The necklace is never empty: every position always
holds one of the secret's own beads, and every move is a swap between two necklace positions.
Uniform secret generation. makeRandomNecklace() samples uniformly over necklaces (rotation-
equivalence classes), not over raw colour strings — those aren't the same thing, since a necklace's
number of representative strings equals its minimal period, so naive per-position random sampling
drastically under-samples high-symmetry necklaces (a mono-colour necklace has exactly 1
representative out of colourCount^n, instead of its fair share). It uses rejection sampling: draw
a raw colour string uniformly, then accept it with probability 1/period (its minimal rotation
period, from necklacePeriod()) and retry otherwise — since a necklace with period p has
exactly p raw representatives, weighting acceptance by 1/p makes every necklace's overall
(representatives × acceptance) probability equal regardless of p, the standard recipe for a
uniform draw from the orbits of a group action (here, rotation). This also gives a clean way to skip
the "degenerate" necklaces that would make Guess 0 an unavoidable instant solve (mono-colour, or
all-but-one beads the same colour) — isDegenerateNecklace() rejects both outright, and
all-but-one is always full-period anyway (a smaller repeated block would have to duplicate the lone
odd bead, so it can never appear just once except at full length). Verified empirically (400k
trials at a few small settings, chi-square against directly-enumerated ground truth) to match a
uniform distribution over the non-degenerate classes.
animateBeadSwap()) and
nothing is left armed afterwards, so every swap is its own fresh pick of two beads. Click/tap the
armed bead again to release it without swapping, e.g. to back out and arm a different starting
bead instead (handleBeadClick(), state.armed). This is the only swap affordance for beads —
native HTML5 drag-and-drop was tried and retired, since it never worked on touch input and its
unstyled default drag image looked wrong even on desktop.Scoring. See scoreGuess(): it rotates the guess against the fixed secret and keeps whichever
rotation gives the most exact matches. Past guesses are shown in that winning rotation, labelled
with just the exact-match count (makeScoreCount()) — no separate colour-only count is
shown, because in this variant it isn't real information: every guess is a rearrangement of the
secret's own beads, so the guess and secret always share the exact same multiset of colours, and
the colour-only count is therefore always exactly BEAD_COUNT - exact. (This is also why ties on
exact matches never need a separate tiebreak: the total matched-colour count is invariant under
rotation, so it's the same for every tied rotation — the smallest clockwise rotation among them is
the one reported.) The tile that actually solves it is highlighted green. History tiles lay out in
a fixed 3-wide grid, numbered from 0 (Guess 0 is the free starting look, not a player move —
"Solved in N guesses" doesn't count it). There's no placeholder tile for the guess in progress
— the status line's "Guess N" is the only cue for that; history only ever shows guesses that
have actually been scored.
Submitting. The ring spins clockwise (animateRotation()) through the exact number of
positions the winning rotation needed, at a constant angular rate (ROTATION_STEP_MS per
position, so a bigger rotation takes proportionally longer rather than being squeezed into one
fixed-length animation). The board is left showing that rotated arrangement — matching the
new history tile — ready to keep swapping for the next guess. Input is disabled for the
duration of the spin. Scoring all positions exact locks the board: further input is disabled and
the winning guess stays in place.
Bead styling. Each colour has its own wavy outline (bulging in and out 3–6 times) and its
own count of short highlight marks (also 3–6), both randomised once per puzzle in
makeBeadStyles() and held fixed for its duration — see wavyCirclePath() and
appendBeadMarks(). The small rings in the scoring history stay as plain flat circles.
Instructions text. The info panel's bullet list is loaded at runtime from
HOW-TO-PLAY.md (loadHowToPlay() in src/game.js) — a plain bullet list,
one - line each, with **bold** supported — so it can be edited directly without
touching markup. Requires running via a local server (see below); opened as a bare file:// page
the fetch silently no-ops and the panel is just empty.
From this directory:
python3 -m http.server 4175 --bind 127.0.0.1
Then open:
http://127.0.0.1:4175/
The app is plain HTML, CSS, and JavaScript. There is no build step.