Folder Structure and the Pack Manifest
In Java Edition, a resource pack starts with a pack.mcmeta file at the root and places everything else inside an assets/<namespace>/ directory. Because every creator uses their own namespace folder, Java packs naturally avoid file collisions. Bedrock Edition drops the assets/<namespace>/ wrapper entirely. Folders like textures, models, sounds, and texts sit directly at the root of the resource pack.
To prevent custom files from overwriting vanilla files or clashing with other packs, Bedrock creators put a studio or project subfolder inside each category—for example, RP/textures/my_pack/blocks/ instead of Java's assets/my_pack/textures/block/. Note that Bedrock also favours plural folder names (textures/blocks, textures/items) whereas modern Java uses singular names (textures/block, textures/item).
Instead of pack.mcmeta with its single integer pack_format, Bedrock requires a manifest.json file at the root of the pack. Every Bedrock manifest needs two distinct Version 4 UUIDs: one in the header and one inside the modules array with a type of resources. If you copy a manifest from another pack without generating new UUIDs, Bedrock treats the pack as a duplicate and refuses to import or load it.
| Java Edition Path | Bedrock Edition Path | Notes |
|---|---|---|
| pack.mcmeta | RP/manifest.json | Bedrock requires two unique V4 UUIDs and a 3-part version array. |
| assets/<namespace>/textures/block/ | RP/textures/blocks/ | Put a custom subfolder inside blocks/ to avoid name collisions. |
| assets/<namespace>/textures/item/ | RP/textures/items/ | Referenced via shortnames registered in item_texture.json. |
| assets/<namespace>/models/ | RP/models/entity/ or RP/models/blocks/ | All Bedrock custom models use the same .geo.json format. |
| assets/<namespace>/lang/en_us.json | RP/texts/en_US.lang | Bedrock uses plain key=value lines instead of a JSON object. |
| assets/<namespace>/sounds.json | RP/sounds/sound_definitions.json | Maps sound events to file paths; RP/sounds.json assigns them to blocks or entities. |
{
"format_version": 2,
"header": {
"name": "pack.name",
"description": "pack.description",
"uuid": "a18b2c4e-5d6f-4a7b-8c9d-0e1f2a3b4c5d",
"version": [1, 0, 0],
"min_engine_version": [1, 20, 80]
},
"modules": [
{
"type": "resources",
"uuid": "f98e7d6c-5b4a-4f3e-9d2c-1b0a9f8e7d6c",
"version": [1, 0, 0]
}
]
}Texture Registration and Shortnames
In Java Edition, a block or item model points directly to a texture path using a namespaced string like my_pack:block/copper_grate. Bedrock decouples file paths from models and blocks through two central registry files: RP/textures/terrain_texture.json for blocks and RP/textures/item_texture.json for items.
Inside these two files, you assign a shortname (for example, my_pack_copper_grate) to a file path relative to the root of the resource pack, leaving off the .png extension. Your block definitions and item scripts then refer to the shortname rather than the file path. This indirection exists because Bedrock compiles block and item textures into texture atlases when the world loads.
Animated textures also work differently. Java uses a .png.mcmeta sidecar file next to any texture to define frame timing and interpolation. Bedrock does not read .mcmeta files. Instead, block and item animations are defined inside RP/textures/flipbook_textures.json, which links a vertical sprite sheet to one of the terrain or item shortnames and specifies the ticks_per_frame. Entity textures do not support flipbook animations directly; to animate an entity texture on Bedrock, you either swap materials/textures via render controllers or scroll UV coordinates inside an animation file.
{
"resource_pack_name": "my_pack",
"texture_name": "atlas.terrain",
"padding": 8,
"num_mip_levels": 4,
"texture_data": {
"my_pack_custom_stone": {
"textures": "textures/my_pack/blocks/custom_stone"
}
}
}Models, Geometry, and Blockstates
Java Edition splits its 3D formats by purpose: blocks and items use JSON element models made of cuboids whose rotations are restricted to 22.5-degree steps on a single axis, while entities are hardcoded in Java unless modified by third-party mods. Bedrock uses one unified geometry format (.geo.json) inside RP/models/entity/ or RP/models/blocks/ for everything—entities, custom blocks, attachables (3D items held or worn), and projectiles.
Bedrock geometry files group cubes into bones with pivot points. Bones can rotate freely on all three axes at any angle, and they use a different coordinate orientation than Java block models. While Blockbench can convert a Java block model to Bedrock geometry automatically, you must check the pivot points and UV mappings afterward, especially if the Java model relied on parent inheritance like block/cube_all, which Bedrock geometry does not use.
Java's assets/<namespace>/blockstates/ folder has no direct equivalent in a Bedrock resource pack. For vanilla blocks, visual mapping is handled inside RP/blocks.json, which binds block identifiers to sounds and terrain_texture.json shortnames. For custom add-on blocks, state-based visual changes—such as rotating a model when placed or swapping a texture when a block state toggles—live inside the Behaviour Pack's block JSON under the minecraft:geometry, minecraft:material_instances, and permutations sections. Because of this split, a Bedrock resource pack alone cannot randomize or state-swap custom block models the way a Java resource pack can; for custom content, the Behaviour Pack drives the states.
{
"format_version": "1.12.0",
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.my_pack.pedestal",
"texture_width": 64,
"texture_height": 64,
"visible_bounds_width": 2,
"visible_bounds_height": 2,
"visible_bounds_offset": [0, 0.5, 0]
},
"bones": [
{
"name": "base",
"pivot": [0, 0, 0],
"cubes": [
{
"origin": [-7, 0, -7],
"size": [14, 4, 14],
"uv": [0, 0]
},
{
"origin": [-5, 4, -5],
"size": [10, 12, 10],
"uv": [0, 18]
}
]
}
]
}
]
}Entities, Attachables, and Custom Model Data
One of the biggest surprises for Java creators is how much control vanilla Bedrock gives over entities. In vanilla Java, changing an entity's model or adding animations requires mods like OptiFine or Entity Model Features. In Bedrock, every entity's visual setup is completely data-driven through a Client Entity file located in RP/entity/.
A client entity file acts as a hub. It links the entity's identifier to dictionaries of textures, geometry identifiers, materials, animations, animation controllers, particle effects, and sound effects. It then passes those shortnames to one or more render controllers (in RP/render_controllers/), which use Molang queries to decide which geometry, material, and texture to draw on each frame. For example, if an entity has a baby variant or a sheared state, the render controller evaluates a Molang expression to pick the matching texture from an array.
Java resource packs frequently use CustomModelData overrides on items to create custom 3D weapons, hats, and tools. Bedrock does not have CustomModelData. Instead, to give a custom or vanilla item a 3D model in first-person and third-person views, you create an Attachable in RP/attachables/. An attachable file looks almost identical to a client entity file: it binds an item identifier to a .geo.json model, a texture path, a material, and first-person/third-person hold animations.
{
"format_version": "1.10.0",
"minecraft:client_entity": {
"description": {
"identifier": "my_pack:beetle",
"materials": {
"default": "entity_alphatest"
},
"textures": {
"default": "textures/my_pack/entity/beetle"
},
"geometry": {
"default": "geometry.my_pack.beetle"
},
"animations": {
"walk": "animation.my_pack.beetle.walk"
},
"scripts": {
"animate": [
{
"walk": "query.modified_move_speed > 0.1"
}
]
},
"render_controllers": [
"controller.render.default"
],
"spawn_egg": {
"base_color": "#3b271c",
"overlay_color": "#8c583a"
}
}
}
}Language Files, Sounds, and Shaders
Java Edition switched its language files in 1.13 from plain text to JSON objects (assets/<namespace>/lang/en_us.json). Bedrock kept the older plain-text .lang format inside RP/texts/. Each translation sits on its own line as key=value, and comments start with ##. Notice the capitalisation of the filename: Bedrock requires RP/texts/en_US.lang with an uppercase region code, and you must also list every supported language code inside RP/texts/languages.json so the game knows to scan for them.
For audio, both editions use .ogg Vorbis files (Bedrock also accepts .fsb and .wav in some contexts, though .ogg is standard for custom packs). Where Java uses a single assets/<namespace>/sounds.json file, Bedrock splits audio setup across RP/sounds/sound_definitions.json (which defines the sound event identifier, category, and file paths) and RP/sounds.json (which hooks those sound events up to block breaking, footsteps, and entity life-cycle events).
Finally, if your Java pack relies on core shaders or post-processing shaders inside assets/minecraft/shaders/, those cannot be ported to a standard Bedrock resource pack. Bedrock uses RenderDragon, a compiled graphics engine that does not load raw GLSL shader files from resource packs. Visual customisation for lighting, fog, and Physically Based Rendering (PBR) heightmaps orMER (Metallic, Emissive, Roughness) textures is instead configured through JSON files inside RP/fogs/, RP/biomes_client.json, and texture_set.json files when Deferred Technical Preview or ray tracing features are active.
pack.name=My Ported Resource Pack
pack.description=Assets moved from Java to Bedrock
entity.my_pack:beetle.name=Forest Beetle
tile.my_pack:pedestal.name=Stone PedestalWhich versions this applies to
Applies to all modern Bedrock versions (1.20.0+ and 1.21.0+). No experimental toggles are required for standard resource pack features such as models, textures, attachables, client entities, sounds, or language files.
When it does not work
| What you see | Why | The fix |
|---|---|---|
| Failed to import pack: Duplicate pack detected | You copied RP/manifest.json from a template or another pack without changing BOTH UUIDs (the header uuid and the modules uuid). | Generate two brand-new Version 4 UUIDs and replace both the header.uuid and modules[0].uuid values in RP/manifest.json. |
| Custom block or item displays a magenta-and-black checkerboard texture in-game | You put the file path directly into your block or item JSON like in Java, or the shortname in terrain_texture.json / item_texture.json does not match what the Behaviour Pack requests, or you included the .png extension in the texture path. | Register a shortname in RP/textures/terrain_texture.json (for blocks) or RP/textures/item_texture.json (for items), omit .png from the path string, and reference only the shortname in your block or item definition. |
| Entity is invisible or shows texture holes where transparent pixels should be | Unlike Java, which handles alpha cutouts automatically for most entity layers, Bedrock's default entity material is opaque or renders backfaces differently depending on the material chosen in the client entity file. | In your RP/entity/<name>.entity.json file under description.materials, change the material from entity to entity_alphatest (for hard transparent cutouts) or entity_alphablend (for semi-transparent pixels). |
| Item and entity names show raw translation keys like tile.my_pack:pedestal.name | You used a JSON language file like Java's en_us.json, named the file en_us.lang with a lowercase country code, or put spaces around the = sign in the .lang file. | Place translations in RP/texts/en_US.lang (uppercase US), format lines strictly as key=value with no spaces around the equals sign, and ensure "en_US" is listed inside RP/texts/languages.json. |
Reference, straight from the game files
Read out of the game itself, so the ids match the version you are building for.
