Skip to content

Browser में open world बनाना, भाग 11: Policy mode, hardcoded mode नहीं

लेखक Oleg Sidorkin, Cinevva के CTO और सह-संस्थापक

यहां नए हैं? series guide का इस्तेमाल करें। यह बताती है कि spike क्या होता है और सभी भागों को जोड़ती है।

Seam की उथल-पुथल वाले भाग के बाद, हमें reacting बंद करके governing शुरू करनी थी।

Spike 23 ने ad-hoc behavior की जगह explicit policy rules रख दिए। Chunks अपने local state के मुताबिक जो मन में आए वो करने के बजाय, अब एक central policy system फैसले लेता था। इस chunk को कौन सा LOD level मिलेगा? यह heightmap के रूप में render होगा या marching cubes के रूप में? इसे transition cells की ज़रूरत है, और किन faces पर? जवाब एक policy function से आते थे जो camera से distance, edit history, और neighbor resolution states को परखता था।

Spike 23 को नए tab में खोलें ↗ · Source देखें

Distance-based LOD assignment camera के चारों ओर concentric rings का इस्तेमाल करती थी, जो clipmap concept जैसी ही है पर chunk grid पर लागू होती है। Ring 0 के chunks को full-resolution MC मिलता है। Ring 1 को half-resolution MC मिलता है। Ring 2 और उससे आगे को heightmap mode मिलता है। Adjacency constraint बेहद ज़रूरी था: किन्हीं दो पड़ोसी chunks के लिए हमें |LiLj|1 चाहिए। एक face के आर-पार resolution ratio 2|LiLj| होता है, और Transvoxel transition tables सिर्फ 2:1 case के लिए परिभाषित हैं (|LiLj|=1)। 2 levels की छलांग के लिए 4:1 transition चाहिए होगा जिसे ये tables व्यक्त नहीं कर सकतीं, इसलिए policy lower-detail chunk को तब तक upgrade करने पर मजबूर करती है जब तक constraint पूरी न हो जाए।

HM/MC switching logic हर chunk के edit bitmap को जांचता था। अगर किसी chunk में कोई भी volumetric edits थीं (caves, tunnels, terrain sculpts), तो वह distance की परवाह किए बिना MC mode में ही रहता था। बिना edit वाले chunks काफी दूर चले जाने पर heightmap mode में आ सकते थे। इस hybrid approach ने हमें वहां volumetric freedom दी जहां वह मायने रखती थी और वहां efficiency दी जहां नहीं रखती थी।

यह spike बाहर से पहले के कुछ spikes के मुकाबले छोटा लगा। असल में यह development के लिए quality-of-life में एक बड़ा सुधार था।

जब आपका system यह बता सकता है कि किसी chunk ने mode क्यों बदला, तो आप अंदाज़ा लगाने में कम समय बिताते हैं। हमने color-coded overlays जोड़े: heightmap chunks के लिए हरा, MC chunks के लिए नीला, transition-active faces के लिए नारंगी। जब seam visibility के लिए dedicated render controls होते हैं, तो visual debugging की उलझन घट जाती है। जब draw ranges को policy system से मिले active vertex counts से साफ़ तौर पर जोड़ा जाता है, तो stale geometry ghosts आपकी दोपहर बर्बाद करना बंद कर देते हैं।

हमने इस spike में camera behavior को भी पूरी तरह बदल दिया। पहले के spikes में simple orbit controls थे जो screenshots के लिए ठीक थे पर bugs को reproduce करने के लिए बेकार थे। Spike 23 ने configurable speed, altitude lock toggle, और position readout के साथ WASD fly camera जोड़ा। यह छोटी बात लगती है। इसका मतलब था "मैंने उस ridge के पास कहीं एक bug देखा" और "bug position (142, 12, -67) पर northwest की ओर मुंह करके दिखता है" के बीच का फर्क।

इस भाग की सबसे अहम बात यह है कि policy ने complexity घटाई नहीं। उसने complexity को व्यवस्थित किया। edge cases की संख्या वही रही। पर अब हर edge case का एक नाम था, एक trigger condition थी, और code में एक जगह थी जहां आप breakpoint लगा सकते थे। यह एक अलग तरह की जीत है, और यही तय करता है कि कोई system विकसित होता रह सकता है या अपने ही बोझ तले बैठ जाता है।

Spike 23 के अंत तक, हमारे पास एक near-field behavior layer था जो इतना predictable था कि उसे interaction bugs के लगातार डर के बिना far-field clipmap ring strategy से जोड़ा जा सके।

भाग 12 में हम Spike 24 को देखेंगे, जहां ring transitions, skybox fog, और Three.js version-level shader integration project के इस अध्याय को समाप्त करते हैं।

इस अध्याय में संदर्भित technology

Distance-based LOD policy. एक central function जो हर chunk को camera से distance, edit history, और neighbor states के आधार पर LOD level और rendering mode देती है। Concentric distance rings base LOD तय करते हैं: ring 0 = full-res MC, ring 1 = half-res MC, ring 2+ = heightmap mode। जैसे-जैसे camera हिलता है, policy function हर frame चलती है और chunk transitions को trigger करती है। यह ad-hoc per-chunk फैसलों की जगह एक predictable, debuggable rule system रख देती है। compute shader के समकक्ष के लिए GPU-driven LOD selection देखें।

Adjacency constraints. Transvoxel algorithm सिर्फ 2:1 resolution ratios संभालता है। अगर दो पड़ोसी chunks एक LOD level से ज़्यादा का फर्क रखते हैं (जैसे LOD 0 के बगल में LOD 2), तो transition tables valid seam geometry नहीं बना सकतीं। Policy system इसे तब लागू करता है जब LOD फर्क 1 से ज़्यादा हो जाने पर lower-detail chunk को upgrade कर देता है। यह constraint propagation cascade कर सकता है: एक chunk को upgrade करने से उसके पड़ोसियों को भी upgrade करना पड़ सकता है। Implementation एक simple iterative pass है जो typical grid configurations के लिए 2-3 iterations में converge हो जाता है।

Mode selection के लिए edit bitmap. हर chunk एक bitmap रखता है जो दर्ज करता है कि उसमें volumetric SDF edits (caves, tunnels, sculpts) हैं या नहीं। किसी भी edit वाले chunks distance की परवाह किए बिना marching cubes mode में रहते हैं, जिससे creator के बदलाव सुरक्षित रहते हैं। बिना edit वाले chunks camera से काफी दूर होने पर heightmap mode में आ जाते हैं, जिससे compute और memory बचती है। Bitmap हर chunk के लिए एक ही flag है पर इसे edit density track करने के लिए बढ़ाया जा सकता है ताकि mode के और बारीक फैसले लिए जा सकें।

Debug visualization overlays. Color-coded chunk rendering जहां हरा = heightmap mode, नीला = MC mode, नारंगी = transition-active faces। LOD level numbers, mode labels, और wireframe toggles के साथ per-chunk overlays। ये development tools हैं, shipped features नहीं, पर LOD transitions और seam artifacts को debug करते समय ये बार-बार अपनी कीमत वसूल कर लेते हैं। exact world position बताने वाले WASD fly camera के साथ मिलकर ये "मैंने कहीं एक bug देखा" को "bug (142, 12, -67) पर इस LOD configuration के साथ दिखता है" में बदल देते हैं।


भाग 11, कुल 12 में से।
पिछला: भाग 10 - Seam की उथल-पुथल और corner का बॉस फाइट
अगला: भाग 12 - Rings, sky fog, और हम फिर से क्या करेंगे
Series guide: /hi/blog/2026-02-25-open-world-browser-series-guide