Underground 2 Revived
Play Need for Speed: Underground 2 (2004) in Chrome and Firefox with WebGPU graphics, Web Audio, up to 120 fps widescreen, controller support, free roam and Online races with friends. Fan project, not
Vitral — um puzzle lógico de dados coloridos. Monte o vitral sem quebrar nenhuma regra.
Translation pending
GamesTypeScript · CSSGitHub @KyandoOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
A cozy stained-glass dice logic puzzle: place every die without breaking a rule.
Translation pending
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
A cozy stained-glass dice logic puzzle.
Place every die in the window without breaking a single rule.
Vitral started as a fork of Inklink, a word-association puzzle inspired by Entre-linhas, Sudoku, Termo and the Einstein riddle. Words are subjective; dice are not. So the board keeps the same shape (rules on rows and columns, one piece per cell, a full board), but the pieces become coloured dice, borrowing the window-building of the board game Sagrada.
Every level gives you exactly one die per cell, and rules written as symbols.Read the full README ↗A cozy stained-glass dice logic puzzle. Place every die in the window without breaking a single rule.
Vitral started as a fork of Inklink, a word-association puzzle inspired by Entre-linhas, Sudoku, Termo and the Einstein riddle. Words are subjective; dice are not. So the board keeps the same shape (rules on rows and columns, one piece per cell, a full board), but the pieces become coloured dice, borrowing the window-building of the board game Sagrada.
Every level gives you exactly one die per cell, and rules written as symbols.
Everything is a die, as in Sagrada: the fill is the color (transparent = any color) and the pips are the number (no pips = any number). Each rule is one composed glyph, read left to right:
| Part | Meaning |
|---|---|
| Subject | a red tile = red · a die with 5 pips = five · an empty die = any die |
| Operator | ×2 exactly 2 (×0 none) · =12 adds up to 12 · <4 all below 4 · >3 all above 3 · ↗ numbers only go up (↘ down) |
| Unique / identical | three small dice that differ (or match) in color or in number: they carry the attribute themselves |
| Scope (modifiers only) | a cross of cells = neighbours · a grid = every row and column |
Where a glyph sits says where it applies: row rules on the left, column rules on top, modifiers above the window (they apply to all of it). Cells use the same language as the board of Sagrada: tinted glass asks for a color, shaded pips ask for a number.
Tap any glyph to read it; the help screen has the full glossary.
Thirteen chapters introduce the language one piece at a time, each with a "new symbol" card the first time it appears: colored and carved cells → counting colors → different colors → sums → different numbers → order → same color → forbidden number → less and greater than → neighbours (first modifier) → neighbours with numbers → every row and column → a final mixed window. A chapter only uses what has already been taught.
There is no Check button: the board is validated on every move, and each rule shows its own state.
Feedback never peeks at the intended solution or at the dice still in the tray, so it only tells you what you could have worked out yourself. The window is complete when the board is full and every rule is satisfied: any arrangement that satisfies the rules wins.
Every level is generated and machine-verified:
The human-style solver only makes sound eliminations: a die can't go where it already breaks a rule, a cell with one possible die is filled, and a rule's bounds are checked against what the other cells could still receive ("this row needs 15 from two dice, so neither can be below 3"). If it fills the board, the solution is unique and reachable by reasoning alone, with no trial and error. Tests also confirm uniqueness with an exhaustive search.
Difficulty comes from board size and how often that deeper "reach" reasoning is needed.
npm install
npm run dev # play locally
npm test # rules, solver agreement, generator and every shipped level
npm run levels # validate levels and print their difficulty (-- --rules to list them)
npm run levels:generate # regenerate the chapters (teaching plan in scripts/generate-levels.ts)
npm run levels:generate -- 3 --dry # preview one chapter without writing it
npm run media # regenerate README screenshots & GIF (uses local Edge)
npm run deploy # build and publish to GitHub Pages
src/
core/ pure TypeScript, no DOM
types.ts level format, dice and rules
rules.ts rule evaluation on partial boards (UI) + compiled incremental checks (solver)
solver.ts exhaustive search (solution counting)
deduce.ts human-style solver → uniqueness proof and difficulty
generate.ts seeded level generator
describe.ts player-facing rule text (pt-BR)
ui/dice.ts dice and the rule glyph renderer
ui/lessons.ts "new symbol" cards and the glossary
game/ session state, undo, persistence
levels/ *.json levels (ordered by file name)
ui/ vanilla DOM + CSS (FLIP animations, pointer drag, synth SFX)
scripts/ level generation, reports, media capture, deploy
tests/ Vitest suite
{
"id": "capela",
"title": "Capela",
"rows": 4,
"cols": 4,
// one die per cell: colour letter (R, Y, G, B, P) + value
"dice": ["R2", "R5", "Y1", "B6"],
"rules": [
{ "type": "adjacent-colors-differ" },
{ "type": "sum", "line": "row", "index": 0, "value": 14 },
{ "type": "color-count", "line": "col", "index": 2, "color": "red", "count": 0 },
{ "type": "cell-color", "row": 1, "col": 3, "color": "blue" }
],
// die codes in reading order
"solution": ["B5", "Y5", "R2", "P2"]
}
Designed and developed by Bruno Ribeiro. Inspired by Sagrada, Entre-linhas, Sudoku, Termo and the Einstein riddle.