BeamNG.Earth
BeamNG.drive용 1:1 비율 실시간 지구, 실제 고도·위성 이미지·부동 원점·보조 서버에서 LOD 스트리밍
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Simple 4D grid games that I've painstakingly vibe-coded such that I and friends may gain spatial intuitions above three dimensions.
Everything below the break is AI generated. This text is human, and user-facing text in the webapp is human, and that's about it. Everything else is Claude, as indicated by the commits. I'm keeping all the prompts around in case I want to share those for the curious.README 전문 보기 ↗Simple 4D grid games that I've painstakingly vibe-coded such that I and friends may gain spatial intuitions above three dimensions.
Everything below the break is AI generated. This text is human, and user-facing text in the webapp is human, and that's about it. Everything else is Claude, as indicated by the commits. I'm keeping all the prompts around in case I want to share those for the curious.
=====
Small games played in four dimensions — and, where it makes sense, in three, two or five. They share one set of controls and one way of drawing the extra direction, so the spatial sense you build in any of them carries into the rest. That transfer is the point of keeping them in one repository rather than four.
| 4D Unknot | Pull a knotted rope taut. One level cannot come undone in three dimensions — and does in four. | https://kenan.schaefkofer.com/4d/unknot/ |
| 4D Snake | Six cubes, six deep, three slabs of lava. Walls on every side, the fourth included. | https://kenan.schaefkofer.com/4d/snake/ |
| 4D Tron | Two riders, one clock, permanent trails. The fourth direction is the lane you flee down when three dimensions run out. Two players. | https://kenan.schaefkofer.com/4d/tron/ |
| 4D Maze | Find one correct path from start to finish in four dimensions. | https://kenan.schaefkofer.com/4d/maze/ |
| 50D Snake | Snake in a 5^50 box, seen only as 25 flat slices through the head. WASD picks the slice, the arrows move in it. | https://kenan.schaefkofer.com/4d/50d-snake/ |
Each game is served from its own directory, so the URL is just the game's name. The root is an index linking to them all.
npm run serve # http://localhost:8123
npm test # every game's model tests, plus the shared engine's
No build step and no dependencies; three.js loads from a CDN.
Everything in shared/ exists because more than one game needs it to behave
identically. A rule that lives in one game's directory is that game's own; a
rule that lives here is a promise to the player.
The fourth direction is a ring of frames. Three axes are drawn as space. The fourth is drawn as separate copies of that space — one cube frame per value — standing on a flat circle in order. The frame you are working in is nearest the camera, and the camera travels round the ring to whichever frame you move into, turning to meet it square on. Something that steps along the fourth axis is then visibly the same thing continuing in the next room, rather than two ghosts overlapping in one.
The ring turns; the camera stands still. The frame you are working in is always the one at the near point of the circle, 6 o'clock, directly in front of you -- so the room you are playing in is in the same place on screen, at the same distance, whatever w you are at, and the view you dialled in survives every move along the fourth dimension.
The frames do not turn as the ring does. Each is placed by translation alone, so all of them keep one fixed orientation however far the ring has rotated: it is a carousel of positions, not of objects. That is what lets up, down, left and right go on meaning one thing while the right room is always in front of you.
A game with two players has no single focus to centre on, so Tron leaves the ring unturned and takes a fixed overview of the whole circle instead.
Whether the ring closes states the rule. A dimension that does not wrap gets one more slot than it has values, and a solid dark block stands in the gap — you can see that the step from the last frame to the first is not available. A dimension that wraps would use exactly as many slots as values, so the ring would close seamlessly and the step really would be there. Every game here walls w, so every ring carries the block: the fourth axis ends where the other three do. Snake and Tron used to wrap it, which made the fourth dimension feel like a direction that was always open — and also like something unlike the first three, which is the wrong lesson. If wrapping comes back it will be an option on every axis at once, and the ring is ready to close for it. No game has to explain any of this in words.
The controls never move. Arrow keys for the horizontal plane, W/S for up
and down, A/D along the fourth dimension — A toward the frame on the left
and D toward the one on the right, matching both the keyboard and the screen.
Those two directions are called kata and ana, the names Hinton coined
for a fourth spatial axis when up and down were already taken (Greek ana "up",
kata "down"; ana is the positive direction, so D). They earn their place for
the same reason north beats "y plus": a direction with a name of its own is
something you can think about, and learning to think about this one is the whole
difficulty these games are made of. One colour per axis, the same colour in every game:
orange for axis 0, green for axis 1, blue for axis 2, purple for the fourth.
Directions that would do nothing are greyed out, so the pad shows what is
possible rather than making you find out by trying.
The view rocks rather than orbits. A gentle sway, a slow nod on top of it at a period that does not divide into the first. A full spin would keep swapping which way is left and which is right, and every one of these games rests on those meaning one fixed thing; a small swing keeps them stable while the parallax separates things that overlap in any single still view. Every view on screen swings from the same clock, so they never disagree about which face you are looking at.
Wall projections. The contents of a room are flattened onto whichever of its walls the camera can see into, which reads as a plan and two elevations. It is what makes a position inside a box legible without turning the box, and it is where you learn to read depth from rather than guessing at perspective.
The movement tutorial is shared. A first-time visitor to any game is sent to it before that game loads, and returned afterwards. It teaches the controls and the ring of rooms -- the fourth dimension, which is the idea all these games are built on -- using Snake's board, because the fourth dimension has to be used to be learned and Snake is the simplest game to use it in. Finishing or skipping it counts everywhere: learning it is a fact about the player, not about the game they happened to learn it in.
Escape opens the pause menu, in every game, with the same items in the same
order: resume, restart, sound, and back to the index. So does the small button
in the top right corner, for a phone with no Escape key. It is the only place a
run can be abandoned. Restarting used to be a bare R, one key from the movement
cluster, which meant a good game was always one slip from being thrown away; it
now takes a deliberate Escape and a click. A game with a clock stops it while
the menu is up, and no input -- keyboard or controller -- reaches the game
behind it.
The sound setting is shared across every game and remembered, on the grounds
that turning sound off says something about how a player wants to play rather
than something about one game. There are no sounds yet; audio.js exists so the
preference is honoured from the moment it is expressed rather than from whenever
sounds arrive.
Controllers, where a game wants them. gamepad.js turns the Gamepad API's
polling into the same (axis, sign) calls the keyboard makes, so a game gains
controller support without learning anything about gamepads. The mapping is
fixed across games for the same reason the keys are: d-pad for the horizontal
plane, A/B for up and down, LB/RB for the fourth dimension. Note that a
browser cannot see a controller until a button is pressed on it, so a game can
never report one as absent -- only invite the player to press something.
A slice panel, where a game wants one. slicemap.js draws a flat
cross-section through the board at whatever the player is steering: two axes
shown, every other axis pinned to the focus cell's own coordinates. That pinning
is the point — everything on the panel is genuinely one step away, with no depth
to judge and no rooms to scan, which is exactly the question a 3D overview
answers worst. Snake takes its y-w plane; the axes are a parameter, so another
game picks whichever pair it is worst at showing.
Everything the player reads lives in a copy module -- shared/copy.js for text
every game shares, shared/index-copy.js for the landing page, and
<game>/src/copy.js for a game's own -- never in a component or a template. The
point is review: nothing an AI drafted ships to a player unread, and that is
only possible while there is a short list of places to look.
That holds for data files too: a level's shape lives in levels.js and the
name and blurb the player reads live in copy.js, joined by an id when the
levels are built. AGENTS.md has the rule in full.
index.html the index page
shared/
ring.js the ring of w-slice frames, and the slide between them
orbit.js orbit camera, with the rock riding on top
rock.js the shared sway clock
pad.js the direction pad: keys, glyphs, live/dead state
grid.js cells, steps, walls and wraps, boxes, seeded randomness
scene.js frames, blockers, wall projections, lighting
table.js the 4D table the frames stand on, sliced at the camera's w
tableshape.js the table's outline as a function of w, pure
tablegrid.js the top surface's vertex grid, pure
tableconst.js the marbling's numbers
noise.js seeded value noise in any number of dimensions
orbs.js hyperspheres over the table, and their reflections
orbshape.js the size of a hypersphere's slice, pure
props.js table and orbs assembled, the same way for every game
slicemap.js a flat cross-section panel, taken at the player's position
gamepad.js controller polling, as (axis, sign) presses
pause.js the pause menu every game shares
audio.js the sound preference, and sounds when there are any
tutorial-flag.js whether the player has done the movement tutorial
tutorial-entry.js sending a first-time visitor to it, and back again
copy.js text shared by every game
index-copy.js the landing page's text
style.css the shared look
unknot/ rope-untangling puzzle
snake/ snake in a 6x6x6x6 box
tron/ two-player tron, on a clock
maze/ a maze whose corridors leave the slice
50d-snake/ snake in a 5^50 box, drawn as 25 slices
test/shared.js tests for the shared engine
Nothing in shared/ knows how many dimensions there are. Cells are plain arrays
and every rule is written over their length, which is what lets the same code
run a 2D board, a 3D one, a 4D one or a 5D one. Writing p[0], p[1], p[2], p[3]
anywhere would quietly fix the dimension count and the family would stop being
one family. Snake's own test suite runs its rules in 2, 3, 4 and 5 dimensions
for exactly this reason.
AGENTS.md carries the conventions that are easy to break without noticing --
where user-facing text goes, what may not import three.js, and what to check
before calling a change done. It is worth reading before the first edit.