Skip to content

Commit

Permalink
migrate blocks interaction (scripting) to global chunks storage (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
MihailRis committed Dec 13, 2024
1 parent 53cc8d3 commit e0b3425
Show file tree
Hide file tree
Showing 16 changed files with 227 additions and 144 deletions.
8 changes: 6 additions & 2 deletions dev/tests/example.lua
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
test.set_setting("chunks.load-distance", 2)
test.set_setting("chunks.load-distance", 3)
test.set_setting("chunks.load-speed", 16)

test.reconfig_packs({"base"}, {})
test.new_world("demo", "2019", "core:default")
local pid = player.create("Xerxes")
assert(player.get_name(pid) == "Xerxes")
test.sleep_until(function() return world.count_chunks() >= 9 end, 1000)
print(world.count_chunks())
assert(block.get(0, 0, 0) == block.index("core:obstacle"))

timeit(1000000, block.get, 0, 0, 0)
timeit(1000000, block.get_slow, 0, 0, 0)

block.destruct(0, 0, 0, pid)
assert(block.get(0, 0, 0) == 0)
test.close_world(true)
22 changes: 12 additions & 10 deletions res/content/base/scripts/world.lua
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
function on_block_broken(id, x, y, z, playerid)
gfx.particles.emit({x+0.5, y+0.5, z+0.5}, 64, {
lifetime=1.0,
spawn_interval=0.0001,
explosion={4, 4, 4},
texture="blocks:"..block.get_textures(id)[1],
random_sub_uv=0.1,
size={0.1, 0.1, 0.1},
spawn_shape="box",
spawn_spread={0.4, 0.4, 0.4}
})
if gfx then
gfx.particles.emit({x+0.5, y+0.5, z+0.5}, 64, {
lifetime=1.0,
spawn_interval=0.0001,
explosion={4, 4, 4},
texture="blocks:"..block.get_textures(id)[1],
random_sub_uv=0.1,
size={0.1, 0.1, 0.1},
spawn_shape="box",
spawn_spread={0.4, 0.4, 0.4}
})
end
end
3 changes: 2 additions & 1 deletion src/frontend/debug_panel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "voxels/Block.hpp"
#include "voxels/Chunk.hpp"
#include "voxels/Chunks.hpp"
#include "voxels/ChunksStorage.hpp"
#include "world/Level.hpp"
#include "world/World.hpp"

Expand Down Expand Up @@ -95,7 +96,7 @@ std::shared_ptr<UINode> create_debug_panel(
std::to_wstring(ParticlesRenderer::aliveEmitters);
}));
panel->add(create_label([&]() {
return L"chunks: "+std::to_wstring(level.chunks->getChunksCount())+
return L"chunks: "+std::to_wstring(level.chunksStorage->size())+
L" visible: "+std::to_wstring(ChunksRenderer::visibleChunks);
}));
panel->add(create_label([&]() {
Expand Down
3 changes: 2 additions & 1 deletion src/frontend/hud.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ void Hud::updateHotbarControl() {

void Hud::updateWorldGenDebugVisualization() {
auto& level = frontend.getLevel();
auto& chunks = *level.chunks;
auto generator =
frontend.getController()->getChunksController()->getGenerator();
auto debugInfo = generator->createDebugInfo();
Expand All @@ -293,7 +294,7 @@ void Hud::updateWorldGenDebugVisualization() {
int az = z - (height - areaHeight) / 2;

data[(flippedZ * width + x) * 4 + 1] =
level.chunks->getChunk(ax + ox, az + oz) ? 255 : 0;
chunks.getChunk(ax + ox, az + oz) ? 255 : 0;
data[(flippedZ * width + x) * 4 + 0] =
level.chunksStorage->fetch(ax + ox, az + oz) ? 255 : 0;

Expand Down
2 changes: 1 addition & 1 deletion src/graphics/render/WorldRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ WorldRenderer::WorldRenderer(
auto& settings = engine->getSettings();
level.events->listen(
EVT_CHUNK_HIDDEN,
[this](lvl_event_type, Chunk* chunk) { chunks->unload(chunk); }
[this](LevelEventType, Chunk* chunk) { chunks->unload(chunk); }
);
auto assets = engine->getAssets();
skybox = std::make_unique<Skybox>(
Expand Down
11 changes: 11 additions & 0 deletions src/logic/scripting/lua/libs/libblock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "voxels/Chunk.hpp"
#include "voxels/Chunks.hpp"
#include "voxels/voxel.hpp"
#include "voxels/ChunksStorage.hpp"
#include "world/Level.hpp"
#include "maths/voxmaths.hpp"
#include "data/StructLayout.hpp"
Expand Down Expand Up @@ -114,6 +115,15 @@ static int l_get(lua::State* L) {
return lua::pushinteger(L, id);
}

static int l_get_slow(lua::State* L) {
auto x = lua::tointeger(L, 1);
auto y = lua::tointeger(L, 2);
auto z = lua::tointeger(L, 3);
auto vox = level->chunksStorage->get(x, y, z);
int id = vox == nullptr ? -1 : vox->id;
return lua::pushinteger(L, id);
}

static int l_get_x(lua::State* L) {
auto x = lua::tointeger(L, 1);
auto y = lua::tointeger(L, 2);
Expand Down Expand Up @@ -598,6 +608,7 @@ const luaL_Reg blocklib[] = {
{"is_replaceable_at", lua::wrap<l_is_replaceable_at>},
{"set", lua::wrap<l_set>},
{"get", lua::wrap<l_get>},
{"get_slow", lua::wrap<l_get_slow>},
{"get_X", lua::wrap<l_get_x>},
{"get_Y", lua::wrap<l_get_y>},
{"get_Z", lua::wrap<l_get_z>},
Expand Down
19 changes: 17 additions & 2 deletions src/maths/voxmaths.hpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,29 @@
#pragma once

#include "typedefs.hpp"

inline constexpr int floordiv(int a, int b) {
if (a < 0 && a % b) {
return (a / b) - 1;
}
return a / b;
}

inline constexpr bool is_pot(int a) {
return (a > 0) && ((a & (a - 1)) == 0);
}

inline constexpr unsigned floorlog2(unsigned x) {
return x == 1 ? 0 : 1 + floorlog2(x >> 1);
}

template<int b>
inline constexpr int floordiv(int a) {
if constexpr (is_pot(b)) {
return a >> floorlog2(b);
} else {
return floordiv(a, b);
}
}

inline constexpr int ceildiv(int a, int b) {
if (a > 0 && a % b) {
return a / b + 1;
Expand Down
43 changes: 0 additions & 43 deletions src/util/WeakPtrsMap.hpp

This file was deleted.

76 changes: 23 additions & 53 deletions src/voxels/Chunks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

#include "data/StructLayout.hpp"
#include "coders/byte_utils.hpp"
#include "coders/json.hpp"
#include "content/Content.hpp"
#include "files/WorldFiles.hpp"
#include "graphics/core/Mesh.hpp"
Expand Down Expand Up @@ -39,7 +38,6 @@ Chunks::Chunks(
worldFiles(wfile) {
areaMap.setCenter(ox-w/2, oz-d/2);
areaMap.setOutCallback([this](int, int, const auto& chunk) {
save(chunk.get());
this->level->events->trigger(EVT_CHUNK_HIDDEN, chunk.get());
});
}
Expand All @@ -48,13 +46,13 @@ voxel* Chunks::get(int32_t x, int32_t y, int32_t z) const {
if (y < 0 || y >= CHUNK_H) {
return nullptr;
}
int cx = floordiv(x, CHUNK_W);
int cz = floordiv(z, CHUNK_D);
int cx = floordiv<CHUNK_W>(x);
int cz = floordiv<CHUNK_D>(z);
auto ptr = areaMap.getIf(cx, cz);
if (ptr == nullptr) {
return nullptr;
}
Chunk* chunk = ptr->get(); // not thread safe
Chunk* chunk = ptr->get();
if (chunk == nullptr) {
return nullptr;
}
Expand Down Expand Up @@ -107,27 +105,27 @@ const AABB* Chunks::isObstacleAt(float x, float y, float z) const {
bool Chunks::isSolidBlock(int32_t x, int32_t y, int32_t z) {
voxel* v = get(x, y, z);
if (v == nullptr) return false;
return indices->blocks.get(v->id)->rt.solid; //-V522
return indices->blocks.require(v->id).rt.solid;
}

bool Chunks::isReplaceableBlock(int32_t x, int32_t y, int32_t z) {
voxel* v = get(x, y, z);
if (v == nullptr) return false;
return indices->blocks.get(v->id)->replaceable; //-V522
return indices->blocks.require(v->id).replaceable;
}

bool Chunks::isObstacleBlock(int32_t x, int32_t y, int32_t z) {
voxel* v = get(x, y, z);
if (v == nullptr) return false;
return indices->blocks.get(v->id)->obstacle; //-V522
return indices->blocks.require(v->id).obstacle;
}

ubyte Chunks::getLight(int32_t x, int32_t y, int32_t z, int channel) const {
if (y < 0 || y >= CHUNK_H) {
return 0;
}
int cx = floordiv(x, CHUNK_W);
int cz = floordiv(z, CHUNK_D);
int cx = floordiv<CHUNK_W>(x);
int cz = floordiv<CHUNK_D>(z);

auto ptr = areaMap.getIf(cx, cz);
if (ptr == nullptr) {
Expand All @@ -146,8 +144,8 @@ light_t Chunks::getLight(int32_t x, int32_t y, int32_t z) const {
if (y < 0 || y >= CHUNK_H) {
return 0;
}
int cx = floordiv(x, CHUNK_W);
int cz = floordiv(z, CHUNK_D);
int cx = floordiv<CHUNK_W>(x);
int cz = floordiv<CHUNK_D>(z);

auto ptr = areaMap.getIf(cx, cz);
if (ptr == nullptr) {
Expand All @@ -166,8 +164,8 @@ Chunk* Chunks::getChunkByVoxel(int32_t x, int32_t y, int32_t z) const {
if (y < 0 || y >= CHUNK_H) {
return nullptr;
}
int cx = floordiv(x, CHUNK_W);
int cz = floordiv(z, CHUNK_D);
int cx = floordiv<CHUNK_W>(x);
int cz = floordiv<CHUNK_D>(z);
if (auto ptr = areaMap.getIf(cx, cz)) {
return ptr->get();
}
Expand Down Expand Up @@ -369,8 +367,8 @@ void Chunks::set(
if (y < 0 || y >= CHUNK_H) {
return;
}
int cx = floordiv(x, CHUNK_W);
int cz = floordiv(z, CHUNK_D);
int cx = floordiv<CHUNK_W>(x);
int cz = floordiv<CHUNK_D>(z);
auto ptr = areaMap.getIf(cx, cz);
if (ptr == nullptr) {
return;
Expand Down Expand Up @@ -673,7 +671,11 @@ void Chunks::resize(uint32_t newW, uint32_t newD) {
}

bool Chunks::putChunk(const std::shared_ptr<Chunk>& chunk) {
return areaMap.set(chunk->x, chunk->z, chunk);
if (areaMap.set(chunk->x, chunk->z, chunk)) {
level->events->trigger(LevelEventType::EVT_CHUNK_SHOWN, chunk.get());
return true;
}
return false;
}

// reduce nesting on next modification
Expand All @@ -692,11 +694,11 @@ void Chunks::getVoxels(VoxelsVolume* volume, bool backlight) const {
int h = volume->getH();
int d = volume->getD();

int scx = floordiv(x, CHUNK_W);
int scz = floordiv(z, CHUNK_D);
int scx = floordiv<CHUNK_W>(x);
int scz = floordiv<CHUNK_D>(z);

int ecx = floordiv(x + w, CHUNK_W);
int ecz = floordiv(z + d, CHUNK_D);
int ecx = floordiv<CHUNK_W>(x + w);
int ecz = floordiv<CHUNK_D>(z + d);

int cw = ecx - scx + 1;
int cd = ecz - scz + 1;
Expand Down Expand Up @@ -768,35 +770,3 @@ void Chunks::getVoxels(VoxelsVolume* volume, bool backlight) const {
void Chunks::saveAndClear() {
areaMap.clear();
}

void Chunks::save(Chunk* chunk) {
if (chunk != nullptr) {
AABB aabb(
glm::vec3(chunk->x * CHUNK_W, -INFINITY, chunk->z * CHUNK_D),
glm::vec3(
(chunk->x + 1) * CHUNK_W, INFINITY, (chunk->z + 1) * CHUNK_D
)
);
auto entities = level->entities->getAllInside(aabb);
auto root = dv::object();
root["data"] = level->entities->serialize(entities);
if (!entities.empty()) {
level->entities->despawn(std::move(entities));
chunk->flags.entities = true;
}
worldFiles->getRegions().put(
chunk,
chunk->flags.entities ? json::to_binary(root, true)
: std::vector<ubyte>()
);
}
}

void Chunks::saveAll() {
const auto& chunks = areaMap.getBuffer();
for (size_t i = 0; i < areaMap.area(); i++) {
if (auto& chunk = chunks[i]) {
save(chunk.get());
}
}
}
2 changes: 0 additions & 2 deletions src/voxels/Chunks.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,6 @@ class Chunks {
void resize(uint32_t newW, uint32_t newD);

void saveAndClear();
void save(Chunk* chunk);
void saveAll();

const std::vector<std::shared_ptr<Chunk>>& getChunks() const {
return areaMap.getBuffer();
Expand Down
Loading

0 comments on commit e0b3425

Please sign in to comment.