chunk builder

This commit is contained in:
adman
2026-04-19 17:41:13 +02:00
parent c2777f2ca9
commit 65fea61667
6 changed files with 119 additions and 1 deletions
+4
View File
@@ -1,5 +1,7 @@
package data
import "errors"
// [
//
// {
@@ -48,6 +50,8 @@ func LookupBiomeById(version string, id int32) (biome *Biome, ok bool) {
return
}
var UnknownBiomeNameErr = errors.New("unknown biome Name")
func LookupBiomeByName(version string, name string) (biome *Biome, ok bool) {
for _, b := range BiomesForVersion(version) {
if b.Name == name {
+2
View File
@@ -81,6 +81,8 @@ func LookupBlockByStateId(version string, stateId int32) (block *Block, ok bool)
return
}
var UnknownBlockNameErr = errors.New("unknown block Name")
func LookupBlockByName(version string, name string) (block *Block, ok bool) {
for _, b := range BlocksForVersion(version) {
if b.Name == name {
+93
View File
@@ -0,0 +1,93 @@
package level
import (
"bytes"
"errors"
"github.com/admin-else/strom/data"
"github.com/admin-else/strom/util"
)
type ChunkBuilder struct {
Biomes, Blocks [][]int32
Bottom, Top int32
Version string
}
func NewChunkBuilder(bottom, top int32, version string) *ChunkBuilder {
return &ChunkBuilder{Bottom: bottom, Top: top, Version: version}
}
func NewOverworldChunkBuilder(version string) *ChunkBuilder {
return NewChunkBuilder(-64, 320, version)
}
func (cb *ChunkBuilder) ColumnHeight() int32 {
absBottom := cb.Bottom
if absBottom < 0 {
absBottom *= -1
}
return absBottom + cb.Top
}
func (cb *ChunkBuilder) FillAllById(block, biome int32) {
numSections := cb.ColumnHeight() / ChunkWidth
blockSection := util.MakeSingleValuedSlice(block, BlocksPerChunkSection)
biomeSection := util.MakeSingleValuedSlice(biome, BiomesPerChunkSection)
cb.Blocks = make([][]int32, numSections)
cb.Biomes = make([][]int32, numSections)
for i := range cb.Blocks {
cb.Blocks[i] = blockSection
cb.Biomes[i] = biomeSection
}
return
}
func (cb *ChunkBuilder) FillAll(biome, block string) (err error) {
blockData, ok := data.LookupBlockByName(cb.Version, block)
if !ok {
err = data.UnknownBlockNameErr
return
}
biomeData, ok := data.LookupBiomeByName(cb.Version, biome)
if !ok {
err = data.UnknownBiomeNameErr
return
}
cb.FillAllById(blockData.DefaultState, biomeData.Id)
return
}
var InvalidChunkPositionErr = errors.New("invalid chunk position")
func (cb *ChunkBuilder) SetBlockId(x, y, z, id int32) (err error) {
if x < 0 || x >= ChunkWidth || z < 0 || z >= ChunkWidth || y < cb.Bottom || y >= cb.Top {
err = InvalidChunkPositionErr
return
}
y += cb.Bottom * -1
section := util.FloorDiv(y, ChunkWidth)
i := (y%ChunkWidth)*ChunkWidth*ChunkWidth + z*ChunkWidth + x
cb.Blocks[section][i] = id
return
}
func (cb *ChunkBuilder) SetBlock(x, y, z int32, block string) (err error) {
blockData, ok := data.LookupBlockByName(cb.Version, block)
if !ok {
err = data.UnknownBlockNameErr
return
}
return cb.SetBlockId(x, y, z, blockData.DefaultState)
}
func (cb *ChunkBuilder) Build() (data []byte, err error) {
b := bytes.NewBuffer(nil)
err = PackSections(cb.Blocks, cb.Biomes, cb.Version, b)
if err != nil {
return
}
data = b.Bytes()
return
}
+2 -1
View File
@@ -12,7 +12,8 @@ import (
)
const (
BlocksPerChunkSection = 16 * 16 * 16
ChunkWidth = 16
BlocksPerChunkSection = ChunkWidth * ChunkWidth * ChunkWidth
BiomesPerChunkSection = 4 * 4 * 4
)
+5
View File
@@ -0,0 +1,5 @@
package util
func FloorDiv(a, b int32) int32 {
return (a - ((a%b + b) % b)) / b
}
+13
View File
@@ -6,3 +6,16 @@ func MustOk[T any](v T, ok bool) T {
}
return v
}
func MustT[T any](v T, err error) T {
if err != nil {
panic(err)
}
return v
}
func Must(err error) {
if err != nil {
panic(err)
}
}