Task 382: .MCPROJECT File Format
Task 382: .MCPROJECT File Format
File Format Specifications for .MCPROJECT
The .MCPROJECT file format is used by the Minecraft Bedrock Editor, an in-engine world editor for Minecraft Bedrock Edition. It is essentially a ZIP archive (the same as .MCWORLD files, but with a different extension to indicate it's a project for the editor). The file can be opened in the editor, and it contains world data, settings, and potentially editor extensions. The primary data is stored in a file called level.dat
inside the ZIP, which is in uncompressed NBT (Named Binary Tag) format. The NBT structure in level.dat
defines the core properties of the world. The ZIP may also contain a db/
folder with LevelDB chunk data, levelname.txt
, and optional folders like behavior_packs/
or resource_packs/
. To use a .MCWORLD as a .MCPROJECT, simply rename the extension.
- List of all the properties of this file format intrinsic to its file system.
The properties are the top-level NBT tags in the level.dat
file inside the ZIP archive. These define the world's configuration, settings, and state. Here is the complete list based on the Bedrock Edition level format:
- abilities: Compound - Default player permissions (sub-tags: attackmobs, attackplayers, build, doorsandswitches, flying, flySpeed, instabuild, invulnerable, lightning, mayfly, mine, mute, noclip, op, opencontainers, permissionsLevel, playerPermissionsLevel, teleport, walkSpeed, worldbuilder).
- allowdestructiveobjects: Byte - Game rule for allowing destructive objects.
- allowmobs: Byte - Game rule for allowing mobs.
- baseGameVersion: String - Maximum version to load resources from.
- biomeOverride: String - Overrides the biome for the world.
- bonusChestEnabled: Byte - Whether the bonus chest is enabled.
- CenterMapsToOrigin: Byte - Whether maps are centered to the origin.
- commandblockoutput: Byte - Whether command block output is enabled.
- commandblocksenabled: Byte - Whether command blocks are enabled.
- commandsEnabled: Byte - Whether commands are enabled.
- ConfirmedPlatformLockedContent: Byte - Whether platform-locked content is confirmed.
- DayTime: Long - The current daytime.
- Difficulty: Int - World difficulty (0 = Peaceful, 1 = Easy, 2 = Normal, 3 = Hard).
- eduOffer: Int - Education Edition offer type.
- educationFeaturesEnabled: Byte - Whether education features are enabled.
- EducationEditionOffer: Int - Education Edition offer ID.
- educationProductID: String - Education product ID.
- GameType: Int - Game mode (0 = Survival, 1 = Creative, 2 = Adventure, 3 = Spectator).
- Generator: Int - World generator type (0 = Old, 1 = Infinite, 2 = Flat).
- hasBeenLoadedInCreative: Byte - Whether the world has been loaded in creative mode.
- hasLockedBehaviorPack: Byte - Whether behavior packs are locked.
- hasLockedResourcePack: Byte - Whether resource packs are locked.
- immutableWorld: Byte - Whether the world is immutable.
- isFromLockedTemplate: Byte - Whether the world is from a locked template.
- isFromWorldTemplate: Byte - Whether the world is from a world template.
- isSingleUseWorld: Byte - Whether the world is single-use.
- isWorldTemplateOptionLocked: Byte - Whether world template options are locked.
- lastOpenedWithVersion: List of Int - Version the world was last opened with.
- LastPlayed: Long - Timestamp when the world was last played.
- LevelName: String - Name of the world.
- LimitedWorldOriginX: Int - Origin X for limited worlds.
- LimitedWorldOriginY: Int - Origin Y for limited worlds.
- LimitedWorldOriginZ: Int - Origin Z for limited worlds.
- lightningLevel: Float - Lightning level.
- LightningTime: Int - Time until next lightning.
- limitedWorld: Byte - Whether the world is limited.
- maxrainlevel: Float - Maximum rain level.
- MaxThreads: Byte - Maximum threads.
- MultiplayerGame: Byte - Whether multiplayer is enabled.
- NetherScale: Int - Nether scale.
- NetworkVersion: Int - Network version.
- Platform: Int - Platform ID.
- platformBroadcastIntent: Int - Platform broadcast intent.
- rainLevel: Float - Rain level.
- RainTime: Int - Time until next rain.
- randomSeed: Long - World seed.
- requiresCopiedPackRemovalCheck: Byte - Whether copied pack removal check is required.
- SpawnV1Villagers: Byte - Whether to spawn V1 villagers.
- spawnMobs: Byte - Whether mobs spawn.
- SpawnX: Int - Spawn X coordinate.
- SpawnY: Int - Spawn Y coordinate.
- SpawnZ: Int - Spawn Z coordinate.
- storageVersion: Int - Storage version (currently 10).
- texturePacksRequired: Byte - Whether texture packs are required.
- time: Long - World time.
- usesPlayerFeatures: Byte - Whether player features are used.
- worldStartCount: Long - World start count.
- XBLBroadcastIntent: Int - Xbox Live broadcast intent.
- experiments: Compound - Experimental features enabled (sub-tags vary by experiments).
- gamerules: Compound - All game rules (sub-tags like doDaylightCycle, doEntityDrops, etc., each a Byte or Int).
- players: Compound - Player data (sub-tags for player UUIDs with inventory, position, etc.).
These properties are intrinsic to the file's structure as they are encoded in the NBT format within level.dat
, which is the core component of the ZIP-based file system.
- Two direct download links for files of format .MCPROJECT.
Since .MCPROJECT files are rare publicly (as they are primarily for editor sharing and identical in format to .MCWORLD files), here are two direct download links for .MCWORLD files, which can be renamed to .MCPROJECT to use as editor projects:
- https://www.mediafire.com/file/vxxotognxldsct9/Minecraft_Underground_Survival_-_Copy.mcworld/file (Minecraft Underground Survival world, episode 10)
- https://www.mediafire.com/file/n3m1wryiimqsrks/Creative_Survival.mcworld/file (Creative Survival world map)
To convert, download and change the extension from .mcworld to .mcproject.
- Ghost blog embedded html javascript that allows a user to drag n drop a file of format .MCPROJECT and it will dump to screen all these properties.
- Python class that can open any file of format .MCPROJECT and decode read and write and print to console all the properties from the above list.
import zipfile
from nbt import nbt # Requires python-nbt library: pip install nbt
class MCProjectHandler:
def __init__(self, filepath):
self.filepath = filepath
self.nbt_data = None
def read(self):
with zipfile.ZipFile(self.filepath, 'r') as zip_ref:
with zip_ref.open('level.dat') as level_dat:
self.nbt_data = nbt.NBTFile(fileobj=level_dat)
return self.nbt_data
def print_properties(self):
if not self.nbt_data:
self.read()
for key, value in self.nbt_data.items():
print(f"{key}: {value.value}")
def write(self, new_filepath=None):
if not self.nbt_data:
return
if not new_filepath:
new_filepath = self.filepath
with zipfile.ZipFile(new_filepath, 'w') as zip_ref:
# Note: This only writes level.dat; to fully write, need to copy other files
with zip_ref.open('level.dat', 'w') as level_dat:
self.nbt_data.write_file(fileobj=level_dat)
# Example usage:
# handler = MCProjectHandler('example.mcproject')
# handler.read()
# handler.print_properties()
# handler.nbt_data['LevelName'].value = 'New Name' # Modify a property
# handler.write('modified.mcproject')
- Java class that can open any file of format .MCPROJECT and decode read and write and print to console all the properties from the above list.
import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
import java.util.Map;
// Note: Requires an NBT library like https://github.com/udoprog/jnbt or similar. Here, assume a simple NBT parser interface.
public class MCProjectHandler {
private String filepath;
private Map<String, Object> nbtData; // Assume NBT is parsed into a Map
public MCProjectHandler(String filepath) {
this.filepath = filepath;
}
public void read() throws IOException {
try (ZipFile zipFile = new ZipFile(filepath)) {
ZipEntry entry = zipFile.getEntry("level.dat");
if (entry != null) {
try (InputStream is = zipFile.getInputStream(entry)) {
nbtData = parseNBT(is); // Implement or use library to parse NBT to Map
}
}
}
}
public void printProperties() {
if (nbtData == null) {
try {
read();
} catch (IOException e) {
e.printStackTrace();
}
}
for (Map.Entry<String, Object> entry : nbtData.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
public void write(String newFilepath) throws IOException {
if (nbtData == null) {
return;
}
try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(newFilepath))) {
zos.putNextEntry(new ZipEntry("level.dat"));
writeNBT(zos, nbtData); // Implement or use library to write NBT from Map
zos.closeEntry();
// To fully write, copy other entries from original ZIP
}
}
// Placeholder for NBT parse/write - in practice, use a library
private Map<String, Object> parseNBT(InputStream is) {
// Implement NBT parsing logic or use library
return null;
}
private void writeNBT(OutputStream os, Map<String, Object> data) {
// Implement NBT writing logic or use library
}
// Example usage:
// public static void main(String[] args) throws IOException {
// MCProjectHandler handler = new MCProjectHandler("example.mcproject");
// handler.read();
// handler.printProperties();
// // Modify nbtData
// handler.write("modified.mcproject");
// }
}
- Javascript class that can open any file of format .MCPROJECT and decode read and write and print to console all the properties from the above list.
const fs = require('fs'); // For Node.js
const JSZip = require('jszip');
const NBTReader = require('nbt-reader'); // Assume an NBT library like nbt-js
class MCProjectHandler {
constructor(filepath) {
this.filepath = filepath;
this.nbtData = null;
}
async read() {
const data = fs.readFileSync(this.filepath);
const zip = await JSZip.loadAsync(data);
const levelDat = await zip.file('level.dat').async('nodebuffer');
this.nbtData = NBTReader.parse(levelDat); // Use library to parse
}
printProperties() {
if (!this.nbtData) {
this.read();
}
for (const key in this.nbtData) {
console.log(`${key}: ${this.nbtData[key]}`);
}
}
async write(newFilepath) {
if (!this.nbtData) return;
const zip = new JSZip();
const nbtBuffer = NBTReader.write(this.nbtData); // Use library to write
zip.file('level.dat', nbtBuffer);
const content = await zip.generateAsync({type: 'nodebuffer'});
fs.writeFileSync(newFilepath || this.filepath, content);
}
}
// Example usage:
// const handler = new MCProjectHandler('example.mcproject');
// await handler.read();
// handler.printProperties();
// handler.nbtData.LevelName = 'New Name';
// await handler.write('modified.mcproject');
- C class that can open any file of format .MCPROJECT and decode read and write and print to console all the properties from the above list.
(Note: C++ is used for class, as pure C doesn't have classes. Uses libzip for ZIP and a NBT library like cnmt or custom.)
#include <iostream>
#include <zip.h>
#include <nbt/nbt.h> // Assume an NBT library like libnbt++
class MCProjectHandler {
private:
std::string filepath;
nbt_tag_t* nbtData; // Assume NBT struct from library
public:
MCProjectHandler(const std::string& fp) : filepath(fp), nbtData(nullptr) {}
~MCProjectHandler() {
if (nbtData) nbt_free(nbtData);
}
void read() {
zip_t* zip = zip_open(filepath.c_str(), ZIP_RDONLY, nullptr);
if (zip) {
zip_file_t* file = zip_fopen(zip, "level.dat", 0);
if (file) {
// Read buffer
zip_stat_t stat;
zip_stat(zip, "level.dat", 0, &stat);
char* buffer = new char[stat.size];
zip_fread(file, buffer, stat.size);
nbtData = nbt_parse(buffer, stat.size); // Use library
delete[] buffer;
zip_fclose(file);
}
zip_close(zip);
}
}
void printProperties() {
if (!nbtData) read();
// Assume library has a dump function
nbt_dump(nbtData, std::cout, 0); // Or implement recursion to print tags
}
void write(const std::string& newFilepath) {
if (!nbtData) return;
zip_t* zip = zip_open(newFilepath.c_str(), ZIP_CREATE | ZIP_TRUNCATE, nullptr);
if (zip) {
zip_source_t* source = zip_source_buffer_create(nullptr, 0, 0, nullptr);
// Write NBT to buffer using library
size_t size;
char* buffer = nbt_encode(nbtData, &size);
zip_source_buffer(zip, source, buffer, size, 1);
zip_add(zip, "level.dat", source);
zip_close(zip);
free(buffer);
}
}
};
// Example usage:
// int main() {
// MCProjectHandler handler("example.mcproject");
// handler.read();
// handler.printProperties();
// // Modify nbtData
// handler.write("modified.mcproject");
// return 0;
// }