{"id":20092342,"url":"https://github.com/rubixdev/mcdata","last_synced_at":"2026-03-06T01:01:39.975Z","repository":{"id":236444091,"uuid":"792624704","full_name":"RubixDev/mcdata","owner":"RubixDev","description":"(De)serializable NBT structures for Minecraft","archived":false,"fork":false,"pushed_at":"2025-07-30T17:26:43.000Z","size":1138,"stargazers_count":4,"open_issues_count":0,"forks_count":4,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-15T05:56:39.555Z","etag":null,"topics":["minecraft","nbt","rust"],"latest_commit_sha":null,"homepage":"https://docs.rs/mcdata/","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RubixDev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-04-27T05:16:38.000Z","updated_at":"2025-07-30T17:26:26.000Z","dependencies_parsed_at":"2025-09-20T20:42:19.741Z","dependency_job_id":null,"html_url":"https://github.com/RubixDev/mcdata","commit_stats":null,"previous_names":["rubixdev/mcdata"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/RubixDev/mcdata","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RubixDev%2Fmcdata","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RubixDev%2Fmcdata/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RubixDev%2Fmcdata/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RubixDev%2Fmcdata/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RubixDev","download_url":"https://codeload.github.com/RubixDev/mcdata/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RubixDev%2Fmcdata/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30156844,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-05T22:39:40.138Z","status":"ssl_error","status_checked_at":"2026-03-05T22:39:24.771Z","response_time":93,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["minecraft","nbt","rust"],"created_at":"2024-11-13T16:36:42.982Z","updated_at":"2026-03-06T01:01:39.914Z","avatar_url":"https://github.com/RubixDev.png","language":"Rust","readme":"# mcdata\n\nA Rust library providing traits and types representing various Minecraft NBT\nstructures.\n\n## Overview\n\nCurrently, this crate provides three traits along with some implementations of\nthose traits:\n\n- [`BlockState`] for block states.\n- [`Entity`] for normal entities.\n- [`BlockEntity`] for block entities.\n\nThere's one \"generic\" implementation for each of these in the corresponding\nmodule. Other implementations are locked behind [features](#features).\n\nWith `serde` support enabled, all types in this crate can be full serialized and\ndeserialized from/to NBT. The recommended crate for that is\n[`fastnbt`](https://crates.io/crates/fastnbt) which is also internally used by\nthe types in this crate. For example [`entity::GenericEntity`] is almost fully\nrepresented by a [`fastnbt::Value`].\n\n## A Warning for Block Entities\n\nIf you intend to use any version-specific `BlockEntity` type with litematica\nfiles, beware that there was a bug in litematica since version `1.18.0-0.9.0`\nthat was only fixed in `1.20.1-0.15.3` which caused the block entity IDs to not\nbe included in saved schematics. The block entity types _do_ support\ndeserialization without an ID, but that can never be perfect. For instance,\n[barrels](mc1_18::block_entity_types::BarrelBlockEntity) and\n[chests](mc1_18::block_entity_types::ChestBlockEntity) in 1.18 have the same\nexact NBT structure, but barrels will always be tested first when deserializing,\nso chests will also be deserialized as barrels when there's no ID distinguishing\nthe two. During serialization, the ID will always be included, so such a chest\nwould become a barrel by just reading and writing the NBT. If that's a problem\nfor you, consider using [`GenericBlockEntity`] instead which won't mess with\nmissing IDs.\n\n## Examples\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eBlock States\u003c/strong\u003e\u003c/summary\u003e\n\n```rust\n# #[cfg(not(feature = \"test\"))]\n# compile_error!(\"tests should be run with the 'test' feature enabled\");\nuse mcdata::mc1_21_4::{BlockState, props};\n\nlet banjo = BlockState::NoteBlock {\n    instrument: props::NoteBlockInstrument::Banjo,\n    note: bounded_integer::BoundedU8::new(10).unwrap(),\n    powered: false,\n};\nlet banjo_nbt = fastnbt::nbt!({\n    \"Name\": \"minecraft:note_block\",\n    \"Properties\": {\n        \"instrument\": \"banjo\",\n        \"note\": \"10\",\n        \"powered\": \"false\",\n    },\n});\nassert_eq!(fastnbt::to_value(\u0026banjo), Ok(banjo_nbt));\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eEntities\u003c/strong\u003e\u003c/summary\u003e\n\n```rust\n# #[cfg(not(feature = \"test\"))]\n# compile_error!(\"tests should be run with the 'test' feature enabled\");\nuse std::collections::HashMap;\nuse mcdata::mc1_21_4::{Entity, entity_types as types, entity_compounds as compounds};\n\nlet axolotl = Entity::Axolotl(types::Axolotl {\n    from_bucket: false,\n    variant: 0,\n    parent: types::Animal {\n        in_love: 0,\n        love_cause: None,\n        parent: types::AgeableMob {\n            age: 0,\n            forced_age: 0,\n            parent: types::PathfinderMob {\n                parent: types::Mob {\n                    armor_drop_chances: vec![0.085; 4],\n                    armor_items: vec![HashMap::new(); 4],\n                    can_pick_up_loot: false,\n                    death_loot_table: None,\n                    body_armor_drop_chance: None,\n                    death_loot_table_seed: None,\n                    hand_drop_chances: vec![0.085; 2],\n                    hand_items: vec![HashMap::new(); 2],\n                    left_handed: false,\n                    no_ai: None,\n                    persistence_required: false,\n                    body_armor_item: None,\n                    leash: None,\n                    parent: types::LivingEntity {\n                        absorption_amount: 0.,\n                        attributes: vec![compounds::AttributeInstance_save {\n                            base: 1.,\n                            id: \"minecraft:generic.movement_speed\".into(),\n                            modifiers: None,\n                        }],\n                        brain: Some(fastnbt::nbt!({ \"memories\": {} })),\n                        death_time: 0,\n                        fall_flying: false,\n                        health: 14.,\n                        hurt_by_timestamp: 0,\n                        hurt_time: 0,\n                        sleeping_x: None,\n                        sleeping_y: None,\n                        sleeping_z: None,\n                        active_effects: None,\n                        parent: types::Entity {\n                            air: 6000,\n                            custom_name: None,\n                            custom_name_visible: None,\n                            fall_distance: 0.,\n                            fire: -1,\n                            glowing: None,\n                            has_visual_fire: None,\n                            invulnerable: false,\n                            motion: vec![0.; 3],\n                            no_gravity: None,\n                            on_ground: false,\n                            passengers: None,\n                            portal_cooldown: 0,\n                            pos: Some(vec![-0.5, 0., 1.5]),\n                            rotation: vec![-107.68715, 0.],\n                            silent: None,\n                            tags: None,\n                            ticks_frozen: None,\n                            uuid: 307716075036743941152627606223512221703,\n                        },\n                    },\n                },\n            },\n        },\n    },\n});\nlet axolotl_nbt = fastnbt::nbt!({\n    \"id\": \"minecraft:axolotl\",\n    \"FromBucket\": false,\n    \"Variant\": 0,\n    \"InLove\": 0,\n    \"Age\": 0,\n    \"ForcedAge\": 0,\n    \"ArmorDropChances\": vec![0.085_f32; 4],\n    \"ArmorItems\": [{}, {}, {}, {}],\n    \"CanPickUpLoot\": false,\n    \"HandDropChances\": vec![0.085_f32; 2],\n    \"HandItems\": [{}, {}],\n    \"LeftHanded\": false,\n    \"PersistenceRequired\": false,\n    \"AbsorptionAmount\": 0_f32,\n    \"attributes\": [{\n        \"base\": 1.,\n        \"id\": \"minecraft:generic.movement_speed\",\n    }],\n    \"Brain\": { \"memories\": {} },\n    \"DeathTime\": 0_i16,\n    \"FallFlying\": false,\n    \"Health\": 14_f32,\n    \"HurtByTimestamp\": 0,\n    \"HurtTime\": 0_i16,\n    \"Air\": 6000_i16,\n    \"FallDistance\": 0_f32,\n    \"Fire\": -1_i16,\n    \"Invulnerable\": false,\n    \"Motion\": vec![0.; 3],\n    \"OnGround\": false,\n    \"PortalCooldown\": 0,\n    \"Pos\": [-0.5, 0., 1.5],\n    \"Rotation\": [-107.68715_f32, 0_f32],\n    \"UUID\": [I; -411044392, 312166398, -1883713137, 1472542727],\n});\nassert_eq!(fastnbt::to_value(\u0026axolotl), Ok(axolotl_nbt));\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eBlock Entities\u003c/strong\u003e\u003c/summary\u003e\n\n```rust\n# #[cfg(not(feature = \"test\"))]\n# compile_error!(\"tests should be run with the 'test' feature enabled\");\nuse mcdata::mc1_21_4::{BlockEntity, block_entity_types as types};\n\nlet command_block = BlockEntity::CommandBlock(types::CommandBlockEntity {\n    command: \"/say hi\".into(),\n    custom_name: None,\n    last_execution: None,\n    last_output: None,\n    success_count: 2,\n    track_output: true,\n    update_last_execution: true,\n    auto: false,\n    condition_met: false,\n    powered: false,\n    parent: types::BlockEntity {\n        x: 0,\n        y: 10,\n        z: -5,\n    },\n});\nlet command_block_nbt = fastnbt::nbt!({\n    \"id\": \"minecraft:command_block\",\n    \"Command\": \"/say hi\",\n    \"SuccessCount\": 2,\n    \"TrackOutput\": true,\n    \"UpdateLastExecution\": true,\n    \"auto\": false,\n    \"conditionMet\": false,\n    \"powered\": false,\n    \"x\": 0,\n    \"y\": 10,\n    \"z\": -5,\n});\nassert_eq!(fastnbt::to_value(\u0026command_block), Ok(command_block_nbt));\n```\n\n\u003c/details\u003e\n\n## Where does this data come from?\n\nAs you can imagine, I did not enter all this data by hand. It is automatically\nextracted from the Minecraft jars using a combination of two custom tools:\n\n1. The\n   [\"data-extractor\"](https://github.com/RubixDev/mcdata/tree/main/data-extractor)\n   is a Java file that acts as a Fabric mod and gets some data at runtime using\n   reflection. This includes everything about block states, and some things\n   about entities (the IDs of all entities and their corresponding classes).\n2. The (badly named)\n   [\"class-parser\"](https://github.com/RubixDev/mcdata/tree/main/class-parser)\n   is almost like a JVM written in Kotlin which takes the data about entities\n   from the \"data-extractor\" and \"interprets\" the Minecraft jars to gather\n   information about their NBT structure. This is necessary because entity NBT\n   is unstructured and the only thing that defines the structure is the actual\n   code itself. This is obviously still a brittle approach, but the best I could\n   think of. Some things are also very difficult to properly support in this\n   \"JVM\", mainly Minecraft's `Codec`s which are getting used more and more with\n   new Minecraft updates. This together means that all types in this crate which\n   describe NBT structure _might_ not be fully correct. If you find any\n   discrepancies, please\n   [open an issue ticket](https://github.com/RubixDev/mcdata/issues).\n\nIf you want to contribute to `mcdata` in any way that involves changing the\ngenerated code, you can run these tools along with the actual code generation\nusing `cargo xtask codegen`. Just make sure you have a working Java 21 JDK,\n`git`, and [`deno`](https://deno.com/) installed and on your PATH.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frubixdev%2Fmcdata","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frubixdev%2Fmcdata","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frubixdev%2Fmcdata/lists"}