Skip to content

Commit e8856d7

Browse files
committed
Refactor chunk generation to use Lua scripts
Replaces hardcoded chunk generation logic with Lua script-based generation in Planet::GenerateChunk. Updates the function signature to accept a script name and modifies PlayerSessionHandler to use planet data from the database for chunk regeneration.
1 parent 73628f9 commit e8856d7

3 files changed

Lines changed: 26 additions & 276 deletions

File tree

include/CommonLib/Planet.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ namespace tsom
4444
void ForEachChunk(Nz::FunctionRef<void(const ChunkIndices& chunkIndices, Chunk& chunk)> callback) override;
4545
void ForEachChunk(Nz::FunctionRef<void(const ChunkIndices& chunkIndices, const Chunk& chunk)> callback) const override;
4646

47-
void GenerateChunk(const BlockLibrary& blockLibrary, Chunk& chunk, Nz::UInt32 seed, const Nz::Vector3ui& chunkCount);
47+
void GenerateChunk(const BlockLibrary& blockLibrary, Chunk& chunk, Nz::UInt32 seed, const Nz::Vector3ui& chunkCount, std::string scriptName);
4848
void GenerateChunks(const BlockLibrary& blockLibrary, Nz::TaskScheduler& taskScheduler, Nz::UInt32 seed, const Nz::Vector3ui& chunkCount, std::string scriptName);
4949
void GeneratePlatform(const BlockLibrary& blockLibrary, Direction upDirection, const BlockIndices& platformCenter);
5050

src/CommonLib/Planet.cpp

Lines changed: 14 additions & 273 deletions
Original file line numberDiff line numberDiff line change
@@ -227,289 +227,30 @@ namespace tsom
227227
callback(chunkIndices, *chunkData.chunk);
228228
}
229229

230-
void Planet::GenerateChunk(const BlockLibrary& blockLibrary, Chunk& chunk, Nz::UInt32 seed, const Nz::Vector3ui& chunkCount)
230+
void Planet::GenerateChunk(const BlockLibrary& blockLibrary, Chunk& chunk, Nz::UInt32 seed, const Nz::Vector3ui& chunkCount, std::string scriptName)
231231
{
232-
constexpr std::size_t freeSpace = 30;
233-
234232
ChunkIndices chunkIndices = chunk.GetIndices();
235-
Nz::UInt32 chunkSeed = seed + static_cast<Nz::UInt32>(chunkIndices.x) + static_cast<Nz::UInt32>(chunkIndices.y) + static_cast<Nz::UInt32>(chunkIndices.z);
236233

237-
std::minstd_rand rand(chunkSeed);
238-
std::bernoulli_distribution dis(0.9);
234+
ScriptingContext scriptingContext = ScriptingContext(m_app);
235+
scriptingContext.RegisterLibrary<MathScriptingLibrary>();
236+
scriptingContext.RegisterLibrary<ChunkScriptingLibrary>();
239237

240-
BlockIndex dirtBlockIndex = blockLibrary.GetBlockIndex("dirt");
241-
BlockIndex grassBlockIndex = blockLibrary.GetBlockIndex("grass");
242-
BlockIndex stoneBlockIndex = blockLibrary.GetBlockIndex("stone");
243-
BlockIndex stoneMossyBlockIndex = blockLibrary.GetBlockIndex("stone_mossy");
244-
BlockIndex snowBlockIndex = blockLibrary.GetBlockIndex("snow");
238+
Nz::Result execResult = scriptingContext.LoadFile(fmt::format("scripts/planets/{}.lua", scriptName));
239+
if (!execResult)
240+
return;
245241

246-
Nz::Vector3i maxHeight((Nz::Vector3i(chunkCount) + Nz::Vector3i(1)) / 2);
247-
maxHeight *= int(Planet::ChunkSize);
242+
sol::protected_function generationFunction = execResult.GetValue();
248243

249244
chunk.LockWrite();
250245
NAZARA_DEFER({ chunk.UnlockWrite(); });
251246

252-
chunk.Reset([&](BlockIndex* blockIndices)
247+
auto result = generationFunction(chunk, seed, chunkCount);
248+
if (!result.valid())
253249
{
254-
// Fill all blocks based on their depth
255-
ChunkIndices chunkIndices = chunk.GetIndices();
256-
257-
double heightScale = 1.5f * m_tileSize;
258-
double scale = 0.02f * m_tileSize;
259-
260-
siv::PerlinNoise perlin;
261-
262-
BlockIndex* blockIndexPtr = blockIndices;
263-
#if 0
264-
for (unsigned int z = 0; z < Planet::ChunkSize; ++z)
265-
{
266-
for (unsigned int y = 0; y < Planet::ChunkSize; ++y)
267-
{
268-
for (unsigned int x = 0; x < Planet::ChunkSize; ++x)
269-
{
270-
Nz::Vector3i blockPos = GetBlockIndices(chunkIndices, { x, y, z });
271-
float distToSurface = sdRoundBox(Nz::Vector3f(blockPos), Nz::Vector3f(80.f, 80.f, 80.f), m_cornerRadius);
272-
273-
if (distToSurface <= 0.f)
274-
*blockIndexPtr++ = dirtBlockIndex;
275-
else
276-
*blockIndexPtr++ = EmptyBlockIndex;
277-
}
278-
}
279-
}
280-
#endif
281-
282-
#if 1
283-
for (unsigned int z = 0; z < Planet::ChunkSize; ++z)
284-
{
285-
for (unsigned int y = 0; y < Planet::ChunkSize; ++y)
286-
{
287-
for (unsigned int x = 0; x < Planet::ChunkSize; ++x)
288-
{
289-
Nz::Vector3i blockPos = GetBlockIndices(chunkIndices, { x, y, z });
290-
unsigned int depth = Nz::SafeCaster(std::min({
291-
maxHeight.x - std::abs(blockPos.x),
292-
maxHeight.y - std::abs(blockPos.z),
293-
maxHeight.z - std::abs(blockPos.y)
294-
}));
295-
296-
if (depth < freeSpace)
297-
{
298-
*blockIndexPtr++ = EmptyBlockIndex;
299-
continue;
300-
}
301-
302-
depth -= freeSpace;
303-
304-
BlockIndices mapPos = GetBlockIndices(chunkIndices, { x, y, z });
305-
double presence = perlin.normalizedOctave3D_01(mapPos.x * scale, mapPos.y * scale, mapPos.z * scale, 4);
306-
307-
if (depth < 20)
308-
presence *= std::max(double(depth) / 20.0, 1.0);
309-
310-
presence += double(depth) / std::max({ maxHeight.x, maxHeight.y, maxHeight.z });
311-
312-
BlockIndex blockIndex;
313-
if (presence > 0.6)
314-
{
315-
if (depth <= 6 * 2)
316-
blockIndex = snowBlockIndex;
317-
else if (depth <= 18 * 2)
318-
blockIndex = dirtBlockIndex;
319-
else
320-
blockIndex = (dis(rand)) ? stoneBlockIndex : stoneMossyBlockIndex;
321-
}
322-
else
323-
blockIndex = EmptyBlockIndex;
324-
325-
if (std::abs(blockPos.x) <= 2 && std::abs(blockPos.z) <= 2)
326-
blockIndex = EmptyBlockIndex;
327-
328-
if (blockIndex != InvalidBlockIndex)
329-
*blockIndexPtr++ = blockIndex;
330-
331-
#if 0
332-
333-
depth -= freeSpace;
334-
335-
BlockIndex blockIndex;
336-
if (depth <= 6 * 2)
337-
blockIndex = snowBlockIndex;
338-
else if (depth <= 18 * 2)
339-
blockIndex = dirtBlockIndex;
340-
else
341-
blockIndex = (dis(rand)) ? stoneBlockIndex : stoneMossyBlockIndex;
342-
343-
if (std::abs(blockPos.x) <= 2 && std::abs(blockPos.z) <= 2)
344-
blockIndex = EmptyBlockIndex;
345-
346-
if (blockIndex != InvalidBlockIndex)
347-
*blockIndexPtr++ = blockIndex;
348-
#endif
349-
}
350-
}
351-
}
352-
#endif
353-
354-
#if 0
355-
Nz::EnumArray<Direction, siv::PerlinNoise> perlin;
356-
for (auto&& [dir, noise] : perlin.iter_kv())
357-
noise.reseed(seed + static_cast<unsigned int>(dir));
358-
359-
double heightScale = 1.5f * m_tileSize;
360-
double scale = 0.02f * m_tileSize;
361-
362-
// +X
363-
for (unsigned int y = 0; y < Planet::ChunkSize; ++y)
364-
{
365-
for (unsigned int x = 0; x < Planet::ChunkSize; ++x)
366-
{
367-
BlockIndices mapPos = GetBlockIndices(chunkIndices, { 0, x, y });
368-
double height = perlin[Direction::Right].normalizedOctave2D_01(mapPos.y * scale, mapPos.z * scale, 4) * heightScale;
369-
370-
int terrainDepth = std::round(std::min<double>(height * (maxHeight.x / 2 - freeSpace) + freeSpace, maxHeight.x / 2));
371-
int blockDepth = maxHeight.x - mapPos.x + 1;
372-
if (blockDepth < terrainDepth)
373-
continue;
374-
375-
unsigned int startHeight = Nz::SafeCaster(blockDepth - terrainDepth);
376-
if (startHeight >= Planet::ChunkSize)
377-
continue;
378-
379-
if (BlockIndex& blockType = blockIndices[chunk.GetBlockLocalIndex({ startHeight, x, y })]; blockType == dirtBlockIndex)
380-
blockType = grassBlockIndex;
381-
382-
for (unsigned int height = startHeight + 1; height < Planet::ChunkSize; ++height)
383-
blockIndices[chunk.GetBlockLocalIndex({ height, x, y })] = EmptyBlockIndex;
384-
}
385-
}
386-
387-
// -X
388-
for (unsigned int y = 0; y < Planet::ChunkSize; ++y)
389-
{
390-
for (unsigned int x = 0; x < Planet::ChunkSize; ++x)
391-
{
392-
BlockIndices mapPos = GetBlockIndices(chunkIndices, { Planet::ChunkSize - 1, x, y });
393-
double height = perlin[Direction::Left].normalizedOctave2D_01(mapPos.y * scale, mapPos.z * scale, 4) * heightScale;
394-
395-
int terrainDepth = std::round(std::min<double>(height * (maxHeight.x / 2 - freeSpace) + freeSpace, maxHeight.x / 2));
396-
int blockDepth = maxHeight.x + mapPos.x + 1;
397-
if (blockDepth < terrainDepth)
398-
continue;
399-
400-
unsigned int startHeight = Nz::SafeCast<unsigned int>(blockDepth - terrainDepth);
401-
if (startHeight >= Planet::ChunkSize)
402-
continue;
403-
404-
if (BlockIndex& blockType = blockIndices[chunk.GetBlockLocalIndex({ Planet::ChunkSize - startHeight - 1, x, y })]; blockType == dirtBlockIndex)
405-
blockType = grassBlockIndex;
406-
407-
for (unsigned int height = startHeight + 1; height < Planet::ChunkSize; ++height)
408-
blockIndices[chunk.GetBlockLocalIndex({ Planet::ChunkSize - height - 1, x, y })] = EmptyBlockIndex;
409-
}
410-
}
411-
412-
// +Y
413-
for (unsigned int z = 0; z < Planet::ChunkSize; ++z)
414-
{
415-
for (unsigned int x = 0; x < Planet::ChunkSize; ++x)
416-
{
417-
BlockIndices mapPos = GetBlockIndices(chunkIndices, { x, z, 0 });
418-
double height = perlin[Direction::Up].normalizedOctave2D_01(mapPos.x * scale, mapPos.z * scale, 4) * heightScale;
419-
420-
int terrainDepth = std::round(std::min<double>(height * (maxHeight.y / 2 - freeSpace) + freeSpace, maxHeight.y / 2));
421-
int blockDepth = maxHeight.y - mapPos.y + 1;
422-
if (blockDepth < terrainDepth)
423-
continue;
424-
425-
unsigned int startHeight = Nz::SafeCaster(blockDepth - terrainDepth);
426-
if (startHeight >= Planet::ChunkSize)
427-
continue;
428-
429-
if (BlockIndex& blockType = blockIndices[chunk.GetBlockLocalIndex({ x, z, startHeight })]; blockType == dirtBlockIndex)
430-
blockType = grassBlockIndex;
431-
432-
for (unsigned int height = startHeight + 1; height < Planet::ChunkSize; ++height)
433-
blockIndices[chunk.GetBlockLocalIndex({ x, z, height })] = EmptyBlockIndex;
434-
}
435-
}
436-
437-
// -Y
438-
for (unsigned int z = 0; z < Planet::ChunkSize; ++z)
439-
{
440-
for (unsigned int x = 0; x < Planet::ChunkSize; ++x)
441-
{
442-
BlockIndices mapPos = GetBlockIndices(chunkIndices, { x, z, Planet::ChunkSize - 1 });
443-
double height = perlin[Direction::Down].normalizedOctave2D_01(mapPos.x * scale, mapPos.z * scale, 4) * heightScale;
444-
445-
int terrainDepth = std::round(std::min<double>(height * (maxHeight.y / 2 - freeSpace) + freeSpace, maxHeight.y / 2));
446-
int blockDepth = maxHeight.y + mapPos.y + 1;
447-
if (blockDepth < terrainDepth)
448-
continue;
449-
450-
unsigned int startHeight = Nz::SafeCast<unsigned int>(blockDepth - terrainDepth);
451-
if (startHeight >= Planet::ChunkSize)
452-
continue;
453-
454-
if (BlockIndex& blockType = blockIndices[chunk.GetBlockLocalIndex({ x, z, Planet::ChunkSize - startHeight - 1 })]; blockType == dirtBlockIndex)
455-
blockType = grassBlockIndex;
456-
457-
for (unsigned int height = startHeight + 1; height < Planet::ChunkSize; ++height)
458-
blockIndices[chunk.GetBlockLocalIndex({ x, z, Planet::ChunkSize - height - 1 })] = EmptyBlockIndex;
459-
}
460-
}
461-
462-
// +Z
463-
for (unsigned int y = 0; y < Planet::ChunkSize; ++y)
464-
{
465-
for (unsigned int x = 0; x < Planet::ChunkSize; ++x)
466-
{
467-
BlockIndices mapPos = GetBlockIndices(chunkIndices, { x, 0, y });
468-
double height = perlin[Direction::Back].normalizedOctave2D_01(mapPos.x * scale, mapPos.y * scale, 4) * heightScale;
469-
470-
int terrainDepth = std::round(std::min<double>(height * (maxHeight.z / 2 - freeSpace) + freeSpace, maxHeight.z / 2));
471-
int blockDepth = maxHeight.z - mapPos.z + 1;
472-
if (blockDepth < terrainDepth)
473-
continue;
474-
475-
unsigned int startHeight = Nz::SafeCaster(blockDepth - terrainDepth);
476-
if (startHeight >= Planet::ChunkSize)
477-
continue;
478-
479-
if (BlockIndex& blockType = blockIndices[chunk.GetBlockLocalIndex({ x, startHeight, y })]; blockType == dirtBlockIndex)
480-
blockType = grassBlockIndex;
481-
482-
for (unsigned int height = startHeight + 1; height < Planet::ChunkSize; ++height)
483-
blockIndices[chunk.GetBlockLocalIndex({ x, height, y })] = EmptyBlockIndex;
484-
}
485-
}
486-
487-
// -Z
488-
for (unsigned int y = 0; y < Planet::ChunkSize; ++y)
489-
{
490-
for (unsigned int x = 0; x < Planet::ChunkSize; ++x)
491-
{
492-
BlockIndices mapPos = GetBlockIndices(chunkIndices, { x, Planet::ChunkSize - 1, y });
493-
double height = perlin[Direction::Front].normalizedOctave2D_01(mapPos.x * scale, mapPos.y * scale, 4) * heightScale;
494-
495-
int terrainDepth = std::round(std::min<double>(height * (maxHeight.z / 2 - freeSpace) + freeSpace, maxHeight.z / 2));
496-
int blockDepth = maxHeight.z + mapPos.z + 1;
497-
if (blockDepth < terrainDepth)
498-
continue;
499-
500-
unsigned int startHeight = Nz::SafeCaster(blockDepth - terrainDepth);
501-
if (startHeight >= Planet::ChunkSize)
502-
continue;
503-
504-
if (BlockIndex& blockType = blockIndices[chunk.GetBlockLocalIndex({ x, Planet::ChunkSize - startHeight - 1, y })]; blockType == dirtBlockIndex)
505-
blockType = grassBlockIndex;
506-
507-
for (unsigned int height = startHeight + 1; height < Planet::ChunkSize; ++height)
508-
blockIndices[chunk.GetBlockLocalIndex({ x, Planet::ChunkSize - height - 1, y })] = EmptyBlockIndex;
509-
}
510-
}
511-
#endif
512-
});
250+
sol::error err = result;
251+
spdlog::error("chunk {};{};{} failed to generate: {}", chunkIndices.x, chunkIndices.y, chunkIndices.z, err.what());
252+
return;
253+
}
513254
}
514255

515256
void Planet::GenerateChunks(const BlockLibrary& blockLibrary, Nz::TaskScheduler& taskScheduler, Nz::UInt32 seed, const Nz::Vector3ui& chunkCount, std::string scriptName)

src/ServerLib/Session/PlayerSessionHandler.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,8 +364,17 @@ namespace tsom
364364

365365
if (Chunk* chunk = planet.GetChunk(chunkIndices))
366366
{
367-
planet.GenerateChunk(blockLibrary, *chunk, 42, Nz::Vector3ui(5));
368-
spdlog::info("regenerated chunk {};{};{}", chunkIndices.x, chunkIndices.y, chunkIndices.z);
367+
std::optional<Nz::UInt32> planetId = planetEnvironment->GetDatabaseId();
368+
serverInstance.GetServerDatabase().GetAllPlanets([&](Database::Planet&& planetData)
369+
{
370+
if (planetData.id == planetId)
371+
{
372+
planet.GenerateChunk(blockLibrary, *chunk, planetData.seed, planetData.chunkCount, planetData.generatorName.data());
373+
spdlog::info("regenerated chunk {};{};{}", chunkIndices.x, chunkIndices.y, chunkIndices.z);
374+
return false;
375+
}
376+
return true;
377+
});
369378
}
370379
return;
371380
}

0 commit comments

Comments
 (0)