Skip to content

These docs were made completely by AI, so they might be right, or wrong, you'll need to test them yourself. This was made for a easier understanding of everything. So use at your own risk. If anything is wrong, please don't hurt to make a PR on the page you have a problem with. ON GITHUB

Creative Mode Tabs

The creative inventory in LCE is split into 8 tabs across the top of the screen. Each tab shows a grid of items that players can pick from. Unlike Java Edition where items register themselves into categories, LCE takes a different approach: every single item in every tab is listed by hand in one big function.

This guide covers everything about how the tab system works, what lives in each tab down to the exact item, and how to change things around.

When a player opens the creative inventory, here is what happens under the hood:

  1. The game creates a UIScene_CreativeMenu (on PS3/PS Vita) or CXuiSceneInventoryCreative (on Xbox 360). Both inherit from IUIScene_CreativeMenu, which holds all the shared logic.

  2. The constructor calls initialiseMovie(), which loads the SWF movie file for the creative menu. The movie name comes from getMoviePath():

wstring UIScene_CreativeMenu::getMoviePath()
{
if(app.GetLocalPlayerCount() > 1)
return L"CreativeMenuSplit";
else
return L"CreativeMenu";
}

In splitscreen, it loads a smaller layout (CreativeMenuSplit). In single player, it loads the full-size CreativeMenu.

  1. The SWF file gets loaded at a resolution that matches the output: CreativeMenu1080.swf, CreativeMenu720.swf, or CreativeMenu480.swf. On PS Vita it loads CreativeMenuVita.swf. These are compiled Flash (SWF) movies rendered through RAD Game Tools’ Iggy library, which acts as a Flash player inside the game.

  2. After the movie loads, mapElementsAndNames() runs. This wires up the C++ code to named elements inside the SWF. It maps 8 touch panels (TouchPanel_0 through TouchPanel_7) for the tab buttons, a TouchPanel_Slider for the scroll bar, a containerList for the 50-slot item grid, and two callable functions: SetActiveTab and SetScrollBar.

  3. An ItemPickerMenu gets created. This is a special AbstractContainerMenu with 50 slots for the item grid plus 9 slots for the hotbar at the bottom.

  4. The constructor sets m_curTab to eCreativeInventoryTab_COUNT (an invalid value) then calls switchTab(eCreativeInventoryTab_BuildingBlocks). Since the current tab differs from the target, updateTabHighlightAndText() fires. On Iggy platforms, this calls into the SWF movie using IggyPlayerCallMethodRS to run the SetActiveTab ActionScript function with the tab index as an argument. The SWF handles highlighting the right tab icon and dimming the rest.

  5. The inventory title label gets set to the localized tab name (like “Building Blocks”) using app.GetString(specs[tab]->m_descriptionId).

  6. populateMenu() fills the 50 container slots with the right items for the current page. The Iggy movie’s custom draw callback then renders each item’s icon into the grid cells.

That is the full pipeline: SWF movie provides the visual layout and tab highlighting, C++ code manages the data and input, and the Iggy library bridges the two.

Every UI screen in LCE on PS3, PS Vita, and PS4 is a compiled Flash movie (.swf file). These are not played as video. They are interactive vector-based layouts with named elements that the C++ code can talk to.

The game uses RAD Game Tools’ Iggy library as the Flash runtime. Iggy loads the SWF, renders it with the game’s GPU, and exposes an API for calling ActionScript functions and reading element positions.

Key Iggy API calls used in the creative menu:

FunctionWhat It Does
IggyPlayerCallMethodRS()Calls an ActionScript function in the SWF by name
IggyPlayerRootPath()Gets the root path of the movie for element lookup
IggyExternalFunctionCallUTF16Handles callbacks from the SWF back to C++

The Xbox 360 version uses Microsoft’s XUI framework instead of Iggy/SWF. XUI scenes are authored in Microsoft’s UI tool and use .xur binary files. The CXuiSceneInventoryCreative class maps tab icons and controls through XUI’s MAP_CONTROL macros:

MAP_CONTROL(IDC_Icon_1, m_hGroupIconA[0])
MAP_CONTROL(IDC_Icon_2, m_hGroupIconA[1])
// ... through ...
MAP_CONTROL(IDC_Icon_8, m_hGroupIconA[7])
MAP_CONTROL(IDC_TabImage1, m_hTabGroupA[0])
MAP_CONTROL(IDC_TabImage2, m_hTabGroupA[1])
// ... through ...
MAP_CONTROL(IDC_TabImage8, m_hTabGroupA[7])

Both systems end up doing the same thing: 8 tab buttons, an item grid, a scroll bar, and a hotbar. The shared logic in IUIScene_CreativeMenu does not care which UI backend is in use.

The creative menu lives in IUIScene_CreativeMenu, defined in Minecraft.Client/Common/UI/IUIScene_CreativeMenu.h and .cpp. There are two important layers to understand:

  1. Inventory Groups are logical buckets of items (like “Building Blocks” or “Redstone” or “Transport”)
  2. Tabs are what the player actually sees on screen. A tab can pull from one or more groups.

For example, the “Redstone & Transport” tab combines the Redstone group and the Transport group into a single tab. The Brewing tab combines the brewing ingredients group with four different potion tier groups.

Everything gets set up in IUIScene_CreativeMenu::staticCtor(), which runs once at startup.

enum ECreativeInventoryTabs
{
eCreativeInventoryTab_BuildingBlocks = 0,
eCreativeInventoryTab_Decorations,
eCreativeInventoryTab_RedstoneAndTransport,
eCreativeInventoryTab_Materials,
eCreativeInventoryTab_Food,
eCreativeInventoryTab_ToolsWeaponsArmor,
eCreativeInventoryTab_Brewing,
eCreativeInventoryTab_Misc,
eCreativeInventoryTab_COUNT,
};

There are exactly 8 tabs. The UI has 8 touch panels hardcoded (TouchPanel_0 through TouchPanel_7), so adding a 9th tab means UI work too.

enum ECreative_Inventory_Groups
{
eCreativeInventory_BuildingBlocks,
eCreativeInventory_Decoration,
eCreativeInventory_Redstone,
eCreativeInventory_Transport,
eCreativeInventory_Materials,
eCreativeInventory_Food,
eCreativeInventory_ToolsArmourWeapons,
eCreativeInventory_Brewing,
eCreativeInventory_Potions_Basic,
eCreativeInventory_Potions_Level2,
eCreativeInventory_Potions_Extended,
eCreativeInventory_Potions_Level2_Extended,
eCreativeInventory_Misc,
eCreativeInventory_ArtToolsDecorations,
eCreativeInventory_ArtToolsMisc,
eCreativeInventoryGroupsCount
};

Groups are just arrays of ItemInstance pointers. A tab references one or more groups and the TabSpec system handles stitching them together for display.

The last two groups (ArtToolsDecorations and ArtToolsMisc) are debug-only groups. They only show up when app.DebugArtToolsOn() returns true. In retail builds compiled with _CONTENT_PACKAGE defined, these groups do not exist at all.

Each tab shows a 10-column by 5-row grid, so 50 item slots per page:

struct TabSpec
{
static const int rows = 5;
static const int columns = 10;
static const int MAX_SIZE = rows * columns; // 50
// ...
};

If a tab has more than 50 items, it gets multiple pages. Players scroll between pages with the right stick or the scroll bar on the side.

All item lists in staticCtor() are built using three macros defined at the top of the file:

#define ITEM(id) list->push_back( \
shared_ptr<ItemInstance>(new ItemInstance(id, 1, 0)) );
#define ITEM_AUX(id, aux) list->push_back( \
shared_ptr<ItemInstance>(new ItemInstance(id, 1, aux)) );
#define DEF(index) list = &categoryGroups[index];

Switches which group you are currently adding items to. The list pointer gets reassigned to point at a different vector in the categoryGroups array.

// From this point on, all ITEM() calls go into the Building Blocks group
DEF(eCreativeInventory_BuildingBlocks)

You can call DEF as many times as you want. Each call just redirects where ITEM() puts things. The groups in the source code are not separated into different functions. They are all in one big block inside staticCtor(), with DEF calls acting as section dividers.

Creates an ItemInstance with the given item/block ID, a stack count of 1, and an aux (damage/data) value of 0. This is what you use for items that only have one variant.

ITEM(Tile::stone_Id) // Stone block, aux 0
ITEM(Item::diamond_Id) // Diamond item, aux 0

Same as ITEM() but lets you set the aux value. The aux value picks which variant of an item/block you want. This is how you get different wood types, dye colors, wool colors, potion types, and mob spawn eggs.

ITEM_AUX(Tile::wood_Id, 0) // Oak planks
ITEM_AUX(Tile::wood_Id, TreeTile::DARK_TRUNK) // Spruce planks
ITEM_AUX(Tile::wood_Id, TreeTile::BIRCH_TRUNK) // Birch planks
ITEM_AUX(Item::dye_powder_Id, 4) // Lapis (blue dye)
ITEM_AUX(Item::spawnEgg_Id, 50) // Creeper spawn egg

Under the hood, both macros call new ItemInstance(id, count, aux):

  • id: The numeric item or block ID
  • count: Always 1 in creative tabs (how many in the stack)
  • aux: The damage/data value (0 for default variant)

The destination for all these items is a static array of vectors:

static vector< shared_ptr<ItemInstance> > categoryGroups[eCreativeInventoryGroupsCount];

There is one vector per group enum value. When staticCtor() runs, each DEF call switches the list pointer to a different vector, and each ITEM/ITEM_AUX call appends to that vector. After staticCtor() finishes, every group’s vector is fully populated and never changes again.

What’s in Each Tab (Complete Item Lists)

Section titled “What’s in Each Tab (Complete Item Lists)”

Here is every item in every group, in the exact order they appear in the source code. This is the order they show up in the creative grid.

#ItemCode
1StoneTile::stone_Id
2Grass BlockTile::grass_Id
3DirtTile::dirt_Id
4CobblestoneTile::cobblestone_Id
5SandTile::sand_Id
6SandstoneTile::sandStone_Id
7Smooth SandstoneTile::sandStone_Id aux TYPE_SMOOTHSIDE
8Chiseled SandstoneTile::sandStone_Id aux TYPE_HEIROGLYPHS
9Block of CoalTile::coalBlock_Id
10Block of GoldTile::goldBlock_Id
11Block of IronTile::ironBlock_Id
12Lapis Lazuli BlockTile::lapisBlock_Id
13Diamond BlockTile::diamondBlock_Id
14Emerald BlockTile::emeraldBlock_Id
15Block of QuartzTile::quartzBlock_Id aux TYPE_DEFAULT
16Coal OreTile::coalOre_Id
17Lapis Lazuli OreTile::lapisOre_Id
18Diamond OreTile::diamondOre_Id
19Redstone OreTile::redStoneOre_Id
20Iron OreTile::ironOre_Id
21Gold OreTile::goldOre_Id
22Emerald OreTile::emeraldOre_Id
23Nether Quartz OreTile::netherQuartz_Id
24BedrockTile::unbreakable_Id
25Oak PlanksTile::wood_Id aux 0
26Spruce PlanksTile::wood_Id aux DARK_TRUNK
27Birch PlanksTile::wood_Id aux BIRCH_TRUNK
28Jungle PlanksTile::wood_Id aux JUNGLE_TRUNK
29Oak LogTile::treeTrunk_Id aux 0
30Spruce LogTile::treeTrunk_Id aux DARK_TRUNK
31Birch LogTile::treeTrunk_Id aux BIRCH_TRUNK
32Jungle LogTile::treeTrunk_Id aux JUNGLE_TRUNK
33GravelTile::gravel_Id
34BricksTile::redBrick_Id
35Mossy CobblestoneTile::mossyCobblestone_Id
36ObsidianTile::obsidian_Id
37Clay BlockTile::clay
38IceTile::ice_Id
39Snow BlockTile::snow_Id
40NetherrackTile::netherRack_Id
41Soul SandTile::soulsand_Id
42GlowstoneTile::glowstone_Id
43Oak FenceTile::fence_Id
44Nether Brick FenceTile::netherFence_Id
45Iron BarsTile::ironFence_Id
46Cobblestone WallTile::cobbleWall_Id aux TYPE_NORMAL
47Mossy Cobblestone WallTile::cobbleWall_Id aux TYPE_MOSSY
48Stone BricksTile::stoneBrick_Id aux TYPE_DEFAULT
49Mossy Stone BricksTile::stoneBrick_Id aux TYPE_MOSSY
50Cracked Stone BricksTile::stoneBrick_Id aux TYPE_CRACKED
51Chiseled Stone BricksTile::stoneBrick_Id aux TYPE_DETAIL
52Infested StoneTile::monsterStoneEgg_Id aux HOST_ROCK
53Infested CobblestoneTile::monsterStoneEgg_Id aux HOST_COBBLE
54Infested Stone BricksTile::monsterStoneEgg_Id aux HOST_STONEBRICK
55MyceliumTile::mycel_Id
56Nether BricksTile::netherBrick_Id
57End StoneTile::endStone_Id
58Chiseled QuartzTile::quartzBlock_Id aux TYPE_CHISELED
59Pillar QuartzTile::quartzBlock_Id aux TYPE_LINES_Y
60TrapdoorTile::trapdoor_Id
61Fence GateTile::fenceGate_Id
62Wooden DoorItem::door_wood_Id
63Iron DoorItem::door_iron_Id
64Stone SlabTile::stoneSlabHalf_Id aux STONE_SLAB
65Sandstone SlabTile::stoneSlabHalf_Id aux SAND_SLAB
66Oak Wood SlabTile::woodSlabHalf_Id aux 0
67Spruce Wood SlabTile::woodSlabHalf_Id aux DARK_TRUNK
68Birch Wood SlabTile::woodSlabHalf_Id aux BIRCH_TRUNK
69Jungle Wood SlabTile::woodSlabHalf_Id aux JUNGLE_TRUNK
70Cobblestone SlabTile::stoneSlabHalf_Id aux COBBLESTONE_SLAB
71Brick SlabTile::stoneSlabHalf_Id aux BRICK_SLAB
72Stone Brick SlabTile::stoneSlabHalf_Id aux SMOOTHBRICK_SLAB
73Nether Brick SlabTile::stoneSlabHalf_Id aux NETHERBRICK_SLAB
74Quartz SlabTile::stoneSlabHalf_Id aux QUARTZ_SLAB
75Oak StairsTile::stairs_wood_Id
76Birch StairsTile::stairs_birchwood_Id
77Spruce StairsTile::stairs_sprucewood_Id
78Jungle StairsTile::stairs_junglewood_Id
79Cobblestone StairsTile::stairs_stone_Id
80Brick StairsTile::stairs_bricks_Id
81Stone Brick StairsTile::stairs_stoneBrick_Id
82Nether Brick StairsTile::stairs_netherBricks_Id
83Sandstone StairsTile::stairs_sandstone_Id
84Quartz StairsTile::stairs_quartz_Id
85Hardened ClayTile::clayHardened_Id
86-101Stained Clay (16 colors)Tile::clayHardened_colored_Id aux 0-15

The 16 stained clay colors appear in this order: Red (14), Orange (1), Yellow (4), Lime (5), Light Blue (3), Cyan (9), Blue (11), Purple (10), Magenta (2), Pink (6), White (0), Light Gray (8), Gray (7), Black (15), Green (13), Brown (12).

#ItemCode
1Skeleton SkullItem::skull_Id aux TYPE_SKELETON
2Wither Skeleton SkullItem::skull_Id aux TYPE_WITHER
3Zombie HeadItem::skull_Id aux TYPE_ZOMBIE
4Steve HeadItem::skull_Id aux TYPE_CHAR
5Creeper HeadItem::skull_Id aux TYPE_CREEPER
6SpongeTile::sponge_Id
7Melon BlockTile::melon_Id
8PumpkinTile::pumpkin_Id
9Jack o’LanternTile::litPumpkin_Id
10Oak SaplingTile::sapling_Id aux TYPE_DEFAULT
11Spruce SaplingTile::sapling_Id aux TYPE_EVERGREEN
12Birch SaplingTile::sapling_Id aux TYPE_BIRCH
13Jungle SaplingTile::sapling_Id aux TYPE_JUNGLE
14Oak LeavesTile::leaves_Id aux NORMAL_LEAF
15Spruce LeavesTile::leaves_Id aux EVERGREEN_LEAF
16Birch LeavesTile::leaves_Id aux BIRCH_LEAF
17Jungle LeavesTile::leaves_Id aux JUNGLE_LEAF
18VinesTile::vine
19Lily PadTile::waterLily_Id
20TorchTile::torch_Id
21Dead Shrub (tall grass)Tile::tallgrass_Id aux DEAD_SHRUB
22Tall GrassTile::tallgrass_Id aux TALL_GRASS
23FernTile::tallgrass_Id aux FERN
24Dead BushTile::deadBush_Id
25DandelionTile::flower_Id
26RoseTile::rose_Id
27Brown MushroomTile::mushroom_brown_Id
28Red MushroomTile::mushroom_red_Id
29CactusTile::cactus_Id
30Snow LayerTile::topSnow_Id
31CobwebTile::web_Id
32Glass PaneTile::thinGlass_Id
33GlassTile::glass_Id
34PaintingItem::painting_Id
35Item FrameItem::itemFrame_Id
36SignItem::sign_Id
37BookshelfTile::bookshelf_Id
38Flower PotItem::flowerPot_Id
39Hay BaleTile::hayBlock_Id
40-55Wool (16 colors)Tile::wool_Id aux 0-15
56-71Carpet (16 colors)Tile::woolCarpet_Id aux 0-15
72-87Stained Glass (16 colors)Tile::stained_glass_Id aux 0-15
88-103Stained Glass Pane (16 colors)Tile::stained_glass_pane_Id aux 0-15

All 16-color sets follow the same color order: Red (14), Orange (1), Yellow (4), Lime (5), Light Blue (3), Cyan (9), Blue (11), Purple (10), Magenta (2), Pink (6), White (0), Light Gray (8), Gray (7), Black (15), Green (13), Brown (12).

Debug only (ArtToolsDecorations): When debug art tools are on, this group adds all painting variants as individual items (each with a unique aux value from 1 through Painting::LAST_VALUE) plus 8 pre-built firework rockets in various shapes and colors.

#ItemCode
1DispenserTile::dispenser_Id
2Note BlockTile::noteblock_Id
3PistonTile::pistonBase_Id
4Sticky PistonTile::pistonStickyBase_Id
5TNTTile::tnt_Id
6LeverTile::lever_Id
7Stone ButtonTile::button_stone_Id
8Wooden ButtonTile::button_wood_Id
9Stone Pressure PlateTile::pressurePlate_stone_Id
10Wooden Pressure PlateTile::pressurePlate_wood_Id
11Redstone DustItem::redStone_Id
12Block of RedstoneTile::redstoneBlock_Id
13Redstone TorchTile::redstoneTorch_on_Id
14Redstone RepeaterItem::repeater_Id
15Redstone LampTile::redstoneLight_Id
16Tripwire HookTile::tripWireSource_Id
17Daylight SensorTile::daylightDetector_Id
18DropperTile::dropper_Id
19HopperTile::hopper_Id
20Redstone ComparatorItem::comparator_Id
21Trapped ChestTile::chest_trap_Id
22Heavy Weighted Pressure PlateTile::weightedPlate_heavy_Id
23Light Weighted Pressure PlateTile::weightedPlate_light_Id
#ItemCode
1RailTile::rail_Id
2Powered RailTile::goldenRail_Id
3Detector RailTile::detectorRail_Id
4Activator RailTile::activatorRail_Id
5LadderTile::ladder_Id
6MinecartItem::minecart_Id
7Minecart with ChestItem::minecart_chest_Id
8Minecart with FurnaceItem::minecart_furnace_Id
9Minecart with HopperItem::minecart_hopper_Id
10Minecart with TNTItem::minecart_tnt_Id
11SaddleItem::saddle_Id
12BoatItem::boat_Id

The Redstone & Transport tab shows Transport group items first, then Redstone group items. This is because the TabSpec is created with {eCreativeInventory_Transport, eCreativeInventory_Redstone} in that order.

#ItemCode
1CoalItem::coal_Id
2CharcoalItem::coal_Id aux 1
3DiamondItem::diamond_Id
4EmeraldItem::emerald_Id
5Iron IngotItem::ironIngot_Id
6Gold IngotItem::goldIngot_Id
7Nether QuartzItem::netherQuartz_Id
8BrickItem::brick_Id
9Nether BrickItem::netherbrick_Id
10StickItem::stick_Id
11BowlItem::bowl_Id
12BoneItem::bone_Id
13StringItem::string_Id
14FeatherItem::feather_Id
15FlintItem::flint_Id
16LeatherItem::leather_Id
17GunpowderItem::gunpowder_Id
18Clay BallItem::clay_Id
19Glowstone DustItem::yellowDust_Id
20Wheat SeedsItem::seeds_wheat_Id
21Melon SeedsItem::seeds_melon_Id
22Pumpkin SeedsItem::seeds_pumpkin_Id
23WheatItem::wheat_Id
24Sugar CaneItem::reeds_Id
25EggItem::egg_Id
26SugarItem::sugar_Id
27Slime BallItem::slimeBall_Id
28Blaze RodItem::blazeRod_Id
29Gold NuggetItem::goldNugget_Id
30Nether WartItem::netherwart_seeds_Id
31-46Dye (16 colors)Item::dye_powder_Id aux values

The 16 dye colors appear in this order: Red (1), Orange (14), Yellow (11), Lime (10), Light Blue (12), Cyan (6), Blue/Lapis (4), Purple (5), Magenta (13), Pink (9), Bone Meal (15), Light Gray (7), Gray (8), Ink Sac/Black (0), Green (2), Cocoa/Brown (3).

Note: Dye aux values are inverted compared to wool/carpet. Wool Red is aux 14, but Dye Red is aux 1. This is just how Minecraft handles dye colors internally.

#ItemCode
1AppleItem::apple_Id
2Golden AppleItem::apple_gold_Id
3Enchanted Golden AppleItem::apple_gold_Id aux 1
4Melon SliceItem::melon_Id
5Mushroom StewItem::mushroomStew_Id
6BreadItem::bread_Id
7CakeItem::cake_Id
8CookieItem::cookie_Id
9Cooked FishItem::fish_cooked_Id
10Raw FishItem::fish_raw_Id
11Cooked PorkchopItem::porkChop_cooked_Id
12Raw PorkchopItem::porkChop_raw_Id
13SteakItem::beef_cooked_Id
14Raw BeefItem::beef_raw_Id
15Raw ChickenItem::chicken_raw_Id
16Cooked ChickenItem::chicken_cooked_Id
17Rotten FleshItem::rotten_flesh_Id
18Spider EyeItem::spiderEye_Id
19PotatoItem::potato_Id
20Baked PotatoItem::potatoBaked_Id
21Poisonous PotatoItem::potatoPoisonous_Id
22CarrotItem::carrots_Id
23Golden CarrotItem::carrotGolden_Id
24Pumpkin PieItem::pumpkinPie_Id

This group is organized in tiers. Each tier gets a full armor set, then a full tool/weapon set laid out together. There are also “spacer” items (compass, empty map, bow, arrow, flint and steel) that visually separate each tier on the 10-column grid.

#ItemCode
1CompassItem::compass_Id
2Leather HelmetItem::helmet_leather_Id
3Leather ChestplateItem::chestplate_leather_Id
4Leather LeggingsItem::leggings_leather_Id
5Leather BootsItem::boots_leather_Id
6Wooden SwordItem::sword_wood_Id
7Wooden ShovelItem::shovel_wood_Id
8Wooden PickaxeItem::pickAxe_wood_Id
9Wooden AxeItem::hatchet_wood_Id
10Wooden HoeItem::hoe_wood_Id
11Empty MapItem::emptyMap_Id
12Chain HelmetItem::helmet_chain_Id
13Chain ChestplateItem::chestplate_chain_Id
14Chain LeggingsItem::leggings_chain_Id
15Chain BootsItem::boots_chain_Id
16Stone SwordItem::sword_stone_Id
17Stone ShovelItem::shovel_stone_Id
18Stone PickaxeItem::pickAxe_stone_Id
19Stone AxeItem::hatchet_stone_Id
20Stone HoeItem::hoe_stone_Id
21BowItem::bow_Id
22Iron HelmetItem::helmet_iron_Id
23Iron ChestplateItem::chestplate_iron_Id
24Iron LeggingsItem::leggings_iron_Id
25Iron BootsItem::boots_iron_Id
26Iron SwordItem::sword_iron_Id
27Iron ShovelItem::shovel_iron_Id
28Iron PickaxeItem::pickAxe_iron_Id
29Iron AxeItem::hatchet_iron_Id
30Iron HoeItem::hoe_iron_Id
31ArrowItem::arrow_Id
32Gold HelmetItem::helmet_gold_Id
33Gold ChestplateItem::chestplate_gold_Id
34Gold LeggingsItem::leggings_gold_Id
35Gold BootsItem::boots_gold_Id
36Gold SwordItem::sword_gold_Id
37Gold ShovelItem::shovel_gold_Id
38Gold PickaxeItem::pickAxe_gold_Id
39Gold AxeItem::hatchet_gold_Id
40Gold HoeItem::hoe_gold_Id
41Flint and SteelItem::flintAndSteel_Id
42Diamond HelmetItem::helmet_diamond_Id
43Diamond ChestplateItem::chestplate_diamond_Id
44Diamond LeggingsItem::leggings_diamond_Id
45Diamond BootsItem::boots_diamond_Id
46Diamond SwordItem::sword_diamond_Id
47Diamond ShovelItem::shovel_diamond_Id
48Diamond PickaxeItem::pickAxe_diamond_Id
49Diamond AxeItem::hatchet_diamond_Id
50Diamond HoeItem::hoe_diamond_Id
51Fire ChargeItem::fireball_Id
52ClockItem::clock_Id
53ShearsItem::shears_Id
54Fishing RodItem::fishingRod_Id
55Carrot on a StickItem::carrotOnAStick_Id
56LeadItem::lead_Id
57Diamond Horse ArmorItem::horseArmorDiamond_Id
58Gold Horse ArmorItem::horseArmorGold_Id
59Iron Horse ArmorItem::horseArmorMetal_Id
60+Enchanted Books (dynamic)One per enchantment at max level

The enchanted books are generated in a loop at the end. It goes through every enchantment in Enchantment::enchantments, skips null entries and ones without a category, then creates an enchanted book at that enchantment’s max level. The exact number depends on how many enchantments are registered.

for(unsigned int i = 0; i < Enchantment::enchantments.length; ++i)
{
Enchantment *enchantment = Enchantment::enchantments[i];
if (enchantment == nullptr || enchantment->category == nullptr) continue;
list->push_back(
Item::enchantedBook->createForEnchantment(
new EnchantmentInstance(enchantment, enchantment->getMaxLevel())
)
);
}

Debug only: When debug settings are on, a special “Sword of Debug” gets added. It is a diamond sword with Sharpness 50 and a custom hover name.

This tab pulls from 5 groups total: the main Brewing group plus 4 potion tier groups.

Brewing Ingredients (eCreativeInventory_Brewing):

#ItemCode
1Bottle o’ EnchantingItem::expBottle_Id
2Ghast TearItem::ghastTear_Id
3Fermented Spider EyeItem::fermentedSpiderEye_Id
4Blaze PowderItem::blazePowder_Id
5Magma CreamItem::magmaCream_Id
6Glistering MelonItem::speckledMelon_Id
7Glass BottleItem::glassBottle_Id
8Water BottleItem::potion_Id aux 0

Potions Basic (eCreativeInventory_Potions_Basic):

Drinkable potions first, then their splash variants:

PotionDrinkableSplash
RegenerationYesYes
SpeedYesYes
PoisonYesYes
Instant HealthYesYes
StrengthYesYes
Instant DamageYesYes

Fire Resistance, Weakness, and Slowness are not in this tier. They show up in Level 2 instead.

Potions Level 2 (eCreativeInventory_Potions_Level2):

PotionDrinkableSplash
Regeneration IIYesYes
Speed IIYesYes
Fire Resistance (base)YesYes
Poison IIYesYes
Weakness (base)YesYes
Strength IIYesYes
Slowness (base)YesYes

Fire Resistance, Weakness, and Slowness appear here at base level because they cannot be upgraded to Level 2, but 4J grouped them with the Level 2 potions.

Potions Extended (eCreativeInventory_Potions_Extended):

PotionDrinkableSplash
Regeneration (extended)YesYes
Speed (extended)YesYes
Poison (extended)YesYes
Night Vision (base)YesYes
Invisibility (base)YesYes
Strength (extended)YesYes

Night Vision and Invisibility appear here (not in Basic) because they do not have a “weak” base variant. The 4J devs moved them here with a comment: // 4J- Moved here as there isn't a weak variant of this potion.

Potions Level 2 Extended (eCreativeInventory_Potions_Level2_Extended):

PotionDrinkableSplash
Regeneration II ExtendedYesYes
Speed II ExtendedYesYes
Fire Resistance (extended)YesYes
Poison II ExtendedYesYes
Instant Health IIYesYes
Night Vision (extended)YesYes
Invisibility (extended)YesYes
Weakness (extended)YesYes
Strength II ExtendedYesYes
Slowness (extended)YesYes
Instant Damage IIYesYes

This is the “everything” tier. It has the strongest and longest-lasting versions of all potions.

Potions use a macro to build their aux value from three parts:

#define MACRO_MAKEPOTION_AUXVAL(potion_type, potion_strength, potion_effect) \
(potion_type | potion_strength | potion_effect)

The three parts are OR’d together as bit flags:

PartValuesHex
TypeNormal = 0, Splash = MASK_SPLASH0x0000 or 0x4000
StrengthRegular = 0, Level 2 = MASK_LEVEL2, Extended = MASK_EXTENDED, Both = MASK_LEVEL2EXTENDED0x0000, 0x0020, 0x0040, 0x0060
EffectRegeneration = 0x2001, Speed = 0x2002, Fire Resistance = 0x2003, etc.0x2001-0x200E

All functional potions have bit 13 (0x2000) set. This stops nether wart from “resetting” them during brewing. The effect ID occupies the lower bits.

So a Splash Potion of Speed II would be: 0x4000 | 0x0020 | 0x2002 = 0x6022.

#ItemCode
1ChestTile::chest_Id
2Ender ChestTile::enderChest_Id
3Crafting TableTile::workBench_Id
4FurnaceTile::furnace_Id
5Brewing StandItem::brewingStand_Id
6Enchanting TableTile::enchantTable_Id
7BeaconTile::beacon_Id
8End Portal FrameTile::endPortalFrameTile_Id
9JukeboxTile::jukebox_Id
10AnvilTile::anvil_Id
11BedItem::bed_Id
12Empty BucketItem::bucket_empty_Id
13Lava BucketItem::bucket_lava_Id
14Water BucketItem::bucket_water_Id
15Milk BucketItem::bucket_milk_Id
16CauldronItem::cauldron_Id
17SnowballItem::snowBall_Id
18PaperItem::paper_Id
19BookItem::book_Id
20Ender PearlItem::enderPearl_Id
21Eye of EnderItem::eyeOfEnder_Id
22Name TagItem::nameTag_Id
23Nether StarItem::netherStar_Id
24Creeper Spawn EggItem::spawnEgg_Id aux 50
25Skeleton Spawn EggItem::spawnEgg_Id aux 51
26Spider Spawn EggItem::spawnEgg_Id aux 52
27Zombie Spawn EggItem::spawnEgg_Id aux 54
28Slime Spawn EggItem::spawnEgg_Id aux 55
29Ghast Spawn EggItem::spawnEgg_Id aux 56
30Zombie Pigman Spawn EggItem::spawnEgg_Id aux 57
31Enderman Spawn EggItem::spawnEgg_Id aux 58
32Cave Spider Spawn EggItem::spawnEgg_Id aux 59
33Silverfish Spawn EggItem::spawnEgg_Id aux 60
34Blaze Spawn EggItem::spawnEgg_Id aux 61
35Magma Cube Spawn EggItem::spawnEgg_Id aux 62
36Bat Spawn EggItem::spawnEgg_Id aux 65
37Witch Spawn EggItem::spawnEgg_Id aux 66
38Pig Spawn EggItem::spawnEgg_Id aux 90
39Sheep Spawn EggItem::spawnEgg_Id aux 91
40Cow Spawn EggItem::spawnEgg_Id aux 92
41Chicken Spawn EggItem::spawnEgg_Id aux 93
42Squid Spawn EggItem::spawnEgg_Id aux 94
43Wolf Spawn EggItem::spawnEgg_Id aux 95
44Mooshroom Spawn EggItem::spawnEgg_Id aux 96
45Ocelot Spawn EggItem::spawnEgg_Id aux 98
46Horse Spawn EggItem::spawnEgg_Id aux 100
47Donkey Spawn EggItem::spawnEgg_Id aux 100 | ((TYPE_DONKEY+1) << 12)
48Mule Spawn EggItem::spawnEgg_Id aux 100 | ((TYPE_MULE+1) << 12)
49Villager Spawn EggItem::spawnEgg_Id aux 120
50Music Disc (13)Item::record_01_Id
51Music Disc (cat)Item::record_02_Id
52Music Disc (blocks)Item::record_03_Id
53Music Disc (chirp)Item::record_04_Id
54Music Disc (far)Item::record_05_Id
55Music Disc (mall)Item::record_06_Id
56Music Disc (mellohi)Item::record_07_Id
57Music Disc (stal)Item::record_08_Id
58Music Disc (strad)Item::record_09_Id
59Music Disc (ward)Item::record_10_Id
60Music Disc (11)Item::record_11_Id
61Music Disc (wait)Item::record_12_Id
62-66Firework Rockets (5 variants)Pre-built with BuildFirework()

The 5 firework rockets at the end are built programmatically using the BuildFirework() helper. Each one has different shapes, colors, flight durations, and effects:

  1. Small burst, light blue, flight 1, flicker
  2. Creeper shape, green, flight 2
  3. Max size (no shape), red, flight 2, orange fade
  4. Burst, magenta, flight 3, flicker, blue fade
  5. Star shape, yellow, flight 2, trail, orange fade

Debug only (ArtToolsMisc): When debug art tools are on, this group adds skeleton horse, zombie horse, 3 cat variants (black, red, siamese), a spider jockey, and an ender dragon spawn egg.

Regular mob spawn eggs just use the entity type ID as the aux value (like 50 for Creeper, 90 for Pig).

Horse variants use a special encoding. The base horse type ID is 100, and the variant is packed into the upper bits:

// Donkey: base ID 100, variant TYPE_DONKEY (1), shifted left 12 bits
ITEM_AUX(Item::spawnEgg_Id, 100 | ((EntityHorse::TYPE_DONKEY + 1) << 12))
// Result: 100 | (2 << 12) = 100 | 8192 = 8292

The +1 offset means 0 in the upper bits means “no variant specified” (regular horse). The debug spawn eggs for skeleton and zombie horses follow the same pattern.

After all the groups are populated, staticCtor() creates TabSpec objects that wire groups to tabs:

specs = new TabSpec*[eCreativeInventoryTab_COUNT];
// Simple: one group, one tab
ECreative_Inventory_Groups blocksGroup[] = {eCreativeInventory_BuildingBlocks};
specs[eCreativeInventoryTab_BuildingBlocks] =
new TabSpec(L"Structures", IDS_GROUPNAME_BUILDING_BLOCKS,
1, blocksGroup);
// Combined: two groups merged into one tab
ECreative_Inventory_Groups redAndTranGroup[] = {
eCreativeInventory_Transport,
eCreativeInventory_Redstone
};
specs[eCreativeInventoryTab_RedstoneAndTransport] =
new TabSpec(L"RedstoneAndTransport", IDS_GROUPNAME_REDSTONE_AND_TRANSPORT,
2, redAndTranGroup);

The TabSpec constructor takes:

ParameterWhat it does
iconWide string name used for the tab icon lookup
descriptionIdString ID for the tab label text
staticGroupsCountHow many groups this tab pulls from
staticGroupsArray of group enum values
dynamicGroupsCountGroups that cycle with LT (unused in current builds, defaults to 0)
dynamicGroupsArray of dynamic group enum values (defaults to nullptr)
debugGroupsCountNumber of debug-only groups (defaults to 0)
debugGroupsArray of debug group enum values (defaults to nullptr)

Here is the full tab-to-group mapping as it appears in the source:

TabGroupsNotes
Building BlocksBuildingBlocks1 group
DecorationsDecoration + debug: ArtToolsDecorationsDebug group only shows in dev builds
Redstone & TransportTransport, RedstoneTransport items appear first
MaterialsMaterials1 group
FoodFood1 group
ToolsToolsArmourWeapons1 group
BrewingBrewing, Potions_Level2_Extended, Potions_Extended, Potions_Level2, Potions_Basic5 groups, strongest potions first
MiscMisc + debug: ArtToolsMiscDebug group only shows in dev builds

Notice the Brewing tab lists the potion groups in reverse order: Level 2 Extended first, then Extended, then Level 2, then Basic. This means when you scroll through the Brewing tab, you see ingredients first, then the strongest potions, working down to the basic ones.

When a tab is selected, TabSpec::populateMenu() fills the 50-slot grid from its assigned groups, handling pagination automatically.

Each tab has an icon name (the first parameter of TabSpec) and a localized description string. The icon names map to UI assets:

TabIcon NameDescription String ID
Building BlocksL"Structures"IDS_GROUPNAME_BUILDING_BLOCKS
DecorationsL"Decoration"IDS_GROUPNAME_DECORATIONS
Redstone & TransportL"RedstoneAndTransport"IDS_GROUPNAME_REDSTONE_AND_TRANSPORT
MaterialsL"Materials"IDS_GROUPNAME_MATERIALS
FoodL"Food"IDS_GROUPNAME_FOOD
ToolsL"Tools"IDS_GROUPNAME_TOOLS_WEAPONS_ARMOR
BrewingL"Brewing"IDS_GROUPNAME_POTIONS_480
MiscL"Misc"IDS_GROUPNAME_MISCELLANEOUS

The active tab gets highlighted through the SetActiveTab function call to the Iggy/XUI movie. On Iggy platforms, this works like:

void UIScene_CreativeMenu::updateTabHighlightAndText(ECreativeInventoryTabs tab)
{
IggyDataValue value[1];
value[0].type = IGGY_DATATYPE_number;
value[0].number = static_cast<F64>(tab);
IggyPlayerCallMethodRS(getMovie(), &result,
IggyPlayerRootPath(getMovie()), m_funcSetActiveTab, 1, value);
m_labelInventory.setLabel(app.GetString(specs[tab]->m_descriptionId));
}

The SWF receives the tab index (0 through 7) and handles the visual highlight. The tab label text appears as the inventory title (where it would normally say “Inventory” in the survival menu).

On Xbox 360/XUI, tab highlighting works through the CXuiControl tab image arrays instead. Each tab icon and tab image control gets toggled based on the active tab index.

When a tab has more items than fit in the 5x10 grid, pagination kicks in. But it does not work in full “pages” of 50 like you might expect. Instead, it scrolls by one row at a time.

m_staticPerPage = columns; // 10 (one row of scrolling)
const int totalRows = (m_staticItems + columns - 1) / columns;
m_pages = std::max<int>(1, totalRows - 5 + 1);

The page count equals the total number of rows minus 4 (since 5 rows are visible). So if a tab has 103 items, that is ceil(103 / 10) = 11 rows, giving 11 - 5 + 1 = 7 pages. Each “page” scrolls the view down by exactly one row (10 items).

This means:

  • Page 0 shows rows 1-5 (items 1-50)
  • Page 1 shows rows 2-6 (items 11-60)
  • Page 2 shows rows 3-7 (items 21-70)
  • And so on…

The populateMenu() method is the workhorse. Here is how it works step by step:

  1. If the tab has dynamic groups (unused in current builds), those items fill from the beginning of the grid.

  2. For static groups, it calculates the start index: page * m_staticPerPage (page number times 10). So page 0 starts at item 0, page 1 at item 10, page 2 at item 20.

  3. It walks through the group arrays to find which group and which item within that group corresponds to the start index. For tabs with multiple groups, the items flow from one group into the next.

  4. It fills slots sequentially until it hits 50 or runs out of items.

  5. Any leftover slots get cleared (set to null) so you do not see stale items.

  6. In debug builds, if debug art tools are on, debug group items fill any remaining empty slots after the static items.

Players can scroll pages in three ways:

InputAction
Right stick up/downScroll one row up or down
Scroll bar dragJump to any page based on vertical position
LT buttonCycle dynamic groups (unused in current builds, was originally for potion tier cycling)

The scroll bar position is sent to the SWF movie via the SetScrollBar function:

void UIScene_CreativeMenu::updateScrollCurrentPage(int currentPage, int pageCount)
{
IggyDataValue value[2];
value[0].type = IGGY_DATATYPE_number;
value[0].number = static_cast<F64>(pageCount);
value[1].type = IGGY_DATATYPE_number;
value[1].number = static_cast<F64>(currentPage) - 1;
IggyPlayerCallMethodRS(getMovie(), &result,
IggyPlayerRootPath(getMovie()), m_funcSetScrollBar, 2, value);
}

On PS Vita, the scroll bar also supports touch input. Dragging your finger on the TouchPanel_Slider area calculates the relative position and jumps to the matching page.

LCE’s creative mode does not have a search tab. Unlike Java Edition (which has a search bar in the creative inventory starting from 1.3), LCE never added search. If you want to find a specific item, you have to know which tab it is in and scroll to it.

This is one of the bigger differences from Java Edition’s creative inventory. Java has a dedicated search tab where you can type to filter all items. LCE keeps things simpler with just the 8 fixed tabs and manual browsing.

In Java Edition, the creative inventory has a “Survival Inventory” tab that shows your regular 2x2 crafting grid and armor slots. LCE does not do this.

In LCE, the creative inventory screen (UIScene_CreativeMenu / CXuiSceneInventoryCreative) and the survival inventory screen (UIScene_InventoryMenu) are completely separate UI scenes with different SWF movies and different C++ classes. They do not share tabs or a tab bar.

The creative menu shows:

  • 8 category tabs across the top
  • A 10x5 item selection grid
  • A 9-slot hotbar at the bottom

The survival inventory shows:

  • A 2x2 crafting grid
  • Armor slots
  • The full 4x9 player inventory
  • No creative tabs at all

When a player in creative mode opens their inventory, the game checks the game mode and opens the creative scene. When a player in survival mode opens their inventory, it opens the survival scene. There is no way to switch between them from inside the UI.

The creative menu also has a special behavior with the X button: pressing it clears the entire hotbar. This is handled in handleValidKeyPress():

if(buttonNum == 1) // X button
{
for(unsigned int i = TabSpec::MAX_SIZE; i < TabSpec::MAX_SIZE + 9; ++i)
{
shared_ptr<ItemInstance> newItem = m_menu->getSlot(i)->getItem();
if(newItem != nullptr)
{
m_menu->getSlot(i)->set(nullptr);
pMinecraft->localgameModes[iPad]->handleCreativeModeItemAdd(
nullptr, i - (int)m_menu->slots.size() + 9 + InventoryMenu::USE_ROW_SLOT_START);
}
}
}

Items show up in the grid in the exact order you list them in staticCtor(). To reorder items, just move the ITEM() or ITEM_AUX() lines around.

For example, to put Diamond Ore before Coal Ore in Building Blocks:

DEF(eCreativeInventory_BuildingBlocks)
ITEM(Tile::stone_Id)
// ... other items ...
ITEM(Tile::diamondOre_Id) // moved up
ITEM(Tile::coalOre_Id) // moved down
ITEM(Tile::lapisOre_Id)

Keep in mind that the 10-column grid means position matters visually. Items at positions 1-10 fill the first row, 11-20 fill the second row, and so on. If you want to line up related items in columns, you might need to add or remove items before them to shift things around.

The Tools tab uses this trick nicely. Each armor/tool tier takes exactly 10 items (1 spacer + 4 armor + 5 tools), so each tier fills exactly one row on the grid. The spacer items (compass, empty map, bow, arrow, flint and steel) are not random. They are placed at the start of each row so the tiers line up perfectly.

Just cut the ITEM() line from one group’s section and paste it into another. There is no registration system to update. The item only exists in whatever group you put it in.

Want sponge in Building Blocks instead of Decorations? Remove it from the Decoration DEF block and add it to the Building Blocks DEF block. Done.

An item can exist in more than one tab too. Just add the same ITEM() call in multiple groups. The creative inventory creates new ItemInstance objects per group, so there is no conflict.

Adding Your Custom Item to an Existing Tab

Section titled “Adding Your Custom Item to an Existing Tab”

The simplest mod: just add your item to a group. Open IUIScene_CreativeMenu.cpp, find the group you want, and add a line.

Say you made a Ruby item (ID 407) and want it in the Materials tab:

// Inside staticCtor(), in the Materials group section:
DEF(eCreativeInventory_Materials)
ITEM(Item::coal_Id)
ITEM_AUX(Item::coal_Id, 1)
ITEM(Item::diamond_Id)
ITEM(Item::emerald_Id)
ITEM(Item::ruby_Id) // <-- your new item
ITEM(Item::ironIngot_Id)
// ...

Order matters. Items show up in the grid in the exact order you list them.

For a new block, same deal. Say you added a Ruby Ore tile:

DEF(eCreativeInventory_BuildingBlocks)
// ... existing ores ...
ITEM(Tile::emeraldOre_Id)
ITEM(Tile::rubyOre_Id) // <-- your new block
ITEM(Tile::netherQuartz_Id)

For items with variants, use ITEM_AUX():

// A Ruby Pickaxe with a variant for enchanted (aux 1) and normal (aux 0)
DEF(eCreativeInventory_ToolsArmourWeapons)
// ... after diamond tools ...
ITEM(Item::pickAxe_ruby_Id) // normal
ITEM_AUX(Item::pickAxe_ruby_Id, 1) // enchanted variant

If you want a new logical grouping (without adding a new tab), add an entry to the ECreative_Inventory_Groups enum:

enum ECreative_Inventory_Groups
{
// ... existing groups ...
eCreativeInventory_Misc,
eCreativeInventory_MyNewGroup, // <-- add before the count
eCreativeInventory_ArtToolsDecorations,
eCreativeInventory_ArtToolsMisc,
eCreativeInventoryGroupsCount
};

Then populate it in staticCtor():

DEF(eCreativeInventory_MyNewGroup)
ITEM(Item::ruby_Id)
ITEM(Tile::rubyOre_Id)
ITEM(Tile::rubyBlock_Id)

And wire it into a tab. You can either add it to an existing tab (the group’s items appear after the other groups on that tab) or create a new tab for it.

To add it to the Misc tab:

ECreative_Inventory_Groups miscGroup[] = {
eCreativeInventory_Misc,
eCreativeInventory_MyNewGroup // items appear after Misc items
};
specs[eCreativeInventoryTab_Misc] =
new TabSpec(L"Misc", IDS_GROUPNAME_MISCELLANEOUS,
2, miscGroup, 0, nullptr);

This is the big one. The UI only supports 8 tabs out of the box, so you either need to replace an existing tab or do UI work to add a 9th.

The easier path. Say you want to split “Redstone & Transport” into two separate tabs, and you are willing to fold Transport items into Misc:

  1. Rename the tab enum value:
enum ECreativeInventoryTabs
{
eCreativeInventoryTab_BuildingBlocks = 0,
eCreativeInventoryTab_Decorations,
eCreativeInventoryTab_Redstone, // was RedstoneAndTransport
eCreativeInventoryTab_Materials,
eCreativeInventoryTab_Food,
eCreativeInventoryTab_ToolsWeaponsArmor,
eCreativeInventoryTab_Brewing,
eCreativeInventoryTab_Misc,
eCreativeInventoryTab_COUNT,
};
  1. Update the TabSpec creation to only reference the Redstone group:
ECreative_Inventory_Groups redstoneGroup[] = {eCreativeInventory_Redstone};
specs[eCreativeInventoryTab_Redstone] =
new TabSpec(L"Redstone", IDS_GROUPNAME_REDSTONE,
1, redstoneGroup, 0, NULL);
  1. Add Transport to the Misc tab’s group array:
ECreative_Inventory_Groups miscGroup[] = {
eCreativeInventory_Misc,
eCreativeInventory_Transport
};
specs[eCreativeInventoryTab_Misc] =
new TabSpec(L"Misc", IDS_GROUPNAME_MISCELLANEOUS,
2, miscGroup, 0, NULL);
  1. Update the SWF movie to change the tab icon from the redstone+transport icon to just a redstone icon (or create a new localization string for the tab name).

If you really want more than 8 tabs, you need changes in three layers: the C++ enums, the C++ UI scene, and the SWF/XUI movie files.

Add your new tab to the enum and bump the count:

enum ECreativeInventoryTabs
{
eCreativeInventoryTab_BuildingBlocks = 0,
eCreativeInventoryTab_Decorations,
eCreativeInventoryTab_RedstoneAndTransport,
eCreativeInventoryTab_Materials,
eCreativeInventoryTab_Food,
eCreativeInventoryTab_ToolsWeaponsArmor,
eCreativeInventoryTab_Brewing,
eCreativeInventoryTab_Misc,
eCreativeInventoryTab_Custom, // <-- new
eCreativeInventoryTab_COUNT, // now 9
};

In UIScene_CreativeMenu.h, add a 9th touch panel:

enum ETouchInput
{
ETouchInput_TouchPanel_0,
ETouchInput_TouchPanel_1,
ETouchInput_TouchPanel_2,
ETouchInput_TouchPanel_3,
ETouchInput_TouchPanel_4,
ETouchInput_TouchPanel_5,
ETouchInput_TouchPanel_6,
ETouchInput_TouchPanel_7,
ETouchInput_TouchPanel_8, // <-- new
ETouchInput_TouchSlider,
ETouchInput_Count,
};

Add the new element mapping:

UI_MAP_ELEMENT( m_TouchInput[ETouchInput_TouchPanel_8], "TouchPanel_8" )

In UIEnums.h, add the new section for the 9th tab:

eSectionInventoryCreativeTab_8, // <-- new, before eSectionInventoryCreativeSlider

Then add case handlers for eSectionInventoryCreativeTab_8 everywhere the other tab sections are handled: handleOtherClicked(), GetPositionOfSection(), GetItemScreenData(), and getSection().

In XUI_Scene_Inventory_Creative.h, expand the icon and tab image arrays from 8 to 9, and add the new control mappings:

CXuiControl m_hTabGroupA[eCreativeInventoryTab_COUNT]; // now size 9
CXuiControl m_hGroupIconA[eCreativeInventoryTab_COUNT]; // now size 9
// In the control map:
MAP_CONTROL(IDC_Icon_9, m_hGroupIconA[8])
MAP_CONTROL(IDC_TabImage9, m_hTabGroupA[8])

You also need to add IDC_Icon_9 and IDC_TabImage9 as control IDs in the XUI scene file, and add the matching visual elements in the XUI authoring tool.

Step 5: SWF Movie Changes (Iggy Platforms)

Section titled “Step 5: SWF Movie Changes (Iggy Platforms)”

This is the biggest piece. You need to edit the Flash source files for the creative menu at each resolution:

  • CreativeMenu1080.swf
  • CreativeMenu720.swf
  • CreativeMenu480.swf
  • CreativeMenuVita.swf
  • Plus the splitscreen variants (CreativeMenuSplit*.swf)

In each SWF, you need to:

  1. Add a new TouchPanel_8 element positioned next to the existing 8 tab buttons. The tabs are probably laid out horizontally, so you need to make room by either shrinking the existing tabs or extending the tab bar.

  2. Add a tab icon for the 9th tab. The icon gets loaded through the substitution texture system using the icon name from the TabSpec.

  3. Update the SetActiveTab ActionScript function to handle index 8. Currently it probably only handles 0 through 7.

  4. Make sure the tab highlight animation works for the new tab.

If you do not have access to the original Flash .fla source files, you can try using SWF decompilers (like JPEXS Free Flash Decompiler) to edit the compiled SWF directly. This is harder but doable for simple layout changes.

Finally, wire up the new tab in staticCtor():

// Create and populate your new group
DEF(eCreativeInventory_MyNewGroup)
ITEM(Item::ruby_Id)
ITEM(Tile::rubyOre_Id)
ITEM(Tile::rubyBlock_Id)
// Wire it to the new tab
ECreative_Inventory_Groups customGroup[] = {eCreativeInventory_MyNewGroup};
specs[eCreativeInventoryTab_Custom] =
new TabSpec(L"Custom", IDS_GROUPNAME_CUSTOM,
1, customGroup, 0, nullptr);

You will also need to add IDS_GROUPNAME_CUSTOM to the string table so the tab has a localized name.

Players switch between tabs using LB and RB (or L1/R1 on PlayStation). The input handling wraps around: pressing RB on the last tab goes back to the first tab, and pressing LB on the first tab goes to the last tab.

case VK_PAD_RSHOULDER:
ECreativeInventoryTabs tab = static_cast<ECreativeInventoryTabs>(m_curTab + dir);
if (tab < 0) tab = static_cast<ECreativeInventoryTabs>(eCreativeInventoryTab_COUNT - 1);
if (tab >= eCreativeInventoryTab_COUNT) tab = eCreativeInventoryTab_BuildingBlocks;
switchTab(tab);
ui.PlayUISFX(eSFX_Focus);

This code works with any number of tabs automatically, since it uses eCreativeInventoryTab_COUNT for the wrap-around. So if you add a 9th tab, the bumper navigation will include it without any extra changes.

The LT button was originally used to cycle through “dynamic groups” (potion tiers). In earlier builds, the Brewing tab had potion groups as dynamic groups that you could cycle through with LT. In the current codebase, all potion groups are static, so LT does nothing visible. But the code still exists:

case VK_PAD_LTRIGGER:
++m_tabDynamicPos[m_curTab];
if(m_tabDynamicPos[m_curTab] >= specs[m_curTab]->m_dynamicGroupsCount)
m_tabDynamicPos[m_curTab] = 0;
switchTab(m_curTab);

When a player clicks an item in the creative grid (A button), a copy of that item gets placed on the cursor. The game then automatically finds the best hotbar slot: either a slot that already has a matching stackable item, or the first empty slot.

If the player holds the quickkey (Y button), they get a full stack instead of 1.

Clicking a hotbar slot while carrying an item places it. The game syncs the change to multiplayer through handleCreativeModeItemAdd().

Players can also drop items by clicking outside the inventory area. Left-click drops the whole carried stack, right-click drops one at a time.

Example 1: Add All Hardened Clay Colors to Building Blocks

Section titled “Example 1: Add All Hardened Clay Colors to Building Blocks”

The stained clay is already in Building Blocks, but say you also wanted regular hardened clay variants in a different order. You could add a section like this:

DEF(eCreativeInventory_BuildingBlocks)
// ... after existing stairs ...
ITEM(Tile::clayHardened_Id) // Plain hardened clay
ITEM_AUX(Tile::clayHardened_colored_Id, 0) // White
ITEM_AUX(Tile::clayHardened_colored_Id, 8) // Light gray
ITEM_AUX(Tile::clayHardened_colored_Id, 7) // Gray
ITEM_AUX(Tile::clayHardened_colored_Id, 15) // Black

Example 2: Create a “Nature” Tab by Replacing Food

Section titled “Example 2: Create a “Nature” Tab by Replacing Food”

If you wanted a Nature tab that combines plants from Decorations with food items:

// 1. Add a new group for nature items
enum ECreative_Inventory_Groups
{
// ... existing ...
eCreativeInventory_Nature, // new
eCreativeInventoryGroupsCount
};
// 2. In staticCtor(), populate it
DEF(eCreativeInventory_Nature)
ITEM_AUX(Tile::sapling_Id, Sapling::TYPE_DEFAULT)
ITEM_AUX(Tile::sapling_Id, Sapling::TYPE_EVERGREEN)
ITEM_AUX(Tile::sapling_Id, Sapling::TYPE_BIRCH)
ITEM_AUX(Tile::sapling_Id, Sapling::TYPE_JUNGLE)
ITEM(Tile::vine)
ITEM(Tile::waterLily_Id)
ITEM(Tile::cactus_Id)
ITEM(Tile::flower_Id)
ITEM(Tile::rose_Id)
// 3. Replace the Food tab
ECreative_Inventory_Groups natureGroup[] = {
eCreativeInventory_Nature,
eCreativeInventory_Food
};
specs[eCreativeInventoryTab_Food] =
new TabSpec(L"Food", IDS_GROUPNAME_FOOD, 2, natureGroup);

The tab still uses the Food icon and name but now shows nature items first, then food items. You would want to update the icon name and string ID to match.

The BuildFirework() helper lets you create pre-made firework rockets. Here is how to add one to the Misc tab:

DEF(eCreativeInventory_Misc)
// ... existing items ...
// A big gold firework with flicker and trail, flight duration 3, blue fade
BuildFirework(list, FireworksItem::TYPE_BIG,
DyePowderItem::YELLOW, 3, true, true, DyePowderItem::BLUE);

The parameters for BuildFirework() are:

ParameterWhat It Does
listThe vector to add the firework to (always list inside staticCtor)
typeShape: TYPE_SMALL, TYPE_BIG, TYPE_STAR, TYPE_CREEPER, TYPE_BURST
colorDye color index for the explosion color
sulphurFlight duration (1-3, higher = longer fuse)
flickerWhether the explosion twinkles (from glowstone dust)
trailWhether particles leave trails (from diamond)
fadeColorOptional: dye color index for the fade-out color (-1 for no fade)

Example 4: Add a Spawn Egg for a Custom Mob

Section titled “Example 4: Add a Spawn Egg for a Custom Mob”

If you added a new mob with entity type ID 130:

DEF(eCreativeInventory_Misc)
// ... after existing spawn eggs ...
ITEM_AUX(Item::spawnEgg_Id, 130) // Custom Mob spawn egg

If your mob has variants (like horses do), pack the variant into the upper bits:

// Custom mob ID 130, variant 2
ITEM_AUX(Item::spawnEgg_Id, 130 | ((2 + 1) << 12))
FileWhat’s in it
Minecraft.Client/Common/UI/IUIScene_CreativeMenu.hTab and group enums, TabSpec struct, ItemPickerMenu class
Minecraft.Client/Common/UI/IUIScene_CreativeMenu.cppstaticCtor() with all item lists, tab wiring, pagination logic, input handling
Minecraft.Client/Common/UI/UIScene_CreativeMenu.hIggy-based UI scene (PS3, PS Vita, PS4) with touch panel mappings
Minecraft.Client/Common/UI/UIScene_CreativeMenu.cppIggy UI input handling, movie loading, and rendering
Minecraft.Client/Common/XUI/XUI_Scene_Inventory_Creative.hXUI-based UI scene (Xbox 360) with tab icon control mappings
Minecraft.Client/Common/UI/UIScene.hBase class for all Iggy movie scenes
Minecraft.Client/Common/Potion_Macros.hPotion aux value macros and bit masks
Minecraft.Client/Common/Media/movies1080.txtList of all SWF movies loaded at 1080p (includes CreativeMenu1080.swf)