I'm not a fount of knowledge about tutorials, unfortunately, but I can improvise a quick overview of the control flow:
We've got
CvMapGenerator::generateRandomMap and
CvMapGenerator::addGameElements in the (GameCore) DLL, which, I think, get called by the EXE – unless the map is re-generated, which happens via
CvGame::regenerateMap in the DLL. generateRandomMap calls generatePlotTypes (ocean, flat, hills, peak) and generateTerrain (Grassland etc.). addGameElements calls addRivers, addLakes, addFeatures, addBonuses, addGoodies, afterGeneration (for misc. final touches). Those are all CvMapGenerator functions. Lastly,
CvGame::setInitialItems causes starting plots to be chosen and to be beefed up ("normalized"); that's all handled by CvGame. All those CvMapGenerator and CvGame subroutines first attempt a Python call to the map script module (CvDLLPythonIFaceBase::getMapScriptModule - this getter is implemented in the EXE). The map script may perform work in addition to the DLL (signaled by calling
CyPythonMgr().allowDefaultImpl()
) or may fully replace the DLL default behavior. For generatePlotTypes and generateTerrain, the DLL has no (useful) default behavior, and CvMapGenerator::addFeatures doesn't place Forest, Jungle and Ice, i.e. map scripts have to implement those functions, but they can (and most do) make use of
CvMapGeneratorUtil.py. In other words, default behavior for land shapes, relief and vegetation, to use non-technical terms, is implemented in Python. For generating shapes (of continents, deserts etc.), CvMapGeneratorUtil.py uses "height maps" produced via the
CvFractal class in the DLL (exposed to Python through the EXE).
For large (navigable) rivers, my approach would probably be to "widen" some of the small rivers into large rivers. Could add a function CvMapGenerator::addLargeRivers for this that gets called after addRivers by addGameElements.
It seems that the latest approach taken by the "We the People" (WtP; successor of RaR) developers has been to add the large rivers in each map script separately
oesn't look like MagisterBelsarius published any such code:
GitHub contributions in 2021
For FaireWeather, or any script of the
PerfectWorld family, it may make sense to generate the large rivers before the small ones based on rainfall data, and I guess it would be nice to generate the large-river terrain along with the other terrain types, i.e. well before small rivers, but, at least in a (BtS) mod that needs to work with many different map scripts, a single algorithm for all map scripts is imo a necessity, and I don't think an additional custom algorithm for e.g. PerfectWorld is going to be worth the extra effort. The small rivers generated by PerfectWorld will be based on rainfall, so large rivers placed based on small rivers will also, indirectly, be based on rainfall.
As for Python being your preferred language, that should not be difficult to accommodate. The DLL can call (through an unwieldy syntax) any function in a Python (v2.4
) module, and all CvPlot and CvMap functions relevant for placing large rivers should already be
exposed to Python. The approach consistent with generatePlotTypes would be to let the map script forward a call received from the DLL to CvMapGeneratorUtil, but that would require every map script to be changed. Better to call the map script from the DLL to
allow an override and, then, if not overridden, to call CvMapGeneratorUtil (or whichever module) directly from the DLL for the default behavior.
edit: clarity