Skip to content

চতুর্থ ব্যাচ / পঞ্চম ব্যাচ / CM সার্ভার কমান্ড —— পোর্টিং কঠিনতা গবেষণা প্রতিবেদন ​

গবেষণা অবজেক্ট: citymania-org/cmclient (vanilla 15.3 ব্রাঞ্চ) সোর্স কোড গভীর পাঠ গবেষণার তারিখ: 2026-08-14 সিদ্ধান্ত: তিনটি কাজের কঠিনতা ব্যাপকভাবে ভিন্ন, প্রতিটি আইটেমের মূল্যায়ন ও প্রস্তাবিত ক্রম দেওয়া হল।


এক. চতুর্থ ব্যাচ: টাউন জোনিং (growth_tiles存档 সহ) ​

বৈশিষ্ট্য গঠন ​

উপাদানফাইলআকারব্যাখ্যা
জোনিং মোড এনামcm_zoning.hpp৩৭ লাইন১২টি মূল্যায়ন মোড (CHECKOPINION/CHECKBUILD/CHECKSTACATCH/CHECKACTIVESTATIONS/CHECKBULUNSER/CHECKINDUNSER/CHECKTOWNZONES/CHECKCBACCEPTANCE/CHECKCBTOWNLIMIT/CHECKTOWNADZONES/CHECKTOWNGROWTHTILES)
মূল্যায়ন লজিকcm_zoning_cmd.cpp৪১৩ লাইনপ্রতিটি মোডের জন্য একটি কুয়েরি ফাংশন (প্যালেট SpriteID ফেরত দেয়), TownZone/Tz ব্যাসার্ধ অ্যালগরিদম, StationFinder কভারেজ চেক, আনসার্ভিসড বিল্ডিং/ইন্ডাস্ট্রি চেক সহ
জোনিং টুলবার GUIcm_zoning_gui.cpp২০৪ লাইনভিতরের/বাইরের দুটি স্তরের জোনিং মোড নির্বাচন উইন্ডো (_zoning.inner/outer গ্লোবাল স্টেট)
growth_tiles存档cm_saveload.cpp/.hpp৯০ লাইনTown এক্সটেনশন ফিল্ড growth_tiles + growth_tiles_last_month (std::map<TileIndex, uint8_t>), vanilla SaveLoad হ্যান্ডলার দিয়ে存档
ডেটা এক্সটেনশনextensions/cmext_town.hpp~৮০ লাইনext::Town: growth_tiles ×2 + প্রচুর CM সার্ভার প্লে ফিল্ড (CBTownInfo কার্গো পরিসংখ্যান, বিজ্ঞাপন/তহবিল ট্র্যাকিং, hs/cs/hr শহর বৃদ্ধি গণনা)
মাসিক ঘূর্ণন + ট্রিগারcm_game.cpp / town_cmd.cpp—NewMonth growth_tiles ঘূর্ণন; বাড়ি নির্মাণ/ভাঙা/পুনর্নির্মাণের স্থানে অবস্থা রেকর্ড

পোর্টিং কঠিনতা প্রতি আইটেম মূল্যায়ন ​

কঠিনতাতীব্রতাব্যাখ্যা
存档体系 পুনর্লিখন🟠 মাঝারিgrowth_tiles vanilla DefaultSaveLoadHandler + SlSetStructListLength/SlObject ব্যবহার করে, jrpm হলো sl/ নতুন体系 (SlTableHeader/SlObjectSaveFiltered)। jrpm-এর NSL/SLE + XSLF বৈশিষ্ট্য গেট দিয়ে পুনর্লিখন করতে হবে (নতুন XSLFI_TOWN_GROWTH_TILES, সংস্করণ ১), পুরনো存档 প্রভাবিত হবে না
Town স্ট্রাকচার এক্সটেনশন🟢 কমশুধু growth_tiles দুটি ম্যাপ নেওয়া হবে (বাদ দেওয়া CBTownInfo/বিজ্ঞাপন/তহবিল ফিল্ড——সেগুলি CM সার্ভার CityBuilder প্লে-নির্দিষ্ট); jrpm Town-এ ফিল্ড যোগ + town_sl.cpp存档 টেবিল মাউন্ট
মূল্যায়ন লজিক🟢 কম-মাঝারিঅধিকাংশই বিশুদ্ধ কুয়েরি (GetTileType/StationFinder/Town ক্যাশে/বাড়ি চেক), jrpm API বিদ্যমান; TownZone ব্যাসার্ধ অ্যালগরিদম (squared_town_zone_radius) jrpm ফিল্ড নামের সাথে মিলাতে হবে
রেন্ডার পাইপলাইন🟠 মাঝারি-উচ্চDrawTileZoning ভিউপোর্ট ড্র পাইপলাইনে সংযুক্ত করতে হবে——তৃতীয় ব্যাচ হাইলাইটের সাথে TileHighlight রেন্ডার মেকানিজম শেয়ার করে। হাইলাইট পাইপলাইন না থাকলে আলাদাভাবে তৈরি করতে হবে (পরামর্শ: প্রথমে হাইলাইট, তারপর জোনিং)
স্প্রাইট রিসোর্স🟠 মাঝারি১২টি প্যালেট CM_SPR_PALETTE_ZONING_* কাস্টম স্প্রাইট ব্যবহার করে, jrpm-এ নেই → বিদ্যমান প্যালেট স্প্রাইট দিয়ে প্রতিস্থাপন বা নতুন রিসোর্স যোগ করতে হবে
ইভেন্ট হুক🟠 মাঝারিgrowth_tiles রেকর্ড cmclient-এর ইভেন্ট বাস-এর উপর নির্ভরশীল (event::HouseBuilt/HouseCleared/..., cm_main.cpp-এর Emit)। jrpm-এ এই মেকানিজম নেই → সরাসরি town_cmd.cpp-তে বাড়ি নির্মাণ/ভাঙার স্থানে হুক যোগ + NewMonth ঘূর্ণন (IntervalTimer)

কঠিনতা সিদ্ধান্ত: 🟠 মাঝারি-উচ্চ (প্রায় ১.৫–২ রাউন্ড বিশেষ কাজ, প্রতি রাউন্ড ৪–৬ ঘন্টা) ​

  • পূর্বশর্ত: দৃঢ়ভাবে পরামর্শ দেওয়া হয় তৃতীয় ব্যাচ হাইলাইট সিস্টেম শেষ করার পর করা (রেন্ডার পাইপলাইন শেয়ারিং)
  • যদি শুধু "১২টি জোনিং রঙিনকরণ, growth_tiles存档 ছাড়া" করা হয়: কঠিনতা 🟡 মাঝারিতে নেমে আসে (存档 এক্সটেনশন বাদ, প্রায় ১ রাউন্ড)

দুই. পঞ্চম ব্যাচ: কমান্ড রিপ্লে + এক্সপোর্ট/রেকর্ডিং ​

২.১ কমান্ড রিপ্লে (cm_command_log + cm_commands + generated) ​

উপাদানআকারব্যাখ্যা
কমান্ড অবজেক্ট লেয়ারcm_command_type.hpp + generated/cm_gen_commands (২২৫১+১৪১৮ লাইন)প্রতিটি vanilla কমান্ড প্রোগ্রামেবল অবজেক্টে র‍্যাপ করা (as_company/with_callback/set_auto), কমান্ড→বিটস্ট্রিম সিরিয়ালাইজেশন সহ
কমান্ড লগ লোডcm_command_log.cpp (২০৩ লাইন)lzma ডিকম্প্রেশন + BitOStream বিটস্ট্রিম পার্স → _fake_commands কিউ (টিক কাউন্টার/প্রত্যাশিত ফলাফল/র্যান্ডম সীড/CommandPacket)
কমান্ড নির্বাহExecuteFakeCommandsটিক কাউন্টার ক্রম অনুযায়ী নির্বাহ: ExecuteCommand(&cp) (vanilla অভ্যন্তরীণ API) + র্যান্ডম সীড/ফলাফল যাচাই (প্রতারণা-বিরোধী), মাল্টিপ্লেয়ারে সব ক্লায়েন্টে ফরোয়ার্ড

মূল পার্থক্য (কঠিনতা নির্ধারণ করে):

cmclientjrpmপ্রভাব
ExecuteCommand(CommandPacket*)এই ফাংশন নেই, কমান্ড মূল হলো DoCommandPInternal(Commands, TileIndex, CommandPayloadBase&, ...)CommandPacket → DoCommandPInternal পেলোড রূপান্তর স্তর লিখতে হবে 🟠
CommandPacket ফিল্ড (vanilla)CommandPacket বিদ্যমান কিন্তু গঠন ভিন্ন (GeneralCommandPacket<DynBaseCommandContainer>)ফিল্ড ম্যাপিং অভিযোজন করতে হবে 🟠
GetCommandName✅ বিদ্যমান (command_func.h:166)🟢
outgoing_queue (মাল্টিপ্লেয়ার ফরোয়ার্ড)jrpm নেটওয়ার্ক স্তর ভিন্ন (OutgoingCommandPacket/ServerNetworkGameSocketHandler::SendCommand)মাল্টিপ্লেয়ার রিপ্লের জন্য ফরোয়ার্ড লজিক পুনর্লিখন প্রয়োজন 🟠
রেকর্ডার (কিভাবে .cmd ফাইল জেনারেট হয়)cmclient-এর রেকর্ডিং হুক কমান্ড অবজেক্ট লেয়ারের post() ইন্টারসেপ্টের উপর নির্ভরশীলjrpm কমান্ড টেমপ্লেটাইজড Post → কমান্ড ডিসপ্যাচ পয়েন্টে রেকর্ডিং হুক যোগ করতে হবে 🔴 মূল কাজ
ফাইল ফরম্যাটপ্রাইভেট (vanilla কমান্ড ID + বিটস্ট্রিম)jrpm কমান্ড ID vanilla থেকে সম্পূর্ণ ভিন্ন → রিপ্লে ফাইল সামঞ্জস্যপূর্ণ নয়, ফরম্যাট পুনরায় ডিজাইন করতে হবে 🟠

২.২ এক্সপোর্ট / রেকর্ডিং (cm_export.cpp, ৫৩৬ লাইন) ​

বৈশিষ্ট্যব্যাখ্যাকঠিনতা
ExportOpenttdDataJSON এক্সপোর্ট বাড়ির স্পেক/কার্গো স্পেক/প্যালেট/ইঞ্জিন তথ্য (JsonWriter)🟢 কম-মাঝারি (স্বাধীন, Spec স্ট্রাকচার পড়ে JSON লেখা)
ViewportExport / ExportFrameSpritesপ্রতি ফ্রেম ভিউপোর্ট স্প্রাইট এক্সপোর্ট (ভিউপোর্ট অভ্যন্তরীণ ড্র ভেক্টর TileSpriteToDrawVector/ParentSpriteToSortVector-এর উপর নির্ভরশীল)🟠 মাঝারি-উচ্চ (jgrpp ভিউপোর্ট পাইপলাইন ভিন্ন, ভেক্টর ইন্টারফেস সারিবদ্ধ করতে হবে)

কঠিনতা সিদ্ধান্ত: 🟠 মাঝারি-উচ্চ (প্রায় ২ রাউন্ড বিশেষ কাজ) ​

  • কমান্ড রিপ্লে সবচেয়ে বড় অংশ: মূল কাজ = ①কমান্ড ডিসপ্যাচ পয়েন্টে রেকর্ডিং হুক যোগ (jrpm টেমপ্লেটাইজড কমান্ড সিস্টেমের অভিযোজন) ②CommandPacket → DoCommandPInternal নির্বাহ স্তর ③নতুন ফাইল ফরম্যাট ডিজাইন। প্রথমে কমান্ড অবজেক্ট লেয়ার পোর্ট করার পরামর্শ দেওয়া হচ্ছে (তৃতীয় ব্যাচ ব্লুপ্রিন্টের ভিত্তি, এছাড়াও রিপ্লের ভিত্তি)
  • এক্সপোর্ট: JSON ডেটা এক্সপোর্ট স্বাধীনভাবে আগে করা যেতে পারে (কম-মাঝারি); ফ্রেম রেকর্ডিং ভিউপোর্ট সারিবদ্ধকরণের উপর নির্ভরশীল (হাইলাইটের সাথে একই ব্যাচে প্রক্রিয়া)

তিন. CM সার্ভার কমান্ড (cm_console_cmds.cpp, ২৮৯ লাইন) ​

কমান্ড তালিকা ও প্রতি আইটেম কঠিনতা ​

কমান্ডবৈশিষ্ট্যjrpm-এর জন্য কঠিনতামন্তব্য
cmgamespeed [n]গেম গতি পরিবর্তন🟢 অত্যন্ত কম (~২০ লাইন)jrpm-এ ইতিমধ্যে _game_speed গ্লোবাল আছে (gfx.cpp:52), শুধু কমান্ড শেলের অভাব
cmstep [n]n টিক ধাপ⏭️ jrpm-এ ইতিমধ্যে আছেstep কমান্ড (ConStepGame) ফাংশন একই, বাদ দিন
cmexportopenttd.json এক্সপোর্ট🟢 কম-মাঝারিExportOpenttdData-র উপর নির্ভরশীল (পঞ্চম ব্যাচ দেখুন)
cmtreemap <file>উচ্চতা ম্যাপ গাছ লাগানো🟡 মাঝারিউচ্চতা ম্যাপ পড়া + গাছ লাগানোর কমান্ড, স্বাধীন
cmreset_town_growthশহর বৃদ্ধি রেকর্ড মুছে ফেলা🟢 কমটাউন জোনিং ফিল্ডের উপর নির্ভরশীল
cmload_commandsকমান্ড রিপ্লে লোড🟠 মাঝারি-উচ্চকমান্ড রিপ্লে পরিকাঠামোর উপর নির্ভরশীল
cmstart_record / cmstop_recordফ্রেম রেকর্ডিং🟠 মাঝারি-উচ্চরেকর্ডিং পরিকাঠামোর উপর নির্ভরশীল
cmgamestatsগেম সেশন পরিসংখ্যান🟢 কমস্বাধীন
cmgfxdebugগ্রাফিক্স ডিবাগ🟢 কমস্বাধীন

কঠিনতা সিদ্ধান্ত: 🟢 সামগ্রিকভাবে কম (প্রতি কমান্ড ০.৫–২ ঘন্টা) ​

প্রস্তাবিত ক্রম: cmgamespeed (১০ মিনিট) → cmgamestats/cmgfxdebug (প্রায় ~১ ঘন্টা) → cmexport (পঞ্চম ব্যাচ এক্সপোর্টের সাথে) → cmtreemap (~২ ঘন্টা) → cmreset_town_growth (চতুর্থ ব্যাচের সাথে) → cmload_commands/cmstart_record (পঞ্চম ব্যাচ রিপ্লে/রেকর্ডিংয়ের সাথে)।


চার. সামগ্রিক প্রস্তাবিত রুট ​

① হাইলাইট সিস্টেম (তৃতীয় ব্যাচ মূল, ~২-৩ রাউন্ড)      ← ব্লুপ্রিন্ট/জোনিংয়ের রেন্ডার ভিত্তি
② কমান্ড অবজেক্ট লেয়ার (তৃতীয় ব্যাচ ব্লুপ্রিন্ট + পঞ্চম ব্যাচ রিপ্লের ভিত্তি, ~১-২ রাউন্ড)
③ ব্লুপ্রিন্ট (~১ রাউন্ড)
④ টাউন জোনিং (~১.৫ রাউন্ড, ① রেন্ডার পাইপলাইনের উপর নির্ভরশীল; growth_tiles XSLF গেটেড)
⑤ কমান্ড রিপ্লে + এক্সপোর্ট (~২ রাউন্ড, ②-র উপর নির্ভরশীল; JSON এক্সপোর্ট আগে স্বাধীনভাবে করা যেতে পারে)
⑥ CM সার্ভার কমান্ড (বিভিন্ন ব্যাচের মধ্যে বিক্ষিপ্তভাবে সন্নিবেশ, gamespeed/step এখনই করা যেতে পারে)

পাঁচ. এখনই কম খরচে বাস্তবায়নযোগ্য আইটেম (কোনো বড় প্রকৌশলের উপর নির্ভরশীল নয়) ​

১. cmgamespeed কমান্ড (~২০ লাইন, _game_speed পরিবর্তন) ২. step ইতিমধ্যে আছে → করার প্রয়োজন নেই ৩. cmgamestats / cmgfxdebug (প্রায় ~১ ঘন্টা, স্বাধীন) ৪. cmexport-এর JSON ডেটা এক্সপোর্ট (~২ ঘন্টা, স্বাধীন) ৫. cmtreemap (~২ ঘন্টা, স্বাধীন)

এই ৫টি আইটেম প্রায় অর্ধেক দিনের কাজ, "শূন্য ব্যাচ" হিসেবে আগে বাস্তবায়ন করা যেতে পারে, তৃতীয়/চতুর্থ/পঞ্চম ব্যাচের সাথে সমান্তরালে কোনো বিরোধ নেই।