TuBrief
구독 채널
비디오
커뮤니티

دليل ترحيل Lore VCS لحل مشكلات تكاليف Git LFS وتضارب أصول Unreal Engine

TuBrief 편집팀
2026년 7월 14일
0
Computing/Software

원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.

العربية한국어EnglishEspañol中文DeutschFrançaisPortuguêsहिन्दीРусскийBahasa Indonesia日本語

관련 영상

Git لا يمكنه التعامل مع الألعاب... لذا قامت Epic ببناء Lore7:44

Git لا يمكنه التعامل مع الألعاب... لذا قامت Epic ببناء Lore

Better Stack

커뮤니티의 다른 글

사내 시스템에 llm api 붙일 때 마주하는 현실적인 한계와 대응법

2026년 9월 13일

레거시 백엔드에 GPT-6 Astra 붙일 때 예산 승인과 보안 통과를 먼저 끝내는 법이 있습니다

2026년 9월 13일

에이전트끼리 대화하다 6천만 원 청구서가 나오는 이유

2026년 9월 13일

사내 RAG 벡터 검색에 Okta 권한 필터를 직접 거는 방법

2026년 9월 13일

브라우저 에이전트에게 내 구글 계정을 통째로 넘기면 안 되는 이유

2026년 9월 12일

Apple Won the AI Race

2026년 9월 12일

댓글 (0)

Log in to leave a comment

아직 작성된 글이 없습니다

© 2026 . All rights reserved.

TuBrief
구독 채널
비디오
커뮤니티
로그인

دليل ترحيل Lore VCS لحل مشكلات تكاليف Git LFS وتضارب أصول Unreal Engine

عندما ينمو المشروع، يتحول Git LFS إلى كارثة حقيقية. إصلاح بضعة أسطر من التعليمات البرمجية يستغرق لحظات، ولكن بمجرد أن تبدأ أصول الفن التي تقاس بالجيجابايت في الاختلاط، تدور الساعة الرملية لعشرات الثواني مع كل عملية دفع (Commit). وبسبب البنية البطيئة لـ LFS التي تعتمد على نسخ الملفات الكبيرة بالكامل، تتجاوز مساحة التخزين في المستودع التيرابايت في وقت قصير، وتظهر أرقام مرعبة في فواتير النطاق الترددي (Bandwidth).

صممت شركة Epic Games أداة Lore مفتوحة المصدر للتعامل مع الملفات الثنائية (Binary files) كأولوية قصوى. فهي تستخدم طريقة FastCDC لتقسيم الملفات إلى كتل وإزالة التكرار، مما يقلل بشكل كبير من حجم الحزمة ونطاق النقل الترددي. لقد قمنا بتلخيص طرق الترحيل العملي والتحسين في Lore التي يمكن للفرق الصغيرة، التي تفتقر إلى متخصصي DevOps، تطبيقها على الفور.


1. الترحيل التدريجي من Git LFS إلى Lore

ليس من الضروري التخلص من سجل التزامات (Commit history) التعليمات البرمجية المتراكم في مستودع Git الحالي. الاستراتيجية الأكثر واقعية هي الإبقاء على التعليمات البرمجية الخفيفة في Git، ونقل الأصول الثنائية الثقيلة فقط إلى مستودع Lore.

يقوم البرنامج النصي أدناه بتحديد قائمة الملفات التي كان يتتبعها Git LFS، وإنشاء هيكل دليل متناظر، ومطابقة تجزئة SHA-256 للنسخ لضمان الانتقال إلى Lore دون فقدان أي بيانات.

`bash
#!/usr/bin/env bash
set -euo pipefail

GIT_REPO_DIR="HOME/projects/my−game−git"LOREREPODIR="HOME/projects/my-game-git" LORE_REPO_DIR="HOME/projects/my−game−git"LORER​EPOD​IR="HOME/projects/my-game-lore"
LORE_SERVER_URL="lore://127.0.0.1:41337/my-project"

echo "[1/5] تهيئة مستودع Lore والربط عن بُعد..."
if [ ! -d "LOREREPODIR"];thenmkdir−p"LORE_REPO_DIR" ]; then mkdir -p "LORER​EPOD​IR"];thenmkdir−p"LORE_REPO_DIR"
cd "LOREREPODIR"lorerepositorycreate"LORE_REPO_DIR" lore repository create "LORER​EPOD​IR"lorerepositorycreate"LORE_SERVER_URL"
else
cd "$LORE_REPO_DIR"
fi

echo "[2/5] جمع قائمة ملفات Git LFS المتتبعة..."
cd "GITREPODIR"LFSFILES=GIT_REPO_DIR" LFS_FILES=GITR​EPOD​IR"LFSF​ILES=(git lfs ls-files -n | grep -E ".(uasset|umap|fbx|png|psd)$" || true)

if [ -z "$LFS_FILES" ]; then
echo "لا توجد ملفات LFS للترحيل."
exit 0
fi

echo "[3/5] نسخ الملفات وإنشاء بيان للتحقق..."
echo "LFSFILES"∣whileread−rfilepath;doif[−f"LFS_FILES" | while read -r filepath; do if [ -f "LFSF​ILES"∣whileread−rfilepath;doif[−f"filepath" ]; then
dest_dir="LOREREPODIR/LORE_REPO_DIR/LORER​EPOD​IR/(dirname "filepath")"mkdir−p"filepath")" mkdir -p "filepath")"mkdir−p"dest_dir"
cp -p "filepath""filepath" "filepath""LORE_REPO_DIR/filepath"sourcehash=filepath" source_hash=filepath"sourceh​ash=(openssl dgst -sha256 "$filepath" | awk '{print 2}') echo "filepath:sourcehash">>"source_hash" >> "sourceh​ash">>"LORE_REPO_DIR/.lore_migration_manifest"
fi
done

echo "[4/5] إلغاء تتبع Git LFS وتجهيز (Staging) Lore..."
cd "GITREPODIR"echo"GIT_REPO_DIR" echo "GITR​EPOD​IR"echo"LFS_FILES" | while read -r filepath; do
git rm --cached "$filepath"
done
sed -i.bak -E 's/filter=lfs diff=lfs merge=lfs//g' .gitattributes

cd "LOREREPODIR"echo"LORE_REPO_DIR" echo "LORER​EPOD​IR"echo"LFS_FILES" | while read -r filepath; do
lore stage "$filepath"
done
lore commit -m "Migration: Transfer heavy assets from Git LFS to Lore"
lore push

echo "[5/5] التحقق من سلامة البيانات..."
lore repository verify state
lore repository verify fragment

if [ -f ".lore_migration_manifest" ]; then
migration_errors=0
while IFS=":" read -r file sha; do
if [ -f "file"];thencurrenthash=file" ]; then current_hash=file"];thencurrenth​ash=(openssl dgst -sha256 "$file" | awk '{print 2}') if [ "sha" != "$current_hash" ]; then
echo "تم اكتشاف ملف تالف: file"migrationerrors=file" migration_errors=file"migratione​rrors=((migration_errors + 1))
fi
fi
done < .lore_migration_manifest

if [ $migration_errors -eq 0 ]; then
    echo "اكتمل الترحيل. تم استعادة جميع البيانات بسلامة 100%."
    rm .lore_migration_manifest
else
    echo "فشل التحقق: هناك مشاكل في سلامة $migration_errors ملفات."
    exit 1
fi

fi

`

افتح المحطة الطرفية (Terminal) واحفظ المحتوى أعلاه باسم migrate.sh. بعد منح إذن التنفيذ باستخدام أمر chmod +x migrate.sh وتعديل المتغيرات لتناسب مساراتك المحلية، يمكنك تنفيذه.

بمجرد الانتهاء من هذه المهمة، سينخفض استخدام تخزين LFS السحابي البعيد على الفور. وفقاً لحالات الاعتماد الفعلية في Epic Games، يمكن لتقنية إزالة تكرار البيانات على مستوى الكتل خفض تكاليف صيانة البنية التحتية بنسبة 50%.


2. تطبيق الاسترداد عند الطلب (On-demand Hydration) في خط أنابيب CI/CD

خطوط الأنابيب التي تقوم بتنزيل مئات الجيجابايت من أصول اللعبة بالكامل في كل دورة بناء هي السبب الرئيسي لإتلاف بطاقات الشبكة وإدخال/إخراج القرص. تدعم Lore الاسترداد عند الطلب (On-demand Hydration) القائم على نظام الملفات الافتراضي لتقليل وقت البناء.

في مرحلة الاستنساخ الأولى (Clone)، يتم نسخ سلسلة هيكل البيانات الوصفية وشجرة الدليل فقط كقشرة خارجية، وعندما يقرأ المترجم الأصول الفعلية أثناء عملية الطهي (Cook)، يتم بث أجزاء الملفات الثنائية اللازمة فقط ديناميكياً لتعبئتها على القرص.

`yaml
name: Game Project On-Demand Production Build

on:
push:
branches: [ release-candidate ]

env:
LORE_SERVER: "lore://10.0.1.50:41337/game-depot"
SHARED_STORE_PATH: "/var/lib/lore_shared_chunk_store"
WORKSPACE_PATH: "game_build_workspace"

jobs:
assemble-assets:
runs-on: self-hosted
steps:
- name: Persistent Shared Store 준비
run: |
if [ ! -d "env.SHAREDSTOREPATH"];thensudomkdir−p"{{ env.SHARED_STORE_PATH }}" ]; then sudo mkdir -p "env.SHAREDS​TOREP​ATH"];thensudomkdir−p"{{ env.SHARED_STORE_PATH }}"
sudo chmod 777 "env.SHAREDSTOREPATH"loreshared−storecreate"{{ env.SHARED_STORE_PATH }}" lore shared-store create "env.SHAREDS​TOREP​ATH"loreshared−storecreate"{{ env.SHARED_STORE_PATH }}"
fi

  - name: Shared Cache를 경유한 Sparse Bare Clone
    run: |
      lore clone \
        --bare \
        --use-shared-store \
        --shared-store-path "${{ env.SHARED_STORE_PATH }}" \
        "${{ env.LORE_SERVER }}" \
        "${{ env.WORKSPACE_PATH }}"

  - name: 뷰 필터를 통한 불필요한 시네마틱 소스 제외
    run: |
      cd "${{ env.WORKSPACE_PATH }}"
      echo "+ /SourceCode/" > .lore/view
      echo "+ /Config/" >> .lore/view
      echo "+ /Content/Core_Assets/" >> .lore/view
      echo "- /Content/Cinematic_RAW/" >> .lore/view

  - name: 필수 청크만 로컬 디스크에 동기화
    run: |
      cd "${{ env.WORKSPACE_PATH }}"
      lore sync

  - name: Unreal Engine Cooker 실행
    run: |
      cd "${{ env.WORKSPACE_PATH }}"
      ./RunUAT.sh BuildCookRun \
        -project="$(pwd)/GameProject.uproject" \
        -platform=Win64 \
        -clientconfig=Development \
        -cook -stage -pak -archive

`

يتم تحقيق أقصى قدر من الفعالية عند توفير مخزن ذاكرة تخزين مؤقت دائم مثل /var/lib/lore_shared_chunk_store على خادم البناء. بعد جلب معلومات الفهرس بسرعة باستخدام أمر lore clone --bare، نترك فقط المسارات الضرورية في ملف التصفية .lore/view ثم نشغل lore sync. من خلال ترسيخ هذا الهيكل، يختفي أكثر من 85% من حركة المرور المرسلة إلى عقدة البناء. ويتم تقليل وقت البناء الإجمالي بنسبة 30% في المتوسط.


3. منع تضارب الأصول باستخدام نظام قفل الملفات

لا يمكن دمج الأصول الثنائية مثل .uasset في Unreal Engine أو ملفات خريطة المستوى تلقائياً في الفرع الرئيسي مثل تعليمات البرمجية النصية. إذا قام فنانان بتعديل نفس الأصل في وقت واحد، فسيحدث حادث حيث يقوم الفنان الذي قام بالدفع لاحقاً بالكتابة فوق عمل الشخص السابق أو التسبب في تشابك الخط الزمني.

توفر Lore ميزة القفل (Lock) التي تنفذ التحكم الحصري بناءً على السجل غير القابل للتغيير للخادم البعيد.

`bash

طلب صلاحية تحرير حصرية لملف نموذج شخصية ثنائي معين

lore lock acquire Content/Characters/HeroMesh.uasset --branch main

التحقق من حالة قفل الموارد تحت مجلد معين

lore lock status Content/Characters/HeroMesh.uasset

البحث عن جميع الملفات التي قفلها عامل معين في المستودع البعيد

lore lock query --branch main --owner developer_artist_03

إرجاع الصلاحية بعد اكتمال العمل والدفع

lore lock release Content/Characters/HeroMesh.uasset --branch main

`

يجب وضع قاعدة تجعل الفنانين يطلبون القفل باستخدام أمر lore lock acquire قبل لمس الملفات. بمجرد انتهاء التعديل وانعكاس الالتزام والدفع على الموقع البعيد، يتم تحرير القفل باستخدام lore lock release لتسليمه إلى العامل التالي.

إذا كان المخططون والفنانون يجدون أوامر المحطة الطرفية غير مألوفة، فيمكن ربط تلك المسارات بأدوات واجهة المستخدم الرسومية لسطح المكتب مثل Anchorpoint، بحيث يمكن تنفيذ أوامر القفل هذه بنقرة زر الماوس الأيمن.


4. دليل ضبط الذاكرة المؤقتة حسب مواصفات الأجهزة

يجب ضبط إعدادات العميل وفقاً لمواصفات بيئة العمل لمنع اختناقات الإدخال/الإخراج للملفات.

ضبط العميل المحلي حسب مواصفات جهاز العامل

  • الأنظمة عالية الأداء (NVMe SSD، ذاكرة وصول عشوائي 32 جيجابايت أو أكثر، وحدة معالجة مركزية متعددة النواة): السماح بالعمليات المباشرة القائمة على خرائط الذاكرة عبر تقنية تعيين الذاكرة الافتراضية لنظام التشغيل. قم بتوسيع سلاسل رسائل التنزيل المتوازية القصوى وحدد فترة احتفاظ طويلة لذاكرة التخزين المؤقت للقرص للتخلص من تأخير المزامنة.
  • أنظمة المبتدئين وأنظمة الفنانين (SATA SSD أو HDD، ذاكرة وصول عشوائي 16 جيجابايت أو أقل): قم بإيقاف تشغيل طريقة تعيين الذاكرة لمنع تعطل المحرك بسبب استنزاف الذاكرة. قم بتشغيل علامات --direct-file-write و --direct-file-io للكتابة مباشرة على القرص، وقم بزيادة الفاصل الزمني لجدول تجميع القمامة (Garbage Collection) لمنع حدوث ظاهرة احتلال القرص المفاجئة أثناء العمل.

تحليل الأداء بناءً على اختيار خوارزمية الضغط

بالرجوع إلى نتائج اجتماع تحديد بنية Lore (ADR-00016)، فإن ضبط معيار Zstandard Level 6 كمحرك ضغط افتراضي هو الأكثر توازناً من حيث الكفاءة.

نوع خوارزمية الضغط نسبة الضغط النهائي للبيانات (%) سرعة عملية الضغط (MiB/s) سرعة فك الضغط (MiB/s) القابلية للنقل والميزات
LZ4 Default 47.6% 718.7 2494.5 سرعة عالية ولكن إهدار كبير لمساحة التخزين
Zstd Level 1 34.5% 602.0 1363.1 نقطة توازن جيدة بين السرعة وحفظ المساحة
Zstd Level 6 (موصى به) 28.9% 136.5 1284.9 أفضل كفاءة معالجة مقارنة بتوفير المساحة
Oodle Kraken 3 (Fast) 28.2% 95.6 1413.1 يتطلب مكتبة Oodle الخاصة بـ Epic Games
Oodle Kraken 6 (الافتراضي السابق) 23.9% 2.2 1312.6 تنخفض السرعة بشدة عند الترحيل بالجيجابايت

كان Oodle Kraken Level 6، الذي كان يستخدم بشكل متكرر في الماضي، السبب الرئيسي لإطالة وقت انتظار الفنانين قبل المغادرة، حيث تنخفض سرعة معالجة الضغط أثناء عملية التسلسل (Serialization) في الخلفية إلى مستوى 2.2 MiB في الثانية.

في المقابل، يوفر Zstd Level 6 نسبة ضغط تقترب من Oodle Kraken 6، بينما سرعة ضغط كتل الأجزاء المحلية تصل إلى 136.5 MiB/s، وهي أسرع بحوالي 62 مرة. إذا كان هناك العديد من المكاتب الخارجية أو العاملين عن بعد مما يسبب تداخلاً في النطاق الترددي، ففكر في تكوين طبقة ثانية من طوبولوجيا الخادم لتكوين عقد ذاكرة تخزين مؤقت فرعية (Proxy edge cache) داخل الشبكة المحلية.