28 KiB
LegacyVulkEdition - Complete Handoff Document
Last updated: 2026-03-19
1. Project Overview
LegacyVulkEdition is a cross-platform port of Minecraft: Legacy Console Edition (LCE) from its original Windows/Xbox D3D11+Iggy (Scaleform/SWF) codebase to a Vulkan+Nuklear stack. The goal is to produce a working, faithful recreation of the LCE client that runs on macOS (Apple Silicon) and Linux, with all the original game logic intact but the rendering and UI layers replaced.
- Repository: https://github.com/coah80/LegacyVulkEdition (private)
- Local path:
/Users/cole/Documents/LegacyVulkEdition - Original LCE source:
/Users/cole/Downloads/minecraft/(the decompiled 4J Studios codebase) - JPEXS-extracted PNGs:
/Users/cole/Downloads/minecraft_swf_pngs/(all SWF sprite assets as PNGs) - Vulkan reference renderer:
/Users/cole/Documents/MinecraftConsole-Vulkan/(standalone Vulkan renderer ported earlier) - Current state: Compiles, links, runs on macOS arm64 (M4 Pro). Vulkan window opens, textures load from the media archive, all 52 menu screens render via Nuklear, game enters main loop. Menu navigation works without crashes.
2. Architecture
High-Level Flow
main() [CrossPlatformMain.cpp]
|
+-- GLFW window creation + Vulkan init (VulkanBootstrapApp)
+-- Nuklear init (NuklearBridge)
+-- NuklearSceneRenderer init (MenuScreens, loads textures)
+-- CMinecraftApp loads MediaWindows64.arc + StringTable
+-- Minecraft::main() (original game bootstrap)
+-- Main loop:
|
+-- glfwPollEvents()
+-- RenderManager.StartFrame()
+-- Manager ticks (Input, Storage, Render, Network)
+-- if gameStarted: Minecraft::run_middle() (game tick + render)
+-- ui.tick() + ui.render() (original UIController, mostly stubbed)
+-- nuklearNewFrame()
+-- NuklearSceneRenderer::render(winW, winH) <-- draws active menu
+-- nuklearRender() <-- converts Nuklear vertex buffers to Vulkan draws
+-- RenderManager.Present()
Layer Separation
The codebase has three distinct layers:
-
Original LCE code (
Minecraft.Client/,Minecraft.World/): The unmodified 4J Studios source. Compiles withUSE_VULKAN_RENDERERdefined, which#ifndef-guards out all Iggy/SWF and D3D11-specific code paths. This code handles game logic, world generation, entities, networking, etc. -
Vulkan renderer (
Minecraft.Client/Platform_Libs/Dev/RenderVk/): A Vulkan backend that implements theC4JRender(RenderManager) API the original game code calls. Ported from the MinecraftConsole-Vulkan reference project. Handles Vulkan instance/device/swapchain, texture management, vertex buffer submission, SPIR-V shader pipelines. -
CrossPlatform layer (
Minecraft.Client/CrossPlatform/): The new code written for this port. Contains the entry point, Nuklear bridge, all menu screen implementations, platform stubs, and GLFW input handling. This is where almost all new development happens.
How Nuklear Integrates with Vulkan
Nuklear does NOT have its own Vulkan backend here. Instead:
nuklearNewFrame()feeds GLFW mouse/keyboard state into Nuklear's input system- Menu render functions call Nuklear's immediate-mode draw API (nk_draw_image, nk_fill_rect, nk_draw_text, etc.) to build a command buffer
nuklearRender()callsnk_convert()to produce vertex/index buffers- Those buffers are translated into
GameVertstructs and submitted viaRenderManager.DrawVertices()(the same draw call the game uses for world geometry) - The Vulkan backend renders these triangles with an orthographic projection
This means Nuklear output goes through the exact same Vulkan pipeline as everything else -- no separate render pass or pipeline needed.
Key Compile Define
USE_VULKAN_RENDERER is defined for the LegacyVulkEdition target. All original Iggy/SWF/D3D11 code is behind #ifndef USE_VULKAN_RENDERER guards, so it compiles out cleanly.
3. File Map
/Minecraft.Client/CrossPlatform/ -- New code (where you will work)
| File | Purpose |
|---|---|
CrossPlatformMain.cpp |
Entry point. GLFW window, Vulkan init, game bootstrap, main loop, input callbacks |
NuklearBridge.h / .cpp |
Nuklear init/shutdown, newFrame (input pump), render (vertex buffer output), loadTexture/loadTextureWithSize (PNG->Vulkan texture) |
MenuScreens.h / .cpp |
NuklearSceneRenderer class: state machine with 52 MenuState enum values, pushState/popState navigation stack, dispatches to Nk*.cpp render functions |
MenuTextureSlot.h |
Simple struct {int id, int w, int h} for loaded texture references |
NkCommon.h / .cpp |
Shared drawing helpers: drawBtn, drawDirtBg, drawPanoramaBg, drawLogo, drawControllerPrompts, drawTitle, drawCenteredText, drawLabel, drawTextInput, drawListItem, pushCleanStyle/popCleanStyle |
NkCoreMenus.h / .cpp |
Main Menu, Pause Menu, Death Menu |
NkSettingsMenus.h / .cpp |
Help & Options, Settings Hub, Options, Audio, Control, Graphics, UI settings |
NkHUD.h / .cpp |
Full HUD overlay (crosshair, health, food, armor, air, XP bar, hotbar) |
NkWorldMenus.h / .cpp |
Load or Join, Create World, Load Menu, Join Menu |
NkInventoryMenus.h / .cpp |
Inventory, Crafting 2x2/3x3, Creative |
NkContainerMenus.h / .cpp |
Furnace, Chest, Anvil, Brewing Stand, Enchanting, Trading, Dispenser |
NkMiscMenus.h / .cpp |
Intro, MessageBox, EULA, SaveMessage, ConnectingProgress, FullscreenProgress |
NkScrollingMenus.h / .cpp |
Credits, End Poem (auto-scrolling text) |
NkBrowseMenus.h / .cpp + NkBrowseMenus2.cpp |
Skin Select, How to Play, Controls, Leaderboards, DLC |
NkGameMenus.h / .cpp + NkGameMenus2.cpp |
Host Options, Player Options, Sign Entry, Teleport, Launch More Options, Reinstall, Debug, Keyboard, Quadrant Signin |
PlatformStubs.cpp |
Stubs for platform APIs the original code expects: C_4JInput, C4JStorage, ConsoleUIController, VoiceChat, WinsockNetLayer |
GameStubs.cpp |
Stubs for game subsystems not yet wired: sound engine helpers, etc. |
PlatformGlobals.cpp |
Global instances of manager objects (RenderManager, InputManager, etc.) |
/Minecraft.Client/Platform_Libs/Dev/RenderVk/ -- Vulkan renderer
| File | Purpose |
|---|---|
VulkanBootstrapApp.h |
Class declaration: Vulkan instance, device, swapchain, pipelines, texture management, draw submission |
VulkanBootstrapAppCore.cpp |
Vulkan init/shutdown, device selection, swapchain creation, command buffers |
VulkanBootstrapAppRender.cpp |
Frame begin/end, vertex buffer upload, draw command recording, pipeline binding |
VulkanRenderManager.cpp |
C4JRender implementation that forwards calls to VulkanBootstrapApp. This is what the game code calls via RenderManager.* |
/Minecraft.Client/ -- Original LCE code (sorted into subdirectories)
| Directory | Contents |
|---|---|
Core/ |
ArchiveFile, ClientConstants, Minecraft class, Options, Timer |
Rendering/ |
Camera, Chunk, Culler, Font, GameRenderer, LevelRenderer, Tesselator |
Entity/Models/ |
All entity models (BlazeModel, ChickenModel, etc.) |
Entity/Renderers/ |
All entity renderers (ArrowRenderer, etc.) |
Particles/ |
Particle system (Bubble, Breaking, Flame, etc.) |
Screens/ |
Original Screen classes (AbstractContainerScreen, ChatScreen, etc.) |
UI/ |
Button, AchievementPopup, and UI components |
Textures/ |
TextureManager, AbstractTexturePack, ClockTexture |
Input/ |
KeyboardMouseInput |
Network/ |
ClientConnection |
Common/ |
Shared code: Audio, GameRules, ConsoleGameMode, zlib |
Windows64/ |
Platform headers, GameConfig, 4JLibs, Iggy headers |
ThirdParty/nuklear/ |
Nuklear single-header library (cloned repo) |
/Minecraft.World/ -- Game world logic
The original LCE world code: Level, Tile (blocks), biomes, chunk format, entity logic, items, world generation. Compiled as a static library MinecraftWorld and linked into the client.
/Minecraft.Server/ -- Dedicated server
The dedicated server target (MinecraftDedicatedServer). Shares code with the client. Has its own Linux/stubs/ directory for compatibility headers and LinuxCompat.h.
/Assets/ -- Runtime assets
| Path | Contents |
|---|---|
fonts/Mojangles.ttf |
Minecraft font, loaded by NuklearBridge at 3 sizes (14px, 20px, 32px) |
shaders/*.spv |
Pre-compiled SPIR-V shaders: mce_color, mce_textured, mce_textured_alphatest, mce_textured_fog, mce_textured_fog_alphatest |
shaders/src/ |
GLSL shader source files |
ui/skinHDGraphics/ |
HD menu textures (buttons, sliders, checkboxes, dirt tile, etc.) |
ui/skinHDGraphicsHud/ |
HD HUD textures (crosshair, hearts, food, armor, air, hotbar, XP bar) |
ui/skinHDGraphicsInGame/ |
HD in-game UI textures |
ui/skinHDWin/ |
Windows-specific HD textures (logo, panorama, controller button icons) |
/cmake/
| File | Purpose |
|---|---|
Sources.cmake |
Lists all MINECRAFT_CLIENT_SOURCES and MINECRAFT_WORLD_SOURCES |
ServerSources.cmake |
Lists server source files |
/docs/
| File | Purpose |
|---|---|
HANDOFF.md |
This file |
wave1-main-menu.md |
Exact original main menu layout: panorama, logo, buttons, splash text, tooltips |
wave1-xui-positions.md |
Every XUI control position for all scenes at 1280x720 |
wave1-button-textures.md |
The 3-layer button system (Norm + Over + Outline), all texture filenames and dimensions |
wave1-settings-layout.md |
Settings menu layouts, differences between original and current Nuklear, priority list of fixes |
nuklear-api-reference.md |
Complete Nuklear API quick reference extracted from nuklear.h |
4. Build Instructions
Prerequisites
- macOS with Apple Silicon (tested on M4 Pro) or Linux
- CMake 3.10+
- Vulkan SDK (MoltenVK on macOS)
- GLFW 3.3+
- C++17 compiler (Clang on macOS)
macOS Setup
brew install cmake vulkan-headers vulkan-loader molten-vk glfw
Build Commands
cd /Users/cole/Documents/LegacyVulkEdition
mkdir -p build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Debug -DBUILD_VULKAN_CLIENT=ON
make -j$(sysctl -n hw.ncpu)
The output binary is build/LegacyVulkEdition.
Build Targets
LegacyVulkEdition-- The Vulkan client (main target)MinecraftWorld-- Static library of world/game logicMinecraftDedicatedServer-- Dedicated server (separate target, no Vulkan)
Key CMake Variables
BUILD_VULKAN_CLIENT(ON by default on Unix) -- enables the Vulkan client targetLCEMP_WORKING_DIR-- runtime working directory, defaults toAssets/MCE_SHADER_DIR-- path to SPIR-V shaders, compiled into the binary as a defineMCE_CLIENT_ROOT-- path to Minecraft.Client, used to set working directory at startup
Compile Standards
- Original LCE code compiles as C++11
- CrossPlatform and Vulkan renderer code compiles as C++17 (set via
COMPILE_FLAGS "-std=c++17") LinuxCompat.his force-included on all Unix translation units for Win32 API compatibility
5. How to Run
Working Directory
The binary sets its working directory to MCE_CLIENT_ROOT (Minecraft.Client/) at startup:
std::filesystem::current_path(std::filesystem::path(MCE_CLIENT_ROOT));
All asset paths in the code are relative to this directory. For example, textures load from ../Assets/ui/skinHDGraphics/... and fonts from ../Assets/fonts/Mojangles.ttf.
Required Assets
The game needs MediaWindows64.arc in the working directory for the original game's texture pack. This archive is loaded by app.loadMediaArchive(). Without it, game textures (blocks, entities) won't load, but menu rendering still works.
Launch
cd /Users/cole/Documents/LegacyVulkEdition/build
./LegacyVulkEdition
What Happens on Launch
- GLFW window opens at 1280x720 titled "Minecraft Community Edition"
- Vulkan initializes (MoltenVK on macOS)
- Nuklear initializes with Mojangles.ttf font at 3 sizes
- Menu textures load from Assets/ui/ (417 PNGs)
- MediaWindows64.arc loads (game textures)
- StringTable loads (localization)
Minecraft::main()runs the game bootstrap- Main menu renders with panorama background, logo, and 6 buttons
- Game enters main loop -- menus are interactive, world can load
Startup Logging
All diagnostic output goes to stderr with [MCE] prefix. Watch for:
[MCE] Working directory: ...[NuklearBridge] Loaded Mojangles.ttf (N bytes)[NuklearBridge] Loaded texture: ... (WxH) -> slot N[MCE] Calling Minecraft::main()...[MCE] Entering main loop...
6. Menu System
State Machine
NuklearSceneRenderer in MenuScreens.h/.cpp is the central menu controller. It has:
- A
MenuState m_stateenum (52 values fromkMenuState_MainMenutokMenuState_EndPoem) - A fixed-size stack (
m_stateStack[16],m_stateStackDepth) for pushState/popState navigation - Per-menu state structs (e.g.,
CreateWorldState,HostOptionsState) stored as members
How render() Works
Each frame, NuklearSceneRenderer::render(windowW, windowH) runs a switch on m_state and calls the corresponding Nk*.cpp render function. Each render function:
- Gets the
nk_context*viagetNkContext() - Creates a fullscreen Nuklear window (
nk_begin) - Draws the background (panorama for main menu, dirt tiles for sub-menus)
- Draws buttons/controls using the shared helpers from NkCommon.cpp
- Returns an action enum (e.g.,
MenuAction,SettingsAction,WorldMenuAction) - The switch statement in render() handles the action by pushing/popping states
Navigation
pushState(newState)-- saves current state to stack, sets new statepopState()-- restores previous state from stack- Escape/Backspace triggers
isEscapePressed()which callspopState()on most menus - Quit action (
kMenuAction_QuitGame) setsm_quit = true, which the main loop checks
How to Add a New Menu
- Create
NkMyMenu.handNkMyMenu.cppinCrossPlatform/ - Define a state struct if needed (e.g.,
MyMenuState) - Define an action enum and render function:
MyMenuAction renderMyMenu(nk_context*, int winW, int winH, MenuTextures&, MyMenuState&) - Add
kMenuState_MyMenuto theMenuStateenum inMenuScreens.h - Add
#include "NkMyMenu.h"inMenuScreens.h - Add
MyMenuState m_myMenuState;member toNuklearSceneRenderer - Add a case in
NuklearSceneRenderer::render()switch statement - Add the .cpp to
CROSSPLATFORM_SOURCESinCMakeLists.txt
Shared Drawing Helpers (NkCommon.cpp)
All Nk*.cpp files use these helpers for consistent visuals:
| Function | Purpose |
|---|---|
pushCleanStyle / popCleanStyle |
Zero out Nuklear window chrome (border, padding, background) |
drawDirtBg |
Tile the dirt texture across the window with dark overlay |
drawPanoramaBg |
Draw the blurred panorama background image |
drawLogo |
Draw the Minecraft logo centered at the top |
drawControllerPrompts |
Draw "[A] Select [B] Back" at bottom-left |
drawBtn |
Draw a textured button (Norm/Over textures, text with shadow), returns true if clicked |
drawTitle |
Draw centered title text |
drawCenteredText |
Draw text centered within a rect |
drawLabel |
Draw left-aligned text |
drawTextInput |
Draw a text input field with border and caret |
drawListItem |
Draw a list item row with selection highlight |
7. Texture System
How Textures Load
NuklearBridge.cpp provides two functions:
loadTexture(path)-- loads a PNG/JPEG, returnsnk_imageloadTextureWithSize(path, &w, &h)-- same but also returns dimensions
The pipeline:
- Read file into memory buffer (
loadFileIntoBuffer) - Decode with
stb_image.h(always 4 channels RGBA) RenderManager.TextureCreate()allocates a Vulkan texture slotRenderManager.TextureData(w, h, pixels, 0)uploads pixel data- Set linear filtering
- Returns
nk_image_id(texId)-- the integer texture slot ID
MenuScreens.cpp::init() loads all shared menu textures into MenuTextures struct slots. Each Nk*.cpp module that needs additional textures has its own texture struct and init function (e.g., loadInventoryMenuTextures, initHUDTextures).
Texture Slot Struct
struct MenuTextureSlot {
int id; // Vulkan texture slot index
int w; // pixel width
int h; // pixel height
};
Where PNGs Live
All UI textures are in Assets/ui/ organized by skin:
| Directory | Contents | Count |
|---|---|---|
skinHDGraphics/ |
Buttons, sliders, checkboxes, dirt tile, inventory elements | ~200 |
skinHDGraphicsHud/ |
HUD elements: crosshair, hearts, food, armor, air, hotbar, XP | ~30 |
skinHDGraphicsInGame/ |
In-game UI elements | ~50 |
skinHDWin/ |
Windows platform: logo, panorama, controller icons | ~140 |
Total: approximately 417 PNGs.
JPEXS Extraction
These PNGs were extracted from the original SWF skin files using JPEXS Free Flash Decompiler. The SWF files (skinHDWin.swf, skinHDGraphics.swf, etc.) contained embedded bitmap assets at fixed sprite indices. JPEXS exports them with their sprite index as a filename prefix (e.g., 191_FJ_MainMenuButton_Norm.png = sprite 191).
The full extraction archive is at /Users/cole/Downloads/minecraft_swf_pngs/.
Key Texture Files
| Purpose | File |
|---|---|
| Dirt tile (tiled background) | skinHDGraphics/164_Dirt_Tile.png |
| Minecraft logo | skinHDWin/180_MenuTitle.png |
| Button normal (gray stone) | skinHDGraphics/191_FJ_MainMenuButton_Norm.png (600x60) |
| Button hover (blue/purple) | skinHDGraphics/189_MainMenuButton_Over.png (600x60) |
| Button outline (yellow) | skinHDGraphics/190_MainMenuButton_Outline.png (606x66) |
| Panorama (day) | skinHDWin/205_Panorama_Background_S.jpg |
| Controller A button | skinHDWin/204_ButtonA.png |
| Controller B button | skinHDWin/203_ButtonB.png |
| Slider background | skinHDGraphics/182_FJ_Slider_Background.png |
| Slider thumb | skinHDGraphics/181_Slider_Graphic.png |
| Checkbox background | skinHDGraphics/178_FJ_Tickbox_Background.png |
| Checkbox tick | skinHDGraphics/177_Tick.png |
| HUD crosshair | skinHDGraphicsHud/27_HUD_Crosshair.png |
| Hotbar background | skinHDGraphicsHud/29_hotbar_item_back.png |
| Health heart (full) | skinHDGraphicsHud/34_Health_Full.png |
8. What Works
Confirmed Working
- Vulkan rendering on M4 Pro (MoltenVK)
- GLFW window with resize handling
- stb_image texture loading (PNG + JPEG)
- Mojangles.ttf font at 3 sizes
- Nuklear UI rendering through Vulkan pipeline
- All 52 menu states implemented and reachable:
- Main Menu with panorama background + logo
- Pause Menu with dirt tile background + logo
- Death Menu
- Help & Options (5 buttons)
- Settings Hub (6 buttons: Options/Audio/Control/Graphics/UI/Reset)
- All 5 settings sub-menus with sliders and checkboxes
- Create World, Load Menu, Join Menu
- Inventory, Crafting 2x2/3x3, Creative
- Furnace, Chest, Anvil, Brewing Stand, Enchanting, Trading, Dispenser
- HUD overlay (crosshair, health, food, armor, air, XP, hotbar)
- Intro, MessageBox, EULA, SaveMessage, ConnectingProgress, FullscreenProgress
- Credits and End Poem (auto-scrolling)
- Skin Select, How to Play, Controls, Leaderboards, DLC
- Host Options, Player Options, Sign Entry, Teleport, Debug, Keyboard, Quadrant Signin
- Menu navigation (push/pop state stack, escape to go back)
- Mouse input (hover, click) on all menus
- Keyboard input (character input for text fields, escape for back)
- Mouse grab/ungrab for in-game look
- F3 debug overlay with frame timings and memory usage
- Game bootstrap (Minecraft::main runs, world subsystems init)
- MediaWindows64.arc loaded, game textures available
- Zero warnings from CrossPlatform code
9. What's Broken / Missing
Visual Issues
- Button width too narrow: Current 600px at 1280 base works for main menu but some menus still use 450px. Original settings menus used ~900px at 1080p.
- Yellow button outline on hover is too bright: Needs to be softer or removed. The original uses the blue/purple 189_Over texture, not a bright yellow outline. The outline should only appear as a subtle glow behind the selected button, at reduced opacity.
- Settings menus use dirt background instead of panorama: When accessed from main menu, settings should show panorama. Dirt background is only correct when accessed from pause menu (in-game).
- No logo on settings/help screens: They show text titles instead.
- No splash text on main menu: The yellow pulsing text at -20 degrees rotation is not implemented.
- No "WINDOWS EDITION" subtitle on logo
- Button 5 label: Memory notes say it should be "Minecraft Store" not "Downloadable Content" -- this appears to have been fixed already in the code (NkCoreMenus.cpp shows "Minecraft Store").
Functional Gaps
- Settings not connected to game state: All settings values are static local variables. Changes aren't persisted or applied to the game.
- No controller/keyboard navigation: Menus are mouse-only. No focus tracking, no gamepad D-pad navigation between controls.
- No tooltip/prompt bar: The "[A] Select [B] Back" footer exists in drawControllerPrompts() but isn't called on all menus.
- No conditional button removal: Buttons that should be hidden based on player role, game state, or platform are always shown.
- HUD uses hardcoded values: Health=20, food=20, armor=20, XP=0.45/level 7. Not wired to actual game state.
- No audio: Sound engine is stubbed. No OGG playback, no menu sounds.
- No save/load: World save/load flow is UI-only, not wired to actual game persistence.
10. What's Left (Remaining Phases)
Phase 5: Visual Polish (In Progress)
- Correct background system (panorama vs dirt based on context)
- Draw logo on settings/help screens
- Splash text implementation (random from splashes.txt, -17deg rotation, sine-wave scale pulsing)
- Selected button blue/white highlight effect for controller navigation
- Controller prompts on all menus
- "WINDOWS EDITION" subtitle
Phase 6: Systems Integration
- Input: Wire GLFW keyboard/mouse input to the game's
KeyboardMouseInputsystem so in-game controls work - Audio: Integrate miniaudio + stb_vorbis for OGG music/sound playback
- HUD: Wire HUD display to actual player state (health, food, armor from
pMinecraft->player) - Hand rendering: First-person hand with depth buffer clear
- Tesselator fixes: TRIANGLE_MODE=false, default white color for correct terrain rendering
Phase 7: Build & Polish
- Rename project in CMake to LegacyVulkEdition (currently "LCEMP")
- GitHub Actions CI/CD
- settings.ini for user config persistence
- Memory limit increase (256MB to 1GB)
- Configurable render distance
Phase 8: Game Integration
- Wire settings menus to actual game options (Options, Audio, Graphics, etc.)
- Save/load world functionality
- Multiplayer join flow
Phase 9-11: Advanced Features
- Mod API foundation
- Plugin loader
- Unit tests
- Crash reporter
11. Key Decisions
Why Nuklear Over ImGui
Nuklear was chosen because:
- It's designed for game UI (styled widgets), not debug overlays like ImGui
- Single-header library with no dependencies
- Has a vertex buffer output mode that lets us feed triangles through the existing Vulkan pipeline without needing a separate render backend
- Supports custom drawing via command buffers (nk_draw_image, nk_draw_text, etc.) which lets us do pixel-perfect texture placement
Why PNGs Over SWFs
The original game used SWF (Flash) files for UI rendering via Iggy (Scaleform). Rather than implementing a SWF renderer:
- All sprite assets were extracted from the SWFs as PNGs using JPEXS
- The PNGs retain the original filenames with sprite index prefixes
- Nuklear renders these as textured quads, achieving the same visual result
- This eliminates the Iggy/Scaleform dependency entirely
Why Iggy Code Is Guarded, Not Deleted
All original Iggy/SWF code is behind #ifndef USE_VULKAN_RENDERER. This preserves the D3D11 path in case someone wants to build the original Windows version. The code also serves as reference for how the original menus worked (what buttons exist, what actions they trigger, layout constants).
State Machine Over UIController
The original game used ConsoleUIController to manage UI scenes. This has been largely stubbed because it was tightly coupled to Iggy. Instead, NuklearSceneRenderer implements a simple state machine with a push/pop stack. This is simpler and gives direct control over menu transitions.
Coordinate System
All Nuklear menu code uses a 1280x720 base coordinate system. Coordinates are scaled by (windowW / 1280.0f, windowH / 720.0f) for resolution independence. The original XUI files also used 1280x720 as their canvas, so the coordinate values match directly.
12. Reference Locations
Source Code
| What | Where |
|---|---|
| This project | /Users/cole/Documents/LegacyVulkEdition |
| Original LCE source | /Users/cole/Downloads/minecraft/ |
| Vulkan reference renderer | /Users/cole/Documents/MinecraftConsole-Vulkan/ |
Assets
| What | Where |
|---|---|
| JPEXS-extracted SWF PNGs (full set) | /Users/cole/Downloads/minecraft_swf_pngs/ |
| HD menu textures (in project) | Assets/ui/skinHDGraphics/ |
| HD HUD textures (in project) | Assets/ui/skinHDGraphicsHud/ |
| Windows-specific textures (in project) | Assets/ui/skinHDWin/ |
| In-game UI textures (in project) | Assets/ui/skinHDGraphicsInGame/ |
| Mojangles font | Assets/fonts/Mojangles.ttf |
| SPIR-V shaders | Assets/shaders/*.spv |
| GLSL shader source | Assets/shaders/src/ |
Documentation
| What | Where |
|---|---|
| Main menu layout reference | docs/wave1-main-menu.md |
| XUI positions for all scenes | docs/wave1-xui-positions.md |
| Button texture system | docs/wave1-button-textures.md |
| Settings layout comparison | docs/wave1-settings-layout.md |
| Nuklear API reference | docs/nuklear-api-reference.md |
Memory / AI Context
| What | Where |
|---|---|
| Project status summary | ~/.claude/projects/-Users-cole/memory/project_lve_status.md |
13. Quick Reference: Code Patterns
Every Nk*.cpp Menu Function Follows This Pattern
MenuAction renderSomeMenu(nk_context *ctx, int windowW, int windowH, MenuTextures &tex) {
MenuAction result = kMenuAction_None;
float scaleX = (float)windowW / 1280.0f;
float scaleY = (float)windowH / 720.0f;
pushCleanStyle(ctx);
if (nk_begin(ctx, "SomeMenu", nk_rect(0, 0, windowW, windowH),
NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_BACKGROUND | NK_WINDOW_NO_INPUT)) {
drawPanoramaBg(ctx, windowW, windowH, tex); // or drawDirtBg
drawLogo(ctx, windowW, windowH, tex);
// Draw buttons at scaled positions
float btnX = 340.0f * scaleX;
float btnY = 250.0f * scaleY;
float btnW = 600.0f * scaleX;
float btnH = 40.0f * scaleY;
bool hovered = nk_input_is_mouse_hovering_rect(&ctx->input,
nk_rect(btnX, btnY, btnW, btnH)) != 0;
if (drawBtn(ctx, "Button Label", btnX, btnY, btnW, btnH, hovered, tex))
result = kMenuAction_SomeAction;
drawControllerPrompts(ctx, windowW, windowH, tex);
}
nk_end(ctx);
popCleanStyle(ctx);
return result;
}
The 3-Layer Button Rendering (drawBtn in NkCommon.cpp)
- Draw button background texture (buttonNormal or buttonHover based on hover state)
- If hovered, draw buttonOutline texture behind the button at reduced opacity
- Draw text centered on the button with dark shadow offset
Texture Loading Pattern
MenuTextureSlot loadSlot(const char *path) {
int w = 0, h = 0;
struct nk_image img = loadTextureWithSize(path, &w, &h);
return {img.handle.id, w, h};
}
14. Glossary
| Term | Meaning |
|---|---|
| LCE | Legacy Console Edition (Minecraft for Xbox/PS/Switch/WiiU by 4J Studios) |
| Iggy | Scaleform/Iggy -- the Flash (SWF) UI engine used by the original game |
| XUI | Xbox UI -- the older Xbox 360 UI system, coexists with Iggy in the source |
| JPEXS | Free Flash Decompiler -- used to extract PNG sprites from SWF files |
| 4J | 4J Studios -- the developer of the original console editions |
| Nuklear | Immediate-mode UI library used as the Iggy replacement |
| RenderManager | Global C4JRender instance -- the abstraction layer the game code calls for all rendering |
| MoltenVK | Vulkan-to-Metal translation layer for macOS |
| MediaWindows64.arc | The game's texture pack archive containing block/entity textures |
| skinHDGraphics | HD resolution skin containing UI element textures |
| skinHDWin | Windows platform-specific UI textures (logo, panorama, controller icons) |