إضافة بلوك جديد هي تمرين ممتاز لأنك تتعامل مع أكثر من طبقة في الوقت نفسه: كود التسجيل، BlockItem، blockstate، model، texture، اللغة، الوصفة، وأحيانًا loot table. إذا ظهر البلوك في القائمة لكنه لا يوضع أو لا يعطي شيئًا عند كسره، فالمشكلة غالبًا في طبقة من هذه الطبقات لا في “فكرة Fabric” كلها.
الفكرة المعمارية: البلوك ليس ملفًا واحدًا
فكّر في البلوك كعقد بين اللعبة وموارد المود. الكود يعرف خصائصه الفيزيائية، ملفات الموارد تخبر العميل كيف يرسمه، وملف loot يحدد ما يحدث عند كسره. توثيق Fabric يشرح أن أدواته تشمل API وأحداثًا وLoom، لكن أسماء الواجهات الدقيقة تتغير حسب إصدار Minecraft [1].
| الطبقة | وظيفتها | علامة الخطأ |
|---|---|---|
| Block registration | تعريف البلوك وخصائصه | Crash أو البلوك غير موجود |
| BlockItem | إعطاء البلوك شكل عنصر في المخزون | يمكن تسجيله لكن لا يظهر في اليد |
| Blockstate | اختيار model حسب الحالة | ملمس أسود/بنفسجي أو شكل خاطئ |
| Loot table | ما يسقط عند الكسر | البلوك يختفي بلا إسقاط |
1. اختَر خصائص البلوك قبل الكود
دوّن هل هو صلب، قابل للكسر، يحتاج أداة، هل يضيء، وهل يسمح بمرور الضوء. لا تستخدم خصائص “بلوك قوي” لمجرد أن المثال استخدمها. التوازن جزء من جودة المود؛ بلوك ديكوري سريع الكسر يجب ألا ينافس خامًا نادرًا بلا سبب.
2. سجّل Block وBlockItem معًا
البلوك يعيش في العالم، والـBlockItem هو ما يحمله اللاعب ويضعه. افصل دالة التسجيل عن دالة التهيئة، واجعل id واحدًا ثابتًا حتى لا تختلف أسماء الملفات.
public static final Block IGNIS_BRICK = Registry.register(
Registries.BLOCK,
Identifier.fromNamespaceAndPath(MOD_ID, "ignis_brick"),
new Block(AbstractBlock.Settings.copy(Blocks.STONE))
);
public static final Item IGNIS_BRICK_ITEM = Registry.register(
Registries.ITEM,
Identifier.fromNamespaceAndPath(MOD_ID, "ignis_brick"),
new BlockItem(IGNIS_BRICK, new Item.Settings())
);الكود السابق تعليمي؛ في إصدارك قد تكون أسماء Settings أو Identifier مختلفة. لا تخلط بين id العنصر وid البلوك؛ الأفضل أن يتساويا حتى يكون تصور المشروع واضحًا.
3. ملفات الموارد الأساسية
ضع الملفات في بنية متطابقة. اسم الملف lowercase، وتأكد أن namespace هو mod id:
assets/ignis_shard/blockstates/ignis_brick.json
assets/ignis_shard/models/block/ignis_brick.json
assets/ignis_shard/models/item/ignis_brick.json
assets/ignis_shard/textures/block/ignis_brick.png
assets/ignis_shard/lang/en_us.jsonملف blockstate يربط الحالة الافتراضية بالنموذج:
{
"variants": {
"": {"model": "ignis_shard:block/ignis_brick"}
}
}نموذج البلوك القياسي يمكن أن يرث من cube_all ويشير إلى texture واحدة. لو أردت texture مختلفة لكل وجه، استخدم نموذج cube مع texture keys منفصلة.
{
"parent": "minecraft:block/cube_all",
"textures": {"all": "ignis_shard:block/ignis_brick"}
}نموذج العنصر يحتاج غالبًا إلى parent من نموذج البلوك حتى يظهر في المخزون بالطريقة الصحيحة:
{
"parent": "ignis_shard:block/ignis_brick"
}4. اللغة والقائمة
أضف key للبلوك وkey للعنصر، ثم أضفه إلى تبويب مناسب. لا تعتمد على اسم id ليظهر للاعب؛ Minecraft ستعرض key إذا غاب ملف اللغة.
{
"block.ignis_shard.ignis_brick": "Ignis Brick",
"item.ignis_shard.ignis_brick": "Ignis Brick"
}5. الوصفة والـloot table
الوصفة تجعل البلوك قابلًا للاستخدام، لكن loot table هي التي تحفظ توقع اللاعب عند كسره. في المشاريع الكبيرة تستطيع استخدام Data Generation لتوليد recipes وadvancements وtags وloot tables بدل تكرار JSON يدويًا؛ توثيق Fabric يعرّف datagen كطريقة لتوليد معظم الملفات المعتمدة على JSON برمجيًا [2].
حتى لو بدأت بملفات يدوية، اكتب اختبارًا يدويًا: ضع البلوك، اكسره بالأداة المناسبة، اكسره بأداة غير مناسبة، جرّب Silk Touch إذا كانت الميزة تدعم ذلك، وتأكد أن كمية الإسقاط منطقية.
6. استخدم Data Generation عندما يتكرر العمل
لتفعيل Data Generation من قالب Fabric اختر الخيار أثناء إنشاء المشروع. عند التفعيل تحصل عادة على run configuration وGradle task باسم runDatagen. عند التشغيل تذهب الملفات الناتجة إلى src/main/generated حسب توثيق Fabric [2]. ميزة هذا المسار أنك تضع تعريف البلوك مرة واحدة وتولّد أسماء الملفات من نفس الثوابت، فتقل أخطاء الكتابة.
7. افحص العميل والخادم
بعض الكود يخص الخادم وبعضه يخص العميل. لا تستورد صنف rendering في initializer المشترك. إذا كان البلوك يحتاج renderer خاصًا، سجله في client entrypoint. الاختبار الصحيح يشمل عميل التطوير، فتح عالم، وضع البلوك، حفظ العالم، ثم إعادة فتحه.
جدول تشخيص سريع
| المشكلة | أول ملف تراجعه | ما الذي تبحث عنه |
|---|---|---|
| لا يظهر في Creative | التسجيل والتبويب | استدعاء register وBlockItem |
| لا يوضع | BlockItem وid | الـitem يشير إلى نفس البلوك |
| شكل بنفسجي | blockstate/model/texture | المسار وحالة الأحرف |
| لا يسقط شيء | loot table أو datagen | الـid والـgenerated resources |
| Crash للعميل | entrypoints | فصل client عن common |
بعد أول بلوك، لا تضف عشرة بلوكات نسخًا من بعضها. ابنِ نظامًا صغيرًا يعيد استخدام التسجيل واللغة والوصفات، ثم أضف ميزة اختلاف حقيقية مثل block entity أو تفاعل عند النقر. بهذه الطريقة تتعلم التصميم، لا مجرد زيادة عدد الملفات.
9. خصائص البلوك ليست مجرد أرقام
اختيار hardness وsound وrequired tool يؤثر في شعور اللاعب. جرّب البلوك في أماكن مختلفة: على الأرض، بجانب الماء، داخل بناء، ومع piston إن كان إصدارك يدعم التفاعل المتوقع. إذا كان البلوك ديكوريًا، اجعل كسره منطقيًا؛ وإذا كان جزءًا من تقدم اللاعب، اربطه بوصفة ومسار موارد واضح.
10. راجع الحزمة بصريًا
افتح البلوك من أربع زوايا وفي إضاءة مختلفة، وضع عدة بلوكات متجاورة، ثم اكسر واحدًا منها. هذه الخطوة تكشف seams في texture أو نموذجًا يبدو صحيحًا منفردًا لكنه يكرر نفسه بشكل مزعج. استخدم alt وcaption في صفحة التوثيق إذا نشرت صورًا للمثال.
في مود متعدد البلوكات، أنشئ helpers لتوليد ملفات متشابهة، لكن لا تجعل helper يخفي اختلافًا مهمًا مثل loot أو hardness. التوليد الجيد يقلل النسخ، ولا يلغي قرار التصميم.
مراجع موثوقة
راجِع هذه الصفحات الرسمية عند اختلاف الإصدار أو تغيّر أسماء الملفات؛ توثيق اللعبة والمنصة يتغير مع الزمن.