কোয়েস্ট আর্কিটেকচার
কোনও স্ক্রিপ্ট নেই। লজিক আছে: কীভাবে নোড এবং ভেরিয়েবলগুলো Romergo-এ সাজানো হয়েছে
যখন গেম এডিটরে লজিকের কথা বলা হয়, সাধারণত দ্রুতই স্ক্রিপ্টের দিকে চলে যায়। কোথাও লেখক JavaScript লিখে, কোথাও Python, আবার কোথাও নিজের ইঞ্জিনের ভাষা শিখছেন। এটি প্রায় অসীম স্বাধীনতা দেয়, কিন্তু এর সঙ্গে আসে সিনট্যাক্স ত্রুটি, আটকে থাকা লুপ, অসংগতিপূর্ণ প্লাগইন এবং এমন কোড যা ছয় মাস পরে তার নিজের লেখকও দেখতে ভয় পায়।
আমি Romergo-এ ভিন্ন পথে গিয়েছিলাম। কুইজের ভিতরে কোনো স্বতঃস্ফূর্ত স্ক্রিপ্ট নেই। কোনো ফাংশন প্রবেশ করানো, নেটওয়ার্ক অনুরোধ করা বা প্লেয়ারের সরাসরি অ্যাক্সেস করা সম্ভব নয়। পরিবর্তে, গল্পটি সীমিত, কিন্তু যথেষ্ট প্রকাশযোগ্য সেট থেকে তৈরি হয়: লজিক্যাল নোড, ভেরিয়েবল, শর্ত এবং প্রভাব।
এটি অর্থ নয় যে Romergo-এ কেবল সাধারণ বিভাজনই করা যায়। খেলোয়াড়ের সিদ্ধান্ত মনে রাখা, পয়েন্ট গণনা করা, বিকল্প খুলতে এবং লুকানো, পরবর্তী অধ্যায়ে বিভিন্ন পথ নির্বাচন করা, র্যান্ডম ইভেন্ট তৈরি করা এবং ইন্টারেক্টিভ ইন্টারফেস তৈরি করা সম্ভব। কেবলমাত্র 'এই কোডটি চালাও' কমান্ডের পরিবর্তে লেখক বর্ণনা দেন 'এই অবস্থায় এটি ঘটতে হবে'।
গ্রাফ ইতিমধ্যেই একটি প্রোগ্রাম
Romergo-এর সবচেয়ে মৌলিক লজিক সরাসরি প্রধান মানচিত্রে রয়েছে। দৃশ্যগুলো সংযোগ পায় ট্রানজিশনের মাধ্যমে, এবং বিশেষ নোড নির্ধারণ করে যে খেলা কোথায় যাবে।
যদি খুব সরলীকৃত করি, ছোট একটি কুয়েস্টটি এভাবে দেখায়:
শুরু
↓
রক্ষকের সঙ্গে কথোপকথন
↓
পাস আছে?
├─ হ্যাঁ → বন্ধ আর্কাইভ
└─ না → বিকল্প পথ
এটি ইতিমধ্যেই কার্যকরী লজিক। Player স্টার্ট নোডে প্রবেশ করে, দৃশ্য দেখায়, ইতিহাসের অবস্থা পড়ে এবং উপযুক্ত ট্রানজিশন বেছে নেয়। লেখক একই পথকে একটি সহজবোধ্য মানচিত্র হিসাবে দেখে, if, goto এবং সার্ভিস আইডেন্টিফায়ারের সমষ্টি হিসাবে নয়।

*বাস্তব Flow-এর অংশ Builder-এ: Final Accusation দৃশ্যটি Switch-এ সিদ্ধান্ত পৌঁছে দেয়, তারপর কিছু If / Else অবস্থার পরীক্ষা করে এবং গল্পটি বিভিন্ন সমাপ্তির দিকে নিয়ে যায়। নিচের খোলা Logic প্যানেলটি সমস্ত উপলব্ধ সেট দেখায়: Dead End, Checkpoint, If / Else, Switch, Random এবং Teleport।*
লজিক প্যানেলে এখন ছয়টি প্রধান নোড আছে:
- **গেমের শেষ** বর্তমান রুটটি বন্ধ করে। এটি পরাজয়, খারাপ সমাপ্তি বা শুধু ইচ্ছাকৃতভাবে বন্ধ করা একটি ফল হতে পারে।
- **চেকপয়েন্ট** এই স্থানে অবস্থান সংরক্ষণ করে এবং নতুন রিটার্ন ইতিহাস শুরু করে। খেলোয়াড় চেকপয়েন্টে ফিরে যেতে পারবে, কিন্তু এর আগে ফিরে যেতে পারবে না।
- **যদি / নাহ** একটি নিয়ম পরীক্ষা করে। সত্যি অবস্থান মিলিত শর্ত অনুসরণ করে, মিথ্যা অবস্থান ব্যাকআপ রুট হিসেবে থাকে।
- **সুইচ** বেশি দুটি বিকল্প থাকলে উপযুক্ত। এর শাখাগুলি উপরের দিকে থেকে পরীক্ষা করা হয়: প্রথম মিলিত শর্তে কাজ করে, এবং শাখার শর্ত না থাকলে এটি ডিফল্ট বিকল্প হয়ে যায়।
- **যাদৃচ্ছিক** সংযুক্ত আউটপুটগুলির মধ্যে একটি বেছে নেয়। যাদৃচ্ছিকতার অবস্থাটি seed এবং পদক্ষেপ সংরক্ষণ রাখে, তাই সংরক্ষণ পুনরুদ্ধার করা সম্ভব, খেলোয়াড়কে অন্য রুটে এলোমেলো নিক্ষেপ করা ছাড়া।
- **টেলিপোর্ট** নিজে কিছু সিদ্ধান্ত নেয় না। এটি দীর্ঘ ভিজ্যুয়াল সংযোগটি বিচ্ছিন্ন করতে এবং বড় মানচিত্রের দূরের অংশগুলি সুন্দরভাবে সংযুক্ত করতে সাহায্য করে।
স্টার্ট এবং ফিনিশ অধ্যায়ের ফ্রেম দেয়, সাধারণ দৃশ্যগুলি বিষয়বস্তু প্রদর্শন করে, এবং লজিক্যাল নোডগুলি সেগুলিকে রুটে পরিণত করে। এই স্তরে ইতিমধ্যেই একটি লিনিয়ার গল্প, শাখা, কয়েকটি সমাপ্তি, যাদৃচ্ছিক ঘটনা এবং একটি নিরাপদ রিটার্ন পয়েন্ট তৈরি করা যায় — একটি স্ক্রিপ্টের লাইনও ছাড়া।
ভেরিয়েবল হল ইতিহাসের স্মৃতি
একটি গ্রাফ যথেষ্ট নয়, যদি ইতিহাসকে মনে রাখতে হয় যে আগে কী ঘটেছিল। এজন্য কুইস্টে তিনটি সাধারণ ধরণের ভেরিয়েবল রয়েছে:
booleanএকটি তথ্য সংরক্ষণ করে: চাবি পাওয়া গেছে কিনা, নায়ক কি মিথ্যা বলেছে, সতর্কতা সক্রিয় হয়েছে কিনা;numberএকটি সংখ্যা সংরক্ষণ করে: বিশ্বাস, স্বাস্থ্য, প্রমাণের পরিমাণ বা খ্যাতি পয়েন্ট;stringনির্বাচিত মান সংরক্ষণ করে: রুটের নাম, ফ্র্যాక్షন বা সমাধানের কোড।
প্রতিটি ভ্যারিয়েবলের একটি কী আছে, লেখকের জন্য একটি বোঝার মতো লেবেল এবং একটি প্রাথমিক মান। সংখ্যাগত ভ্যারিয়েবলের জন্য অতিরিক্তভাবে ন্যূনতম এবং সর্বাধিক মান উল্লেখ করা যেতে পারে, আর সেবামূলক ভ্যারিয়েবলটি খেলোয়াড়ের স্টেট প্যানেল থেকে লুকানো বা শুধুমাত্র শর্ত পূরণের সময় প্রদর্শন করা যেতে পারে।
এখানের মূল বিষয় হলো ভ্যারিয়েবলগুলি পুরো কাহিনীর জন্য প্রযোজ্য, শুধুমাত্র একটি দৃশ্যের জন্য নয়। যদি খেলোয়াড় প্রথম অধ্যায়ে অনুমতি পায়, তবে চতুর্থ অধ্যায়ে একই ফ্ল্যাগ পরীক্ষা করা যায়। ফিনিশের মধ্য দিয়ে পরবর্তী অধ্যায়ে যাওয়ার সময় অবস্থা শূন্যে প্রেরণ করা হয় না। এটি নির্বাচিত বিকল্প, প্রয়োগ করা প্রভাব, চেকপয়েন্ট এবং বর্তমান রেন্ডমিটি ধাপের সাথে সংরক্ষিত থাকে।
ফলস্বরূপ সহজ লেখকের চক্র পাওয়া যায়:
খেলোয়াড়ের পছন্দ মানটি সংরক্ষণ করে
↓
ভেরিয়েবল অবস্থাটি রাখে
↓
শর্ত পরে এটি পড়ে
↓
গ্রাফ, দৃশ্য বা ইন্টারফেস প্রতিক্রিয়া দেখায়
উদাহরণস্বরূপ, প্রথম দৃশ্যে "পাওয়া ছবি দেখাও" পছন্দটি portrait_revealed = true সেট করতে পারে। পরে **যদি / অন্যথায়** নোড এই ফ্ল্যাগটি পরীক্ষা করবে এবং নতুন কথোপকথনের দৃশ্য খুলবে। আরো পরে টার্মিনাল ইন্টারফেস শুধুমাত্র সেই খেলোয়াড়দের জন্য অতিরিক্ত এন্ট্রি দেখাবে যারা ছবিটি উন্মোচন করেছে।
একটি ভেরিয়েবল তিনটি ভিন্ন কুইস্টের অংশকে সংযুক্ত করে। এর জন্য দৃশ্য বা অধ্যায়গুলোর মধ্যে মান ম্যানুয়ালি স্থানান্তর করার প্রয়োজন নেই: তারা একই সাধারণ প্রগতি অবস্থাকে পড়ে।

*ভেরিয়েবল route-এর একটি কার্ডে স্থায়ী কী, বোঝার মতো নাম, মানের ধরন এবং অবস্থার দৃশ্যমানতা নির্ধারিত আছে। পছন্দ এবং শাখার সংযোগ একই পৃষ্ঠার নীচে রয়েছে।*
পছন্দ লেখে, শাখা পড়ে
সাধারণ দৃশ্যে, অবস্থার পরিবর্তনের সবচেয়ে স্পষ্ট উপায় হল বিকল্প নির্বাচনে একটি ইফেক্ট যোগ করা। ভিজ্যুয়াল এডিটরে এটি নিম্নরূপ দেখতে হয়:
«মারির উপর বিশ্বাস করা» → ally = "mary"
«একাই চলে যাওয়া» → ally = "none"
এরপর Switch খেলোয়াড়কে প্রয়োজনীয় দৃশ্যে ally মানের মাধ্যমে পাঠাতে পারে। ভেরিয়েবল পৃষ্ঠাটি আলাদাভাবে দেখায়, কোন নির্বাচনের মাধ্যমে ভেরিয়েবলটি লেখা হয় এবং কোন শাখাগুলো এটি পড়ে। এটি একটি ছোট খুঁটিনাটি, তবে বড় কুয়েস্টে এটি দশকের বেশী দৃশ্যের মধ্যে ব্যথাদায়ক খোঁজ প্রতিস্থাপন করে।

*Switch শাখাগুলি উপরে থেকে নিচে পরীক্ষা করা হয়। এই উদাহরণে Laboratory রুট route = lab-এ সক্রিয় হয়, এবং Habitat route = habitat-এ।*
শর্তগুলি সাধারণ তুলনাগুলি সমর্থন করে:
- সমান এবং অসমান;
- বড়, বড় বা সমান;
- ছোট, ছোট বা সমান;
- মান রয়েছে বা এখনও তৈরি হয়নি।
সাধারণ ক্ষেত্রে লেখক সরাসরি If / Else বা Switch সেটিংসে ভেরিয়েবল, অপারেটর এবং মান নির্বাচন করে। আরও জটিল লজিকের জন্য, সাধারণ runtime বোঝে **সমস্ত শর্ত**, **যেকোনো শর্ত** এবং বর্জনকারী গ্রুপগুলি।
এমন নিয়মটি কাঠামোগতভাবে এইভাবে বর্ণনা করা যায়:
{
"op": "all",
"conditions": [
{ "op": "gte", "key": "evidence", "value": 3 },
{ "op": "eq", "key": "alarm_active", "value": false }
]
}
এটি একটি ছোট স্ক্রিপ্টের মত দেখায়, তবে মূলত এটি স্ক্রিপ্ট নয়। এখানে কোনো ফাংশন কল করা বা আকস্মিক কিছু পরিবর্তন করা যায় না। Romergo পূর্বেই সমস্ত বৈধ অপারেশন জানে, কাঠামো পরীক্ষা করে এবং Builder প্রিভিউতে এবং প্রকাশিত Player-এ একইভাবে সম্পাদন করে।
প্রভাব: প্রোগ্রামিং ভাষা ছাড়া ছোট কমান্ড
শর্তটি অবস্থা পড়ে, এবং প্রভাব এটি পরিবর্তন করে। Runtime Romergo কয়েকটি পরমাণু অপারেশন সমর্থন করে:
setএকটি নির্দিষ্ট মান লিখে;incএবংdecসংখ্যা বাড়ায় বা কমায়;toggleলজিক্যাল ফ্ল্যাগ সুইচ করে;clampসংখ্যাটিকে নির্ধারিত সীমার মধ্যে রাখে।
সাধারণ সিলেকশন ইন্সপেক্টরে মূল দৃশ্যটি ইচ্ছাকৃতভাবে সহজ: একটি ভেরিয়েবল নির্বাচন করুন এবং set এর মাধ্যমে নতুন মান লিখুন। উন্নত লজিক ইন্টারফেস দৃশ্যে শর্ত এবং প্রভাব পরীক্ষা করা যায় এমন স্ট্রাকচার হিসাবে নির্ধারণ করা যায়। উদাহরণস্বরূপ, টার্মিনালের অবস্থার মধ্যে পরিবর্তন একই সময়ে সিদ্ধান্ত মনে রাখতে পারে, সাক্ষ্য যোগ করতে পারে এবং সতর্কতা চালু করতে পারে:

*প্রভাব সরাসরি উত্তর বিকল্পের সাথে সংযুক্ত: তিনটি নির্বাচন route-এ lab, habitat এবং server মানগুলি লিখে। পরিবর্তনশীল ক্ষেত্র এবং নতুন মান সংক্ষিপ্ত পরিদর্শকের মধ্যে পৃথক থাকে।*
[
{ "op": "set", "key": "terminal_decision", "value": "cut-power" },
{ "op": "inc", "key": "evidence", "amount": 1 },
{ "op": "toggle", "key": "alarm_active" }
]
এভাবে কাজ করার একটি গুরুত্বপূর্ণ সীমাবদ্ধতা রয়েছে: এটি ব্যতিরেকে যে কোনও সূত্রের গণক নয়। evidence * trust / 2 লেখা, চক্র চালানো বা নিজের ফাংশন তৈরি করা সম্ভব নয়। জটিল আচরণ কয়েকটি স্পষ্ট ধাপ থেকে তৈরি হয়, এবং লজিক সম্প্রসারণ নতুন যাচাইকৃত অপারেশন runtime-এর মাধ্যমে করা হয়, অজানা কোড চালানোর মাধ্যমে নয়।
লেখকের জন্য এটি কিছুটা কম সীমাহীন, তবে গল্পটি পূর্বানুমেয় থাকে। একই প্রভাবগুলোর পরীক্ষা প্রকাশনার আগে করা যায়, সংরক্ষণ করা যায়, খেলোয়াড়দের মধ্যে সমন্বয় করা যায় এবং অগ্রগতি পুনরায় লোড করার পর পুনরায় চালানো যায়।
কেন লজিক নোডের ভিতরে এখনো আরেকটি Flow নেই
সব পূর্বানুমেয়তার মধ্যে বর্তমান পদ্ধতির একটি স্পষ্ট অসুবিধা আছে: অভিজ্ঞতা ছাড়া একজন মানুষের জন্য 'ভেরিয়েবল — অপারেটর — মান' ফর্মটি ইতিমধ্যেই প্রোগ্রামিং মনে হতে পারে। আর যখন পাশে শর্তের গ্রুপ এবং একাধিক প্রভাব আসে, তখন ডিক্লারেটিভ কাঠামো Player-এর জন্য নিরাপদ থাকে, কিন্তু লেখকের জন্য সহজ হয়ে ওঠার নিশ্চয়তা নেই।
এটি স্বাভাবিক মনে হয় একদিন ভিজ্যুয়াল নোড এবং লগিকের ভিতরে পর্যন্ত পৌঁছানো। শর্তগুলোর তালিকার পরিবর্তে, ব্লকগুলোর **এবং**, **অথবা**, **না**, ভেরিয়েবলের তুলনা এবং মান পরিবর্তন সংযুক্ত করা যায়। কাগজে এটি পাঠ্য বা JSON এর চেয়ে বন্ধুসুলভ দেখায়।
কিন্তু তারপর আমি বাস্তব পরিস্থিতি কল্পনা করি: লেখক চ্যাপ্টারের মানচিত্রে একটি লগিক নোড খুলে, এবং তার ভিতরে আরেকটি Flow খুঁজে পায় যার নিজস্ব নোড এবং সংযোগ রয়েছে। ফলে গ্রাফের ভিতরে গ্রাফ তৈরি হয়। বুঝতে হবে তুমি এখন কোথায় আছ, কিভাবে গল্পের স্তরে ফিরে যেতে হবে এবং কোন দুটি Flow এর মধ্যে ভুল খুঁজতে হবে। নতুনদের জন্য এমন নেস্টিং বর্তমান ফর্মের চেয়ে ভয়ানক হতে পারে।
সুতরাং আপাতত সমঝোতা ব্যবহৃত হচ্ছে। গল্পের রুট ভিজ্যুয়ালভাবে থাকে, আর নোডের ভিতরের শর্ত এবং প্রভাবগুলো কমপ্যাক্ট, স্পষ্ট ফিল্ডে দেখানো হয়। এটা কাজ করে, কিন্তু আমি মনে করি না যে ইন্টারফেস চূড়ান্তভাবে সমাধান হয়েছে। হতে পারে, পরে আরও বোঝার মতো সমন্বয় দেখা দেবে প্রস্তুত টেমপ্লেট, ধাপে ধাপে কনফিগারেশন এবং ভিজ্যুয়াল ব্লকের — এমন কিছু যা সত্যিই জটিলতা কমাবে, শুধুমাত্র এটিকে অন্য একটি এডিটরে স্থানান্তর করবে না।
লজিক শুধু মানচিত্রে থাকে না
ইন্টারফেস দৃশ্যগুলি একই অবস্থার ব্যবহার করে। উইজেট, বার্তা, উত্তর বিকল্প, কাজ, বিজ্ঞপ্তি বা মিডিয়াপ্লে কেবল showWhen মিললে প্রদর্শিত হতে পারে। মেট্রিক মান একটি ভেরিয়েবলের সাথে যুক্ত করা যেতে পারে, এবং উইজেটের অবস্থার মধ্যে স্থানান্তর — বিলম্বের পর, শর্তে বা খেলোয়াড়ের ক্রিয়ার পরে চালানো যেতে পারে।
উদাহরণস্বরূপ, বোর্ড কম্পিউটারের স্ক্রিনটি এইভাবে আচরণ করতে পারে:
1. প্রথমে কেবল একটি লক করা টার্মিনাল দেখা যায়।
2. খেলোয়াড়ের পছন্দের পরে প্রভাব terminal_unlocked = true স্থাপন করে।
3. শর্তটি জাহাজের স্কিমা এবং নতুন বাটন খুলে।
4. বাটনে চাপ দেওয়া উইজেটের অবস্থা পরিবর্তন করে এবং evidence বাড়ায়।
5. যখন evidence >= 3, একটি গোপন নোটিফিকেশন প্রদর্শিত হয় এবং একটি নতুন কুইস্ট শাখা কার্যকর হয়।
চ্যাপ্টারের মানচিত্র, সাধারণ নির্বাচন এবং ইন্টারঅ্যাকটিভ ইন্টারফেস তিনটি পৃথক সিস্টেম তৈরি করে না। তারা একটি স্টেট অবজেক্ট পড়ে এবং পরিবর্তন করে। তাই ডায়ালগে পাওয়া ক্লু ইন্টারফেসের একটি উপাদান খুলতে পারে, এবং ইন্টারফেসের ভিতরে একটি কাজ পরবর্তী দৃশ্য পরিবর্তন করতে পারে।
এখানেই ডেক্লারেটিভ লজিক আসল প্রোগ্রামিং হিসেবে অনুভূত হওয়া শুরু করে। ফাইল, ফাংশন এবং ইভেন্ট বাসের পরিবর্তে, লেখক ইতিহাসের সহজবোধ্য সত্তাগুলি নিয়ে কাজ করেন: ঘটনা, নির্বাচন, শর্ত এবং পরিবর্তন।
কেন আমি ইচ্ছাকৃতভাবে যেকোনো JavaScript যোগ করছি না
স্ক্রিপ্ট সন্নিবেশ করার সম্ভাবনা যে কোনো নতুন মেকানিকের জন্য সবচেয়ে ছোট পথ মনে হয়। কিন্তু একবার প্রকাশিত কুয়েস্টটি যেকোনো কোড চালানোর অধিকার পেলে, পুরো পণ্যের মডেল পরিবর্তিত হয়।
এই কোডের জন্য কোন ব্রাউজার APIগুলো ব্যবহারযোগ্য তা নির্ধারণ করতে হবে, নেটওয়ার্ক এবং স্টোরেজকে কীভাবে সীমিত করতে হবে তা, অসীম লুপগুলোর ক্ষেত্রে কী করা উচিত তা, কুইস্টকে অফলাইন কিভাবে স্থানান্তর করা যায় তা, এটি একত্রিত খেলার সময় কীভাবে সিঙ্ক্রোনাইজ করা যায় তা এবং পুরনো প্রকল্পটি আপডেটের পরেও কিভাবে কাজ করবে তা নিশ্চিত করতে হবে।
ঘোষণামূলক নিয়ম যে কোনো সাধারণ ফাংশনের তুলনায় অনেক বেশি নীরস — এবং ঠিক এজন্যই এটি আরও নির্ভরযোগ্য। এটি রান করার আগে ভ্যালিডেশন করা যায়। বোঝা যায় কোন ভেরিয়েবলগুলো এটি পড়ে এবং লিখে। চেইনের মাঝপথে নিরাপদভাবে প্রগতি সংরক্ষণ করা যেতে পারে। কুইস্টকে একইভাবে ব্রাউজার, স্বতন্ত্র বিল্ড এবং এমবেডেড Player-এ কার্যকর করা যায়।
সীমিত শব্দকোষ এখানে যুক্তিকে বাধা দেয় না, বরং তার সীমা নির্ধারণ করে। যদি সত্যিই কোনো ব্যবহারযোগ্য অপারেশন উপস্থিত হয়, তবে এটি সাধারণ runtime তে যোগ করাই উত্তম এবং সকল লেখকের জন্য একই পরীক্ষিত কার্যকারিতা দেওয়া উত্তম, পরিবর্তে প্রতিটি প্রকল্পকে নিজস্ব ইঞ্জিন উদ্ভাবনে বাধ্য করা।
ডেজার্টের জন্য — নিজের HTML এবং CSS
সাথে সাথে Romergo তবুও সঠিক কোডের জন্য জায়গা রাখে, যেখানে এটি সবচেয়ে নিরাপদ: সাধারণ দৃশ্যের বিন্যাসে।
প্রকল্পে আপনি HTML এবং CSS-এ আপনার নিজস্ব থিম তৈরি করতে পারেন এবং এটি বিভিন্ন অধ্যায়ে ব্যবহার করতে পারেন। HTML প্রস্তুত অঞ্চলের অবস্থান নির্ধারণ করে — সংলাপের উইন্ডো, প্রতিকৃতি, চরিত্রের নাম, লেখা, প্রশ্ন এবং নির্বাচনের বোতাম। CSS এই অঞ্চলে গুরুত্বপূর্ণ পরিবর্তন করতে দেয়: বর্ডার, ব্যাকগ্রাউন্ড, কার্ডের আকার, মার্জিন, টাইপোগ্রাফি এবং স্ক্রিনের আকারের প্রতিক্রিয়া।
প্রস্তুত থিম **Standard**, **Minimalism**, **Brutalism**, **Romance** এবং **Neon** নিশ্চিত করা রেঞ্জ দেখায় কোন ম্যানুয়াল লেআউট ছাড়াই। কাস্টম থিম তৈরি করার সময় Romergo নির্বাচিত টেমপ্লেটটি কপি করে: এর পরে এর HTML এবং CSS সম্পাদনা করা যায় এবং তাৎক্ষণিকভাবে প্রকৃত Player প্রিভিউতে পরীক্ষা করা যায়।

*এখানে কোনো কনসেপ্ট-আর্ট নেই: বামদিকে দেখানো হয়েছে আসল CSS ইন্টিগ্রেটেড থিম Brutalism, ডানদিকে — একই কোডের ফলাফল ফোন প্রিভিউতে। Desktop / Mobile সুইচটি ব্যবহার করে অ্যাডাপ্টিভ নিয়মগুলি অবিলম্বে পরীক্ষা করা যায়, এবং কাস্টম থিম নির্বাচিত টেমপ্লেটের কপি থেকে কাজ শুরু করে।*
কিন্তু সীমারেখা আগের মতোই থাকে। কাস্টম HTML-এ নেই <script>, ইভেন্ট হ্যান্ডলার, ফর্ম, iframe এবং বাইরের রিসোর্স। CSS বাহ্যিক url() বা @import লোড করতে পারে না। দৃশ্যের বাধ্যতামূলক ক্ষেত্রগুলি স্থিত থাকতে হবে; যদি টেমপ্লেট তা হারায়, Player নিরাপদ মানক ফরম্যাটে ফিরে যায়।
অর্থাৎ HTML এবং CSS নির্দেশ করে, **কাহিনীর কেমন দেখায়**, এবং নোড, ভেরিয়েবল, শর্তাবলী এবং প্রভাব নির্দেশ করে, **কাহিনী কিভাবে কাজ করে**।
আমি এই ধরনের বিভাজনটা পছন্দ করি। লেখক ভিজ্যুয়ালি কুয়েস্টটিকে অন্যদের থেকে আলাদা করতে পারে, কিন্তু তা পার হলেও তা এখনও সামগ্রিক পরীক্ষা করা runtime-এর অংশ থাকে। বাইরের স্তরটি ক্রান্তিকভাবে রঙ পরিবর্তন করে এবং পুনর্গঠন করা যায়, প্রতিটি থিমকে আলাদা প্রোগ্রামে রূপান্তর না করেই।
কোডবিহীন কোড মানেই লজিকের অভাব নয়
Romergo-এর লক্ষ্য ছবি ব্যবহার করে প্রোগ্রামিং ভাষা প্রতিস্থাপন করা নয়। গ্রাফ জটিল গণিতের জন্য খুব উপযুক্ত নয়, এবং পরমাণু প্রভাবের সেট একটি সার্বজনীন স্বয়ংক্রিয় ইঞ্জিনে পরিণত হবে না।
তবে ইন্টারেক্টিভ গল্পের জন্য প্রায়শই অন্য জিনিসের প্রয়োজন হয়: একটি তথ্য মনে রাখা, কাউন্টার পরিবর্তন করা, একটি বিকল্প খুলতে, পথ নির্বাচন করা, ইন্টারফেসের অবস্থা দেখানো, রিটার্ন পয়েন্ট সংরক্ষণ করা এবং এই সব সিদ্ধান্ত পরবর্তী অধ্যায়ে পৌঁছে দেওয়া।
এই জন্য নোড এবং ভেরিয়েবল স্ক্রিপ্টের সরলীকৃত সংস্করণ নয়, বরং গল্পের নিজস্ব আরও সরাসরি ভাষা হিসাবে প্রমাণিত হয়। লেখক কম্পিউটারকে কমান্ড দেয় না, বরং বিশ্বের কারণ-প্রভাব সম্পর্ক বর্ণনা করে: খেলোয়াড় একটি সিদ্ধান্ত নিয়েছে, অবস্থা পরিবর্তিত হয়েছে, গল্প প্রতিক্রিয়া দেখিয়েছে।
আর যদি কিছু বাস্তব কোডের ইচ্ছে হয়, HTML এবং CSS তবুও ডেজার্টের জন্য অপেক্ষা করছে।