যখন আপনি ৩২-ওয়াগন ট্রেনের বিশাল একটা স্টেশন সামলান, যেখানে প্রতিটি সাইডে ২টা করে চেস্ট থাকে, তখন আপনাকে প্রায় ১২৮টা চেস্ট ম্যানেজ করতে হয়। আমি আগে যেটা করতাম তাকে বলতাম "শিফট-ক্লিক ড্যান্স"—অর্থাৎ শিফট আর রাইট ক্লিক দিয়ে ইনসার্টার কপি করে শিফট আর লেফট ক্লিক দিয়ে ১২৮ বার পেস্ট করা। কাজটা করতে যেমন সময় লাগে, ভুল হওয়ার সম্ভাবনাও তত বেশি।

Factorio Silo - A massive 32-wagon train docking at a high-speed loading station

ঝামেলাটা হলো, যদি আপনি এই ১২৮টার মধ্যে জাস্ট একটা ইনসার্টার মিস করেন, তবে পুরো স্টেশনের ব্যালেন্স নষ্ট হয়ে যায়। একটা চেস্ট বেশি ফিল হয়ে যায়, যার ফলে ট্রেন লোড বা আনলোড হতে দেরি হয়। এর ফলে আপনার পুরো প্রোডাকশন লাইন স্থবির হয়ে যেতে পারে। আমি যখন দেখলাম আমি নিজের হাতের উপর ভরসা করতে পারছি না, তখনই সিদ্ধান্ত নিলাম একটা Factorio Mod লিখে ফেলার।

ইউআই (GUI) এর সেই ১৯৯০ দশকের স্বাদ

আমি ভেবেছিলাম ফ্যাক্টোরিও-এর লুয়া এপিআই (Lua API) হয়তো বেশ মডার্ন হবে। কিন্তু আমি মারাত্মক ভুল ছিলাম। এর জিইউআই (GUI) এপিআই অনেকটা ১৯৯০ দশকের ডেস্কটপ অ্যাপ ডেভেলপমেন্টের মতো—ম্যানুয়ালি প্রতিটি সুইচবোর্ড তার দিয়ে জোড়া দেওয়ার মতো অবস্থা। আপনি যদি একটা স্লাইডার আর টেক্সট বক্স সিঙ্ক করতে চান, তবে আপনাকে দুটোর জন্যই আলাদা আলাদা ইভেন্ট হ্যান্ডলার লিখতে হবে।

-- স্লাইডার আর টেক্সট বক্স সিঙ্ক রাখা বেশ যন্ত্রণার কাজ
if element.name == "issm_slider" then
    M.gui.elements.textfield.text = tostring(element.slider_value)
end

আমার মনে হয় আমি মডের লজিক লিখতে যে সময় দিয়েছি, তার চেয়ে বেশি সময় ব্যয় করেছি on_gui_value_changed এর সাথে যুদ্ধ করতে।

ব্যাচ আপডেট এবং আমার মুক্তি

আমার বানানো এই Factorio Mod এর সবচেয়ে স্যাটিসফায়িং পার্ট হলো গ্রিন বক্স ড্র্যাগ করা। এক সেকেন্ডের মধ্যে ১২৮টা ইনসার্টার একদম নিখুঁত স্ট্যাক সাইজে সেট হয়ে যায়। ফ্যাক্টোরিও এখন আর একঘেয়ে খাটুনির গেম মনে হয় না, বরং ইঞ্জিনিয়ারিং টুল মনে হয়।

এটির জন্য আমি selection-tool ব্যবহার করেছি। ইঞ্জিন নিজেই আমাকে সিলেক্ট করা এরিয়ার ভেতর সব এনটিটি (Entity) এর টেবিল দিয়ে দেয়। আমি শুধু ফিল্টার করে দেখি কোনটা ইনসার্টার। ১০ মিনিটের যন্ত্রণাদায়ক ক্লিকিং ম্যারাথন এখন হাফ-সেকেন্ডের ব্যাচ আপডেটে পরিণত হয়েছে।

ইনভেন্টরি ফুল হলে যা ঘটে

মডটা ইউজেবল করার জন্য আমি একটা কুইক গ্র্যাব হটকি যোগ করেছিলাম যা player.clear_cursor() কল করে। কিন্তু একটা মজার (আসলে বিরক্তিকর) জিনিস খেয়াল করলাম—যদি প্লেয়ারের ইনভেন্টরি ফুল থাকে, তবে clear_cursor() একদম নিরবে ফেইল করে! কোনো এরর মেসেজ দেয় না, মড ক্রাশও করে না, শুধু কোনো কাজই হয় না। আমি প্রথমে ভেবেছিলাম কোডে কোনো বাগ আছে, পরে বুঝলাম এটা গেম ইঞ্জিনের সীমাবদ্ধতা। এখনো এর কোনো ভালো সলিউশন খুঁজে পাইনি।

আপনার যদি মেগাবেস (Megabase) সামলানোর শখ থাকে, তবে ছোটখাটো কিছু মড আসলে লাইফসেভার হতে পারে। আমি আমার এই প্রথম মড থেকে যে শিক্ষা নিয়েছি, তা পরবর্তীতে আরও জটিল প্রজেক্টে কাজে লাগবে।

লুয়া (Lua) এপিআই ব্যবহার করে নিজের প্রথম Factorio Mod বানানোর গল্প। জিইউআই হ্যান্ডলিং, ইনসার্টার স্ট্যাক সাইজ মডিফাই এবং ফ্যাক্টোরিও মডিংয়ের চ্যালেঞ্জ নিয়ে বিস্তারিত জানুন।

Asaduzzaman Pavel

About the Author

Asaduzzaman Pavel is a Software Engineer who actually enjoys the friction of a well-architected system. He has over 15 years of experience building high-performance backends and infrastructure that can actually handle the real-world chaos of scale.

Currently looking for new opportunities to build something amazing.