ft_transcendence — منصة Pong متعددة اللاعبين بزمن حقيقي
منصة ويب حول لعبة Pong تجمع مباريات بزمن حقيقي ودردشة بقنوات ورسائل خاصة وحسابات مرتبطة بـ OAuth شبكة 42. مشروع التخرّج في مسار 42 أبوظبي، أُنجز ضمن فريق من خمسة مطوّرين.

عن هذا المشروع
منصة Pong متعددة اللاعبين بزمن حقيقي مع دردشة وقنوات ونظام أصدقاء ومطابقة، مبنية على NestJS وPostgreSQL وواجهة TypeScript، وتُشغَّل عبر Docker Compose.
التقنيات
مشروع التخرّج في مسار 42 أبوظبي — أوسع بناء full-stack في المسار، أُنجز ضمن فريق من خمسة مطوّرين.
نظرة عامة
ft_transcendence منصة ويب تدور حول لعبة Pong، لكنها في جوهرها ثلاثة أنظمة تعمل معاً: مباريات متعددة اللاعبين تجري بزمن حقيقي، ودردشة بقنوات ورسائل خاصة، وطبقة حسابات مرتبطة بنظام OAuth الخاص بشبكة 42.
الواجهة الخلفية مبنية على NestJS، والواجهة الأمامية بـ TypeScript، والتخزين في PostgreSQL. المنصة كاملة تُشغَّل بأمر واحد:
docker-compose up --buildالمشكلة
صعوبة المشروع ليست في أي ميزة بمفردها، بل في أن الميزات الثلاث تتقاطع كلها في نقطة واحدة: حالة المستخدم.
- زمن حقيقي على مسارين مختلفين. اللعبة تحتاج تحديثات متلاحقة ومنخفضة الكمون، والدردشة تحتاج بثّاً موثوقاً للرسائل. الاثنان يتشاركان الاتصال نفسه والمستخدم نفسه، لكن متطلباتهما ليست واحدة.
- هوية واحدة تخدم كل شيء. المستخدم الذي سجّل دخوله عبر 42 يجب أن يُعرَف في الدردشة، وفي قائمة الأصدقاء، وفي طابور المطابقة، وفي سجلّ المباريات — دون أن تُعاد المصادقة في كل موضع.
- صلاحيات متداخلة. القناة لها مالك ومشرفون وأعضاء ومحظورون، وللمستخدم قائمة حظر خاصة به. تقاطع هاتين الطبقتين هو ما يحدّد ما إذا كانت الرسالة تصل أصلاً.
- عمل جماعي. خمسة مطوّرين على قاعدة واحدة يعني أن حدود الوحدات يجب أن تُرسم قبل الكتابة لا بعدها.
التخطيط
قُسّم النظام إلى ثلاثة نطاقات مستقلة، لكلٍّ منها نماذجه في قاعدة البيانات ومسارات API خاصة به، بحيث يستطيع كل مطوّر التقدّم دون انتظار البقية:
| النطاق | ما يملكه | ما يعتمد عليه |
|---|---|---|
| الحسابات | OAuth، الاسم المعروض، الصورة الرمزية، التحقق الثنائي | لا شيء — هو الأساس |
| العلاقات | الأصدقاء، الحظر، حالة الاتصال | الحسابات |
| الدردشة | القنوات، الأدوار، الرسائل الخاصة | الحسابات + العلاقات |
| اللعبة | المطابقة، المباراة، السجلّ والإحصاءات | الحسابات |
ترتيب البناء تبع هذا الاعتماد حرفياً: لا شيء قبل الحسابات، ولا دردشة قبل نظام الحظر — لأن الحظر شرط في تسليم الرسالة، لا ميزة تُضاف لاحقاً.
القرارات المعمارية
تفويض المصادقة إلى 42 Intranet بدل بناء نظام كلمات مرور. البديل — تسجيل محلي كامل — كان يعني إدارة استرجاع كلمات المرور وتأكيد البريد وسياسات التعقيد، وكل ذلك خارج موضوع المشروع. مع OAuth تصبح الهوية مسألة محسومة من طرف موثوق، ويبقى على المنصة أن تدير الجلسة فقط. ما يُخزَّن محلياً من أسرار يُحفظ مجزّأً (hashed)، والاعتمادات تُقرأ من ملف .env لا من الشيفرة.
التحقق الثنائي كطبقة اختيارية فوق OAuth. إضافته بعد المصادقة الخارجية — لا بدلاً منها — تُبقي مسار الدخول الأساسي بسيطاً وتترك القرار للمستخدم.
اتصال دائم عبر Socket.IO بدل الاستقصاء الدوري. الدردشة عبر polling تعني تأخيراً محسوساً وطلبات مهدورة، واللعبة عبره غير ممكنة أصلاً. الاتصال الدائم يجعل الخادم هو من يدفع التحديث عند وقوعه، ويسمح باستخدام مجالات أسماء منفصلة للدردشة واللعبة فوق البنية نفسها.
التحقق على الخادم دائماً. لا يُوثق بأي قيمة قادمة من العميل: الصلاحيات تُفحص عند كل عملية، والاستعلامات تُبنى بطريقة تمنع حقن SQL. في نظام تنافسي، العميل طرف مهتم بالنتيجة — لذا لا يُمنح سلطة تقريرها.
Docker Compose بيئةً موحّدة. خمسة مطوّرين + خادم + قاعدة بيانات + واجهة يعني خمس بيئات محلية مختلفة إن تُركت للإعداد اليدوي. ملف تركيب واحد جعل "يعمل على جهازي" مسألة غير قابلة للحدوث.
التنفيذ
الحساب. الدخول عبر OAuth شبكة 42، ثم اختيار اسم معروض فريد ورفع صورة رمزية مع خيار افتراضي جاهز، وتفعيل التحقق الثنائي عند الرغبة. لكل مستخدم صفحة تعرض إحصاءاته وسجلّ مبارياته.
العلاقات. إضافة الأصدقاء مع عرض حالة كل صديق، وحظر المستخدمين — والحظر يسري على مستوى التسليم لا العرض فقط.
الدردشة.
- قنوات عامة، أو خاصة، أو محمية بكلمة مرور.
- رسائل مباشرة بين مستخدمين.
- ملكية للقناة وإدارة لها: المالك يعيّن المشرفين، والمشرفون يديرون الأعضاء.
- دعوات مباريات Pong تُرسَل من داخل المحادثة — وهي نقطة الوصل التي تربط نطاق الدردشة بنطاق اللعبة.
اللعبة. مباريات Pong بزمن حقيقي ضد لاعبين آخرين، نظام مطابقة يضع اللاعب في طابور حتى يجد خصماً، وخيارات تخصيص للمباراة مع نمط افتراضي يعمل دون أي إعداد.
النتيجة والدروس
الناتج منصة واحدة يدخل إليها المستخدم بحسابه من 42، فيجد أصدقاءه وقنواته ومبارياته وسجلّه في مكان واحد — لا أربعة تطبيقات ملصوقة ببعضها.
- ترتيب البناء يتبع اتجاه الاعتماد. بناء الدردشة قبل نظام الحظر كان سيعني إعادة كتابة مسار تسليم الرسائل بالكامل. الرسم المبكر لخريطة الاعتمادات وفّر هذه الإعادة.
- التخصص بالنطاق أفضل من التخصص بالطبقة. توزيع العمل على "واجهة/خلفية" يُنتج انتظاراً متبادلاً دائماً؛ توزيعه على نطاقات كاملة يجعل كل مطوّر قادراً على إنهاء ميزة من طرفها إلى طرفها.
- العميل ليس مصدراً للحقيقة. كل قاعدة تُفرض في الواجهة فقط هي قاعدة اختيارية عملياً — وهذا يصبح واضحاً في اللحظة التي يصبح فيها للنتيجة قيمة تنافسية.
الروابط
- المستودع: github.com/i99dev/ft_transcendence