Difference between revisions of "Engine/Mapgen"
Line 1: | Line 1: | ||
[[Category:Core]] | [[Category:Core]] | ||
+ | == Overview == | ||
+ | A map generator (hereinafter referred to as 'mapgen') object creates new map and responds to queries about map terrain. Each derived Mapgen class must implement the two pure virtual methods in the Mapgen interface, makeChunk() and getGroundLevelAtPoint(). | ||
+ | === Mapgen === | ||
+ | ===== Pure virtual methods to be implemented ===== | ||
+ | <source lang="cpp"> | ||
+ | virtual int getGroundLevelAtPoint(v2s16 p); | ||
+ | </source> | ||
+ | Returns the ground height at the 2d coordinates p. | ||
+ | <br /> | ||
+ | <source lang="cpp"> | ||
+ | virtual void makeChunk(BlockMakeData *data); | ||
+ | </source> | ||
+ | Given a BlockMakeData structure, update the included ManualMapVoxelManipulator for the range of blocks from blockpos_min up to and also blockpos_max with MapNodes from the included INodeDefManager. | ||
+ | <br /> | ||
+ | ===== Non-virtual methods ===== | ||
+ | <source lang="cpp"> | ||
+ | void updateLiquid(UniqueQueue<v3s16> *trans_liquid, v3s16 nmin, v3s16 nmax); | ||
+ | </source> | ||
+ | Add liquids that need to be updated to the transforming_liquid queue. | ||
+ | <source lang="cpp"> | ||
+ | void setLighting(v3s16 nmin, v3s16 nmax, u8 light); | ||
+ | </source> | ||
+ | Set all nodes' light levels in vm to the specified, uniform light level. | ||
+ | <source lang="cpp"> | ||
+ | void updateLighting(v3s16 nmin, v3s16 nmax); | ||
+ | </source> | ||
+ | Calculate and update the lighting for nodes in vm. | ||
+ | <source lang="cpp"> | ||
+ | void updateLightingOld(v3s16 nmin, v3s16 nmax); | ||
+ | </source> | ||
+ | Same as updateLighting() and may be slightly more accurate, but 22x slower on average. | ||
+ | |||
+ | ===== Members ===== | ||
+ | ManualMapVoxelManipulator *vm | ||
+ | Must be a pointer to a valid ManualMapVoxelManipulator while makeChunk() is executed. Set this equal to what is given in BlockMakeData. | ||
+ | INodeDefManager *ndef | ||
+ | Must be a pointer to a valid INodeDefManager while makeChunk() is executed. Set this equal to what is given in BlockMakeData. | ||
+ | |||
+ | === BlockMakeData === | ||
+ | A BlockMakeData structure has the following members:<br /> | ||
+ | ManualMapVoxelManipulator *vmanip | ||
+ | The ManualMapVoxelManipulator where nodes are to be written to. Already contains the current map contents in the contained coordinates. If a node has not previously been written to, it is CONTENT_IGNORE.<br /> | ||
+ | u64 seed | ||
+ | The 64-bit map seed to be used for randomized events. Not need anymore, as the base MapgenParams object passed to MapgenFactory::createMapgen() will contain this as well.<br /> | ||
+ | v3s16 blockpos_min | ||
+ | v3s16 blockpos_max | ||
+ | Respectively, the minimum and maximum (inclusive) block (NOT NODE) coordinates to be generated.<br /> | ||
+ | v3s16 blockpos_requested | ||
+ | The block coordinate of the actual block requested for generation. Not really necessary.<br /> | ||
+ | UniqueQueue<v3s16> transforming_liquid | ||
+ | A UniqueQueue of 3d coordinates specifying which nodes are liquid and need a liquid transform applied after generation so they can flow. <br /> | ||
+ | INodeDefManager *nodedef | ||
+ | A NodeDef that contains the definitions for nodes to be placed to the ManualMapVoxelManipulator.<br /> | ||
+ | |||
== Boilerplate Mapgen Code == | == Boilerplate Mapgen Code == | ||
− | Here is the bare minimum for a (playable) map generator | + | Here is the bare minimum for a (playable) map generator: |
<source lang="cpp"> | <source lang="cpp"> | ||
class MapgenTest : public Mapgen { | class MapgenTest : public Mapgen { | ||
Line 18: | Line 72: | ||
for (int x = node_min.X; x <= node_max.X; x++) { | for (int x = node_min.X; x <= node_max.X; x++) { | ||
int i = vm->m_area.index(x, y, z); | int i = vm->m_area.index(x, y, z); | ||
− | + | vm->m_data[i] = (y == -4) ? n_grass : n_air; | |
− | |||
− | |||
− | |||
} | } | ||
} | } |
Revision as of 16:10, 16 March 2013
Overview
A map generator (hereinafter referred to as 'mapgen') object creates new map and responds to queries about map terrain. Each derived Mapgen class must implement the two pure virtual methods in the Mapgen interface, makeChunk() and getGroundLevelAtPoint().
Mapgen
Pure virtual methods to be implemented
virtual int getGroundLevelAtPoint(v2s16 p);
Returns the ground height at the 2d coordinates p.
virtual void makeChunk(BlockMakeData *data);
Given a BlockMakeData structure, update the included ManualMapVoxelManipulator for the range of blocks from blockpos_min up to and also blockpos_max with MapNodes from the included INodeDefManager.
Non-virtual methods
void updateLiquid(UniqueQueue<v3s16> *trans_liquid, v3s16 nmin, v3s16 nmax);
Add liquids that need to be updated to the transforming_liquid queue.
void setLighting(v3s16 nmin, v3s16 nmax, u8 light);
Set all nodes' light levels in vm to the specified, uniform light level.
void updateLighting(v3s16 nmin, v3s16 nmax);
Calculate and update the lighting for nodes in vm.
void updateLightingOld(v3s16 nmin, v3s16 nmax);
Same as updateLighting() and may be slightly more accurate, but 22x slower on average.
Members
ManualMapVoxelManipulator *vm
Must be a pointer to a valid ManualMapVoxelManipulator while makeChunk() is executed. Set this equal to what is given in BlockMakeData.
INodeDefManager *ndef
Must be a pointer to a valid INodeDefManager while makeChunk() is executed. Set this equal to what is given in BlockMakeData.
BlockMakeData
A BlockMakeData structure has the following members:
ManualMapVoxelManipulator *vmanip
The ManualMapVoxelManipulator where nodes are to be written to. Already contains the current map contents in the contained coordinates. If a node has not previously been written to, it is CONTENT_IGNORE.
u64 seed
The 64-bit map seed to be used for randomized events. Not need anymore, as the base MapgenParams object passed to MapgenFactory::createMapgen() will contain this as well.
v3s16 blockpos_min v3s16 blockpos_max
Respectively, the minimum and maximum (inclusive) block (NOT NODE) coordinates to be generated.
v3s16 blockpos_requested
The block coordinate of the actual block requested for generation. Not really necessary.
UniqueQueue<v3s16> transforming_liquid
A UniqueQueue of 3d coordinates specifying which nodes are liquid and need a liquid transform applied after generation so they can flow.
INodeDefManager *nodedef
A NodeDef that contains the definitions for nodes to be placed to the ManualMapVoxelManipulator.
Boilerplate Mapgen Code
Here is the bare minimum for a (playable) map generator:
class MapgenTest : public Mapgen {
void makeChunk(BlockMakeData *data) {
vm = data->vmanip;
ndef = data->nodedef;
v3s16 node_min = data->blockpos_min * MAP_BLOCKSIZE;
v3s16 node_max = (data->blockpos_max + v3s16(1,1,1)) * MAP_BLOCKSIZE - v3s16(1,1,1);
MapNode n_air(ndef->getId("mapgen_air"));
MapNode n_grass(ndef->getId("mapgen_dirt_with_grass"));
for (int z = node_min.Z; z <= node_max.Z; z++) {
for (int y = node_min.Y; y <= node_max.Y; y++) {
for (int x = node_min.X; x <= node_max.X; x++) {
int i = vm->m_area.index(x, y, z);
vm->m_data[i] = (y == -4) ? n_grass : n_air;
}
}
}
updateLighting(node_min, node_max);
}
int getGroundLevelAtPoint(v2s16 p) {
return 0;
}
};
class MapgenTestParams : public MapgenParams {
bool readParams(Settings *settings) {
return true;
}
void writeParams(Settings *settings) {
}
};
class MapgenTestFactory : public MapgenFactory {
Mapgen *createMapgen(int mgid, MapgenParams *params, EmergeManager *emerge) {
return new MapgenTest();
}
MapgenParams *createMapgenParams() {
return new MapgenTestParams();
}
};
Then, simply add
registerMapgen("test", new MapgenTestFactory());
to EmergeManager::EmergeManager().