Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
72be7ee
feat: implement end crystals + respawn anchors
cqdetdev May 9, 2026
ddc0113
minor: undo debug change
cqdetdev May 9, 2026
b2939e5
chore: clean up code
cqdetdev May 9, 2026
7c8e09b
chore: abstract end crystal behavior to its own file
cqdetdev May 9, 2026
8ec3d79
Integrate current upstream base for reviewable crystal and anchor fixes
HashimTheArab May 24, 2026
db8af78
Align crystal and anchor behavior with source-backed parity
HashimTheArab May 24, 2026
4263cdf
Merge pull request #1 from HashimTheArab/codex/pr1247-crystal-anchor-…
HashimTheArab May 24, 2026
0f64f81
Make respawn anchor spawn priority explicit
HashimTheArab May 24, 2026
1820f66
Clean up crystal and anchor metadata helpers
HashimTheArab May 24, 2026
cc54c23
Merge branch 'master' into feat/crystals+anchors
didntpot May 24, 2026
af45db8
Clean up crystal and anchor metadata helpers
HashimTheArab May 24, 2026
a193d1f
Document shared entity damage helper returns
HashimTheArab May 24, 2026
5021cb4
Name the respawn block contract
HashimTheArab May 24, 2026
6f5385b
Restore Bedrock bed fallback text
HashimTheArab May 24, 2026
75df119
Preserve dimensioned respawns and crystal parity
HashimTheArab May 24, 2026
9bcc140
Merge pull request #2 from cqdetdev/codex/pr1247-parity-fixes
HashimTheArab May 24, 2026
6227483
cube/trace: add BlockIntersects and BBoxIntersects methods (#1262)
HashimTheArab May 28, 2026
bb1a7a7
world/chunk: add Clone methods to chunk, subchunk, and palette (#1264)
HashimTheArab May 28, 2026
c08da57
block/grass.go: Fix bone meal duplication glitch (#1266)
Dasciam Jun 1, 2026
64d40fd
server/block: Implement bonemeal huge growth particles (#1267)
Dasciam Jun 1, 2026
83a8f57
item/crossbow.go: Always set critical flag to match vanilla (#1270)
Dasciam Jun 9, 2026
7c30428
item/crossbow.go: Fix crossbow charging animation played even if the …
Dasciam Jun 9, 2026
0f8cf2e
dragonfly: Updated for 1.26.30 (#1268)
didntpot Jun 16, 2026
716292c
leveldat/level_dat.go: Always read full file to prevent potential rea…
TrippleAWap Jun 17, 2026
7f68b06
updated contributor list
TwistedAsylumMC Jun 17, 2026
477b816
session/session.go: fix panic when sessionless player logs (#1276)
RestartFU Jun 22, 2026
1746dd7
session/entity_metadata.go: guard nil session handle in metadata (#1278)
RestartFU Jun 22, 2026
8be43f3
leveldat/data.go: Add missing fields (#1277)
smell-of-curry Jun 24, 2026
723721f
updated contributor list
TwistedAsylumMC Jun 24, 2026
26be2a6
chunk/block_registry.go: Add RuntimeIDToHash in BlockRegistry interfa…
HashimTheArab Jun 28, 2026
263fb85
server/block: Implement bamboo building blocks and items (#1292)
MEMOxiiii Jul 1, 2026
026c062
updated contributor list
HashimTheArab Jul 1, 2026
556a712
Merge branch 'master' into feat/crystals+anchors
HashimTheArab Jul 2, 2026
d9f3cf5
Fix vanilla parity issues from review
cqdetdev Jul 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ require (
github.com/brentp/intintmap v0.0.0-20251106190759-56907b1f8479
github.com/cespare/xxhash/v2 v2.3.0
github.com/df-mc/goleveldb v1.1.9
github.com/df-mc/worldupgrader v1.0.20
github.com/df-mc/worldupgrader v1.0.21
github.com/go-gl/mathgl v1.2.0
github.com/google/uuid v1.6.0
github.com/pelletier/go-toml v1.9.5
github.com/sandertv/gophertunnel v1.56.2
github.com/sandertv/gophertunnel v1.57.0
github.com/segmentio/fasthash v1.0.3
golang.org/x/exp v0.0.0-20250103183323-7d7fa50e5329
golang.org/x/mod v0.22.0
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ github.com/df-mc/goleveldb v1.1.9 h1:ihdosZyy5jkQKrxucTQmN90jq/2lUwQnJZjIYIC/9YU
github.com/df-mc/goleveldb v1.1.9/go.mod h1:+NHCup03Sci5q84APIA21z3iPZCuk6m6ABtg4nANCSk=
github.com/df-mc/jsonc v1.0.5 h1:O7oh07kbS5AYY+l2Fji6l4h0iHcdjKbxCtK5VlZlLMU=
github.com/df-mc/jsonc v1.0.5/go.mod h1:+Q++JuCE9IKiP8v7sWImdf/RjQX0nfXyfX6PdfTTmc4=
github.com/df-mc/worldupgrader v1.0.20 h1:wfJyG3bFeaM/HXy7TCiO4HKVw3Mf3N4gPFmgxMHsKnc=
github.com/df-mc/worldupgrader v1.0.20/go.mod h1:tsSOLTRm9mpG7VHvYpAjjZrkRHWmSbKZAm9bOLNnlDk=
github.com/df-mc/worldupgrader v1.0.21 h1:Qr4/QB8ek7En0vkTuRXYq4FrZM0HHSOXsJOL7Ko4Cjg=
github.com/df-mc/worldupgrader v1.0.21/go.mod h1:tsSOLTRm9mpG7VHvYpAjjZrkRHWmSbKZAm9bOLNnlDk=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/go-gl/mathgl v1.2.0 h1:v2eOj/y1B2afDxF6URV1qCYmo1KW08lAMtTbOn3KXCY=
github.com/go-gl/mathgl v1.2.0/go.mod h1:pf9+b5J3LFP7iZ4XXaVzZrCle0Q/vNpB/vDe5+3ulRE=
Expand Down Expand Up @@ -41,8 +41,8 @@ github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3v
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/sandertv/go-raknet v1.15.1-0.20260112202637-beca0b10c217 h1:UZQq2253Q+7co/C9Et62RYPBggzz+L+2yqGlvQhSNM8=
github.com/sandertv/go-raknet v1.15.1-0.20260112202637-beca0b10c217/go.mod h1:/yysjwfCXm2+2OY8mBazLzcxJ3irnylKCyG3FLgUPVU=
github.com/sandertv/gophertunnel v1.56.2 h1:eFc58AkMQo43ntR0Wmvz8GRFSdOgABKVDn52GMbIYag=
github.com/sandertv/gophertunnel v1.56.2/go.mod h1:F8+ZPbzxJ0LqunXEaDjqeyUgHVB0rI5ZU+PHnptXGfI=
github.com/sandertv/gophertunnel v1.57.0 h1:UkgVg1xLCsOSm79rP09WmodGSHgA8M7+l4quL01cIL8=
github.com/sandertv/gophertunnel v1.57.0/go.mod h1:W4VnrX9AIPIVXNDMEIKMIRj1T80EdOgdqXpGbQpyAbE=
github.com/segmentio/fasthash v1.0.3 h1:EI9+KE1EwvMLBWwjpRDc+fEM+prwxDYbslddQGtrmhM=
github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY=
golang.org/x/exp v0.0.0-20250103183323-7d7fa50e5329 h1:9kj3STMvgqy3YA4VQXBrN7925ICMxD5wzMRcgA30588=
Expand Down
78 changes: 78 additions & 0 deletions server/block/bamboo_block.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package block

import (
"github.com/df-mc/dragonfly/server/block/cube"
"github.com/df-mc/dragonfly/server/item"
"github.com/df-mc/dragonfly/server/world"
"github.com/go-gl/mathgl/mgl64"
"time"
)

// BambooBlock is a rotatable flammable block made from bamboo.
type BambooBlock struct {
solid
bass

// Axis is the axis which the bamboo block faces.
Axis cube.Axis
// Stripped specifies if the bamboo block is stripped.
Stripped bool
}

// FlammabilityInfo ...
func (BambooBlock) FlammabilityInfo() FlammabilityInfo {
return newFlammabilityInfo(5, 5, true)
}

// BreakInfo ...
func (b BambooBlock) BreakInfo() BreakInfo {
return newBreakInfo(2.0, alwaysHarvestable, axeEffective, oneOf(b))
}

// FuelInfo ...
func (BambooBlock) FuelInfo() item.FuelInfo {
return newFuelInfo(time.Second * 15)
}

// UseOnBlock ...
func (b BambooBlock) UseOnBlock(pos cube.Pos, face cube.Face, _ mgl64.Vec3, tx *world.Tx, user item.User, ctx *item.UseContext) (used bool) {
pos, face, used = firstReplaceable(tx, pos, face, b)
if !used {
return
}
b.Axis = face.Axis()

place(tx, pos, b, user, ctx)
return placed(ctx)
}

// Strip ...
func (b BambooBlock) Strip() (world.Block, world.Sound, bool) {
return BambooBlock{Axis: b.Axis, Stripped: true}, nil, !b.Stripped
}

// EncodeItem ...
func (b BambooBlock) EncodeItem() (name string, meta int16) {
if b.Stripped {
return "minecraft:stripped_bamboo_block", 0
}
return "minecraft:bamboo_block", 0
}

// EncodeBlock ...
func (b BambooBlock) EncodeBlock() (name string, properties map[string]any) {
meta := map[string]any{"pillar_axis": b.Axis.String()}
if b.Stripped {
return "minecraft:stripped_bamboo_block", meta
}
return "minecraft:bamboo_block", meta
}

// allBambooBlocks ...
func allBambooBlocks() (blocks []world.Block) {
for _, axis := range cube.Axes() {
blocks = append(blocks, BambooBlock{Axis: axis})
blocks = append(blocks, BambooBlock{Axis: axis, Stripped: true})
}
return
}
42 changes: 42 additions & 0 deletions server/block/bamboo_mosaic.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package block

import (
"github.com/df-mc/dragonfly/server/item"
"time"
)

// BambooMosaic is a decorative bamboo plank variant.
type BambooMosaic struct {
solid
bass
}

// FlammabilityInfo ...
func (BambooMosaic) FlammabilityInfo() FlammabilityInfo {
return newFlammabilityInfo(5, 20, true)
}

// BreakInfo ...
func (b BambooMosaic) BreakInfo() BreakInfo {
return newBreakInfo(2, alwaysHarvestable, axeEffective, oneOf(b)).withBlastResistance(15)
}

// RepairsWoodTools ...
func (BambooMosaic) RepairsWoodTools() bool {
return true
}

// FuelInfo ...
func (BambooMosaic) FuelInfo() item.FuelInfo {
return newFuelInfo(time.Second * 15)
}

// EncodeItem ...
func (BambooMosaic) EncodeItem() (name string, meta int16) {
return "minecraft:bamboo_mosaic", 0
}

// EncodeBlock ...
func (BambooMosaic) EncodeBlock() (string, map[string]any) {
return "minecraft:bamboo_mosaic", nil
}
4 changes: 2 additions & 2 deletions server/block/bed.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,8 @@ func (b Bed) Activate(pos cube.Pos, _ cube.Face, tx *world.Tx, u item.User, _ *i
return false
}

previousSpawn := w.PlayerSpawn(s.UUID())
if previousSpawn != headPos {
previousSpawn, ok := w.PlayerSpawnPoint(s.UUID())
if !ok || previousSpawn.Pos != headPos || previousSpawn.Dim != world.Overworld {
w.SetPlayerSpawn(s.UUID(), headPos)
s.Messaget(chat.MessageRespawnPointSet)
}
Expand Down
8 changes: 4 additions & 4 deletions server/block/beetroot_seeds.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@ func (BeetrootSeeds) SameCrop(c Crop) bool {
}

// BoneMeal ...
func (b BeetrootSeeds) BoneMeal(pos cube.Pos, tx *world.Tx) bool {
func (b BeetrootSeeds) BoneMeal(pos cube.Pos, tx *world.Tx) item.BoneMealResult {
if b.Growth == 7 {
return false
return item.BoneMealResultNone
}
if rand.Float64() < 0.75 {
b.Growth++
tx.SetBlock(pos, b, nil)
return true
return item.BoneMealResultSmall
}
return false
return item.BoneMealResultNone
}

// UseOnBlock ...
Expand Down
6 changes: 3 additions & 3 deletions server/block/carrot.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ func (c Carrot) Consume(_ *world.Tx, co item.Consumer) item.Stack {
}

// BoneMeal ...
func (c Carrot) BoneMeal(pos cube.Pos, tx *world.Tx) bool {
func (c Carrot) BoneMeal(pos cube.Pos, tx *world.Tx) item.BoneMealResult {
if c.Growth == 7 {
return false
return item.BoneMealResultNone
}
c.Growth = min(c.Growth+rand.IntN(4)+2, 7)
tx.SetBlock(pos, c, nil)
return true
return item.BoneMealResultSmall
}

// UseOnBlock ...
Expand Down
9 changes: 5 additions & 4 deletions server/block/cocoa_bean.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package block

import (
"math/rand/v2"

"github.com/df-mc/dragonfly/server/block/cube"
"github.com/df-mc/dragonfly/server/block/model"
"github.com/df-mc/dragonfly/server/item"
"github.com/df-mc/dragonfly/server/world"
"github.com/go-gl/mathgl/mgl64"
"math/rand/v2"
)

// CocoaBean is a crop block found in jungle biomes.
Expand All @@ -20,13 +21,13 @@ type CocoaBean struct {
}

// BoneMeal ...
func (c CocoaBean) BoneMeal(pos cube.Pos, tx *world.Tx) bool {
func (c CocoaBean) BoneMeal(pos cube.Pos, tx *world.Tx) item.BoneMealResult {
if c.Age == 2 {
return false
return item.BoneMealResultNone
}
c.Age++
tx.SetBlock(pos, c, nil)
return true
return item.BoneMealResultSmall
}

// HasLiquidDrops ...
Expand Down
35 changes: 35 additions & 0 deletions server/block/cube/trace/bbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,41 @@ func BBoxIntercept(bb cube.BBox, start, end mgl64.Vec3) (result BBoxResult, ok b
return BBoxResult{bb: bb, pos: *vec, face: f}, true
}

// BBoxIntersects checks if the line segment from start to end intersects the BBox.
// Unlike BBoxIntercept, it only reports whether an intersection exists and does not
// calculate the closest hit position or face.
func BBoxIntersects(bb cube.BBox, start, end mgl64.Vec3) bool {
min, max := bb.Min(), bb.Max()
dir := end.Sub(start)
tMin, tMax := 0.0, 1.0

for axis := range 3 {
if mgl64.FloatEqual(dir[axis], 0) {
if start[axis] < min[axis] || start[axis] > max[axis] {
return false
}
continue
}

inv := 1 / dir[axis]
t1 := (min[axis] - start[axis]) * inv
t2 := (max[axis] - start[axis]) * inv
if t1 > t2 {
t1, t2 = t2, t1
}
if t1 > tMin {
tMin = t1
}
if t2 < tMax {
tMax = t2
}
if tMin > tMax {
return false
}
}
return true
}

// vec3OnLineWithX returns an mgl64.Vec3 on the line between mgl64.Vec3 a and b with an X value passed. If no such vec3
// could be found, the bool returned is false.
func vec3OnLineWithX(a, b mgl64.Vec3, x float64) *mgl64.Vec3 {
Expand Down
21 changes: 21 additions & 0 deletions server/block/cube/trace/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package trace

import (
"github.com/df-mc/dragonfly/server/block/cube"
"github.com/df-mc/dragonfly/server/block/model"
"github.com/df-mc/dragonfly/server/world"
"github.com/go-gl/mathgl/mgl64"
"math"
Expand Down Expand Up @@ -70,3 +71,23 @@ func BlockIntercept(pos cube.Pos, src world.BlockSource, b world.Block, start, e

return BlockResult{bb: hit.BBox(), pos: hit.Position(), face: hit.Face(), blockPos: pos}, true
}

// BlockIntersects checks if the line segment from start to end intersects the block model of b at pos. Unlike
// BlockIntercept, it only reports whether an intersection exists and does not calculate the closest hit position, face,
// or bounding box.
func BlockIntersects(pos cube.Pos, src world.BlockSource, b world.Block, start, end mgl64.Vec3) bool {
m := b.Model()
switch m.(type) {
case model.Empty:
return false
case model.Solid:
return BBoxIntersects(cube.Box(0, 0, 0, 1, 1, 1).Translate(pos.Vec3()), start, end)
}

for _, bb := range m.BBox(pos, src) {
if BBoxIntersects(bb.Translate(pos.Vec3()), start, end) {
return true
}
}
return false
}
4 changes: 2 additions & 2 deletions server/block/double_flower.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ func (d DoubleFlower) FlammabilityInfo() FlammabilityInfo {
}

// BoneMeal ...
func (d DoubleFlower) BoneMeal(pos cube.Pos, tx *world.Tx) bool {
func (d DoubleFlower) BoneMeal(pos cube.Pos, tx *world.Tx) item.BoneMealResult {
dropItem(tx, item.NewStack(d, 1), pos.Vec3Centre())
return true
return item.BoneMealResultSmall
}

// NeighbourUpdateTick ...
Expand Down
6 changes: 3 additions & 3 deletions server/block/fern.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ func (g Fern) BreakInfo() BreakInfo {
}

// BoneMeal attempts to affect the block using a bone meal item.
func (g Fern) BoneMeal(pos cube.Pos, tx *world.Tx) bool {
func (g Fern) BoneMeal(pos cube.Pos, tx *world.Tx) item.BoneMealResult {
upper := DoubleTallGrass{Type: FernDoubleTallGrass(), UpperPart: true}
if replaceableWith(tx, pos.Side(cube.FaceUp), upper) {
tx.SetBlock(pos, DoubleTallGrass{Type: FernDoubleTallGrass()}, nil)
tx.SetBlock(pos.Side(cube.FaceUp), upper, nil)
return true
return item.BoneMealResultSmall
}
return false
return item.BoneMealResultNone
}

// CompostChance ...
Expand Down
10 changes: 6 additions & 4 deletions server/block/flower.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package block

import (
"math/rand/v2"
"time"

"github.com/df-mc/dragonfly/server/block/cube"
"github.com/df-mc/dragonfly/server/entity/effect"
"github.com/df-mc/dragonfly/server/item"
"github.com/df-mc/dragonfly/server/world"
"github.com/go-gl/mathgl/mgl64"
"math/rand/v2"
"time"
)

// Flower is a non-solid plant that occur in a variety of shapes and colours. They are primarily used for decoration
Expand All @@ -32,7 +33,8 @@ func (f Flower) EntityInside(_ cube.Pos, _ *world.Tx, e world.Entity) {
}

// BoneMeal ...
func (f Flower) BoneMeal(pos cube.Pos, tx *world.Tx) (success bool) {
func (f Flower) BoneMeal(pos cube.Pos, tx *world.Tx) (result item.BoneMealResult) {
result = item.BoneMealResultNone
if f.Type == WitherRose() {
return
}
Expand All @@ -54,7 +56,7 @@ func (f Flower) BoneMeal(pos cube.Pos, tx *world.Tx) (success bool) {
}
}
tx.SetBlock(p, Flower{Type: flowerType}, nil)
success = true
result = item.BoneMealResultArea
}
return
}
Expand Down
Loading