عندما يحتوي المود على عنصرين أو ثلاثة، قد تبدو كتابة JSON يدويًا سهلة. بعد إضافة عشرات العناصر والوصفات والترجمات تبدأ الأخطاء: ملف ناقص، id مكتوب بحرف مختلف، أو recipe تشير إلى texture قديمة. Data Generation يحوّل جزءًا كبيرًا من هذه الأعمال إلى كود قابل لإعادة الاستخدام.
ما الذي يعنيه Data Generation؟
تصف وثائق Fabric datagen بأنه API لتوليد recipes وadvancements وtags وitem models وlanguage files وloot tables وكل ما هو قائم على JSON تقريبًا [1]. الفائدة ليست “توفير الكتابة” فقط؛ بل جعل تعريفاتك مركزية، بحيث تستخدم نفس الثوابت لتوليد أسماء الملفات والمعرّفات.
متى تستخدمه؟
| حجم المشروع | الاختيار العملي |
|---|---|
| تجربة من عنصر واحد | JSON يدوي مقبول للتعلم |
| عدة عناصر ووصفات | فعّل datagen مبكرًا |
| مود كبير متعدد اللغات | datagen مع تقسيم providers |
| مشروع فريق | datagen + مراجعة generated files |
1. التفعيل عند إنشاء المشروع
أسهل طريقة هي اختيار Enable Data Generation من Advanced Options في Fabric Template Mod Generator. توثيق Fabric يذكر أن التفعيل ينشئ إعداد تشغيل وGradle task باسم runDatagen عادة [1]. إذا لم تفعّله في البداية، لا تعِد إنشاء المشروع بالضرورة؛ يمكنك تفعيله يدويًا.
2. التفعيل اليدوي
أضف إعداد Fabric API الخاص بتوليد البيانات في build.gradle، ثم أنشئ class يطبق DataGeneratorEntrypoint، وسجّل entrypoint باسم fabric-datagen في fabric.mod.json. أسماء الحزم تختلف باختلاف الإصدار، لكن شكل الفكرة ثابت:
public class IgnisDataGenerator implements DataGeneratorEntrypoint {
@Override
public void onInitializeDataGenerator(FabricDataGenerator generator) {
FabricDataGenerator.Pack pack = generator.createPack();
// سجّل providers هنا
}
}إذا نسيت الفاصلة في JSON أو كتبت اسم entrypoint في قسم خاطئ، سيعمل المود العادي وقد يفشل datagen فقط؛ راجع log الخاص بالمهمة بدل تخمين المشكلة.
3. شغّل المهمة وراجع المخرجات
من IDE استخدم run configuration أو نفّذ ./gradlew runDatagen. تذكر وثائق Fabric أن الملفات الناتجة تذهب إلى src/main/generated [1]. لا تكتفِ بتشغيل المهمة؛ افتح الناتج واقرأ JSON، لأن provider قد يولّد ملفًا صحيحًا تقنيًا لكنه لا يعبر عن تصميمك.
4. providers منفصلة حسب الوظيفة
قسّم الكود إلى providers: Provider للوصفات، وآخر للترجمات، وآخر للـloot، وربما Provider للنماذج. هذا التقسيم يجعل رسالة الخطأ مرتبطة بمساحة صغيرة. استخدم أسماء واضحة مثل IgnisRecipeProvider وIgnisLangProvider.
5. الوصفات من الثوابت
لا تكتب string id في كل مكان. استورد العناصر المسجلة من ModItems، ثم استخدمها في provider. بذلك، إذا غيرت id قبل الإصدار، يظهر أثر التغيير في compile بدل أن تكتشف ملفًا مكسورًا داخل اللعبة.
صمّم الوصفة على أساس gameplay: هل المادة متاحة في المرحلة التي تريدها؟ هل الناتج قوي أكثر من اللازم؟ هل recipe shaped أم shapeless؟ الجودة هنا ليست في أن JSON يمر، بل في أن اللاعب يفهم منطق الحصول على العنصر.
6. الترجمات والـfallback
توليد اللغات يقلل نسيان key جديد. اكتب اللغة الأساسية التي تريدها، ثم راجع هل اللعبة تستخدم locale مناسبًا. لا تضع نصوصًا طويلة داخل أسماء العناصر؛ استخدم tooltip أو صفحة README للشرح التفصيلي، لأن الاسم يجب أن يظل قابلًا للقراءة في inventory.
7. loot tables بدون مفاجآت
loot table تحدد ما يسقط عند كسر البلوك أو قتل الكيان. اختبر إسقاطاتك مع الأدوات المختلفة والخصائص مثل Silk Touch وFortune إن كانت تنطبق. لا تجعل provider يولّد loot table باسم يختلف عن block id. أضف اختبارًا يدويًا لعالم جديد وعالم موجود.
8. generated files وGit
قرّر مع فريقك هل تلتزم بإضافة generated files إلى Git. في مشاريع كثيرة تُحفظ الملفات الناتجة حتى يستطيع أي شخص بناء المشروع من checkout نظيف، لكن القرار يجب أن يطابق قالبك وأدوات الفريق. لا تحفظ ملفات مؤقتة أو cache، ولا ترفع مجلدات IDE.
أخطاء شائعة
| الخطأ | النتيجة | الإجراء |
|---|---|---|
| entrypoint غير مسجل | لا تعمل runDatagen | راجع fabric.mod.json |
| provider لا يضيف الملفات | مهمة ناجحة بلا output مفيد | أنشئ Pack وسجّل provider |
| generated خارج source set | اللعبة لا ترى الملفات | راجع إعداد Gradle |
| id مكتوب يدويًا | فروقات وأخطاء صامتة | استخدم الثوابت |
خطة تطبيق على مود حقيقي
- فعّل datagen على branch منفصل.
- ولّد لغة وموديل عنصر واحد.
- قارن generated مع ملفاتك اليدوية.
- أضف recipe ثم loot table.
- شغّل build من checkout نظيف.
- اختبر الـJAR داخل اللعبة.
بعد أن تتعود على datagen، ستجد أن إضافة محتوى جديد أصبحت أقرب إلى تعريف بيانات منظمة بدل نسخ ملفات. هذا يترك وقتًا أكبر لتصميم الميكانيكية واختبارها، وهما الجزء الذي يراه اللاعب فعلًا.
9. مراجعة generated output
ضع generated files في مراجعة الكود كما تراجع Java. ابحث عن id خاطئ، recipe غير متوازنة، أو translation ناقصة. لا تقبل آلاف الملفات من غير diff مفهوم؛ قسّم التوليد إلى commits منطقية. إذا تغيرت أسماء الملفات كلها بعد تحديث dependency، افهم السبب قبل الدمج.
10. اجعل datagen جزءًا من CI
في فريق صغير يمكنك تشغيل runDatagen وbuild قبل الدمج. الهدف ليس بناء نظام معقد، بل اكتشاف أن provider لا compile أو أن output لم يتغير كما توقع المطور. احتفظ بنسخة من إعدادات الإصدار حتى يستطيع عضو جديد إعادة إنتاج النتيجة.
Data Generation أداة تنظيم، وليست ضمانًا تلقائيًا لصحة gameplay. افتح اللعبة واختبر الناتج دائمًا.
مراجع موثوقة
راجِع هذه الصفحات الرسمية عند اختلاف الإصدار أو تغيّر أسماء الملفات؛ توثيق اللعبة والمنصة يتغير مع الزمن.