चौथा बैच / पाँचवाँ बैच / CM सर्वर कमांड — पोर्टिंग कठिनाई अनुसंधान रिपोर्ट
अनुसंधान वस्तु: citymania-org/cmclient (vanilla 15.3 शाखा) स्रोत कोड गहन पठन अनुसंधान तिथि: 2026-08-14 निष्कर्ष: तीन कार्यों की कठिनाई बहुत भिन्न है, प्रत्येक का मूल्यांकन और अनुशंसित क्रम दिया गया है।
एक, चौथा बैच: टाउन ज़ोनिंग (growth_tiles सेव सहित)
कार्य संरचना
| घटक | फ़ाइल | आकार | विवरण |
|---|---|---|---|
| ज़ोनिंग मोड एनम | cm_zoning.hpp | 37 पंक्तियाँ | 12 मूल्यांकन मोड (CHECKOPINION/CHECKBUILD/CHECKSTACATCH/CHECKACTIVESTATIONS/CHECKBULUNSER/CHECKINDUNSER/CHECKTOWNZONES/CHECKCBACCEPTANCE/CHECKCBTOWNLIMIT/CHECKTOWNADZONES/CHECKTOWNGROWTHTILES) |
| मूल्यांकन तर्क | cm_zoning_cmd.cpp | 413 पंक्तियाँ | प्रत्येक मोड के लिए एक क्वेरी फ़ंक्शन (पैलेट SpriteID लौटाता है), TownZone/Tz त्रिज्या एल्गोरिदम, StationFinder कवरेज जाँच, अनसर्विस्ड भवन/उद्योग जाँच सहित |
| ज़ोनिंग टूलबार GUI | cm_zoning_gui.cpp | 204 पंक्तियाँ | आंतरिक/बाहरी दो-स्तरीय ज़ोनिंग मोड चयन विंडो (_zoning.inner/outer वैश्विक स्थिति) |
| growth_tiles सेव | cm_saveload.cpp/.hpp | 90 पंक्तियाँ | 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) |
| कमांड निष्पादन | ExecuteFakeCommands | tick counter क्रम में निष्पादित: ExecuteCommand(&cp) (vanilla आंतरिक API) + यादृच्छिक बीज/परिणाम सत्यापन (एंटी-चीट), मल्टीप्लेयर में सभी क्लाइंट को अग्रेषित करें |
मुख्य अंतर (कठिनाई निर्धारित करने वाले):
| cmclient | jrpm | प्रभाव |
|---|---|---|
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 पंक्तियाँ)
| सुविधा | विवरण | कठिनाई |
|---|---|---|
| ExportOpenttdData | JSON में मकान विनिर्देश/कार्गो विनिर्देश/पैलेट/इंजन जानकारी निर्यात (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) समान कार्यक्षमता, छोड़ें |
cmexport | openttd.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 तुरंत किए जा सकते हैं)पाँच, तुरंत कम लागत में लागू करने योग्य आइटम (किसी बड़ी परियोजना पर निर्भर नहीं)
cmgamespeedकमांड (~20 पंक्तियाँ,_game_speedबदलें)stepपहले से मौजूद → करने की आवश्यकता नहींcmgamestats/cmgfxdebug(प्रत्येक ~1h, स्वतंत्र)cmexportका JSON डेटा एक्सपोर्ट (~2h, स्वतंत्र)cmtreemap(~2h, स्वतंत्र)
ये 5 आइटम लगभग आधे दिन का कार्यभार हैं, "शून्य बैच" के रूप में पहले लागू किए जा सकते हैं, तीसरे/चौथे/पाँचवें बैच के साथ समानांतर रूप से चल सकते हैं।