Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
861f628
feat: implement nether portals
xNatsuri Oct 1, 2025
e9fe553
add obsidian and a nether portal frame block
xNatsuri Oct 1, 2025
6b0bdd0
changes
xNatsuri Oct 1, 2025
db14f1e
Merge remote-tracking branch 'upstream/master' into feature/portal
didntpot Feb 13, 2026
f2912b1
Merge branch 'master' into feature/portal
didntpot Feb 13, 2026
e28598c
Merge branch 'master' into feature/portal
HashimTheArab May 6, 2026
54c7ab9
Use block-inside events for portal travel
HashimTheArab May 6, 2026
0609eeb
NeighbourUpdateTick now skips portal rescans for perpendicular horizo…
HashimTheArab May 6, 2026
a76b792
server: tighten Nether portal scan, frame and travel handling
HashimTheArab May 6, 2026
c2ed28f
server: add Nether portal and travel tests, run them in CI
HashimTheArab May 6, 2026
eaff6f4
remove useless docs
HashimTheArab May 6, 2026
46aa0d9
remove useless docs
HashimTheArab May 6, 2026
3083946
add light emission to portal block
HashimTheArab May 6, 2026
c48fef7
remove Place interface check:
HashimTheArab May 6, 2026
68ee5aa
portal/nether.go: simplify and improve code and clarify doc
HashimTheArab May 6, 2026
961db45
entity: harden TravelComputer and extract portal coord translation
HashimTheArab May 6, 2026
1b75559
Floor Nether portal scaling for negative Overworld coordinates
HashimTheArab May 6, 2026
59d0c6f
rename variable
HashimTheArab May 6, 2026
48ed0b2
fix portal blocks being ignored if it didnt have obsidian below it
HashimTheArab May 6, 2026
19e963f
fix: Prevent portal-crossed ender pearls from teleporting owners
HashimTheArab May 6, 2026
8d145f1
Tighten Nether portal scan failure semantics
HashimTheArab May 6, 2026
ca05e5a
Merge branch 'master' into feature/portal
HashimTheArab May 8, 2026
f45ce65
add portal teleport method to avoid calling handler
HashimTheArab May 7, 2026
982e1b3
feat: allow entities to travel through portals
HashimTheArab May 9, 2026
8bbe5fb
remove test file
HashimTheArab May 9, 2026
f277982
add offset and neighborface
HashimTheArab May 9, 2026
8944d58
use neighborface
HashimTheArab May 9, 2026
baea218
Use shared range iteration for portal scans
HashimTheArab May 16, 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
ca55084
Merge remote-tracking branch 'upstream/master' into natsuri-feature-p…
HashimTheArab Jul 2, 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
3 changes: 3 additions & 0 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,6 @@ jobs:

- name: Lint
run: make lint

- name: Test
run: go test ./...
3 changes: 3 additions & 0 deletions .github/workflows/push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ jobs:
- name: Lint
run: make lint

- name: Test
run: go test ./...

deploy:
name: Deploy
needs: build
Expand Down
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
7 changes: 7 additions & 0 deletions server/block/air.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package block

import "github.com/df-mc/dragonfly/server/world"

// Air is the block present in otherwise empty space.
type Air struct {
empty
Expand All @@ -12,6 +14,11 @@ func (Air) HasLiquidDrops() bool {
return false
}

// PortalInterior returns true if air may occupy the inside of a portal frame before activation for the target dimension.
func (Air) PortalInterior(target world.Dimension) bool {
return target == world.Nether
}

// EncodeItem ...
func (Air) EncodeItem() (name string, meta int16) {
return "minecraft:air", 0
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
}
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
14 changes: 14 additions & 0 deletions server/block/cube/axis.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,20 @@ func (a Axis) RotateRight() Axis {
return a.RotateLeft()
}

// Faces returns the negative and positive Face along the Axis. For X it
// returns FaceWest, FaceEast; for Y, FaceDown, FaceUp; for Z, FaceNorth,
// FaceSouth.
func (a Axis) Faces() (negative, positive Face) {
switch a {
case X:
return FaceWest, FaceEast
case Y:
return FaceDown, FaceUp
default:
return FaceNorth, FaceSouth
}
}

// Vec3 returns a unit Vec3 of either (1, 0, 0), (0, 1, 0) or (0, 0, 1),
// depending on the Axis.
func (a Axis) Vec3() mgl64.Vec3 {
Expand Down
21 changes: 21 additions & 0 deletions server/block/cube/face.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package cube

import "github.com/go-gl/mathgl/mgl64"

const (
// FaceDown represents the bottom face of a block.
FaceDown Face = iota
Expand Down Expand Up @@ -89,6 +91,25 @@ func (f Face) RotateLeft() Face {
return f
}

// Offset returns the position offset of the Face.
func (f Face) Offset() mgl64.Vec3 {
switch f {
case FaceUp:
return mgl64.Vec3{0, 1, 0}
case FaceDown:
return mgl64.Vec3{0, -1, 0}
case FaceNorth:
return mgl64.Vec3{0, 0, -1}
case FaceSouth:
return mgl64.Vec3{0, 0, 1}
case FaceWest:
return mgl64.Vec3{-1, 0, 0}
case FaceEast:
return mgl64.Vec3{1, 0, 0}
}
panic("invalid face")
}
Comment thread
cursor[bot] marked this conversation as resolved.

// String returns the Face as a string.
func (f Face) String() string {
switch f {
Expand Down
36 changes: 22 additions & 14 deletions server/block/cube/pos.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,21 +96,29 @@ func (p Pos) Side(face Face) Pos {
// Face returns the face that the other Pos was on compared to the current Pos.
// The other Pos is assumed to be a direct neighbour of the current Pos.
func (p Pos) Face(other Pos) Face {
switch other {
case p.Add(Pos{0, 1}):
return FaceUp
case p.Add(Pos{0, -1}):
return FaceDown
case p.Add(Pos{0, 0, -1}):
return FaceNorth
case p.Add(Pos{0, 0, 1}):
return FaceSouth
case p.Add(Pos{-1, 0, 0}):
return FaceWest
case p.Add(Pos{1, 0, 0}):
return FaceEast
face, _ := p.NeighbourFace(other)
return face
}

// NeighbourFace returns the face that the other Pos was on compared to the
// current Pos, if the other Pos is a direct neighbour of the current Pos.
// Example: Pos{0, 0, 0}.NeighbourFace(Pos{0, 1, 0}) returns FaceUp, true.
func (p Pos) NeighbourFace(other Pos) (Face, bool) {
switch other.Sub(p) {
case Pos{0, 1, 0}:
return FaceUp, true
case Pos{0, -1, 0}:
return FaceDown, true
case Pos{0, 0, -1}:
return FaceNorth, true
case Pos{0, 0, 1}:
return FaceSouth, true
case Pos{-1, 0, 0}:
return FaceWest, true
case Pos{1, 0, 0}:
return FaceEast, true
}
return FaceUp
return FaceUp, false
}

// Neighbours calls the function passed for each of the block position's
Expand Down
Loading