#Blockens, my little voxel game/learning project

1296 messages Β· Page 2 of 2 (latest)

rigid arch
#

my chunk position lengths are always evenly divisible by 36

spice geyser
#

is fast, is easy to port, only issue is that you'd need/want the current chunks data padded with neighbor chunk voxel data, so an array of (chunk_size + 2) ^ 3
cosmos (the maintainer) also added vertex pulling stuff, check the branches

rigid arch
#

what do you mean by both directions?

#

oh you mean going negative?

spice geyser
#

i see what you mean here, it's a similar but different idea

#

you're merging voxels to make bigger voxels and hence make bigger quads

rigid arch
#

yes

spice geyser
#

but don't think about the voxels, think about just the surface

#

there a quad has two dimensions, width and height

rigid arch
#

yes I was experimenting with this

#

I hadn't made it work and I already had the existing mesher code and it performed really well

#

I see what you're saying though

spice geyser
#

you're currently doing unnecessary computations because: the merged big voxels only produce a mesh on its surface but you still had to sample basically the entire voxel data array

rigid arch
#

oh how do you avoid that

spice geyser
#

can recommend checking out binary-greedy-meshing (on phone, too lazy to send you the github link lol)

rigid arch
#

I will research it thank you

spice geyser
# rigid arch oh how do you avoid that

im kind of shushing a few things and brushing them under the table:
simplified, the idea is to use a bitmask of solid/empty voxel data
that way you can

  1. cull occluded faces very easily and efficiently and
  2. greedy meshing also becomes very easy and efficient: you can use the bitmask to detect rows of set bits
    and only for the set bits do you need to read and compare the voxel data
#

and im brushing stuff under the table because: you need to construct the bitmask first or have it already
otherwise, yes you do read all the voxel data but it's still in a much nicer linear fashion rather than the 'random' reads you could get by trying to enlarge/merge voxels

#

but if you ignore constructing the bitmask - you only ever read the voxel data of surface voxels
all other voxels don't contribute a quad to the final mesh and won't have their data read

sand lava
#

the bitmask is why my render blocks are 8x8x8

rigid arch
#

how do you store your chunk data on disk? I literally just have big arrays where the index increments x every index, y every dimension length and z every dimension ^ 2

sand lava
#

atm, i dont

spice geyser
#

im very bad at explaining stuff, i recommend watching "tantan"s latest video on youtube
he explains most of the binary greedy meshing algorithm (tho i don't like his code, the original repo is much better)

sand lava
#

finally

rigid arch
sand lava
#

doesnt match ground so its a bit flying lmao

merry flume
#

that looks impressive

rigid arch
#

I might make a bit of a foundation part of the castle

sand lava
#

yeh

#

this is using the same system i use for the trees

#

it loads a magicavoxel model

#

and plops it into a location

merry flume
#

basically a tree castle πŸ™‚

sand lava
#

tho because the castle is a hekin chonker, it uses a fancier system to detect when a world tile overlaps with a "big" structure

#

this does mean i can do a evil tower

#

which ill do next because i want an evil tower

rigid arch
#

yeah I think I might modify the magicavoxel model to make it have a foundation, instead of changing the terrain maybe, or pick location where castle goes, adjust terrain, and then add castle

#

really neat

#

evil towers nice

sand lava
#

kek

#

fucked up the bounds

sand lava
#

magicavoxel is really mostly a stopgap

#

it obviously misses a lot of actual game items that need to be setup in the game, think stuff like chest or special block types

#

what are your ideas for editing the map?

#

are you going full procgen, some prebaked, math only, edited chunks?

merry flume
#

funny looking deccer cubes πŸ˜›

rigid arch
#

well my game's entire strategy is full customization for everything in game, a large part of the game is a content creator, I'll ship with some default content, but basically anyone can create whatever world they want, can customize their own terrain gen, create their own block types with their own textures, and create their own trees, they're own structures and buildings, their own mobs etc

#

I'm basically building the tools to build the content to put in the game

#

so however I do it, the application code needs to follow some type of content creation set of instructions

#

I do want to have the default game to have cool stuff in it and a game

#

I think the terrain gen will be pocedurally generated, and then there will be scripts to dump stuff into the world

#

these are just grand ideas and I really don't know yet, I don't even have trees yet

#

it would be really cool if someone used my game to make a better game than what I came up with

#

it's all a pipe dream, I am focused on one problem at a time and working hard to keep hope alive

#

that I'll keep making progress

#

I want to build command blocks that allow you to write lua scripts for the command blocks and let you do cool stuff in game

merry flume
#

why not zig? πŸ˜›

rigid arch
#

because I'd have to ship a zig compiler

sand lava
#

im going to be hooking lua into this soon

rigid arch
#

I'm not sure how that would work

sand lava
#

need a way to script blocks in a modular way

#

for custom types and biomes generators and all that stuff

#

i think ill directly pilfer what factorio does

merry flume
sand lava
#

godlike

#

im actually pretty happy with my iteration loop

#

i have a f5 "reload world" button, and combined with livepp... thats basically it

#

so my noises and worldgen are hardcoded af and i just reload code and refresh map

merry flume
#

i mean worst case you have a button somewhere or press a hotkey and have it reload stuff

rigid arch
#

there's no hot reload with zig right now

sand lava
#

madrigal tech is amazing

#

his blender hotreload stuff is incredible

#

i wonder if i can implemnt something similar with my engine

#

have an "editor" executable that has no world, only template editing

#

and then you can modify something and it refreshes in-world

#

have you seen the jonathan blow engine streams?

#

of his sokoban game with jai

#

apart from the jai stuff, there is something i found super cool for the workflow side

#

first of them is that he has 1 key to load previus/next map, and another key to trigger a replay playthorugh of it. He also has a button that sends him into the "prototype world" where there is 1 of each item in the game, and he can click and edit them there, then come back to the map (where he left off, state is not restarted) and see how it goes

#

the entire workflow is fast

rigid arch
sand lava
#

he doesnt have a direct hot-reload, but instead has some other trick. Remember Jai compiles his entire game in 2 seconds, so he has a button where the game closes, it compiles the code, and it re-launches where he was before at the exact same point. whole iteration loop takes something like 3 seconds total

rigid arch
#

I would love hot reload

sand lava
#

i use this

#

its paid but it Just Works and well

#

absolute must have

rigid arch
#

looks like you can build a shared library with zig

sand lava
#

ah yeah, zig is a clike, so the dll bounds/etc stuff is less dodgy

#

you can probably do what the machinery dudes did

rigid arch
#

it's C-ABI compatible yes

merry flume
#

i love his stuff too

rigid arch
#

oh can you not follow that link?

merry flume
#

nope links only work when you are on the server

honest wigeon
merry flume
#

preview where you can join but not join, yes

#

links still do be working like that

rigid arch
#

time to get block editing to work with my new small chunks, then I can remove the old big chunks

sand lava
#

so one thing im thinking now (that might be useful to all of you other block people), is to unload the data from cpu while keeping cpu structures around

#

so, only keep the tiles in memory on an "active radius" around the player, where they also do entity ticking and stuff

#

but past that, once they generate their gpu structures, drop their cpu side memory and leave them in an unloaded state

rigid arch
#

Yup makes sense to not hang on to memory not being used

rigid arch
#

I finally figured out how to do cross context OpenGL so I can have a dedicated graphics thread πŸ˜…

#

that took a bit of time to figure out

#

I started with driver panics, seg faults, moved to error mapping buffers, built a dedicated thread system with send and receive channels and now it works and I can make progress again, two day journey of ignorance

merry flume
#

still sucks that you have to make the context you want top operate on current

rigid arch
#

yes

merry flume
#

and that is usually a costly operation

rigid arch
#

I'm not sure how my performance is impacted yet, I just now got it finally working

#

I don't really have any alternative to this other than move sorting to the GPU I guess

#

it's just too slow to do on the same thread that I render on

sand lava
#

you dont need a full sort

#

you can just partition near vs far and thats good enough

rigid arch
#

it's culling that's also slow

#

I can probably improve that

sand lava
#

how?

rigid arch
#

it's pretty naive

sand lava
#

how many objects you cull per ms

rigid arch
#

all my subchunks

sand lava
#

a decent system should easily do 100k in 1 core in sub 1 ms

rigid arch
#

1k*

sand lava
#

1k is nothing

rigid arch
#

ok maybe my culling sucks

sand lava
#

something is beyond fuckd

#

whats your data structure

rigid arch
#

yeah

#

for culling it's just a [8]@Vector(4, f32)

#

I think it's just a really slow and dumb first attempt at culling

#

for each subchunk

sand lava
#

its strange because vkguide doesnt even try and its like 20k a ms easy

rigid arch
#

what is vkguide

sand lava
#

so 1k being anywhere near slow means something is odd

rigid arch
#

are you culling on the gpu

sand lava
#

cpu

rigid arch
#

yeah me being new to this is the problem, I'll look at that too

#

hrm

sand lava
#

on cpu throught tryharding i once did 300k culls per ms on ps4 shite cpu

#

a frustum cull should run at whatever your memory bandwidth is

#

and on pc thats 50 gbs a sec

#

have you benched it properly?

rigid arch
#

I just see what it is in tracy

sand lava
#

i fail to understand how culling 1000 objects can be slow when even the old godot, which was the absolute worsr impl you can imagine, did 1000 elements in 0.2 ms

#

try a sampling profiler (or tracy sampling mode) to get per_line info

merry flume
#

absolute worst impl is something naive as in aabb vs frustum neh?

sand lava
#

ni

#

as in "linked list iterated shit octree"

merry flume
#

ah

sand lava
#

3 cache misses per object minimum

merry flume
#

hehe

#

whats the least shit impl on the cpu?

#

still octree or some other bvhism?

rigid arch
#

I'm sure this is jus a skill issue, and I've embarrased myself

sand lava
#

just iterate over array

#

of abb or sphere structures

merry flume
#

ofc, rather than linked list bs, gotcha

sand lava
#

if you do that you are already at the 100k per ms ballpark

#

without simd

rigid arch
#

I made it a bit faster by making my culling and sorting logic less dumb and am now attempting to build an aabb structure and that should all help.

#

it's still pretty naive but it should help

#

As an aside, early on in my project I was initially calling things up, down, front, back, left right in my data structures. And it always led to mistakes and inconsistencies and hard to understand code and I've since just call things dimension_sign (like x_pos x_neg, y_pos etc) and it's lead to much cleaner and understandable code.

#

like the surfaces of my voxels, or in chunk traversal code

sand lava
#

why an aabb structure? you dont need that @rigid arch

#

i was still doing bruteforce culling on my super high distance system just fine

#

you will run out of vram and drawcalls way before you need anything but a for loop over array for culling

rigid arch
#

it's just checking the effective radius of each chunk is less or equal to the dot product of the planes of the frustum and the center point of the chunk

#

I already did all the aabb tree code yesterday so I'm just going to use it, it's pretty cool, I wrote tests and everything

#

I have a bunch of books on rendering, and that one is the best one by far

#

I have another one by the same author but this one is better

rigid arch
#

I think I'm going to spend some time going through this book and improve my basic understanding

sand lava
#

thats a pretty good one

sand lava
#

update.. my block renderer with the fancy pixel shader thingy runs like garbage on a steam deck :/

merry flume
#

you import glfw and glad into "c" namespace so to speak

#

but you use glfw.xyz and c.glThisAndThat

#

which is a little weird

#

from a naming perspective

rigid arch
#

yeah I was just experimenting with glad, most zig people don't use glad

merry flume
#

you have a namespace alias for gl.glThisAndThat at the bottom πŸ™‚

rigid arch
#

but that's how cImport works

#

right the gl I made is my own module

merry flume
#

oh

rigid arch
#

it's importing my gl.zig

merry flume
#

ah

#

your abstraction basically

#

i see

rigid arch
#

right this is kind of inbetween

merry flume
#

should be "rhi" then

#

or "frontend"

rigid arch
#

something like that, I usually call it gfx

#

but yeah

merry flume
#

alot of rs and go and zig people would call that gfx for some reason πŸ™‚

#

(ive seen that in other people's shit too)

rigid arch
#

this ^^ is the zig-gamedev version of it

#

but they made zig bindings for opengl

merry flume
#

thats the bare minimum

rigid arch
#

what I'm doing

merry flume
#

and if you only use raw glfw/gl thats what i would do too then

rigid arch
#

is bare minimum

merry flume
#

and wrap them into my rhi

rigid arch
#

yeah

merry flume
#

thats actually what i am doing right now πŸ˜›

rigid arch
#

I just want the straight up C because zig is unstable

#

and it's such a pain to depend on other people's zig libraries

merry flume
#
auto InitializeRhi() -> bool;
auto UnloadRhi() -> void;
auto CreateSampler(const SSamplerDescriptor& samplerDescriptor) -> SSampler;
auto CreateTexture(const SCreateTextureDescriptor& createTextureDescriptor) -> STexture;
auto CreateFramebuffer(const SFramebufferDescriptor& framebufferDescriptor) -> SFramebuffer;
auto ClearFramebuffer(SFramebuffer framebuffer) -> void;
auto DeleteFramebuffer(SFramebuffer framebuffer) -> void;
auto CreateGraphicsPipeline(const SGraphicsPipelineDescriptor& graphicsPipelineDescriptor) -> std::expected<SGraphicsPipeline, std::string>;
auto CreateComputePipeline(const SComputePipelineDescriptor& computePipelineDescriptor) -> std::expected<SComputePipeline, std::string>;
rigid arch
#

because nobody is really in step with all the constant breaking changes in zig

merry flume
#

yeah as long as its unstable its probably best like so

rigid arch
#

so by using just C deps I avoid all of that

merry flume
#

but the danger is that all the other 100 "gamedev" zig people do the same

#

and you end up having 300 shit libs

rigid arch
#

I still have to update all my own code with any zig breaking changes, but that's usually easy and if you use the stable 0.12.0 you don't have to worry about it

merry flume
#

same in c# ecosystem and npm and anywhere else πŸ˜„ unfortunately

rigid arch
#

yeah

#

zig-gamedev has a concept of pinned releases

#

so if it is the only dependency you have you can just always pin your zig to that version but that only works if you only have that as your only dep

merry flume
#

the danger is also that a lot of kids and noobs come up with shit which makes no sense

#

and then people build on top of that : )

rigid arch
merry flume
#

ah this guy

#

i rember him

#

from the dx12 engine thing in zig

rigid arch
#

yes, that's his new project

merry flume
#

ah i also dont mean to make it bad or anything

rigid arch
merry flume
#

ah neat

rigid arch
#

he handed off zig-gamedev to the community

merry flume
#

thats what i mean

#

now everyone adds stuff

#

quality control is probably 0

#

dont get me wrong, its like that everywhere and its cool and good that people can contribute like that

rigid arch
#

do I reuse this thread if I wanted to share anything I make with my new project while this one is on hold?

#

it's going to take me a bit to get back to my voxel engine

#

I'll probably rewrite it

#

it was a learning project and I have learned a lot from it

#

I don't know, what I'm doing now isn't really interesting to others

#

I'm going to call that module rhi then instead of gl or gfx, I like that way better as a name, having just looked it up

merry flume
#

up to you πŸ™‚

#

there is no limit of who and how many threads one opens

rigid arch
#

ah ok thank you

merry flume
#

you can rename the thread too if you like, and adjust the first post

#

really up to you

rigid arch
#

ah ok thank you, makes sense and appreciate it

#

I think I'll maybe make a game-dev with zig thread at some point

#

or something

merry flume
#

or new thread and you put a link here

rigid arch
#

once there's something worth sharing

#

graphics programming with zig I mean

merry flume
#

ah

rigid arch
#

btw I'm not sure I'm a fan of glad in zig because I tried a multi-context build of glad and the zig c-interpret made all the gl functions nullable, so they would require a .? unwrap in zig to call: gl.clear.?(... in addition to the zig-gamedev approach there are also gl generators with loaders written in zig as an alternative to using glad https://github.com/ziglibs/zgl for example

merry flume
#

i dont think you really need multi context

rigid arch
#

requires some comptime fancy stuff and pointer tricks though

merry flume
#

does everything HAVE to be comptime

#

i do the same though, in my c# EngineKit bs, i load glfw dynamically, get its GlfwGetProcAddress to load GL functions πŸ™‚

rigid arch
#

comptime is pretty cool, it's basically zig's replacement for macros, and allows for some polymorphism

#

I haven't used it much personally

merry flume
#

macros bad

#

i thought its closer to constexpr

rigid arch
#

well when you create an std.ArrayList, which is like zig's version of a cpp vector you define what types are in the arraylist via comptime declaration

#

it's not macros, zig doesn't have macros

#

it's like you can use zig at compile time

#

and during that time you can create types

merry flume
#

ah

#

like a generator of sorts, more like c++'s templates then

rigid arch
#

I'm really new at all of this and the zig discord has a lot of brilliant people

#

Compile-time parameters is how Zig implements generics. It is compile-time duck typing.

merry flume
#

perhaps i should also just try to reimplement what i have right now in ziggorino

rigid arch
#

yes so like C++ templates

rigid arch
#

maxes out at 300-400 fps benchmarks, that's what I saw in blockens too

#

I'm going to create a new community project thread tbh

vocal wind
#

have you done this? didn't wanna use vma with @cImport and decided to build zig bindings for vma

rigid arch
#

no I haven't

#

seems weird to use a zig allocator for gpu memory

vocal wind
#

yeah, I meant to ask about if you used vma rather than specific zig allocator impl*, my bad

rigid arch
#

what is vma?

vocal wind
#

vulkan memory allocator

rigid arch
#

oh no I haven't

#

don't your zig bindings have to @cImport though?

vocal wind
#

oh yeah, ofc

#

but for structs I'd like to use packed structs

rigid arch
#

I don't like writing zig bindings for C lib stuff

#

I just have a single C import file and I import what it imports all over my project

#

gl is a bit different because I want to build a vulkan backend also

vocal wind
#

that's currently how I use sdl2, but for vulkan I'm using vulkan-zig, which generates implementations from a xml if I'm not mistaken. so thought having a similar api for vma would be fun

rigid arch
#

so I abstract that

#

but not for C/zig reasons

rigid arch