2026-07-29 21:42:34 -04:00
2026-07-29 19:03:11 -04:00
2026-07-29 21:42:34 -04:00
2026-07-29 21:42:34 -04:00
2026-07-28 13:01:38 -04:00
2026-07-28 13:01:38 -04:00
2026-07-29 21:42:34 -04:00
2026-07-29 21:42:34 -04:00
2026-07-28 16:14:43 -04:00
2026-07-28 16:14:43 -04:00
2026-07-29 21:42:34 -04:00

Dramatic Shape Voxel Mod

A mod for the Pokémon Gen 1 Recompilation Project.

The overworld as a 3D diorama. Terrain is extruded into real geometry, occlusion comes from a depth buffer rather than a y-sort, characters stand as leaning sprite slabs, a shadow map throws real cast shadows across whatever they land on, and an optional tilt-shift pass sells the miniature-model look.

And battles fought on that world rather than on a white field. When something picks a fight the map's NPCs are culled, the engine's own wipe plays over the empty map, and the battle draws over the nearest patch of clear ground — shot over the shoulder, the player's mon low and left and the enemy high and right, with a slow parallax drift behind them and a depth-of-field pass that keeps both of them sharp.

Purely presentational. Nothing here reaches collision, movement, triggers or scripts — it changes what the world looks like and nothing about what it is. The battle arena is where the camera goes, not where anybody goes: no cell, facing, flag or warp is written, so the player is standing exactly where the fight found them when it ends.

Controls

Every key is free-roam only, and each one is also a row on the OPTIONS menu.

control does
3, or the VOXEL options row OFF → 15 → 35 → 50 → 75 → OFF (camera pitch)
5, or the V-GRID options row OFF / ON — a one-pixel wireframe on every voxel
6, or the T-SHIFT options row OFF → 1 → 2 → 3 → OFF (miniature blur)
7, or the V-CURVE options row OFF → 1 → 2 → 3 — bend the world over the horizon
8, or the 3D-BTL options row ON / OFF — fight on the map instead of on a white field
the DAYTIME options row DAY / NIGHT / DUSK / DAWN / CYCLE — what time it is outdoors

3D-BTL is on by default and is independent of VOXEL: battles draw on the world whether or not the free-roam camera is pitched over.

The void behind the diorama is a gradient sky at every VOXEL rung: four blues as flat horizontal bands, deepest overhead and palest at the bottom, with a checkerboard of the next band dithered into the bottom of each one — the 8-bit way to get more colours out of a palette than it holds. Every channel is a multiple of 8, where a five-bit GBC channel lands. No clouds, and no image asset.

At 75 the camera is pitched far enough over that the ground plane's vanishing line is in frame, and the pale end meets it; at the steeper rungs that line is above the top edge, so the bands take a fixed slice of the frame and the haze below them fills the void where the ground runs out. Nothing is resampled — no baked 160×144 picture scaled up, no texture at all, just one rectangle through a shader that answers each pixel from its own coordinate — and the band edges and dither cells are measured in the diorama's own pixels, handed in every frame, so a ZOOM change lands immediately and stays crisp at any window size. The palette goes through the display-mode transform like everything else here, so GRAY gets four greys and CLASSIC four greens. Overworld only — a battle's placed camera looks up from under the horizon and keeps its flat sky.

Tunables live at the top of lib/Sky.luaSky.DITHER, Sky.DITHER_START (how far down each band the checker begins — lower is a wider blend, 1 switches it off), Sky.SPAN (how much of the frame the bands cover on the rungs whose horizon is off-screen), and Sky.DISC_FRAC (the sun and moon's size, as a fraction of the frame) — and the palettes live in lib/DayNight.lua (DayNight.PALETTES, one per phase, lightest first), because the sky belongs to the clock:

What time it is

The DAYTIME row is one twenty-minute clock — ten minutes of sun, ten of moon. DAY, NIGHT, DUSK and DAWN are pins on that dial (noon, mid-night, sunset, sunrise) and CYCLE lets it run, picking up from whichever pin was showing. Everything is a pure function of the clock, so the pinned DUSK is exactly the running cycle stopped at sunset. Setting VOXEL to FULL switches DAYTIME to CYCLE with the rest of the preset.

The sun and moon hang in the sky, projected through the same matrix the geometry is drawn with, so each stands over the point on the horizon its shadows point away from at any pitch, window shape or zoom. Noon is this mod's existing sun to the digit — southeast, 45° up, overhead behind the north-facing camera and correctly out of frame — and the arc swings north at both ends, so the disc stands in frame through dawn and dusk, half-set on the horizon line. The moon walks the northern sky all night, due north at mid-night. Both are cell art on the sky's own grid, sized by the frame, and scissored to the sky's region: a setting body slips below the horizon point and is gone — never under the map.

The sky, the shadows and the light follow. Six-band phase palettes blend along the dial and re-quantise onto the 5-bit lattice — the evening bending through a golden-hour waypoint and both edges of the night through a violet civil twilight, because a straight lerp between complements bottoms out in grey — and a dithered, posterised glow warms the bands around the low sun through the twilights. The shadow shear comes off the clock (opposite the body's bearing, cotangent-long, clamped at twice the caster's height), fading out over the last twelve degrees before the horizon so sunset hands off to moonrise through a soft shadowless gap; moonlight presses at about two-thirds the sun's weight. The scene shader multiplies every surface by the hour's tint — neutral at noon, warm at the twilights, dim blue under the moon.

Outdoors only. Indoors keeps the noon rig, the neutral tint and no sky: a cave at midnight is exactly as dark as a cave at noon. A battle staged on an outdoor map fights under the hour — night void behind the arena, tinted mons, sunset taking the arena's shadows with it — and an indoor arena is untouched. The engine's world.tod hook is answered (MORNING/DAY/EVENING/NIGHT), so palette or music packs keyed to the period ride this clock for free. In CYCLE, the time is written into the mod's own bucket in the save file when the game saves, and read back when the save is opened; a save with no clock in it starts at day.

While a battle can be staged on the map — 3D-BTL on, or VOXEL on FULL, which owns that row — the engine's BATTLE LAYOUT row is set to OG and taken off the OPTIONS menu. The staged shot is composed in the Game Boy's own 160x144 frame: the arena camera is solved to put a cell under each of the two pics' feet, and WIDE re-lays that screen out on a 304x144 surface, which moves every anchor it is solved against. Switching 3D-BTL off hands the row straight back with WIDE selectable again.

Leaving a battle fades rather than cuts while VOXEL is on: the battle screen fades to black, closes behind it, and the map fades up out of it. The engine wipes into a fight and cut straight out of one, which is a big jump between the arena's placed camera and the walking diorama. It applies to every battle while the mode is on — including one that found no arena and drew on the flat battle screen — and not at all while the mode is off. The timing is a voxel_battle_exit transitions record, so a data pack can retune it.

The two HP boxes snap to the window's own edges while a battle is staged — the foe's to the left, yours to the right — instead of huddling in the middle of the frame with map showing either side of them. Same tiles, same size, same rows, on the same frosted glass; only the pair's position changes. On a window shaped like the GB screen there is nowhere to snap to and nothing moves.

Where a battle is staged

The mod looks for the nearest clearing shaped like this, where every x is a cell the player could walk onto — the two mons three cells apart down the middle, with a one-cell apron so the camera looks across floor rather than into a wall:

x x x
x O x     O   the enemy's mon
x x x
x x x
x P x     P   your mon
x x x

Indoors, in a corridor or in a cave there is often no room for that, so the search relaxes to the same three-cell gap with the apron given up:

O
x
x
P

If neither will fit — and on a map with no open ground at all, or on a machine with no depth-buffer support — the battle draws exactly the way it always did. Water counts as open ground while you are surfing and not otherwise, and warp tiles never count, so a fight is never framed in a doorway.

Two of those keys are taken off the engine: 3 was TILT and 5 was GBC FX. Neither is reachable by key while this mod is enabled, and both are still on the OPTIONS menu. Pressing 3 also switches both off — they fight the diorama, and it is the way back from having left one on.

S
Description
No description provided
Readme 11 MiB
Languages
Lua 92.5%
Python 7.5%