Skip to content

चौथा बैच / पाँचवाँ बैच / CM सर्वर कमांड — पोर्टिंग कठिनाई अनुसंधान रिपोर्ट ​

अनुसंधान वस्तु: citymania-org/cmclient (vanilla 15.3 शाखा) स्रोत कोड गहन पठन अनुसंधान तिथि: 2026-08-14 निष्कर्ष: तीन कार्यों की कठिनाई बहुत भिन्न है, प्रत्येक का मूल्यांकन और अनुशंसित क्रम दिया गया है।


एक, चौथा बैच: टाउन ज़ोनिंग (growth_tiles सेव सहित) ​

कार्य संरचना ​

घटकफ़ाइलआकारविवरण
ज़ोनिंग मोड एनमcm_zoning.hpp37 पंक्तियाँ12 मूल्यांकन मोड (CHECKOPINION/CHECKBUILD/CHECKSTACATCH/CHECKACTIVESTATIONS/CHECKBULUNSER/CHECKINDUNSER/CHECKTOWNZONES/CHECKCBACCEPTANCE/CHECKCBTOWNLIMIT/CHECKTOWNADZONES/CHECKTOWNGROWTHTILES)
मूल्यांकन तर्कcm_zoning_cmd.cpp413 पंक्तियाँप्रत्येक मोड के लिए एक क्वेरी फ़ंक्शन (पैलेट SpriteID लौटाता है), TownZone/Tz त्रिज्या एल्गोरिदम, StationFinder कवरेज जाँच, अनसर्विस्ड भवन/उद्योग जाँच सहित
ज़ोनिंग टूलबार GUIcm_zoning_gui.cpp204 पंक्तियाँआंतरिक/बाहरी दो-स्तरीय ज़ोनिंग मोड चयन विंडो (_zoning.inner/outer वैश्विक स्थिति)
growth_tiles सेवcm_saveload.cpp/.hpp90 पंक्तियाँTown विस्तारित फ़ील्ड growth_tiles + growth_tiles_last_month (std::map<TileIndex, uint8_t>), vanilla SaveLoad हैंडलर के साथ संग्रहीत
डेटा विस्तारextensions/cmext_town.hpp~80 पंक्तियाँ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, संस्करण 1), पुराने सेव प्रभावित नहीं होंगे
Town संरचना विस्तार🟢 कमकेवल growth_tiles के दो मैप लें (CBTownInfo/विज्ञापन/धन फ़ील्ड छोड़ें — वे CM सर्वर CityBuilder गेमप्ले-विशिष्ट हैं); jrpm Town में फ़ील्ड जोड़ें + town_sl.cpp सेव तालिका माउंट करें
मूल्यांकन तर्क🟢 कम-मध्यमअधिकांश शुद्ध क्वेरी (GetTileType/StationFinder/Town कैश/मकान जाँच), jrpm API मौजूद है; TownZone त्रिज्या एल्गोरिदम (squared_town_zone_radius) को jrpm फ़ील्ड नामों से मिलान करने की आवश्यकता है
रेंडरिंग पाइपलाइन🟠 मध्यम-उच्चDrawTileZoning को व्यूपोर्ट ड्रॉइंग पाइपलाइन में जोड़ना होगा — तीसरे बैच के हाइलाइट के साथ TileHighlight रेंडरिंग तंत्र साझा करता है। हाइलाइट पाइपलाइन के बिना अलग से बनाना होगा (सुझाव: पहले हाइलाइट करें, फिर ज़ोनिंग करें)
स्प्राइट संसाधन🟠 मध्यम12 पैलेट CM_SPR_PALETTE_ZONING_* कस्टम स्प्राइट का उपयोग करते हैं, jrpm में नहीं हैं → मौजूदा पैलेट स्प्राइट से बदलना होगा या नए संसाधन जोड़ने होंगे
ईवेंट हुक🟠 मध्यमgrowth_tiles रिकॉर्डिंग cmclient के ईवेंट बस (event::HouseBuilt/HouseCleared/..., cm_main.cpp का Emit) पर निर्भर करती है। jrpm में यह तंत्र नहीं है → सीधे town_cmd.cpp में मकान निर्माण/विध्वंस स्थानों पर हुक जोड़ें + NewMonth रोटेशन (IntervalTimer)

कठिनाई निष्कर्ष: 🟠 मध्यम-उच्च (लगभग 1.5–2 राउंड विशेष, प्रति राउंड 4–6 घंटे) ​

  • पूर्व शर्त: दृढ़ता से सुझाव है कि तीसरे बैच के हाइलाइट सिस्टम के बाद ही करें (रेंडरिंग पाइपलाइन साझा)
  • यदि केवल "12 प्रकार की ज़ोनिंग रंग, growth_tiles सेव के बिना" करें: कठिनाई घटकर 🟡 मध्यम (सेव विस्तार बचत, लगभग 1 राउंड)

दो, पाँचवाँ बैच: कमांड रीप्ले + एक्सपोर्ट/रिकॉर्डिंग ​

2.1 कमांड रीप्ले (cm_command_log + cm_commands + generated) ​

घटकआकारविवरण
कमांड ऑब्जेक्ट लेयरcm_command_type.hpp + generated/cm_gen_commands (2251+1418 पंक्तियाँ)प्रत्येक vanilla कमांड को प्रोग्राम करने योग्य ऑब्जेक्ट में लपेटा गया (as_company/with_callback/set_auto), कमांड→बिटस्ट्रीम सीरियलाइज़ेशन सहित
कमांड लॉग लोडिंगcm_command_log.cpp (203 पंक्तियाँ)lzma डीकंप्रेसन + BitOStream बिटस्ट्रीम पार्सिंग → _fake_commands कतार (tick counter/अपेक्षित परिणाम/यादृच्छिक बीज/CommandPacket)
कमांड निष्पादनExecuteFakeCommandstick counter क्रम में निष्पादित: ExecuteCommand(&cp) (vanilla आंतरिक API) + यादृच्छिक बीज/परिणाम सत्यापन (एंटी-चीट), मल्टीप्लेयर में सभी क्लाइंट को अग्रेषित करें

मुख्य अंतर (कठिनाई निर्धारित करने वाले):

cmclientjrpmप्रभाव
ExecuteCommand(CommandPacket*)यह फ़ंक्शन मौजूद नहीं, कमांड कोर DoCommandPInternal(Commands, TileIndex, CommandPayloadBase&, ...) हैCommandPacket → DoCommandPInternal payload रूपांतरण लेयर लिखनी होगी 🟠
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 से पूरी तरह भिन्न → रीप्ले फ़ाइल संगत नहीं, प्रारूप पुनः डिज़ाइन आवश्यक 🟠

2.2 एक्सपोर्ट / रिकॉर्डिंग (cm_export.cpp, 536 पंक्तियाँ) ​

सुविधाविवरणकठिनाई
ExportOpenttdDataJSON में मकान विनिर्देश/कार्गो विनिर्देश/पैलेट/इंजन जानकारी निर्यात (JsonWriter)🟢 कम-मध्यम (स्वतंत्र, Spec संरचना पढ़ें JSON लिखें)
ViewportExport / ExportFrameSpritesफ्रेम-दर-फ्रेम व्यूपोर्ट स्प्राइट निर्यात (व्यूपोर्ट आंतरिक ड्रॉइंग वेक्टर TileSpriteToDrawVector/ParentSpriteToSortVector पर निर्भर)🟠 मध्यम-उच्च (jgrpp व्यूपोर्ट पाइपलाइन भिन्न, वेक्टर इंटरफ़ेस संरेखित करना होगा)

कठिनाई निष्कर्ष: 🟠 मध्यम-उच्च (लगभग 2 राउंड विशेष) ​

  • कमांड रीप्ले सबसे बड़ा हिस्सा है: मुख्य कार्य = ① कमांड डिस्पैच पॉइंट पर रिकॉर्ड हुक जोड़ना (jrpm टेम्पलेटेड कमांड सिस्टम का अनुकूलन) ② CommandPacket → DoCommandPInternal निष्पादन लेयर ③ नया फ़ाइल प्रारूप डिज़ाइन। पहले कमांड ऑब्जेक्ट लेयर पोर्ट करने का सुझाव (तीसरे बैच ब्लूप्रिंट का आधार, रीप्ले का भी आधार)
  • एक्सपोर्ट: JSON डेटा एक्सपोर्ट स्वतंत्र रूप से पहले किया जा सकता है (कम-मध्यम); फ्रेम रिकॉर्डिंग व्यूपोर्ट संरेखण पर निर्भर (हाइलाइट के समान बैच में)

तीन, CM सर्वर कमांड (cm_console_cmds.cpp, 289 पंक्तियाँ) ​

कमांड सूची और प्रति-आइटम कठिनाई ​

कमांडकार्यक्षमताjrpm के लिए कठिनाईनोट्स
cmgamespeed [n]गेम गति बदलें🟢 बहुत कम (~20 पंक्तियाँ)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ग्राफिक्स डिबग🟢 कमस्वतंत्र

कठिनाई निष्कर्ष: 🟢 कुल मिलाकर कम (प्रति कमांड 0.5–2 घंटे) ​

अनुशंसित क्रम: cmgamespeed (10 मिनट) → cmgamestats/cmgfxdebug (प्रत्येक ~1h) → cmexport (पाँचवें बैच के साथ) → cmtreemap (~2h) → cmreset_town_growth (चौथे बैच के साथ) → cmload_commands/cmstart_record (पाँचवें बैच रीप्ले/रिकॉर्डिंग के साथ)।


चार, समग्र अनुशंसित मार्ग ​

① हाइलाइट सिस्टम (तीसरे बैच का मूल, ~2-3 राउंड)      ← ब्लूप्रिंट/ज़ोनिंग का रेंडरिंग आधार
② कमांड ऑब्जेक्ट लेयर (तीसरे बैच ब्लूप्रिंट + पाँचवें बैच रीप्ले का आधार, ~1-2 राउंड)
③ ब्लूप्रिंट (~1 राउंड)
④ टाउन ज़ोनिंग (~1.5 राउंड, ① रेंडरिंग पाइपलाइन पर निर्भर; growth_tiles XSLF गेटिंग के साथ)
⑤ कमांड रीप्ले + एक्सपोर्ट (~2 राउंड, ② पर निर्भर; JSON एक्सपोर्ट पहले स्वतंत्र रूप से किया जा सकता है)
⑥ CM सर्वर कमांड (बैचों के बीच बिखरे हुए, gamespeed/step तुरंत किए जा सकते हैं)

पाँच, तुरंत कम लागत में लागू करने योग्य आइटम (किसी बड़ी परियोजना पर निर्भर नहीं) ​

  1. cmgamespeed कमांड (~20 पंक्तियाँ, _game_speed बदलें)
  2. step पहले से मौजूद → करने की आवश्यकता नहीं
  3. cmgamestats / cmgfxdebug (प्रत्येक ~1h, स्वतंत्र)
  4. cmexport का JSON डेटा एक्सपोर्ट (~2h, स्वतंत्र)
  5. cmtreemap (~2h, स्वतंत्र)

ये 5 आइटम लगभग आधे दिन का कार्यभार हैं, "शून्य बैच" के रूप में पहले लागू किए जा सकते हैं, तीसरे/चौथे/पाँचवें बैच के साथ समानांतर रूप से चल सकते हैं।