Table of Contents

چرا یک پلتفرم داستانی تعاملی بسازید؟

داستان سرایی تعاملی خوانندگان را به شرکت کنندگان تبدیل می کند، به آنها آژانس در مورد جهت طرح، تصمیم گیری شخصیت و ساخت جهانی می دهد.یک پلت فرم مبتنی بر جاوا اسکریپت به سازندگان امکان می دهد تا غنی، روایت های شاخه ای را بسازند که به طور کامل در مرورگر اجرا می شوند، هیچ سرور مورد نیاز نیست.

مفاهیم اصلی روایت های تعاملی

قبل از نوشتن یک خط کد، باید بلوک های ساختمانی بنیادی را که کار داستانی تعاملی را انجام می دهند، درک کنید: اجزای زیر ضروری هستند:

  • ساختار تاریخی: شاخه های غیر خطی (nodes) متصل با انتخاب. نمودار روایت می تواند یک درخت، یک نمودار یک دایره ای هدایت شده، و یا حتی اجازه می دهد حلقه (سفر یا بازدید).
  • کشور: متغیرهای ردیابی آمار بازیکن، موجودی، پرچم، و گره های بازدید شده، محتوای مشروط را هدایت می کنند و مسیرهای جدید را باز می کنند.
  • رابط کاربری: لایه ارائه - ارائه متن، دکمه های انتخاب، جاسازی رسانه ها باید پاسخگو و قابل دسترس باشد.
  • [FLT: 1 ] [FLT: 1 ] موتور که داده های داستان را تجزیه می کند، شرایط را ارزیابی می کند، انتقال را مدیریت می کند و پیشرفت (محلی یا شاخصDB) را ادامه می دهد.

بررسی استانداردهای موجود مانند سبزیجات فرمت های داستانی (Harlowe، SugarCube، Chapel) و ink زبان برای دیدن اینکه چگونه ابزارهای بالغ این مفاهیم را اداره می کنند، بهترین شیوه ها را می توان قرض کرد.

طراحی چارچوب داستانی

موتور داستان شما به یک مدل داده نیاز دارد که هم بیانی و هم آسان برای نویسنده است.یک طرح مبتنی بر JSON به خوبی برای پلتفرم های وب کار می کند.

معرفی یک گره

هر گره روایت (یا "passage") شامل:

  • [در این باره] [[[۱]] [۱۰] [۱] [۱] [۱۰]] [۳] [۳] [۳] [۳] [۱] [۳] [۱] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۱] [۳] [۳] [۱] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [۳] [
  • متن: آرایه ای از رشته ها یا محتوای مشابه (در یک مبدل HTML امن)
  • گزینه ها: مجموعه ای از گزینه ها، هر کدام با یک شناسه گره هدف، شرایط اختیاری و اثر اختیاری بر حالت.
  • (فَلَّهُمْهُمْهُمْهُمْهُمْهُمْهُمْهُمْهُمْهُمِهُمِهُوا مِنَهُمْهُمِهُوا مِنْمِنَهُمِهُمِهُوا مِنِهُوا مِنْهُمِنَا مِنْهُوا مِنْهُمْهُوا مِنْهُوا مِنْهُمْهُوا مِنْمْمِنْهُمْهُوا مِنْهُوَهُمْهُمْهُوا مِنْهُمَاَا مِنْهُمْهُمْهُمْهُوا مِنَاَهُمِنَهُمِنَاَهُمِنَهُوَهُوَهُوَهُوَهُوَهُوَ
  • در قسمت چپ و راست: هوک ها برای اجرای زبان های دلخواه جاوا اسکریپت (صدا، تغییرات تصویر، به روز رسانی آمار).
{
 "start": {
 "text": [
 "You stand at the edge of a dark forest.",
 "The wind carries a faint whisper."
 ],
 "tags": ["outdoor", "moody"],
 "choices": [
 { "text": "Enter the forest", "target": "forest_path",
 "effect": "playerStats.fear++" },
 { "text": "Turn back to the village", "target": "village_square",
 "condition": "player.hasCompass" }
 ]
 }
}

مدیریت دولت

متغیرهای دولتی در یک فروشگاه واکنشی زندگی می کنند.استفاده از یک شی ساده با گیرنده ها / نامه ها و یک سیستم اطلاع رسانی تغییر، بنابراین UI به طور خودکار در به روز رسانی های دولتی دوباره فعال می شود.

class StoryState {
 constructor(initialData) {
 this._state = { ...initialData };
 this._listeners = [];
 }
 get(key) { return this._state[key]; }
 set(key, value) {
 this._state[key] = value;
 this._notify();
 }
 subscribe(fn) { this._listeners.push(fn); }
 _notify() { this._listeners.forEach(fn => fn(this._state)); }
}

این الگو منطق داستان را از DOM جدا می کند و باعث می شود که پلت فرم قابل آزمایش و آسان گسترش یابد.

ساخت موتور جاوا اسکریپت

این موتور داده های داستانی (به صورت مداوم وارد شده یا به عنوان JSON) را می خواند و ناوبری را کنترل می کند: در اینجا یک پیاده سازی حداقل وجود دارد:

دانلود و ارائه یک گره

function renderNode(nodeId, storyData, state) {
 const node = storyData[nodeId];
 if (!node) throw new Error(`Node ${nodeId} not found`);

 // Run hooks before rendering
 if (node.onEnter) node.onEnter(state);

 const container = document.getElementById('story-content');
 container.innerHTML = ''; // Clear previous content

 // Render text paragraphs
 node.text.forEach(para => {
 const p = document.createElement('p');
 p.textContent = para; // Use a safe renderer for markdown
 container.appendChild(p);
 });

 // Render choices, filtered by conditions
 const choicesContainer = document.getElementById('choices');
 choicesContainer.innerHTML = '';
 node.choices.forEach(choice => {
 if (choice.condition && !evaluateCondition(choice.condition, state)) return;
 const btn = document.createElement('button');
 btn.textContent = choice.text;
 btn.addEventListener('click', () => {
 if (choice.effect) applyEffect(choice.effect, state);
 renderNode(choice.target, storyData, state);
 });
 choicesContainer.appendChild(btn);
 });

 // Run exit hooks
 if (node.onLeave) node.onLeave(state);
}

ارزیابی وضعیت

شرایط می تواند ساده مانند ارزیابی از طریق یک روان شناس بیان ایمن (avoid ) استفاده از یک تعریف سبک مانند ارزیابی شده است یا نوشتن یک cursive gravor که تنها اجازه می دهد متغیر و اپراتورهای اصلی هرگز نویسندگان کد سازی ناخواسته مگر اینکه شن و ماسه.

نجات و سرعت بخشیدن

از [FLT-7] برای ادامه حالت (از جمله گره های بازدید شده، گره فعلی و متغیرهای) استفاده کنید تا یک تابع خودکار را که پس از هر انتقال گره آتش می زند و یک ذخیره دستی / ذخیره سازی دستی.

function save(state, nodeId) {
 localStorage.setItem('story_save', JSON.stringify({
 state: state._state,
 current: nodeId,
 timestamp: Date.now()
 }));
}

function load() {
 const raw = localStorage.getItem('story_save');
 if (!raw) return null;
 return JSON.parse(raw);
}

برای داستان های بزرگتر، IndexedDB را در نظر بگیرید تا دارایی های باینری مانند تصاویر یا قطعات صوتی را ذخیره کند.

قابلیت User Experience

رابط متن و دکمه های اساسی کار می کند، اما مخاطبان مدرن انتظار طراحی چند رسانه ای، پاسخگو و دسترسی دارند.

ادغام رسانه ها

  • Images: از تگ هایی که از طریق انتقال CSS محو می شوند، استفاده از تصاویر خط در متن داستان با استفاده از یک الگو مانند توسط رندر کننده.
  • Audio: حلقه های محیط پس و اثرات صوتی ایجاد شده توسط [FLT 11] قلاب استفاده از Web Audio API برای پخش کم و کنترل حجم.
  • ویدئو: کلیپ های سینمایی کوتاه برای صحنه های کلیدی.محافظه از طریق با کنترل و یا خودکار پخش (با فعال سازی حرکت کاربر).

قابلیت های پاسخگو و قابل دسترسی UI

  • از HTML معنایی استفاده کنید: [FLT13] برای انتخاب، برای موجودی یا log نوار.
  • ویژگی های ARIA را اضافه کنید: [FLT16] برای به روز رسانی های متنی پویا در ظروف انتخابی.
  • پشتیبانی از ناوبری صفحه کلید: از طریق انتخاب، وارد شوید تا تمرکز غیر قابل تقسیم بر انتخاب های پنهان.
  • سیستم مسابقه با پرس و جو رسانه های CSS.

معماری مبتنی بر جزء (اختیاری)

اگر قصد دارید یک چارچوب دید مانند React یا Vue را در نظر بگیرید، آنها مدیریت دولتی را ساده می کنند و دوباره به اشتراک می گذارند.برای داستان تعاملی، یک ماشین دولتی نامحدود] [به عنوان مثال، X State می تواند نمودار داستان پیچیده با نگهبانان، اقدامات و دولت های موازی را مدل سازی کند.

ویژگی های پیشرفته

برای متمایز کردن پلت فرم خود، قابلیت هایی را که نویسندگان و بازیکنان تمایل دارند، اضافه کنید.

چند شاخه و فرمت؛ متغیرهای

فراتر از جفت های ساده انتخاب، اجازه دهید:

  • [[۱] [۱۰] متن متن متن: [۱۰] پاراگراف های مختلف بر اساس حالت (به عنوان مثال، شما هشدار پیرمرد را به یاد دارید، تنها در صورتی که [FLT 19]
  • ] آمار و ارقام فساد و زیان آور: [ [FLT 1 ] انتخاب بر صفات مانند شجاعت، اعتماد یا سحر و جادو تاثیر می گذارد.
  • [[۱] [۱۰]: [[۱]] فهرست مواردی که انتخاب ها یا مصرف اقلام نیاز دارند.
  • پرچم جهانی: متغیرهای بولانی که اعمال گذشته را ثبت کرده و شاخه های جدید را باز می کنند.

عدم هدایت

اجازه دهید دکمه های "back"، انتخاب فصل یا یک دیدگاه نقشه ای را پیاده سازی کنید.یک پشته تاریخ از گره های بازدید شده را پیاده سازی کنید تا بازیکنان بتوانند بدون از دست دادن حالت، به قسمت های دیگر مراجعه کنند (اما اگر انتخاب ها اثرات دائمی داشته باشند، از پارادوکس ها استفاده کنند).

زمان واقعی نویسنده

برای یک ابزار نویسنده مبتنی بر وب، از WebSockets (یا خدماتی مانند Firebase) استفاده کنید تا نویسندگان چندگانه به طور همزمان یک نمودار داستانی را ویرایش کنند. پلت فرم مقاله می تواند گسترش یابد تا یک ویرایشگر بصری با گره های کشیدن و رها کردن را شامل شود.

تست و دبوش

داستان های تعاملی دارای شمارش مسیر نمایی هستند. تست دستی غیر ممکن است؛ شما به ابزارهای خودکار نیاز دارید.

تست های Unit

ارزیابی وضعیت آزمون، جهش های دولتی و بارگیری گره با Jest یا Mocha. Mock DOM و LocalStorage.

test('renderNode shows correct text for start node', () => {
 document.body.innerHTML = `
`; const storyData = { start: { text: ['Hello'], choices: [] } }; const state = new StoryState({}); renderNode('start', storyData, state); expect(document.getElementById('story-content').innerHTML).toContain('Hello'); });

پوشش گراف

یک اسکریپت بنویسید که تمام گره های قابل دسترس را از ابتدا عبور می کند، جمع آوری تغییرات دولتی را تضمین می کند که هر گره حداقل یک مسیر برای تکمیل دارد (گوست پایانی) که پرچم مرده یا گره های یتیم است.

دسترسی به حسابرسی

بررسی های خودکار محور در خط لوله CI خود را با خوانندگان صفحه نمایش (NVDA، VoiceOver) و اطمینان از کنتراست رنگ با استانداردهای WCAG 2.1 AA مطابقت دارد.

اجرای بستر

یک سایت استاتیک که از طریق CDN ارائه می شود، ایده آل برای داستان های تعاملی است. No backend به معنی هزینه های پایین تر و میزبانی ساده تر است.

ساخت خط لوله

  • از یک بسته (Vite یا Webpack) برای بسته بندی موتور، داده های داستانی و دارایی ها استفاده کنید.
  • فصل های داستانی لودوز اگر JSON بزرگ باشد (به چندین فایل متصل می شود).
  • یک کارمند خدمات آفلاین را به کار ببرید تا بازیکنان بتوانند بدون اینترنت به آن ادامه دهند.

Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics Analytics

تجزیه و تحلیل حریم خصوصی دوستانه (به عنوان مثال، Plausible، امت) را یکپارچه کنید تا ببینید کدام انتخاب ها محبوب، نقاط کشویی و زمان بازی به طور متوسط استفاده از این داده ها برای اصلاح داستان است.

مطالعه موردی: یک داستان ترسناک ساده

تصور کنید یک دموی دو گره که موتور کامل را در عمل نشان می دهد، گره شروع یک انتخاب را ارائه می دهد: وارد خانه خالی شده یا فرار کنید، انتخاب یک پرچم (FLT:21) را انتخاب کنید و منجر به گره با یک تصویر ترسناک پرش می شود. بازیکن می تواند عقب نشینی کند یا ادامه دهد.این مثال کوچک انتقال حالت را تأیید می کند، بارگذاری رسانه ها و ذخیره / بارگیری.

نتیجه گیری

ساخت یک پلت فرم داستان سرایی تعاملی مبتنی بر جاوا اسکریپت یک پروژه ارزشمند است که طراحی روایت، مهندسی نرم افزار و تجربه کاربر را ترکیب می کند.با مدل سازی ساختار داستان به عنوان یک نمودار، پیاده سازی یک موتور دولتی واکنشی، و تمرکز بر دسترسی و ادغام رسانه ها، شما می توانید یک ابزار ایجاد کنید که هر کسی را قادر می سازد تا داستان های شاخه ای را ایجاد کند. شروع کوچک، آن را با نویسندگان واقعی، و پلت فرم شما به عنوان منبع باز برای رشد یک داستان سرایت می کند.