Optimize the MeshVertex format.

master
Auri 2021-08-04 22:17:40 -07:00
parent e9d7fd0ee9
commit f8a3889f6d
53 changed files with 527 additions and 449 deletions

View File

@ -8,11 +8,11 @@ layout (location = 4) in float aNormal;
layout (location = 3) in vec2 aBlendMaskCoords;
layout (location = 1) in vec2 aTexCoords;
layout (location = 2) in vec3 aBlend;
layout (location = 5) in vec4 aLight;
layout (location = 2) in ivec3 aBlend;
layout (location = 5) in ivec4 aLight;
layout (location = 6) in float aShaderMod;
layout (location = 7) in vec3 aModValues;
layout (location = 6) in int aShaderMod;
layout (location = 7) in ivec3 aModValues;
out VS_OUT {
vec3 pos;
@ -40,7 +40,7 @@ void main() {
vs_out.blendMaskCoords = aBlendMaskCoords;
vs_out.texCoords = aTexCoords;
vs_out.blend = aBlend;
vs_out.blend = vec3(aBlend / 255.0);
vs_out.light = light;
vs_out.modType = aShaderMod;

View File

@ -201,8 +201,8 @@ add_library(Zepha_Core
server/ServerClient.h
server/ServerClients.cpp
server/ServerClients.h
server/ServerConfig.cpp
server/ServerConfig.h
server/ServerInfoSender.cpp
server/ServerInfoSender.h
server/stream/ServerGenStream.cpp
server/stream/ServerGenStream.h
server/stream/ServerPacketStream.cpp

View File

@ -8,7 +8,7 @@
Window::Window() : Window({ 800, 600 }) {};
Window::Window(glm::ivec2 win) :
Window::Window(ivec2 win) :
win(win), center(win.x / 2, win.y / 2) {
if (!glfwInit()) {
@ -61,6 +61,11 @@ Window::Window(glm::ivec2 win) :
void Window::update() {
input.update();
for (let it = resizeCallbacks.begin(); it != resizeCallbacks.end();) {
if (it->first.unique()) it = resizeCallbacks.erase(it);
else it++;
}
}
bool Window::shouldClose() {
@ -71,15 +76,13 @@ void Window::swapBuffers() {
glfwSwapBuffers(mainWindow);
}
void Window::addResizeCallback(const std::string& identifier, std::function<void(glm::ivec2)> cb) {
resizeCallbacks.emplace(identifier, cb);
Window::RCBLock Window::onResize(std::function<void(ivec2)> cb) {
RCBLock lock = make_shared<bool>(true);
resizeCallbacks.emplace_back(std::pair(lock, cb));
return lock;
}
void Window::removeResizeCallback(const std::string& identifier) {
resizeCallbacks.erase(identifier);
}
glm::ivec2 Window::getSize() {
ivec2 Window::getSize() {
return win;
}
@ -87,13 +90,12 @@ void Window::setCursorHand(bool hand) {
glfwSetCursor(mainWindow, hand ? handCursor : nullptr);
}
void Window::scrollCallback(GLFWwindow* window, double xO, double yO) {
void Window::scrollCallback(GLFWwindow* window, f64 xO, f64 yO) {
// auto w = static_cast<Window*>(glfwGetWindowUserPointer(window));
}
void Window::resizeCallback(GLFWwindow* window, int width, int height) {
auto w = static_cast<Window*>(glfwGetWindowUserPointer(window));
void Window::resizeCallback(GLFWwindow* window, i32 width, i32 height) {
let w = static_cast<Window*>(glfwGetWindowUserPointer(window));
glfwGetFramebufferSize(window, &w->win.x, &w->win.y);
glViewport(0, 0, w->win.x, w->win.y);

View File

@ -4,17 +4,21 @@
#pragma once
#include <map>
#include <list>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "util/Types.h"
#include "Input.h"
class Window {
public:
public:
using RCBLock = sptr<bool>;
Window();
Window(glm::ivec2 win);
Window(ivec2 win);
void update();
@ -22,11 +26,9 @@ class Window {
void swapBuffers();
void addResizeCallback(const std::string& identifier, std::function<void(glm::ivec2)> cb);
RCBLock onResize(std::function<void(ivec2)> cb);
void removeResizeCallback(const std::string& identifier);
glm::ivec2 getSize();
ivec2 getSize();
void setCursorHand(bool hand);
@ -34,19 +36,20 @@ class Window {
Input input;
GLFWwindow* mainWindow = nullptr;
private:
static void scrollCallback(GLFWwindow* window, double xO, double yO);
private:
static void scrollCallback(GLFWwindow* window, f64 xO, f64 yO);
static void resizeCallback(GLFWwindow* window, int width, int height);
static void resizeCallback(GLFWwindow* window, i32 width, i32 height);
GLFWcursor* handCursor = nullptr;
glm::ivec2 win;
glm::ivec2 center;
ivec2 win;
ivec2 center;
bool keys[1024]{};
bool keys[1024] {};
std::map<std::string, std::function<void(glm::ivec2)>> resizeCallbacks;
std::list<std::pair<RCBLock, std::function<void(ivec2)>>> resizeCallbacks {};
};

View File

@ -39,7 +39,7 @@ Renderer::Renderer(glm::ivec2 win) :
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
window.addResizeCallback("renderer", [&](glm::ivec2 win) {
lock = window.onResize([&](glm::ivec2 win) {
ssao.windowResized(win);
blur.windowResized(win);
light.windowResized(win);

View File

@ -75,5 +75,7 @@ private:
GLint currentModelUniform;
double elapsedTime = 0;
Window::RCBLock lock;
};

View File

@ -19,7 +19,8 @@
#include "game/atlas/LocalDefinitionAtlas.h"
ChunkMeshGenerator::ChunkMeshGenerator(MeshChunkDetails* meshDetails, LocalDefinitionAtlas& defs,
LocalBiomeAtlas& biomes, uptr<Chunk> chk, array<uptr<Chunk>, 6> adj, array<NoiseSample, 3>& blockOffsets) :
LocalBiomeAtlas& biomes, uptr<Chunk> chk, array<uptr<Chunk>, 6> adj, array<NoiseSample, 3>& blockOffsets,
Detail detail) :
defs(defs),
biomes(biomes),
chunk(std::move(chk)),
@ -43,8 +44,8 @@ ChunkMeshGenerator::ChunkMeshGenerator(MeshChunkDetails* meshDetails, LocalDefin
if (!biome || biome->index != biomesArr[i])
biome = &biomes.biomeFromId(biomesArr[i]);
BlockModel& model = block->model;
vec3 biomeTint = biome->tint;
BlockModel& model = detail == Detail::HIGH ? block->model : block->farModel;
u8vec3 biomeTint = u8vec3(biome->tint * 255.f);
if (!model.visible) continue;
@ -96,16 +97,16 @@ u16 ChunkMeshGenerator::getBlockAt(const ivec3& pos) {
}
u8vec4 ChunkMeshGenerator::getLightAt(const ivec3& pos) {
// auto dir = glm::floor(vec3(pos) / 16.f);
// if (dir.x != 0 || dir.y != 0 || dir.z != 0) {
// u8 ind = static_cast<u8>(Vec::TO_ENUM.at(dir));
// return adjacent[ind]->getLight(Space::Block::index(pos));
// }
return u8vec4 { 0, 0, 0, 15 };
// return chunk->getLight(Space::Block::index(pos));
auto dir = glm::floor(vec3(pos) / 16.f);
if (dir.x != 0 || dir.y != 0 || dir.z != 0) {
u8 ind = static_cast<u8>(Vec::TO_ENUM.at(dir));
return adjacent[ind]->getLight(Space::Block::index(pos));
}
return chunk->getLight(Space::Block::index(pos));
}
void ChunkMeshGenerator::addFaces(const vec3& offset, const vec<MeshPart>& meshParts, const vec3& tint, u8vec4 light) {
void ChunkMeshGenerator::addFaces(const vec3& offset,
const vec<MeshPart>& meshParts, const u8vec3& tint, const u8vec4& light) {
for (const MeshPart& mp : meshParts) {
vec3 modData = {};
@ -122,14 +123,14 @@ void ChunkMeshGenerator::addFaces(const vec3& offset, const vec<MeshPart>& meshP
}
for (const BlockModelVertex& vertex : mp.vertices) {
meshDetails->vertices.push_back({
meshDetails->vertices.push_back(MeshChunk::Vertex {
vertex.pos + offset,
vertex.tex,
mp.blendInd ? tint : vec3 { 1, 1, 1 },
mp.blendInd ? tint : u8vec3(255),
mp.blendInd ? vertex.blendMask : vec2 { -1, -1 },
Util::packFloat(vertex.nml),
glm::vec4(light),
static_cast<float>(mp.shaderMod),
light,
static_cast<u8>(mp.shaderMod),
modData
});
}

View File

@ -14,14 +14,19 @@ class LocalDefinitionAtlas;
class ChunkMeshGenerator {
public:
enum class Detail {
HIGH,
LOW
};
ChunkMeshGenerator(MeshChunkDetails* meshDetails, LocalDefinitionAtlas& defs, LocalBiomeAtlas& biomes,
uptr<Chunk> chunk, array<uptr<Chunk>, 6> adjacent, array<NoiseSample, 3>& blockOffsets);
uptr<Chunk> chunk, array<uptr<Chunk>, 6> adjacent, array<NoiseSample, 3>& blockOffsets, Detail detail);
private:
inline u16 getBlockAt(const ivec3& pos);
inline u8vec4 getLightAt(const ivec3& pos);
void addFaces(const vec3& offset, const vec<MeshPart>& meshParts, const vec3& tint, u8vec4 light);
void addFaces(const vec3& offset, const vec<MeshPart>& meshParts, const u8vec3& tint, const u8vec4& light);
LocalDefinitionAtlas& defs;
LocalBiomeAtlas& biomes;

View File

@ -27,13 +27,13 @@ void EntityMesh::initModel() {
&vertices.front(), &indices.front());
unsigned int idx = 0;
createVertexAttrib(idx++, 3, GL_FLOAT, STRIDE_OFFSET_ENTITY(position));
createVertexAttrib(idx++, 4, GL_FLOAT, STRIDE_OFFSET_ENTITY(colorData));
createVertexAttrib(idx++, 3, GL_FLOAT, STRIDE_OFFSET_ENTITY(colorBlend));
createVertexAttrib(idx++, 1, GL_FLOAT, STRIDE_OFFSET_ENTITY(useTex));
createVertexAttrib(idx++, 3, GL_FLOAT, STRIDE_OFFSET_ENTITY(normal));
createVertexAttrib(idx++, 4, GL_INT, STRIDE_OFFSET_ENTITY(boneIDs));
createVertexAttrib(idx, 4, GL_FLOAT, STRIDE_OFFSET_ENTITY(boneWeights));
createVertexAttrib(idx++, 3, GL_FLOAT, false, STRIDE_OFFSET_ENTITY(position));
createVertexAttrib(idx++, 4, GL_FLOAT, false, STRIDE_OFFSET_ENTITY(colorData));
createVertexAttrib(idx++, 3, GL_FLOAT, false, STRIDE_OFFSET_ENTITY(colorBlend));
createVertexAttrib(idx++, 1, GL_FLOAT, false, STRIDE_OFFSET_ENTITY(useTex));
createVertexAttrib(idx++, 3, GL_FLOAT, false, STRIDE_OFFSET_ENTITY(normal));
createVertexAttrib(idx++, 4, GL_INT, true, STRIDE_OFFSET_ENTITY(boneIDs));
createVertexAttrib(idx, 4, GL_FLOAT, false, STRIDE_OFFSET_ENTITY(boneWeights));
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

View File

@ -26,8 +26,8 @@ void Mesh::genArrays(usize vboLength, usize iboLength, const void* vertices, con
glBufferData(GL_ARRAY_BUFFER, vboLength, vertices, GL_STATIC_DRAW);
}
void Mesh::createVertexAttrib(u32 offset, u32 size, GLenum type, u32 stride, const void* pointer) {
void Mesh::createVertexAttrib(u32 offset, u32 size, GLenum type, bool integral, u32 stride, const void* pointer) {
glEnableVertexAttribArray(offset);
if (type == GL_INT) glVertexAttribIPointer(offset, size, type, stride, pointer);
if (integral) glVertexAttribIPointer(offset, size, type, stride, pointer);
else glVertexAttribPointer(offset, size, type, GL_FALSE, stride, pointer);
}

View File

@ -20,7 +20,7 @@ protected:
void genArrays(usize vboLength, usize iboLength, const void* vertices, const void* indices);
/** Creates a vertex attribute on the VBO. */
void createVertexAttrib(u32 offset, u32 size, GLenum type, u32 stride, const void* pointer);
void createVertexAttrib(u32 offset, u32 size, GLenum type, bool integral, u32 stride, const void* pointer);
usize indCount = 0;
u32 VAO = 0, VBO = 0, IBO = 0;

View File

@ -25,12 +25,12 @@ MeshChunk::Mesh::Mesh(const vec<Vertex>& vertices, const vec<u32>& indices) {
genArrays(vertices.size() * sizeof(Vertex), indices.size() * sizeof(u32), &vertices.front(), &indices.front());
u32 idx = 0;
createVertexAttrib(idx++, 3, GL_FLOAT, STRIDE_OFFSET(Vertex, position));
createVertexAttrib(idx++, 2, GL_FLOAT, STRIDE_OFFSET(Vertex, texCoords));
createVertexAttrib(idx++, 3, GL_FLOAT, STRIDE_OFFSET(Vertex, blendColor));
createVertexAttrib(idx++, 2, GL_FLOAT, STRIDE_OFFSET(Vertex, blendMaskCoords));
createVertexAttrib(idx++, 1, GL_FLOAT, STRIDE_OFFSET(Vertex, normal));
createVertexAttrib(idx++, 4, GL_FLOAT, STRIDE_OFFSET(Vertex, light));
createVertexAttrib(idx++, 1, GL_FLOAT, STRIDE_OFFSET(Vertex, shaderMod));
createVertexAttrib(idx, 3, GL_FLOAT, STRIDE_OFFSET(Vertex, modValues));
createVertexAttrib(idx++, 3, GL_FLOAT, false, STRIDE_OFFSET(Vertex, position));
createVertexAttrib(idx++, 2, GL_FLOAT, false, STRIDE_OFFSET(Vertex, texCoords));
createVertexAttrib(idx++, 3, GL_UNSIGNED_BYTE, true, STRIDE_OFFSET(Vertex, blendColor));
createVertexAttrib(idx++, 2, GL_FLOAT, false, STRIDE_OFFSET(Vertex, blendMaskCoords));
createVertexAttrib(idx++, 1, GL_FLOAT, false, STRIDE_OFFSET(Vertex, normal));
createVertexAttrib(idx++, 4, GL_UNSIGNED_BYTE, true, STRIDE_OFFSET(Vertex, light));
createVertexAttrib(idx++, 1, GL_UNSIGNED_BYTE, true, STRIDE_OFFSET(Vertex, shaderMod));
createVertexAttrib(idx, 3, GL_UNSIGNED_BYTE, true, STRIDE_OFFSET(Vertex, modValues));
}

View File

@ -16,17 +16,17 @@ public:
/** A single vertex of a ChunkMesh. */
struct Vertex {
vec3 position;
vec3 position;
vec2 texCoords;
vec3 blendColor;
vec2 blendMaskCoords;
vec2 texCoords;
u8vec3 blendColor;
vec2 blendMaskCoords;
f32 normal;
vec4 light;
f32 normal; // packed vec3
u8vec4 light;
f32 shaderMod;
vec3 modValues;
u8 shaderMod;
u8vec3 modValues;
};
/** Represents a MeshChunk's underlying mesh. */

View File

@ -45,7 +45,7 @@ ConnectScene::ConnectScene(Client& client, Address addr) : Scene(client),
connection.attemptConnect(std::move(addr));
client.renderer.window.addResizeCallback("scene", [&](glm::ivec2 win) {
client.renderer.window.onResize([&](glm::ivec2 win) {
components.get<GuiRect>("loadBar")->setPos({ 0, win.y - 32 });
});
}
@ -244,8 +244,4 @@ void ConnectScene::draw() {
renderer.enableTexture(&client.game->textures.atlasTexture);
components.draw(renderer);
}
void ConnectScene::cleanup() {
client.renderer.window.removeResizeCallback("scene");
}

View File

@ -6,6 +6,7 @@
#include "Scene.h"
#include "client/Window.h"
#include "client/gui/basic/GuiContainer.h"
class ServerConnection;
@ -30,8 +31,6 @@ public:
void draw() override;
void cleanup() override;
void handleConnecting();
private:
@ -41,4 +40,6 @@ private:
GuiContainer components;
double dotsTime = 0;
Window::RCBLock lock;
};

View File

@ -16,8 +16,8 @@ GameScene::GameScene(Client& client) : Scene(client),
client.game->init(world, world.l()->getPlayer(), client);
world.l()->updatePlayerDimension();
// client.renderer.window.addResizeCallback("gamescene", Util::bind_this(&debugGui, &DebugGui::bufferResized));
client.renderer.setClearColor(148, 194, 240);
// client.renderer.setClearColor(16, 24, 32);
client.renderer.window.input.lockMouse(true);
}
@ -56,7 +56,3 @@ void GameScene::draw() {
perf.start("idle");
}
void GameScene::cleanup() {
// client.renderer.window.removeResizeCallback("gamescene");
}

View File

@ -17,8 +17,6 @@ public:
void draw() override;
void cleanup() override;
private:
vec<string> perfSections = { "update:mods", "update:world", "update:player", "update:net", "update:chunks",
"draw:world", "draw:entities", "draw:interface", "update:debug", "idle" };

View File

@ -34,7 +34,7 @@ LuaErrorScene::LuaErrorScene(Client& client, const std::string& err) : Scene(cli
errorText->setPos({ 16, 48 });
container->add(errorText);
client.renderer.window.addResizeCallback("scene", [&](glm::ivec2 win) {
lock = client.renderer.window.onResize([&](glm::ivec2 win) {
components.get<GuiRect>("container")->setPos({ win.x / 2 - 800 / 2, win.y / 2 - 500 / 2 });
});
}
@ -52,8 +52,4 @@ void LuaErrorScene::draw() {
renderer.enableTexture(&client.game->textures.atlasTexture);
components.draw(renderer);
}
void LuaErrorScene::cleanup() {
client.renderer.window.removeResizeCallback("scene");
}

View File

@ -6,6 +6,7 @@
#include "Scene.h"
#include "client/Window.h"
#include "client/gui/basic/GuiContainer.h"
class LuaErrorScene : public Scene {
@ -16,9 +17,9 @@ class LuaErrorScene : public Scene {
void draw() override;
void cleanup() override;
private:
GuiContainer components;
const std::string err;
Window::RCBLock lock;
};

View File

@ -123,7 +123,7 @@ MainMenuScene::MainMenuScene(Client& client) :
positionElements();
client.renderer.window.addResizeCallback("mainmenu", [&](ivec2 newWin) {
lock = client.renderer.window.onResize([&](ivec2 newWin) {
win = newWin;
sandboxArea = newWin - ivec2(0, 18 * GS);
positionElements();
@ -243,5 +243,4 @@ void MainMenuScene::draw() {
void MainMenuScene::cleanup() {
client.renderer.window.setCursorHand(false);
client.renderer.window.removeResizeCallback("mainmenu");
}

View File

@ -3,6 +3,7 @@
#include "Scene.h"
#include "util/Types.h"
#include "client/Window.h"
#include "client/menu/SubgameDef.h"
#include "client/menu/MenuSandbox.h"
@ -55,5 +56,7 @@ private:
/** A reference to the currently selected subgame. */
SubgameDef* selectedSubgame = nullptr;
Window::RCBLock lock;
};

View File

@ -13,13 +13,13 @@ public:
explicit Scene(Client& client) : client(client) {}
/** Called every game loop to update internal state. */
virtual void update() = 0;
virtual void update() {};
/** Called every game loop to draw objects. */
virtual void draw() = 0;
virtual void draw() {};
/** Called when the scene will be destroyed. */
virtual void cleanup() = 0;
virtual void cleanup() {};
virtual ~Scene() = default;

View File

@ -57,15 +57,15 @@ std::vector<MeshChunkDetails*> MeshGenStream::update() {
j.meshDetails->pos = pos;
// TODO: Is it necessary to construct the new chunk in there?
j.thisChunk = std::make_unique<Chunk>(Chunk(*chunk));
j.detail = glm::distance(vec3 {}, vec3(pos)) <= HIGH_DETAIL_RANGE ?
ChunkMeshGenerator::Detail::HIGH : ChunkMeshGenerator::Detail::LOW;
j.thisChunk = make_unique<Chunk>(*chunk);
int ind = 0;
for (const glm::ivec3& dir : Vec::TO_VEC) {
std::shared_ptr<Chunk> adjacent = dimension.getChunk(pos + dir);
if (!adjacent) goto breakAddTask;
// TODO: Here too
j.adjacentChunks[ind++] = std::make_unique<Chunk>(Chunk(*adjacent));
j.adjacentChunks[ind++] = std::make_unique<Chunk>(*adjacent);
}
j.busy = true;
@ -93,7 +93,7 @@ void MeshGenStream::Thread::exec() {
assert(u.thisChunk);
for (int i = 0; i < u.adjacentChunks.size(); i++) assert(u.adjacentChunks[i]);
ChunkMeshGenerator m(u.meshDetails, game.getDefs(), game.getBiomes(),
std::move(u.thisChunk), std::move(u.adjacentChunks), offsetSamplers);
std::move(u.thisChunk), std::move(u.adjacentChunks), offsetSamplers, u.detail);
empty = false;
u.busy = false;
}
@ -104,7 +104,8 @@ void MeshGenStream::Thread::exec() {
void MeshGenStream::queue(glm::ivec3 pos, bool priority) {
if (!queuedMap.count(pos)) {
priority ? queuedTasks.push_front(pos) : queuedTasks.push_back(pos);
if (priority) queuedTasks.push_front(pos);
else queuedTasks.push_back(pos);
queuedMap.insert(pos);
}
}

View File

@ -8,6 +8,7 @@
#include <thread>
#include <glm/vec3.hpp>
#include <unordered_set>
#include <client/graph/mesh/ChunkMeshGenerator.h>
#include "util/Vec.h"
#include "util/CovariantPtr.h"
@ -36,6 +37,7 @@ public:
std::vector<MeshChunkDetails*> update();
struct Job {
ChunkMeshGenerator::Detail detail;
std::unique_ptr<Chunk> thisChunk = nullptr;
std::array<std::unique_ptr<Chunk>, 6> adjacentChunks {};
@ -66,5 +68,7 @@ private:
std::array<NoiseSample, 3> noiseSampler;
std::deque<glm::ivec3> queuedTasks;
std::unordered_set<glm::vec3, Vec::vec3> queuedMap;
constexpr const static u8 HIGH_DETAIL_RANGE = 4;
};

View File

@ -84,15 +84,15 @@ void WorldInterpolationStream::Thread::run() {
if (u.packet->type == Packet::Type::CHUNK) {
u.chunks.reserve(1);
u.chunks.emplace_back(std::make_shared<Chunk>());
u.chunks.back()->decompressFromString(u.packet->d.data);
u.chunks.emplace_back(std::make_shared<Chunk>(u.packet->d.data));
// u.chunks.back()->decompressFromString(u.packet->d.data);
}
else if (u.packet->type == Packet::Type::MAPBLOCK) {
u.chunks.reserve(64);
while (!u.packet->d.atEnd()) {
string data = u.packet->d.read<string>();
u.chunks.emplace_back(make_shared<Chunk>());
u.chunks.back()->decompressFromString(data);
u.chunks.emplace_back(make_shared<Chunk>(data));
// u.chunks.back()->decompressFromString(data);
}
}

View File

@ -32,5 +32,5 @@ struct BiomeDef {
std::vector<std::shared_ptr<Structure>> schematics;
glm::vec3 tint{};
glm::vec3 tint {};
};

View File

@ -88,7 +88,7 @@ namespace RegisterBlock {
static std::pair<BlockModel, BlockModel>
createBlockModel(sol::table blockTable, sol::table blockModels, TextureAtlas* atlas) {
// Get the specified block model
auto modelStr = blockTable.get_or<std::string>("model", "default:cube");
auto modelStr = blockTable.get_or<std::string>("model", "base:block");
auto modelOpt = blockModels.get<sol::optional<sol::table>>(modelStr);
if (!modelOpt) throw std::runtime_error("Non-existent model \"" + modelStr + "\" specified");

View File

@ -15,7 +15,7 @@
Server::Server(u16 port, const std::string& subgame) :
seed(69),
port(port),
config(game),
infoSender(game),
clients(game),
handler(port, 32),
game(make_shared<ServerSubgame>(subgame, seed)),
@ -23,7 +23,7 @@ Server::Server(u16 port, const std::string& subgame) :
game.s()->init(world);
world.s()->init("world");
config.init();
infoSender.init();
std::cout << Log::info << "Server started successfully, listening for clients." << Log::endl;
while (alive) update();
@ -60,7 +60,7 @@ void Server::update() {
auto client = static_cast<ServerClient*>(event.peer->data);
if (client->player) return playerPacketReceived(p, clients.getClient(client->id)->player);
if (config.handlePacket(*client, p)) {
if (infoSender.handlePacket(*client, p)) {
auto clientShr = clients.getClient(client->id);
clients.createPlayer(clientShr, world->getDefaultDimension());
}

View File

@ -4,7 +4,7 @@
#include "world/ServerWorld.h"
#include "game/ServerSubgame.h"
#include "util/net/NetHandler.h"
#include "server/ServerConfig.h"
#include "server/ServerInfoSender.h"
#include "server/ServerClients.h"
#include "world/inv/ServerInventoryRefs.h"
@ -41,8 +41,8 @@ private:
/** The network handler, manages client connections. */
NetHandler handler;
/** Handles passing data to newly connecting clients. TODO: Rename. */
ServerConfig config;
/** Handles passing data to newly connecting clients. */
ServerInfoSender infoSender;
/** A list of connected clients. */
ServerClients clients;

View File

@ -2,7 +2,7 @@
// Created by aurailus on 03/07/19.
//
#include "ServerConfig.h"
#include "ServerInfoSender.h"
#include "game/def/ItemDef.h"
#include "game/def/BiomeDef.h"
@ -12,9 +12,9 @@
#include "server/ServerClient.h"
#include "game/atlas/asset/AssetType.h"
ServerConfig::ServerConfig(SubgamePtr game) : game(game) {}
ServerInfoSender::ServerInfoSender(SubgamePtr game) : game(game) {}
void ServerConfig::init() {
void ServerInfoSender::init() {
blockIdentifierList.reserve(game->getDefs().size());
for (usize i = 0; i < game->getDefs().size(); i++)
blockIdentifierList.push_back(game->getDefs().fromId(i).identifier);
@ -24,7 +24,7 @@ void ServerConfig::init() {
biomeIdentifierList.push_back(game->getBiomes().biomeFromId(i).identifier);
}
bool ServerConfig::handlePacket(ServerClient& client, PacketView& r) {
bool ServerInfoSender::handlePacket(ServerClient& client, PacketView& r) {
switch (r.type) {
default:
break;

View File

@ -11,9 +11,9 @@ class PacketView;
class ServerClient;
class ServerSubgame;
class ServerConfig {
class ServerInfoSender {
public:
explicit ServerConfig(SubgamePtr game);
explicit ServerInfoSender(SubgamePtr game);
void init();

View File

@ -3,6 +3,7 @@
#include "util/PerfTimer.h"
#include "util/net/PacketView.h"
#include "client/graph/Renderer.h"
#include "world/dim/chunk/Chunk.h"
#include "world/player/LocalPlayer.h"
#include "client/stream/WorldInterpolationStream.h"
@ -12,8 +13,11 @@ LocalWorld::LocalWorld(SubgamePtr game, ServerConnection& conn, Renderer& render
net(conn, *this),
refs(make_shared<LocalInventoryRefs>(game, net)),
debugGui(renderer.window.getSize(), game, *this, perfSections),
worldGenStream(make_shared<WorldInterpolationStream>(*game.l(), *this, 55)),
player(make_shared<LocalPlayer>(game, *this, DimensionPtr(nullptr), renderer)) {}
// worldGenStream(make_shared<WorldInterpolationStream>(*game.l(), *this, 55)),
player(make_shared<LocalPlayer>(game, *this, DimensionPtr(nullptr), renderer)) {
renderer.window.onResize(Util::bind_this(&debugGui, &DebugGui::bufferResized));
}
void LocalWorld::init() {
net.init(Util::bind_this(&(*refs), &LocalInventoryRefs::packetReceived));
@ -44,9 +48,9 @@ void LocalWorld::update(f64 delta, vec<usize>& perfTimings, PerfTimer& perf) {
// Commit interpolated mapblocks
perf.start("update:chunks");
auto finishedChunks = worldGenStream->update();
lastInterpolations = finishedChunks->size() / 64;
for (const auto& chunk : *finishedChunks) commitChunk(chunk);
// auto finishedChunks = worldGenStream->update();
// lastInterpolations = finishedChunks->size() / 64;
// for (const auto& chunk : *finishedChunks) commitChunk(chunk);
// Update debug interface
perf.start("update:debug");
@ -74,7 +78,11 @@ void LocalWorld::update(f64 delta, vec<usize>& perfTimings, PerfTimer& perf) {
}
void LocalWorld::handleWorldPacket(uptr<PacketView> p) {
worldGenStream->queuePacket(std::move(p));
if (p->type == Packet::Type::CHUNK)
commitChunk(make_shared<Chunk>(p->d.data));
else if (p->type == Packet::Type::MAPBLOCK)
while (!p->d.atEnd())
commitChunk(make_shared<Chunk>(p->d.read<string>()));
}
void LocalWorld::handlePlayerEntPacket(uptr<PacketView> p) {

View File

@ -2,11 +2,11 @@
#include "World.h"
#include "client/Window.h"
#include "client/gui/DebugGui.h"
#include "world/dim/LocalDimension.h"
#include "client/conn/ClientNetworkInterpreter.h"
class Window;
class Renderer;
class PerfTimer;
class LocalPlayer;
@ -27,10 +27,10 @@ public:
/** Initializes the world, binding callbacks to the network handler. */
void init();
/** Sets the player's dimension to the default one, if it exists. TODO: Could this be done in init()? */
/** Sets the player's dimension to the default one, if it exists. */
bool updatePlayerDimension();
/** Updates the dimension and the player, reads incoming packets, and commits decoded chunks. TODO: Decoding all the chunks from the getgo seems unnecessary... */
/** Updates the dimension and the player, reads incoming packets, and commits decoded chunks. */
void update(f64 delta, vec<usize>& perfTimings, PerfTimer& perf);
/** Queues a packet to be read. */
@ -104,6 +104,8 @@ private:
/** A pointer to the active dimension. */
sptr<LocalDimension> activeDimension = nullptr;
Window::RCBLock lock;
/** A reference to the world gen stream. */
sptr<WorldInterpolationStream> worldGenStream;
// sptr<WorldInterpolationStream> worldGenStream;
};

View File

@ -75,7 +75,7 @@ void ServerWorld::update(f64 delta) {
let dim = getDimension(data.dim);
for (const auto& chunkPair : *data.created) {
updatedChunks.insert(ivec4(chunkPair.first, data.dim));
dim->setChunk(sptr<Chunk>(chunkPair.second));
dim->setChunk(chunkPair.second);
}
auto mapBlock = dim->getMapBlock(ivec3(data.pos));

View File

@ -25,7 +25,10 @@ Chunk::Chunk(ivec3 pos, bool partial) :
compressionState(CompressionState::DECOMPRESSED),
generationState(partial ? GenerationState::PARTIAL : GenerationState::EMPTY) {}
Chunk::Chunk(ivec3 pos, const string& data) : pos(pos), c(data) {}
Chunk::Chunk(const string& data) : c(data) {
Deserializer raw(data);
pos = raw.read<ivec3>();
}
bool Chunk::setBlock(u16 ind, u16 blk) {
useDecompressed();
@ -89,7 +92,6 @@ string Chunk::compressToString() const {
}
void Chunk::decompressFromString(const string& data) {
Deserializer raw(data);
pos = raw.read<ivec3>();

View File

@ -81,7 +81,7 @@ public:
Chunk(ivec3 pos = { 0, 0, 0 }, bool partial = false);
/** Creates a chunk with the compressed data specified. */
Chunk(ivec3 pos, const string& data);
Chunk(const string& data);
/** Returns the position of the chunk. */
inline ivec3 getPos() const;
@ -250,7 +250,7 @@ private:
time_t lastUsed = 0;
/** The number of non-transparent blocks in the chunk. */
u16 renderableBlocks = 0;
u16 renderableBlocks = 1; // TODO: Don't hack this.
/** Internal decompressed chunk data. */
uptr<ChunkData> d = nullptr;

View File

@ -104,6 +104,8 @@ std::unique_ptr<MapGen::ChunkMap> MapGen::generateArea(u16 dim, ivec3 origin, u1
}
}
propogateSunlightNodes(job);
for (let& chunk : *job.chunks) {
chunk.second->compress();
}
@ -182,7 +184,7 @@ void MapGen::generateChunkBlocks(Job& job, ivec3 localPos, vec<u16> biomeMap, Ch
auto partial = (job.chunks->count(chunkPos) ? job.chunks->at(chunkPos) : nullptr);
if (partial) job.chunks->erase(chunkPos);
auto& chunk = *(*job.chunks->emplace(chunkPos, new Chunk(chunkPos)).first).second;
auto& chunk = *(*job.chunks->emplace(chunkPos, make_shared<Chunk>(chunkPos)).first).second;
u16 partialBlock = DefinitionAtlas::INVALID;
@ -201,7 +203,7 @@ void MapGen::generateChunkBlocks(Job& job, ivec3 localPos, vec<u16> biomeMap, Ch
: depth <= 4 ? biome.soilBlock
: biome.rockBlock;
if (chunk.d == nullptr) std::cout << "THE DATA ISNT LOADED." << std::endl;
assert(chunk.d != nullptr);
chunk.d->blocks[i] = blockId;
}
@ -219,7 +221,7 @@ void MapGen::generateChunkDecorAndLight(Job& job, ivec3 localPos, vec<u16> biome
auto& chunk = job.chunks->at(job.pos + localPos);
ivec3 abovePos = job.pos + localPos + ivec3 { 0, 1, 0 };
Chunk* above = (localPos.y != job.size - 1) ?
sptr<Chunk> above = (localPos.y != job.size - 1) ?
job.chunks->count(abovePos) ? job.chunks->at(abovePos) : nullptr : nullptr;
for (u16 i = 0; i < 256; i++) {
@ -253,24 +255,24 @@ void MapGen::generateChunkDecorAndLight(Job& job, ivec3 localPos, vec<u16> biome
break;
}
// if (light == -1) light = above ? above->getLight(Space::Block::index(indPos), 3) :
// game.getDefs().blockFromId(chunk->getBlock(indPos)).lightPropagates ? 15 : 0;
if (light == -1) light = above ? above->getLight(Space::Block::index(indPos), 3) :
game.getDefs().blockFromId(chunk->getBlock(indPos)).lightPropagates ? 15 : 0;
// if (!light) continue;
if (!light) continue;
// auto& blockDef = game.getDefs().blockFromId(chunk->getBlock(indPos));
// if (!blockDef.lightPropagates) light = 0;
// else {
// chunk->setLight(ind, 3, light);
// job.sunlightQueue.emplace(ind, chunk);
// }
auto& blockDef = game.getDefs().blockFromId(chunk->getBlock(indPos));
if (!blockDef.lightPropagates) light = 0;
else {
chunk->setLight(ind, 3, light);
job.sunlightQueue.emplace(ind, chunk.get());
}
}
}
chunk->generationState = Chunk::GenerationState::GENERATED;
}
void MapGen::setBlock(MapGen::Job& job, ivec3 worldPos, u16 block, Chunk* hint) {
void MapGen::setBlock(MapGen::Job& job, ivec3 worldPos, u16 block, sptr<Chunk> hint) {
if (block == DefinitionAtlas::INVALID) return;
u16 ind = Space::Block::index(worldPos);
@ -285,33 +287,33 @@ void MapGen::setBlock(MapGen::Job& job, ivec3 worldPos, u16 block, Chunk* hint)
}
void MapGen::propogateSunlightNodes(Job& job) {
// auto& defs = game.getDefs();
//
// while (!job.sunlightQueue.empty()) {
// SunlightNode& node = job.sunlightQueue.front();
//
// unsigned char lightLevel = node.chunk->getLight(node.index, 3);
// glm::ivec3 worldPos = node.chunk->pos * 16 + Space::Block::fromIndex(node.index);
//
// for (const auto& i : Vec::TO_VEC) {
// glm::ivec3 check = worldPos + i;
//
// Chunk* chunk;
// glm::ivec3 chunkPos = Space::Chunk::world::fromBlock(check);
// if (node.chunk->pos == chunkPos) chunk = node.chunk;
// else {
// auto found = job.chunks->find(chunkPos);
// if (found == job.chunks->end()) continue;
// chunk = found->second.get();
// }
//
// auto ind = Space::Block::index(check);
// if (defs.blockFromId(chunk->getBlock(ind)).lightPropagates && chunk->getLight(ind, 3) + 2 <= lightLevel) {
// chunk->setLight(ind, 3, lightLevel - static_cast<int>(!(lightLevel == 15 && i.y == -1)));
// job.sunlightQueue.emplace(ind, chunk);
// }
// }
//
// job.sunlightQueue.pop();
// }
auto& defs = game.getDefs();
while (!job.sunlightQueue.empty()) {
SunlightNode& node = job.sunlightQueue.front();
unsigned char lightLevel = node.chunk->getLight(node.index, 3);
glm::ivec3 worldPos = node.chunk->pos * 16 + ivec3(Space::Block::fromIndex(node.index));
for (const auto& i : Vec::TO_VEC) {
glm::ivec3 check = worldPos + i;
Chunk* chunk;
glm::ivec3 chunkPos = Space::Chunk::world::fromBlock(check);
if (node.chunk->pos == chunkPos) chunk = node.chunk;
else {
auto found = job.chunks->find(chunkPos);
if (found == job.chunks->end()) continue;
chunk = found->second.get();
}
auto ind = Space::Block::index(check);
if (defs.blockFromId(chunk->getBlock(ind)).lightPropagates && chunk->getLight(ind, 3) + 2 <= lightLevel) {
chunk->setLight(ind, 3, lightLevel - static_cast<int>(!(lightLevel == 15 && i.y == -1)));
job.sunlightQueue.emplace(ind, chunk);
}
}
job.sunlightQueue.pop();
}
}

View File

@ -1,8 +1,3 @@
//
// Generates terrain in the form of MapBlocks.
// Created by aurailus on 28/01/19.
//
#pragma once
#include <queue>
@ -11,9 +6,9 @@
#include <unordered_map>
#include <unordered_set>
#include "util/Vec.h"
#include "MapGenProps.h"
#include "NoiseSample.h"
#include "util/Vec.h"
#include "util/Voronoi3D.h"
class World;
@ -32,7 +27,7 @@ public:
constexpr static u8 TERP = 4;
/** A type alias for the type the map of Chunks stored in the Job. */
typedef std::unordered_map<ivec3, Chunk*, Vec::ivec3> ChunkMap;
typedef std::unordered_map<ivec3, sptr<Chunk>, Vec::ivec3> ChunkMap;
/**
* A struct representing a single position in a chunk at which sunlight should be updated at.
@ -208,7 +203,7 @@ private:
* @param hint - An optional parameter that may speed up the function if set to the chunk to set to.
*/
static void setBlock(Job& job, ivec3 worldPos, u16 block, Chunk* hint);
static void setBlock(Job& job, ivec3 worldPos, u16 block, sptr<Chunk> hint);
/**
* Calculates and smooths sunlight for an entire Job's chunks.

View File

@ -25,7 +25,7 @@ LocalPlayer::LocalPlayer(SubgamePtr game, LocalWorld& world, DimensionPtr dim, R
handItemModel.parent = &handModel;
renderer.window.addResizeCallback("player", [&](glm::ivec2 win) { gameGui.winResized(win); });
lock = renderer.window.onResize([&](glm::ivec2 win) { gameGui.winResized(win); });
}
void LocalPlayer::update(Input& input, f64 delta, vec2 mouseDelta) {
@ -448,8 +448,4 @@ void LocalPlayer::updateInteract(Input& input, f64 delta) {
dim->wieldItemUse(target, static_cast<LocalWorld&>(dim->getWorld()).getPlayer());
}
}
}
LocalPlayer::~LocalPlayer() {
renderer.window.removeResizeCallback("player");
}
}

View File

@ -4,6 +4,7 @@
#include "client/graph/Drawable.h"
#include "util/Target.h"
#include "client/Window.h"
#include "client/gui/GameGui.h"
#include "world/dim/LocalDimension.h"
#include "client/entity/WireframeEntity.h"
@ -152,14 +153,6 @@ public:
virtual void handleAssertion(Deserializer& d) override;
/**
* Removes the resize callback from the callbacks.
* TODO: The resize callbacks should be stored in a shared pointer member, instead of string identified,
* to reduce the chance of forgetting to unbind it, and to not require explicit destructors.
*/
~LocalPlayer();
private:
/**
@ -238,5 +231,7 @@ private:
/** The actual wield-item model, set to the currently held item. */
DrawableEntity handItemModel;
Window::RCBLock lock;
};

View File

@ -4,6 +4,7 @@ runfile(_PATH .. "podzol")
runfile(_PATH .. "dirt")
runfile(_PATH .. "grass")
runfile(_PATH .. "leaves")
runfile(_PATH .. "cactus")
runfile(_PATH .. "sand")
runfile(_PATH .. "sandstone")
runfile(_PATH .. "stone")

View File

@ -0,0 +1,18 @@
zepha.register_block(":cactus", {
name = "Cactus",
culls = false,
textures = {
"tint(0, zeus:default:leaves_opaque)"
},
tool_props = {
health = 5,
multipliers = {
snap = 2.0,
cut = 2.0
}
},
yields = "zeus:default:cactus"
})

View File

@ -8,7 +8,7 @@ zepha.register_block(":grass", {
"tint(0, zeus:default:grass_side_under, zeus:default:grass_side_under_mask)",
"tint(0, zeus:default:grass_floating)",
},
far_textures = {
lowdef_textures = {
"tint(0, zeus:default:grass_top)",
"zeus:default:dirt",
"tint(0, zeus:default:grass_side_ld, zeus:default:grass_side_ld_mask)"

View File

@ -7,7 +7,7 @@ zepha.register_block(":leaves", {
"tint(0, zeus:default:leaves)",
"tint(0, zeus:default:leaves_puff)"
},
far_textures = {
lowdef_textures = {
"tint(0, zeus:default:leaves_opaque)",
},

View File

@ -6,7 +6,7 @@ for i = 1, 5, 1 do
solid = false,
model = "base:cross_plant",
textures = { "tint(0, zeus:default:tallgrass_"..i..")" },
far_render = false,
lowdef_render = false,
selection_box = {{1/16, 0, 1/16, 15/16, 0.30 + i * 0.1, 15/16}},

View File

@ -66,11 +66,11 @@ zepha.register_entity("zeus:default:bee", {
end
end
})
if zepha.server then
zepha.bind("new_player", function(player)
for i = 0, 10 do
player.dim:add_entity(player.pos + V { math.random(-100, 100), 30, math.random(-100, 100) }, "zeus:default:bee")
end
end)
end
--
-- if zepha.server then
-- zepha.bind("new_player", function(player)
-- for i = 0, 10 do
-- player.dim:add_entity(player.pos + V { math.random(-100, 100), 30, math.random(-100, 100) }, "zeus:default:bee")
-- end
-- end)
-- end

View File

@ -45,10 +45,10 @@ zepha.register_entity("zeus:default:test", {
-- end, 0)
--end
if zepha.server then
zepha.bind("player_join", function(player)
for i = 0, 4 do
player.dim:add_entity(V(-145, -32, -30), "zeus:default:test")
end
end)
end
-- if zepha.server then
-- zepha.bind("player_join", function(player)
-- for i = 0, 4 do
-- player.dim:add_entity(V(-145, -32, -30), "zeus:default:test")
-- end
-- end)
-- end

View File

@ -22,6 +22,7 @@ for _,flower in pairs(flowers) do
textures = {
"zeus:flowers:" .. flower
},
light_propagates = true,
lowdef_render = false,
selection_box = {
{4/16, 0, 4/16, 12/16, 14/16, 12/16}

View File

@ -1,49 +1,99 @@
-- local identifier = "zeus:world:desert"
--
-- local noise = {
local identifier = "zeus:world:desert"
local structures = {}
table.insert(structures, zepha.create_structure({
origin = V(),
probability = 0.001,
layout = {{{ "zeus:default:cactus" }}, {{ "zeus:default:cactus" }}}
}))
table.insert(structures, zepha.create_structure({
origin = V(),
probability = 0.001,
layout = {{{ "zeus:default:cactus" }}, {{ "zeus:default:cactus" }}, {{ "zeus:default:cactus" }}}
}))
table.insert(structures, zepha.create_structure({
origin = V(),
probability = 0.001,
layout = {{{ "zeus:default:cactus" }}, {{ "zeus:default:cactus" }}, {{ "zeus:default:cactus" }}, {{ "zeus:default:cactus" }}}
}))
local noise = {
-- heightmap = {
-- module = "add",
-- sources = {{
-- module = "const",
-- value = -80
-- module = "min",
-- sources = {{
-- module = "turbulence",
-- power = 1,
-- frequency = 0.3,
-- source = {
-- module = "add",
-- sources = {{
-- -- Elevation
-- module = "scale_bias",
-- source = {
-- module = "spheres",
-- frequency = 0.2
-- },
-- scale = 20
-- }, {
-- -- Features
-- module = "scale_bias",
-- source = {
-- module = "perlin",
-- frequency = 0.1,
-- octaves = 6,
-- },
-- scale = 8
-- }}
-- }
-- }, {
-- -- Elevation
-- module = "scale_bias",
-- source = {
-- module = "perlin",
-- frequency = 0.02,
-- octaves = 8
-- },
-- scale = 20,
-- bias = 32
-- module = "scale_bias",
-- scale = 1,
-- bias = 1000,
-- source = {
-- module = "perlin",
-- frequency = 0.2
-- }
-- }}
-- }, {
-- -- Features
-- module = "scale_bias",
-- source = {
-- module = "perlin",
-- frequency = 0.8,
-- octaves = 3,
-- },
-- scale = 5,
-- bias = 6
-- module = "const",
-- value = -40
-- }}
-- }
-- }
--
-- zepha.register_biome(identifier, {
-- environment = {
-- temperature = 40/100,
-- humidity = 20/100,
-- roughness = 10/100
-- },
-- blocks = {
-- top = "zeus:default:sand",
-- soil = "zeus:default:sand",
-- rock = "zeus:default:sandstone"
-- },
-- tags = { natural = 1, default = 1 },
-- biome_tint = "#e6fa61",
-- noise = noise
-- })
--
-- return identifier;
volume = {
module = "scale_bias",
scale = 3000,
bias = -3500,
source = {
module = "scale_point",
y_scale = 2,
source = {
module = "perlin",
frequency = 0.1
}
}
}
}
zepha.register_biome(identifier, {
environment = {
temperature = 40/100,
humidity = 20/100,
roughness = 10/100
},
blocks = {
top = "zeus:default:sand",
soil = "zeus:default:sand",
rock = "zeus:default:sandstone"
},
tags = { natural = 1, default = 1 },
biome_tint = "#e6fa61",
noise = noise,
structures = structures
})
return identifier;

View File

@ -1,178 +1,178 @@
-- local identifier = "zeus:world:forest"
local identifier = "zeus:world:forest"
local wood = "zeus:default:wood"
local leaf = "zeus:default:leaves"
local none = "invalid"
local structures = {}
--
-- local noise = {
-- heightmap = {
-- module = "add",
-- sources = {
-- runfile(_PATH .. 'world_noise'), {
-- -- Features
-- module = "scale_bias",
-- source = {
-- module = "perlin",
-- frequency = .5,
-- octaves = 3,
-- },
-- scale = 3,
-- bias = 0
-- } }
-- }
-- }
-- table.insert(structures, zepha.create_structure({
-- -- noise = {
-- -- module = "perlin",
-- -- frequency = 0.002,
-- -- octaves = 8
-- -- },
-- -- region_size = 4,
-- probability = 0.1,
-- -- origin = V{1, 1, 1},
-- origin = V(),
-- layout = {{{ "zeus:flowers:flower_geranium" }}}
-- }))
for i = 1, 5 do
table.insert(structures, zepha.create_structure({
origin = V(),
probability = 0.025,
layout = {{{ "zeus:default:tall_grass_" .. tostring(i) }}}
}))
end
--
-- --local woo = "zeus:default:wood"
-- --local lea = "zeus:default:leaves"
-- --local inv = "invalid"
-- --
-- --local trunk_layer_0 = {
-- -- { inv, inv, inv, inv, inv },
-- -- { inv, woo, woo, woo, inv },
-- -- { inv, woo, woo, woo, inv },
-- -- { inv, woo, woo, woo, inv },
-- -- { inv, inv, inv, inv, inv }
-- --}
-- --
-- --local trunk_layer_1 = {
-- -- { inv, inv, inv, inv, inv },
-- -- { inv, inv, woo, inv, inv },
-- -- { inv, woo, woo, woo, inv },
-- -- { inv, inv, woo, inv, inv },
-- -- { inv, inv, inv, inv, inv }
-- --}
-- --
-- --local trunk_layer_2 = {
-- -- { inv, inv, inv, inv, inv },
-- -- { inv, inv, inv, inv, inv },
-- -- { inv, inv, woo, inv, inv },
-- -- { inv, inv, inv, inv, inv },
-- -- { inv, inv, inv, inv, inv }
-- --}
-- --
-- --local leaf_layer_1 = {
-- -- { inv, lea, lea, lea, inv },
-- -- { lea, lea, lea, lea, lea },
-- -- { lea, lea, woo, lea, lea },
-- -- { lea, lea, lea, lea, lea },
-- -- { inv, lea, lea, lea, inv }
-- --}
-- --
-- --local leaf_layer_2 = {
-- -- { inv, inv, inv, inv, inv },
-- -- { inv, lea, lea, lea, inv },
-- -- { inv, lea, woo, lea, inv },
-- -- { inv, lea, lea, lea, inv },
-- -- { inv, inv, inv, inv, inv }
-- --}
-- --
-- --local leaf_layer_3 = {
-- -- { inv, inv, inv, inv, inv },
-- -- { inv, lea, lea, inv, inv },
-- -- { inv, lea, lea, lea, inv },
-- -- { inv, inv, lea, lea, inv },
-- -- { inv, inv, inv, inv, inv }
-- --}
-- --
-- --local tree = zepha.create_structure({
-- -- origin = V(2, 2, 2),
-- -- probability = 0.01,
-- -- schematic = {
-- -- trunk_layer_0,
-- -- trunk_layer_0,
-- -- trunk_layer_0,
-- -- trunk_layer_0,
-- -- trunk_layer_1,
-- -- trunk_layer_1,
-- -- trunk_layer_1,
-- -- trunk_layer_2,
-- -- trunk_layer_2,
-- -- trunk_layer_2,
-- -- trunk_layer_2,
-- -- trunk_layer_2,
-- -- trunk_layer_2,
-- -- trunk_layer_2,
-- -- trunk_layer_2,
-- -- trunk_layer_2,
-- -- trunk_layer_2,
-- -- trunk_layer_2,
-- -- leaf_layer_2,
-- -- leaf_layer_1,
-- -- leaf_layer_1,
-- -- leaf_layer_1,
-- -- leaf_layer_1,
-- -- leaf_layer_2,
-- -- leaf_layer_3
-- -- }
-- --})
-- --
-- --local woo = "zeus:default:wood"
-- --local lea = "zeus:default:leaves"
-- --local inv = "invalid"
-- --
-- --local shrub_layer_0 = {
-- -- { inv, inv, inv },
-- -- { inv, woo, inv },
-- -- { inv, inv, inv }
-- --}
-- --
-- --local shrub_layer_1 = {
-- -- { inv, lea, inv },
-- -- { lea, woo, lea },
-- -- { inv, lea, inv }
-- --}
-- --
-- --local shrub_layer_2 = {
-- -- { inv, inv, inv },
-- -- { inv, lea, inv },
-- -- { inv, inv, inv }
-- --}
-- --
-- --local shrub = zepha.create_structure({
-- -- origin = V{1, 1, 1},
-- -- probability = 0.005,
-- -- schematic = {
-- -- shrub_layer_0,
-- -- shrub_layer_1,
-- -- shrub_layer_2,
-- -- }
-- --})
-- --
-- --local structures = { tree, shrub }
-- --
-- --for i = 1, 5 do
-- -- table.insert(structures, zepha.create_structure({
-- -- origin = V(),
-- -- probability = 0.01,
-- -- schematic = {{{ "zeus:default:tall_grass_" .. tostring(i) }}}
-- -- }))
-- --end
-- --
-- --table.insert(structures, zepha.create_structure({
-- -- origin = V(),
-- -- probability = 0.0025,
-- -- schematic = {{{ "zeus:flowers:flower_red_mushroom" }}}
-- --}))
-- --
-- --table.insert(structures, zepha.create_structure({
-- -- origin = V(),
-- -- probability = 0.0025,
-- -- schematic = {{{ "zeus:flowers:flower_brown_mushroom" }}}
-- --}))
--
-- local structures = {}
--
-- zepha.register_biome(identifier, {
-- environment = {
-- temperature = 15/100,
-- humidity = 80/100,
-- roughness = 20/100,
-- },
-- blocks = {
-- top = "zeus:default:podzol",
-- soil = "zeus:default:dirt",
-- rock = "zeus:default:stone"
-- },
-- tags = { natural = 1, default = 1 },
-- structures = structures,
-- biome_tint = "#7beb26",
-- noise = noise
-- })
--
-- return identifier
table.insert(structures, zepha.create_structure({
origin = V(),
probability = 0.05,
layout = {{{ "zeus:flowers:flower_red_mushroom" }}}
}))
table.insert(structures, zepha.create_structure({
origin = V(),
probability = 0.05,
layout = {{{ "zeus:flowers:flower_brown_mushroom" }}}
}))
table.insert(structures, zepha.create_structure({
origin = V(1),
probability = 0.1,
layout = {{
{ none, none, none },
{ none, wood, none },
{ none, none, none }
}, {
{ none, leaf, none },
{ leaf, wood, leaf },
{ none, leaf, none }
}, {
{ none, none, none },
{ none, leaf, none },
{ none, none, none }
}}
}))
local woo = "zeus:default:wood"
local lea = "zeus:default:leaves"
local inv = "invalid"
local trunk_layer_0 = {
{ inv, inv, inv, inv, inv },
{ inv, woo, woo, woo, inv },
{ inv, woo, woo, woo, inv },
{ inv, woo, woo, woo, inv },
{ inv, inv, inv, inv, inv }
}
local trunk_layer_1 = {
{ inv, inv, inv, inv, inv },
{ inv, inv, woo, inv, inv },
{ inv, woo, woo, woo, inv },
{ inv, inv, woo, inv, inv },
{ inv, inv, inv, inv, inv }
}
local trunk_layer_2 = {
{ inv, inv, inv, inv, inv },
{ inv, inv, inv, inv, inv },
{ inv, inv, woo, inv, inv },
{ inv, inv, inv, inv, inv },
{ inv, inv, inv, inv, inv }
}
local leaf_layer_1 = {
{ inv, lea, lea, lea, inv },
{ lea, lea, lea, lea, lea },
{ lea, lea, woo, lea, lea },
{ lea, lea, lea, lea, lea },
{ inv, lea, lea, lea, inv }
}
local leaf_layer_2 = {
{ inv, inv, inv, inv, inv },
{ inv, lea, lea, lea, inv },
{ inv, lea, woo, lea, inv },
{ inv, lea, lea, lea, inv },
{ inv, inv, inv, inv, inv }
}
local leaf_layer_3 = {
{ inv, inv, inv, inv, inv },
{ inv, lea, lea, inv, inv },
{ inv, lea, lea, lea, inv },
{ inv, inv, lea, lea, inv },
{ inv, inv, inv, inv, inv }
}
table.insert(structures, zepha.create_structure({
origin = V(2, 2, 2),
probability = 0.05,
layout = {
trunk_layer_0,
trunk_layer_0,
trunk_layer_0,
trunk_layer_0,
trunk_layer_1,
trunk_layer_1,
trunk_layer_1,
trunk_layer_2,
trunk_layer_2,
trunk_layer_2,
trunk_layer_2,
trunk_layer_2,
trunk_layer_2,
trunk_layer_2,
trunk_layer_2,
trunk_layer_2,
trunk_layer_2,
trunk_layer_2,
leaf_layer_2,
leaf_layer_1,
leaf_layer_1,
leaf_layer_1,
leaf_layer_1,
leaf_layer_2,
leaf_layer_3
}
}))
local noise = {
-- heightmap = runfile(_PATH .. 'world_noise'),
volume = {
module = "scale_bias",
scale = 3000,
bias = -3500,
source = {
module = "scale_point",
y_scale = 2,
source = {
module = "perlin",
frequency = 0.1
}
}
}
}
zepha.register_biome(identifier, {
environment = {
temperature = 25/100,
humidity = 70/100,
roughness = 20/100,
},
blocks = {
top = "zeus:default:grass",
soil = "zeus:default:dirt",
rock = "zeus:default:stone"
},
tags = { natural = 1, default = 1 },
structures = structures,
biome_tint = "#aaed45",
noise = noise
})
return identifier

View File

@ -40,7 +40,7 @@ table.insert(structures, zepha.create_structure({
}))
table.insert(structures, zepha.create_structure({
origin = V(),
origin = V(1),
probability = 0.025,
layout = {{
{ none, none, none },

View File

@ -5,8 +5,8 @@ zepha.create_dimension('zeus:world:default', {
biomes = { '#natural', '#default' }
})
-- zepha.create_dimension('zeus:world:endless_desert', {
-- biomes = { 'zeus:world:desert' }
-- })
zepha.create_dimension('zeus:world:endless_desert', {
biomes = { 'zeus:world:desert' }
})
zepha.set_default_dimension('zeus:world:default')

View File

@ -23,7 +23,7 @@ zepha.register_item(':key_silver', {
zepha.register_item(':key_gold', {
name = 'Gold Key',
textures = { 'zeus:world:key_gold' },
stack = 1024,
on_use = function(stack, target, player)
player.dim:add_entity(player.pos, "zeus:default:bee")
stack.count = stack.count - 1
@ -36,7 +36,7 @@ if zepha.server then
local inv = player:get_inventory():get_list('hot_wheel_2')
inv:add_stack({'zeus:world:key_iron', 64})
inv:add_stack({'zeus:world:key_silver', 64})
inv:add_stack({'zeus:world:key_gold', 64})
inv:add_stack({'zeus:world:key_gold', 1024})
end)
end