diff --git a/cmd/generator.go b/cmd/generator.go
index 016062a..7d1e52c 100644
--- a/cmd/generator.go
+++ b/cmd/generator.go
@@ -5,6 +5,7 @@ import (
 	"io"
 	"net/http"
 	"os"
+	"os/exec"
 	"strings"
 )
 
@@ -66,6 +67,9 @@ func main() {
 	_ = os.WriteFile("world_handler_func_types.go", []byte(generateFuncTypes("World", "*world.World", "w", worldHandlers)), 0644)
 	_ = os.WriteFile("player_handlers.go", []byte(generateHandlerList("Player", handlers)), 0644)
 	_ = os.WriteFile("world_handlers.go", []byte(generateHandlerList("World", worldHandlers)), 0644)
+
+	_ = exec.Command("goimports", "-l", "-w", ".").Run()
+	_ = exec.Command("gofmt", "-s", "-w", ".").Run()
 }
 
 func generateFuncTypes(prefix string, param1 string, param1Name string, handlers []Handler) string {
@@ -76,16 +80,30 @@ func generateFuncTypes(prefix string, param1 string, param1Name string, handlers
 		str.WriteString(prefix)
 		str.WriteString(handler.FuncName)
 		str.WriteString("Func func(")
-		str.WriteString(param1Name)
-		str.WriteString(" ")
-		str.WriteString(param1)
-		if len(handler.Args) > 0 {
-			str.WriteString(", ")
-		}
+		//str.WriteString(param1Name)
+		//str.WriteString(" ")
+		//str.WriteString(param1)
+		//if len(handler.Args) > 0 {
+		//	str.WriteString(", ")
+		//}
 		for i, arg := range handler.Args {
 			str.WriteString(arg.Name)
 			str.WriteString(" ")
-			str.WriteString(arg.Type)
+			if arg.Name == "ctx" || arg.Name == "context" {
+				str.WriteString("*")
+				str.WriteString(strings.ToLower(prefix))
+				str.WriteString(".Context")
+			} else {
+				if arg.Type == "*Player" {
+					str.WriteString("*player.Player")
+				} else if arg.Type == "*World" {
+					str.WriteString("*world.World")
+				} else if arg.Type == "*Tx" {
+					str.WriteString("*world.Tx")
+				} else {
+					str.WriteString(arg.Type)
+				}
+			}
 			if i != len(handler.Args)-1 {
 				str.WriteString(", ")
 			}
@@ -202,7 +220,21 @@ func generateBridge(name string, nativeHandler string, param1 string, param1Name
 		for i, arg := range handler.Args {
 			str.WriteString(arg.Name)
 			str.WriteString(" ")
-			str.WriteString(arg.Type)
+			if arg.Name == "ctx" || arg.Name == "context" {
+				str.WriteString("*")
+				str.WriteString(strings.ToLower(name))
+				str.WriteString(".Context")
+			} else {
+				if arg.Type == "*Player" {
+					str.WriteString("*player.Player")
+				} else if arg.Type == "*World" {
+					str.WriteString("*world.World")
+				} else if arg.Type == "*Tx" {
+					str.WriteString("*world.Tx")
+				} else {
+					str.WriteString(arg.Type)
+				}
+			}
 			if i != len(handler.Args)-1 {
 				str.WriteString(", ")
 			}
@@ -214,12 +246,12 @@ func generateBridge(name string, nativeHandler string, param1 string, param1Name
 		fn = strings.ToLower(fn[:1]) + fn[1:]
 		str.WriteString(fn)
 		str.WriteString("Handlers {\n")
-		str.WriteString("\t\thandler.h")
-		str.WriteString("(h.")
-		str.WriteString(param1Name)
-		if len(handler.Args) > 0 {
-			str.WriteString(", ")
-		}
+		str.WriteString("\t\thandler.h(")
+		//str.WriteString("(h.")
+		//str.WriteString(param1Name)
+		//if len(handler.Args) > 0 {
+		//	str.WriteString(", ")
+		//}
 		for i, arg := range handler.Args {
 			str.WriteString(arg.Name)
 			if i != len(handler.Args)-1 {
diff --git a/go.mod b/go.mod
index b34c339..339513d 100644
--- a/go.mod
+++ b/go.mod
@@ -1,32 +1,33 @@
 module github.com/venitynetwork/vhandler
 
-go 1.22
+go 1.23
 
-toolchain go1.22.8
+toolchain go1.23.3
 
 require (
 	github.com/brentp/intintmap v0.0.0-20190211203843-30dc0ade9af9 // indirect
-	github.com/cespare/xxhash/v2 v2.2.0 // indirect
-	github.com/df-mc/dragonfly v0.9.18 // indirect
+	github.com/cespare/xxhash/v2 v2.3.0 // indirect
+	github.com/df-mc/dragonfly v0.9.20-0.20241128065957-206bf97c6c88 // indirect
 	github.com/df-mc/goleveldb v1.1.9 // indirect
-	github.com/df-mc/worldupgrader v1.0.17 // indirect
-	github.com/go-gl/mathgl v1.1.0 // indirect
+	github.com/df-mc/worldupgrader v1.0.18 // indirect
+	github.com/go-gl/mathgl v1.2.0 // indirect
 	github.com/go-jose/go-jose/v3 v3.0.3 // indirect
 	github.com/golang/snappy v0.0.4 // indirect
 	github.com/google/uuid v1.6.0 // indirect
-	github.com/klauspost/compress v1.17.9 // indirect
+	github.com/klauspost/compress v1.17.11 // indirect
 	github.com/muhammadmuzzammil1998/jsonc v1.0.0 // indirect
 	github.com/pelletier/go-toml v1.9.5 // indirect
 	github.com/rogpeppe/go-internal v1.11.0 // indirect
-	github.com/sandertv/go-raknet v1.14.1 // indirect
-	github.com/sandertv/gophertunnel v1.41.0 // indirect
+	github.com/sandertv/go-raknet v1.14.2 // indirect
+	github.com/sandertv/gophertunnel v1.42.2 // indirect
 	github.com/segmentio/fasthash v1.0.3 // indirect
 	github.com/sirupsen/logrus v1.9.3 // indirect
-	golang.org/x/crypto v0.24.0 // indirect
-	golang.org/x/exp v0.0.0-20230206171751-46f607a40771 // indirect
-	golang.org/x/image v0.17.0 // indirect
-	golang.org/x/net v0.26.0 // indirect
-	golang.org/x/oauth2 v0.21.0 // indirect
-	golang.org/x/sys v0.21.0 // indirect
-	golang.org/x/text v0.16.0 // indirect
+	golang.org/x/crypto v0.29.0 // indirect
+	golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f // indirect
+	golang.org/x/image v0.22.0 // indirect
+	golang.org/x/mod v0.22.0 // indirect
+	golang.org/x/net v0.31.0 // indirect
+	golang.org/x/oauth2 v0.24.0 // indirect
+	golang.org/x/sys v0.27.0 // indirect
+	golang.org/x/text v0.20.0 // indirect
 )
diff --git a/go.sum b/go.sum
index dcf8fed..9c7a3c4 100644
--- a/go.sum
+++ b/go.sum
@@ -2,17 +2,27 @@ github.com/brentp/intintmap v0.0.0-20190211203843-30dc0ade9af9 h1:/G0ghZwrhou0Wq
 github.com/brentp/intintmap v0.0.0-20190211203843-30dc0ade9af9/go.mod h1:TOk10ahXejq9wkEaym3KPRNeuR/h5Jx+s8QRWIa2oTM=
 github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
 github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
+github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/df-mc/dragonfly v0.9.18 h1:Ul+BuMn4rzjNj5C2dxlhM/DqR1/MazSmoS93c6bfMHE=
 github.com/df-mc/dragonfly v0.9.18/go.mod h1:1G+G/KKvsDLWRfLy26ALUH83uq4Focb4O5xhmmKKfDE=
+github.com/df-mc/dragonfly v0.9.19 h1:5UcB9MAO04V4/AFBzt2dmDDQx6j953wnY4sqhBfyo+A=
+github.com/df-mc/dragonfly v0.9.19/go.mod h1:WUHhJftm79ctWLXy+eBm1URymVSP4wDJX5HoaaS1iP0=
+github.com/df-mc/dragonfly v0.9.20-0.20241128065957-206bf97c6c88 h1:ZzbIW9qSlIHD1zRxd+g9R/WegjhvHLgbXLsfySFtpbQ=
+github.com/df-mc/dragonfly v0.9.20-0.20241128065957-206bf97c6c88/go.mod h1:PL0I6xzy+HpgsMSI1UdJPFlCaWaMS4juq0xppV7zdWA=
 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/worldupgrader v1.0.17 h1:9NRTihn8/KFL+ajUHDc+KikZcsrhoxR/Tq2ekA5ZR7k=
 github.com/df-mc/worldupgrader v1.0.17/go.mod h1:tsSOLTRm9mpG7VHvYpAjjZrkRHWmSbKZAm9bOLNnlDk=
+github.com/df-mc/worldupgrader v1.0.18 h1:Q34X9ID/hGuDyj9oiq+dpyjOaJdNxhVmVUepf/EPYDA=
+github.com/df-mc/worldupgrader v1.0.18/go.mod h1:tsSOLTRm9mpG7VHvYpAjjZrkRHWmSbKZAm9bOLNnlDk=
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
 github.com/go-gl/mathgl v1.1.0 h1:0lzZ+rntPX3/oGrDzYGdowSLC2ky8Osirvf5uAwfIEA=
 github.com/go-gl/mathgl v1.1.0/go.mod h1:yhpkQzEiH9yPyxDUGzkmgScbaBVlhC06qodikEM0ZwQ=
+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=
 github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k=
 github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=
 github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -26,6 +36,8 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO
 github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
 github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
 github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
+github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
+github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
 github.com/muhammadmuzzammil1998/jsonc v1.0.0 h1:8o5gBQn4ZA3NBA9DlTujCj2a4w0tqWrPVjDwhzkgTIs=
 github.com/muhammadmuzzammil1998/jsonc v1.0.0/go.mod h1:saF2fIVw4banK0H4+/EuqfFLpRnoy5S+ECwTOCcRcSU=
 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
@@ -38,8 +50,12 @@ github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDN
 github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
 github.com/sandertv/go-raknet v1.14.1 h1:V2Gslo+0x4jfj+p0PM48mWxmMbYkxSlgeKy//y3ZrzI=
 github.com/sandertv/go-raknet v1.14.1/go.mod h1:/yysjwfCXm2+2OY8mBazLzcxJ3irnylKCyG3FLgUPVU=
+github.com/sandertv/go-raknet v1.14.2 h1:UZLyHn5yQU2Dq2GVq/LlxwAUikaq4q4AA1rl/Pf3AXQ=
+github.com/sandertv/go-raknet v1.14.2/go.mod h1:/yysjwfCXm2+2OY8mBazLzcxJ3irnylKCyG3FLgUPVU=
 github.com/sandertv/gophertunnel v1.41.0 h1:PGqqALaatGqcZ+qWXOcR4+CHPhQohnm/ZrnHdhWRtNw=
 github.com/sandertv/gophertunnel v1.41.0/go.mod h1:uSaX7RbVaCcxsGAx2vyZnkT0M6kZFGCdAqLn0+wuKyY=
+github.com/sandertv/gophertunnel v1.42.2 h1:YWi4vAkq9IpNFIDxOrSMeGh2wkWMCMO8Kg45/R7VTQs=
+github.com/sandertv/gophertunnel v1.42.2/go.mod h1:krvLSeRUNQ2iEYJNEgzrKtWO8W5ybZxN5lFfSCkHoNk=
 github.com/segmentio/fasthash v1.0.3 h1:EI9+KE1EwvMLBWwjpRDc+fEM+prwxDYbslddQGtrmhM=
 github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY=
 github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
@@ -52,13 +68,29 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
 golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
 golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
 golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
+golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
+golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
+golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
+golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
 golang.org/x/exp v0.0.0-20230206171751-46f607a40771 h1:xP7rWLUr1e1n2xkK5YB4LI0hPEy3LJC6Wk+D4pGlOJg=
 golang.org/x/exp v0.0.0-20230206171751-46f607a40771/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
+golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY=
+golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8=
+golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f h1:XdNn9LlyWAhLVp6P/i8QYBW+hlyhrhei9uErw2B5GJo=
+golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f/go.mod h1:D5SMRVC3C2/4+F/DB1wZsLRnSNimn2Sp/NPsCrsv8ak=
 golang.org/x/image v0.0.0-20190321063152-3fc05d484e9f/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
 golang.org/x/image v0.17.0 h1:nTRVVdajgB8zCMZVsViyzhnMKPwYeroEERRC64JuLco=
 golang.org/x/image v0.17.0/go.mod h1:4yyo5vMFQjVjUcVk4jEQcU9MGy/rulF5WvUILseCM2E=
+golang.org/x/image v0.21.0 h1:c5qV36ajHpdj4Qi0GnE0jUc/yuo33OLFaa0d+crTD5s=
+golang.org/x/image v0.21.0/go.mod h1:vUbsLavqK/W303ZroQQVKQ+Af3Yl6Uz1Ppu5J/cLz78=
+golang.org/x/image v0.22.0 h1:UtK5yLUzilVrkjMAZAZ34DXGpASN8i8pj8g+O+yd10g=
+golang.org/x/image v0.22.0/go.mod h1:9hPFhljd4zZ1GNSIZJ49sqbp45GKK9t6w+iXvGqZUz4=
 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
 golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
+golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
+golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
+golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
 golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
@@ -67,8 +99,16 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
 golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
 golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
+golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
+golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
+golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo=
+golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM=
 golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs=
 golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
+golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
+golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
+golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE=
+golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -85,6 +125,10 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
 golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
+golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
+golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@@ -98,6 +142,10 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
 golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
 golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
 golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
+golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
+golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
+golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
+golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
diff --git a/player_handler_func_types.go b/player_handler_func_types.go
index 77b98b8..2faf284 100644
--- a/player_handler_func_types.go
+++ b/player_handler_func_types.go
@@ -1,50 +1,52 @@
 package vhandler
 
 import (
-	"github.com/df-mc/dragonfly/server/block/cube"
 	"github.com/df-mc/dragonfly/server/cmd"
-	"github.com/df-mc/dragonfly/server/event"
+	"net"
+	"time"
+
+	"github.com/df-mc/dragonfly/server/block/cube"
 	"github.com/df-mc/dragonfly/server/item"
 	"github.com/df-mc/dragonfly/server/player"
-	"github.com/df-mc/dragonfly/server/player/diagnostics"
 	"github.com/df-mc/dragonfly/server/player/skin"
+	"github.com/df-mc/dragonfly/server/session"
 	"github.com/df-mc/dragonfly/server/world"
 	"github.com/go-gl/mathgl/mgl64"
-	"net"
-	"time"
 )
 
-type PlayerHandleMoveFunc func(p *player.Player, ctx *event.Context, newPos mgl64.Vec3, newYaw float64, newPitch float64)
+type PlayerHandleMoveFunc func(ctx *player.Context, newPos mgl64.Vec3, newRot cube.Rotation)
 type PlayerHandleJumpFunc func(p *player.Player)
-type PlayerHandleTeleportFunc func(p *player.Player, ctx *event.Context, pos mgl64.Vec3)
-type PlayerHandleChangeWorldFunc func(p *player.Player, before *world.World, after *world.World)
-type PlayerHandleToggleSprintFunc func(p *player.Player, ctx *event.Context, after bool)
-type PlayerHandleToggleSneakFunc func(p *player.Player, ctx *event.Context, after bool)
-type PlayerHandleChatFunc func(p *player.Player, ctx *event.Context, message *string)
-type PlayerHandleFoodLossFunc func(p *player.Player, ctx *event.Context, from int, to *int)
-type PlayerHandleHealFunc func(p *player.Player, ctx *event.Context, health *float64, src world.HealingSource)
-type PlayerHandleHurtFunc func(p *player.Player, ctx *event.Context, damage *float64, attackImmunity *time.Duration, src world.DamageSource)
+type PlayerHandleTeleportFunc func(ctx *player.Context, pos mgl64.Vec3)
+type PlayerHandleChangeWorldFunc func(before *world.World, after *world.World)
+type PlayerHandleToggleSprintFunc func(ctx *player.Context, after bool)
+type PlayerHandleToggleSneakFunc func(ctx *player.Context, after bool)
+type PlayerHandleChatFunc func(ctx *player.Context, message *string)
+type PlayerHandleFoodLossFunc func(ctx *player.Context, from int, to *int)
+type PlayerHandleHealFunc func(ctx *player.Context, health *float64, src world.HealingSource)
+type PlayerHandleHurtFunc func(ctx *player.Context, damage *float64, immune bool, attackImmunity *time.Duration, src world.DamageSource)
 type PlayerHandleDeathFunc func(p *player.Player, src world.DamageSource, keepInv *bool)
 type PlayerHandleRespawnFunc func(p *player.Player, pos *mgl64.Vec3, w **world.World)
-type PlayerHandleSkinChangeFunc func(p *player.Player, ctx *event.Context, skin *skin.Skin)
-type PlayerHandleFireExtinguishFunc func(p *player.Player, ctx *event.Context, pos cube.Pos)
-type PlayerHandleStartBreakFunc func(p *player.Player, ctx *event.Context, pos cube.Pos)
-type PlayerHandleBlockBreakFunc func(p *player.Player, ctx *event.Context, pos cube.Pos, drops *[]item.Stack, xp *int)
-type PlayerHandleBlockPlaceFunc func(p *player.Player, ctx *event.Context, pos cube.Pos, b world.Block)
-type PlayerHandleBlockPickFunc func(p *player.Player, ctx *event.Context, pos cube.Pos, b world.Block)
-type PlayerHandleItemUseFunc func(p *player.Player, ctx *event.Context)
-type PlayerHandleItemUseOnBlockFunc func(p *player.Player, ctx *event.Context, pos cube.Pos, face cube.Face, clickPos mgl64.Vec3)
-type PlayerHandleItemUseOnEntityFunc func(p *player.Player, ctx *event.Context, e world.Entity)
-type PlayerHandleItemConsumeFunc func(p *player.Player, ctx *event.Context, item item.Stack)
-type PlayerHandleAttackEntityFunc func(p *player.Player, ctx *event.Context, e world.Entity, force *float64, height *float64, critical *bool)
-type PlayerHandleExperienceGainFunc func(p *player.Player, ctx *event.Context, amount *int)
-type PlayerHandlePunchAirFunc func(p *player.Player, ctx *event.Context)
-type PlayerHandleSignEditFunc func(p *player.Player, ctx *event.Context, pos cube.Pos, frontSide bool, oldText string, newText string)
-type PlayerHandleLecternPageTurnFunc func(p *player.Player, ctx *event.Context, pos cube.Pos, oldPage int, newPage *int)
-type PlayerHandleItemDamageFunc func(p *player.Player, ctx *event.Context, i item.Stack, damage int)
-type PlayerHandleItemPickupFunc func(p *player.Player, ctx *event.Context, i *item.Stack)
-type PlayerHandleItemDropFunc func(p *player.Player, ctx *event.Context, e world.Entity)
-type PlayerHandleTransferFunc func(p *player.Player, ctx *event.Context, addr *net.UDPAddr)
-type PlayerHandleCommandExecutionFunc func(p *player.Player, ctx *event.Context, command cmd.Command, args []string)
+type PlayerHandleSkinChangeFunc func(ctx *player.Context, skin *skin.Skin)
+type PlayerHandleFireExtinguishFunc func(ctx *player.Context, pos cube.Pos)
+type PlayerHandleStartBreakFunc func(ctx *player.Context, pos cube.Pos)
+type PlayerHandleBlockBreakFunc func(ctx *player.Context, pos cube.Pos, drops *[]item.Stack, xp *int)
+type PlayerHandleBlockPlaceFunc func(ctx *player.Context, pos cube.Pos, b world.Block)
+type PlayerHandleBlockPickFunc func(ctx *player.Context, pos cube.Pos, b world.Block)
+type PlayerHandleItemUseFunc func(ctx *player.Context)
+type PlayerHandleItemUseOnBlockFunc func(ctx *player.Context, pos cube.Pos, face cube.Face, clickPos mgl64.Vec3)
+type PlayerHandleItemUseOnEntityFunc func(ctx *player.Context, e world.Entity)
+type PlayerHandleItemReleaseFunc func(ctx *player.Context, item item.Stack, dur time.Duration)
+type PlayerHandleItemConsumeFunc func(ctx *player.Context, item item.Stack)
+type PlayerHandleAttackEntityFunc func(ctx *player.Context, e world.Entity, force *float64, height *float64, critical *bool)
+type PlayerHandleExperienceGainFunc func(ctx *player.Context, amount *int)
+type PlayerHandlePunchAirFunc func(ctx *player.Context)
+type PlayerHandleSignEditFunc func(ctx *player.Context, pos cube.Pos, frontSide bool, oldText string, newText string)
+type PlayerHandleLecternPageTurnFunc func(ctx *player.Context, pos cube.Pos, oldPage int, newPage *int)
+type PlayerHandleItemDamageFunc func(ctx *player.Context, i item.Stack, damage int)
+type PlayerHandleItemPickupFunc func(ctx *player.Context, i *item.Stack)
+type PlayerHandleHeldSlotChangeFunc func(ctx *player.Context, from int, to int)
+type PlayerHandleItemDropFunc func(ctx *player.Context, s item.Stack)
+type PlayerHandleTransferFunc func(ctx *player.Context, addr *net.UDPAddr)
+type PlayerHandleCommandExecutionFunc func(ctx *player.Context, command cmd.Command, args []string)
 type PlayerHandleQuitFunc func(p *player.Player)
-type PlayerHandleDiagnosticsFunc func(p *player.Player, d diagnostics.Diagnostics)
+type PlayerHandleDiagnosticsFunc func(p *player.Player, d session.Diagnostics)
diff --git a/player_handlers.go b/player_handlers.go
index cad3f47..eee076c 100644
--- a/player_handlers.go
+++ b/player_handlers.go
@@ -22,6 +22,7 @@ type PlayerHandlers struct {
 	itemUseHandlers          []*handlerWrapper[PlayerHandleItemUseFunc]
 	itemUseOnBlockHandlers   []*handlerWrapper[PlayerHandleItemUseOnBlockFunc]
 	itemUseOnEntityHandlers  []*handlerWrapper[PlayerHandleItemUseOnEntityFunc]
+	itemReleaseHandlers      []*handlerWrapper[PlayerHandleItemReleaseFunc]
 	itemConsumeHandlers      []*handlerWrapper[PlayerHandleItemConsumeFunc]
 	attackEntityHandlers     []*handlerWrapper[PlayerHandleAttackEntityFunc]
 	experienceGainHandlers   []*handlerWrapper[PlayerHandleExperienceGainFunc]
@@ -30,6 +31,7 @@ type PlayerHandlers struct {
 	lecternPageTurnHandlers  []*handlerWrapper[PlayerHandleLecternPageTurnFunc]
 	itemDamageHandlers       []*handlerWrapper[PlayerHandleItemDamageFunc]
 	itemPickupHandlers       []*handlerWrapper[PlayerHandleItemPickupFunc]
+	heldSlotChangeHandlers   []*handlerWrapper[PlayerHandleHeldSlotChangeFunc]
 	itemDropHandlers         []*handlerWrapper[PlayerHandleItemDropFunc]
 	transferHandlers         []*handlerWrapper[PlayerHandleTransferFunc]
 	commandExecutionHandlers []*handlerWrapper[PlayerHandleCommandExecutionFunc]
@@ -60,6 +62,7 @@ func NewPlayerHandlers() *PlayerHandlers {
 		itemUseHandlers:          make([]*handlerWrapper[PlayerHandleItemUseFunc], 0),
 		itemUseOnBlockHandlers:   make([]*handlerWrapper[PlayerHandleItemUseOnBlockFunc], 0),
 		itemUseOnEntityHandlers:  make([]*handlerWrapper[PlayerHandleItemUseOnEntityFunc], 0),
+		itemReleaseHandlers:      make([]*handlerWrapper[PlayerHandleItemReleaseFunc], 0),
 		itemConsumeHandlers:      make([]*handlerWrapper[PlayerHandleItemConsumeFunc], 0),
 		attackEntityHandlers:     make([]*handlerWrapper[PlayerHandleAttackEntityFunc], 0),
 		experienceGainHandlers:   make([]*handlerWrapper[PlayerHandleExperienceGainFunc], 0),
@@ -68,6 +71,7 @@ func NewPlayerHandlers() *PlayerHandlers {
 		lecternPageTurnHandlers:  make([]*handlerWrapper[PlayerHandleLecternPageTurnFunc], 0),
 		itemDamageHandlers:       make([]*handlerWrapper[PlayerHandleItemDamageFunc], 0),
 		itemPickupHandlers:       make([]*handlerWrapper[PlayerHandleItemPickupFunc], 0),
+		heldSlotChangeHandlers:   make([]*handlerWrapper[PlayerHandleHeldSlotChangeFunc], 0),
 		itemDropHandlers:         make([]*handlerWrapper[PlayerHandleItemDropFunc], 0),
 		transferHandlers:         make([]*handlerWrapper[PlayerHandleTransferFunc], 0),
 		commandExecutionHandlers: make([]*handlerWrapper[PlayerHandleCommandExecutionFunc], 0),
@@ -181,6 +185,11 @@ func (h *PlayerHandlers) OnItemUseOnEntity(handler PlayerHandleItemUseOnEntityFu
 	sortHandlers(h.itemUseOnEntityHandlers)
 }
 
+func (h *PlayerHandlers) OnItemRelease(handler PlayerHandleItemReleaseFunc, priority Priority) {
+	h.itemReleaseHandlers = append(h.itemReleaseHandlers, &handlerWrapper[PlayerHandleItemReleaseFunc]{priority, handler})
+	sortHandlers(h.itemReleaseHandlers)
+}
+
 func (h *PlayerHandlers) OnItemConsume(handler PlayerHandleItemConsumeFunc, priority Priority) {
 	h.itemConsumeHandlers = append(h.itemConsumeHandlers, &handlerWrapper[PlayerHandleItemConsumeFunc]{priority, handler})
 	sortHandlers(h.itemConsumeHandlers)
@@ -221,6 +230,11 @@ func (h *PlayerHandlers) OnItemPickup(handler PlayerHandleItemPickupFunc, priori
 	sortHandlers(h.itemPickupHandlers)
 }
 
+func (h *PlayerHandlers) OnHeldSlotChange(handler PlayerHandleHeldSlotChangeFunc, priority Priority) {
+	h.heldSlotChangeHandlers = append(h.heldSlotChangeHandlers, &handlerWrapper[PlayerHandleHeldSlotChangeFunc]{priority, handler})
+	sortHandlers(h.heldSlotChangeHandlers)
+}
+
 func (h *PlayerHandlers) OnItemDrop(handler PlayerHandleItemDropFunc, priority Priority) {
 	h.itemDropHandlers = append(h.itemDropHandlers, &handlerWrapper[PlayerHandleItemDropFunc]{priority, handler})
 	sortHandlers(h.itemDropHandlers)
diff --git a/player_native_bridge_handler.go b/player_native_bridge_handler.go
index e303677..5ef949c 100644
--- a/player_native_bridge_handler.go
+++ b/player_native_bridge_handler.go
@@ -1,17 +1,17 @@
 package vhandler
 
 import (
-	"github.com/df-mc/dragonfly/server/block/cube"
 	"github.com/df-mc/dragonfly/server/cmd"
-	"github.com/df-mc/dragonfly/server/event"
+	"net"
+	"time"
+
+	"github.com/df-mc/dragonfly/server/block/cube"
 	"github.com/df-mc/dragonfly/server/item"
 	"github.com/df-mc/dragonfly/server/player"
-	"github.com/df-mc/dragonfly/server/player/diagnostics"
 	"github.com/df-mc/dragonfly/server/player/skin"
+	"github.com/df-mc/dragonfly/server/session"
 	"github.com/df-mc/dragonfly/server/world"
 	"github.com/go-gl/mathgl/mgl64"
-	"net"
-	"time"
 )
 
 type PlayerNativeBridgeHandler struct {
@@ -22,206 +22,218 @@ type PlayerNativeBridgeHandler struct {
 // Compile-time check to ensure that the PlayerNativeBridgeHandler implements the PlayerHandler interface.
 var _ player.Handler = &PlayerNativeBridgeHandler{}
 
-func (h *PlayerNativeBridgeHandler) HandleMove(ctx *event.Context, newPos mgl64.Vec3, newYaw float64, newPitch float64) {
+func (h *PlayerNativeBridgeHandler) HandleMove(ctx *player.Context, newPos mgl64.Vec3, newRot cube.Rotation) {
 	for _, handler := range h.h.moveHandlers {
-		handler.h(h.p, ctx, newPos, newYaw, newPitch)
+		handler.h(ctx, newPos, newRot)
 	}
 }
 
-func (h *PlayerNativeBridgeHandler) HandleJump() {
+func (h *PlayerNativeBridgeHandler) HandleJump(p *player.Player) {
 	for _, handler := range h.h.jumpHandlers {
-		handler.h(h.p)
+		handler.h(p)
 	}
 }
 
-func (h *PlayerNativeBridgeHandler) HandleTeleport(ctx *event.Context, pos mgl64.Vec3) {
+func (h *PlayerNativeBridgeHandler) HandleTeleport(ctx *player.Context, pos mgl64.Vec3) {
 	for _, handler := range h.h.teleportHandlers {
-		handler.h(h.p, ctx, pos)
+		handler.h(ctx, pos)
 	}
 }
 
 func (h *PlayerNativeBridgeHandler) HandleChangeWorld(before *world.World, after *world.World) {
 	for _, handler := range h.h.changeWorldHandlers {
-		handler.h(h.p, before, after)
+		handler.h(before, after)
 	}
 }
 
-func (h *PlayerNativeBridgeHandler) HandleToggleSprint(ctx *event.Context, after bool) {
+func (h *PlayerNativeBridgeHandler) HandleToggleSprint(ctx *player.Context, after bool) {
 	for _, handler := range h.h.toggleSprintHandlers {
-		handler.h(h.p, ctx, after)
+		handler.h(ctx, after)
 	}
 }
 
-func (h *PlayerNativeBridgeHandler) HandleToggleSneak(ctx *event.Context, after bool) {
+func (h *PlayerNativeBridgeHandler) HandleToggleSneak(ctx *player.Context, after bool) {
 	for _, handler := range h.h.toggleSneakHandlers {
-		handler.h(h.p, ctx, after)
+		handler.h(ctx, after)
 	}
 }
 
-func (h *PlayerNativeBridgeHandler) HandleChat(ctx *event.Context, message *string) {
+func (h *PlayerNativeBridgeHandler) HandleChat(ctx *player.Context, message *string) {
 	for _, handler := range h.h.chatHandlers {
-		handler.h(h.p, ctx, message)
+		handler.h(ctx, message)
 	}
 }
 
-func (h *PlayerNativeBridgeHandler) HandleFoodLoss(ctx *event.Context, from int, to *int) {
+func (h *PlayerNativeBridgeHandler) HandleFoodLoss(ctx *player.Context, from int, to *int) {
 	for _, handler := range h.h.foodLossHandlers {
-		handler.h(h.p, ctx, from, to)
+		handler.h(ctx, from, to)
 	}
 }
 
-func (h *PlayerNativeBridgeHandler) HandleHeal(ctx *event.Context, health *float64, src world.HealingSource) {
+func (h *PlayerNativeBridgeHandler) HandleHeal(ctx *player.Context, health *float64, src world.HealingSource) {
 	for _, handler := range h.h.healHandlers {
-		handler.h(h.p, ctx, health, src)
+		handler.h(ctx, health, src)
 	}
 }
 
-func (h *PlayerNativeBridgeHandler) HandleHurt(ctx *event.Context, damage *float64, attackImmunity *time.Duration, src world.DamageSource) {
+func (h *PlayerNativeBridgeHandler) HandleHurt(ctx *player.Context, damage *float64, immune bool, attackImmunity *time.Duration, src world.DamageSource) {
 	for _, handler := range h.h.hurtHandlers {
-		handler.h(h.p, ctx, damage, attackImmunity, src)
+		handler.h(ctx, damage, immune, attackImmunity, src)
 	}
 }
 
-func (h *PlayerNativeBridgeHandler) HandleDeath(src world.DamageSource, keepInv *bool) {
+func (h *PlayerNativeBridgeHandler) HandleDeath(p *player.Player, src world.DamageSource, keepInv *bool) {
 	for _, handler := range h.h.deathHandlers {
-		handler.h(h.p, src, keepInv)
+		handler.h(p, src, keepInv)
 	}
 }
 
-func (h *PlayerNativeBridgeHandler) HandleRespawn(pos *mgl64.Vec3, w **world.World) {
+func (h *PlayerNativeBridgeHandler) HandleRespawn(p *player.Player, pos *mgl64.Vec3, w **world.World) {
 	for _, handler := range h.h.respawnHandlers {
-		handler.h(h.p, pos, w)
+		handler.h(p, pos, w)
 	}
 }
 
-func (h *PlayerNativeBridgeHandler) HandleSkinChange(ctx *event.Context, skin *skin.Skin) {
+func (h *PlayerNativeBridgeHandler) HandleSkinChange(ctx *player.Context, skin *skin.Skin) {
 	for _, handler := range h.h.skinChangeHandlers {
-		handler.h(h.p, ctx, skin)
+		handler.h(ctx, skin)
 	}
 }
 
-func (h *PlayerNativeBridgeHandler) HandleFireExtinguish(ctx *event.Context, pos cube.Pos) {
+func (h *PlayerNativeBridgeHandler) HandleFireExtinguish(ctx *player.Context, pos cube.Pos) {
 	for _, handler := range h.h.fireExtinguishHandlers {
-		handler.h(h.p, ctx, pos)
+		handler.h(ctx, pos)
 	}
 }
 
-func (h *PlayerNativeBridgeHandler) HandleStartBreak(ctx *event.Context, pos cube.Pos) {
+func (h *PlayerNativeBridgeHandler) HandleStartBreak(ctx *player.Context, pos cube.Pos) {
 	for _, handler := range h.h.startBreakHandlers {
-		handler.h(h.p, ctx, pos)
+		handler.h(ctx, pos)
 	}
 }
 
-func (h *PlayerNativeBridgeHandler) HandleBlockBreak(ctx *event.Context, pos cube.Pos, drops *[]item.Stack, xp *int) {
+func (h *PlayerNativeBridgeHandler) HandleBlockBreak(ctx *player.Context, pos cube.Pos, drops *[]item.Stack, xp *int) {
 	for _, handler := range h.h.blockBreakHandlers {
-		handler.h(h.p, ctx, pos, drops, xp)
+		handler.h(ctx, pos, drops, xp)
 	}
 }
 
-func (h *PlayerNativeBridgeHandler) HandleBlockPlace(ctx *event.Context, pos cube.Pos, b world.Block) {
+func (h *PlayerNativeBridgeHandler) HandleBlockPlace(ctx *player.Context, pos cube.Pos, b world.Block) {
 	for _, handler := range h.h.blockPlaceHandlers {
-		handler.h(h.p, ctx, pos, b)
+		handler.h(ctx, pos, b)
 	}
 }
 
-func (h *PlayerNativeBridgeHandler) HandleBlockPick(ctx *event.Context, pos cube.Pos, b world.Block) {
+func (h *PlayerNativeBridgeHandler) HandleBlockPick(ctx *player.Context, pos cube.Pos, b world.Block) {
 	for _, handler := range h.h.blockPickHandlers {
-		handler.h(h.p, ctx, pos, b)
+		handler.h(ctx, pos, b)
 	}
 }
 
-func (h *PlayerNativeBridgeHandler) HandleItemUse(ctx *event.Context) {
+func (h *PlayerNativeBridgeHandler) HandleItemUse(ctx *player.Context) {
 	for _, handler := range h.h.itemUseHandlers {
-		handler.h(h.p, ctx)
+		handler.h(ctx)
 	}
 }
 
-func (h *PlayerNativeBridgeHandler) HandleItemUseOnBlock(ctx *event.Context, pos cube.Pos, face cube.Face, clickPos mgl64.Vec3) {
+func (h *PlayerNativeBridgeHandler) HandleItemUseOnBlock(ctx *player.Context, pos cube.Pos, face cube.Face, clickPos mgl64.Vec3) {
 	for _, handler := range h.h.itemUseOnBlockHandlers {
-		handler.h(h.p, ctx, pos, face, clickPos)
+		handler.h(ctx, pos, face, clickPos)
 	}
 }
 
-func (h *PlayerNativeBridgeHandler) HandleItemUseOnEntity(ctx *event.Context, e world.Entity) {
+func (h *PlayerNativeBridgeHandler) HandleItemUseOnEntity(ctx *player.Context, e world.Entity) {
 	for _, handler := range h.h.itemUseOnEntityHandlers {
-		handler.h(h.p, ctx, e)
+		handler.h(ctx, e)
 	}
 }
 
-func (h *PlayerNativeBridgeHandler) HandleItemConsume(ctx *event.Context, item item.Stack) {
+func (h *PlayerNativeBridgeHandler) HandleItemRelease(ctx *player.Context, item item.Stack, dur time.Duration) {
+	for _, handler := range h.h.itemReleaseHandlers {
+		handler.h(ctx, item, dur)
+	}
+}
+
+func (h *PlayerNativeBridgeHandler) HandleItemConsume(ctx *player.Context, item item.Stack) {
 	for _, handler := range h.h.itemConsumeHandlers {
-		handler.h(h.p, ctx, item)
+		handler.h(ctx, item)
 	}
 }
 
-func (h *PlayerNativeBridgeHandler) HandleAttackEntity(ctx *event.Context, e world.Entity, force *float64, height *float64, critical *bool) {
+func (h *PlayerNativeBridgeHandler) HandleAttackEntity(ctx *player.Context, e world.Entity, force *float64, height *float64, critical *bool) {
 	for _, handler := range h.h.attackEntityHandlers {
-		handler.h(h.p, ctx, e, force, height, critical)
+		handler.h(ctx, e, force, height, critical)
 	}
 }
 
-func (h *PlayerNativeBridgeHandler) HandleExperienceGain(ctx *event.Context, amount *int) {
+func (h *PlayerNativeBridgeHandler) HandleExperienceGain(ctx *player.Context, amount *int) {
 	for _, handler := range h.h.experienceGainHandlers {
-		handler.h(h.p, ctx, amount)
+		handler.h(ctx, amount)
 	}
 }
 
-func (h *PlayerNativeBridgeHandler) HandlePunchAir(ctx *event.Context) {
+func (h *PlayerNativeBridgeHandler) HandlePunchAir(ctx *player.Context) {
 	for _, handler := range h.h.punchAirHandlers {
-		handler.h(h.p, ctx)
+		handler.h(ctx)
 	}
 }
 
-func (h *PlayerNativeBridgeHandler) HandleSignEdit(ctx *event.Context, pos cube.Pos, frontSide bool, oldText string, newText string) {
+func (h *PlayerNativeBridgeHandler) HandleSignEdit(ctx *player.Context, pos cube.Pos, frontSide bool, oldText string, newText string) {
 	for _, handler := range h.h.signEditHandlers {
-		handler.h(h.p, ctx, pos, frontSide, oldText, newText)
+		handler.h(ctx, pos, frontSide, oldText, newText)
 	}
 }
 
-func (h *PlayerNativeBridgeHandler) HandleLecternPageTurn(ctx *event.Context, pos cube.Pos, oldPage int, newPage *int) {
+func (h *PlayerNativeBridgeHandler) HandleLecternPageTurn(ctx *player.Context, pos cube.Pos, oldPage int, newPage *int) {
 	for _, handler := range h.h.lecternPageTurnHandlers {
-		handler.h(h.p, ctx, pos, oldPage, newPage)
+		handler.h(ctx, pos, oldPage, newPage)
 	}
 }
 
-func (h *PlayerNativeBridgeHandler) HandleItemDamage(ctx *event.Context, i item.Stack, damage int) {
+func (h *PlayerNativeBridgeHandler) HandleItemDamage(ctx *player.Context, i item.Stack, damage int) {
 	for _, handler := range h.h.itemDamageHandlers {
-		handler.h(h.p, ctx, i, damage)
+		handler.h(ctx, i, damage)
 	}
 }
 
-func (h *PlayerNativeBridgeHandler) HandleItemPickup(ctx *event.Context, i *item.Stack) {
+func (h *PlayerNativeBridgeHandler) HandleItemPickup(ctx *player.Context, i *item.Stack) {
 	for _, handler := range h.h.itemPickupHandlers {
-		handler.h(h.p, ctx, i)
+		handler.h(ctx, i)
+	}
+}
+
+func (h *PlayerNativeBridgeHandler) HandleHeldSlotChange(ctx *player.Context, from int, to int) {
+	for _, handler := range h.h.heldSlotChangeHandlers {
+		handler.h(ctx, from, to)
 	}
 }
 
-func (h *PlayerNativeBridgeHandler) HandleItemDrop(ctx *event.Context, e world.Entity) {
+func (h *PlayerNativeBridgeHandler) HandleItemDrop(ctx *player.Context, s item.Stack) {
 	for _, handler := range h.h.itemDropHandlers {
-		handler.h(h.p, ctx, e)
+		handler.h(ctx, s)
 	}
 }
 
-func (h *PlayerNativeBridgeHandler) HandleTransfer(ctx *event.Context, addr *net.UDPAddr) {
+func (h *PlayerNativeBridgeHandler) HandleTransfer(ctx *player.Context, addr *net.UDPAddr) {
 	for _, handler := range h.h.transferHandlers {
-		handler.h(h.p, ctx, addr)
+		handler.h(ctx, addr)
 	}
 }
 
-func (h *PlayerNativeBridgeHandler) HandleCommandExecution(ctx *event.Context, command cmd.Command, args []string) {
+func (h *PlayerNativeBridgeHandler) HandleCommandExecution(ctx *player.Context, command cmd.Command, args []string) {
 	for _, handler := range h.h.commandExecutionHandlers {
-		handler.h(h.p, ctx, command, args)
+		handler.h(ctx, command, args)
 	}
 }
 
-func (h *PlayerNativeBridgeHandler) HandleQuit() {
+func (h *PlayerNativeBridgeHandler) HandleQuit(p *player.Player) {
 	for _, handler := range h.h.quitHandlers {
-		handler.h(h.p)
+		handler.h(p)
 	}
 }
 
-func (h *PlayerNativeBridgeHandler) HandleDiagnostics(d diagnostics.Diagnostics) {
+func (h *PlayerNativeBridgeHandler) HandleDiagnostics(p *player.Player, d session.Diagnostics) {
 	for _, handler := range h.h.diagnosticsHandlers {
-		handler.h(h.p, d)
+		handler.h(p, d)
 	}
 }
diff --git a/world_handler_func_types.go b/world_handler_func_types.go
index d5bece4..e59cd8d 100644
--- a/world_handler_func_types.go
+++ b/world_handler_func_types.go
@@ -2,18 +2,18 @@ package vhandler
 
 import (
 	"github.com/df-mc/dragonfly/server/block/cube"
-	"github.com/df-mc/dragonfly/server/event"
 	"github.com/df-mc/dragonfly/server/world"
 	"github.com/go-gl/mathgl/mgl64"
 )
 
-type WorldHandleLiquidFlowFunc func(w *world.World, ctx *event.Context, from cube.Pos, into cube.Pos, liquid world.Liquid, replaced world.Block)
-type WorldHandleLiquidDecayFunc func(w *world.World, ctx *event.Context, pos cube.Pos, before world.Liquid, after world.Liquid)
-type WorldHandleLiquidHardenFunc func(w *world.World, ctx *event.Context, hardenedPos cube.Pos, liquidHardened world.Block, otherLiquid world.Block, newBlock world.Block)
-type WorldHandleSoundFunc func(w *world.World, ctx *event.Context, s world.Sound, pos mgl64.Vec3)
-type WorldHandleFireSpreadFunc func(w *world.World, ctx *event.Context, from cube.Pos, to cube.Pos)
-type WorldHandleBlockBurnFunc func(w *world.World, ctx *event.Context, pos cube.Pos)
-type WorldHandleCropTrampleFunc func(w *world.World, ctx *event.Context, pos cube.Pos)
-type WorldHandleEntitySpawnFunc func(w *world.World, e world.Entity)
-type WorldHandleEntityDespawnFunc func(w *world.World, e world.Entity)
-type WorldHandleCloseFunc func(w *world.World)
+type WorldHandleLiquidFlowFunc func(ctx *world.Context, from cube.Pos, into cube.Pos, liquid world.Liquid, replaced world.Block)
+type WorldHandleLiquidDecayFunc func(ctx *world.Context, pos cube.Pos, before world.Liquid, after world.Liquid)
+type WorldHandleLiquidHardenFunc func(ctx *world.Context, hardenedPos cube.Pos, liquidHardened world.Block, otherLiquid world.Block, newBlock world.Block)
+type WorldHandleSoundFunc func(ctx *world.Context, s world.Sound, pos mgl64.Vec3)
+type WorldHandleFireSpreadFunc func(ctx *world.Context, from cube.Pos, to cube.Pos)
+type WorldHandleBlockBurnFunc func(ctx *world.Context, pos cube.Pos)
+type WorldHandleCropTrampleFunc func(ctx *world.Context, pos cube.Pos)
+type WorldHandleLeavesDecayFunc func(ctx *world.Context, pos cube.Pos)
+type WorldHandleEntitySpawnFunc func(tx *world.Tx, e world.Entity)
+type WorldHandleEntityDespawnFunc func(tx *world.Tx, e world.Entity)
+type WorldHandleCloseFunc func(tx *world.Tx)
diff --git a/world_handlers.go b/world_handlers.go
index d8ba0ed..3bdbf7b 100644
--- a/world_handlers.go
+++ b/world_handlers.go
@@ -8,6 +8,7 @@ type WorldHandlers struct {
 	fireSpreadHandlers    []*handlerWrapper[WorldHandleFireSpreadFunc]
 	blockBurnHandlers     []*handlerWrapper[WorldHandleBlockBurnFunc]
 	cropTrampleHandlers   []*handlerWrapper[WorldHandleCropTrampleFunc]
+	leavesDecayHandlers   []*handlerWrapper[WorldHandleLeavesDecayFunc]
 	entitySpawnHandlers   []*handlerWrapper[WorldHandleEntitySpawnFunc]
 	entityDespawnHandlers []*handlerWrapper[WorldHandleEntityDespawnFunc]
 	closeHandlers         []*handlerWrapper[WorldHandleCloseFunc]
@@ -22,6 +23,7 @@ func NewWorldHandlers() *WorldHandlers {
 		fireSpreadHandlers:    make([]*handlerWrapper[WorldHandleFireSpreadFunc], 0),
 		blockBurnHandlers:     make([]*handlerWrapper[WorldHandleBlockBurnFunc], 0),
 		cropTrampleHandlers:   make([]*handlerWrapper[WorldHandleCropTrampleFunc], 0),
+		leavesDecayHandlers:   make([]*handlerWrapper[WorldHandleLeavesDecayFunc], 0),
 		entitySpawnHandlers:   make([]*handlerWrapper[WorldHandleEntitySpawnFunc], 0),
 		entityDespawnHandlers: make([]*handlerWrapper[WorldHandleEntityDespawnFunc], 0),
 		closeHandlers:         make([]*handlerWrapper[WorldHandleCloseFunc], 0),
@@ -63,6 +65,11 @@ func (h *WorldHandlers) OnCropTrample(handler WorldHandleCropTrampleFunc, priori
 	sortHandlers(h.cropTrampleHandlers)
 }
 
+func (h *WorldHandlers) OnLeavesDecay(handler WorldHandleLeavesDecayFunc, priority Priority) {
+	h.leavesDecayHandlers = append(h.leavesDecayHandlers, &handlerWrapper[WorldHandleLeavesDecayFunc]{priority, handler})
+	sortHandlers(h.leavesDecayHandlers)
+}
+
 func (h *WorldHandlers) OnEntitySpawn(handler WorldHandleEntitySpawnFunc, priority Priority) {
 	h.entitySpawnHandlers = append(h.entitySpawnHandlers, &handlerWrapper[WorldHandleEntitySpawnFunc]{priority, handler})
 	sortHandlers(h.entitySpawnHandlers)
diff --git a/world_native_bridge_handler.go b/world_native_bridge_handler.go
index dab7905..65bd1cb 100644
--- a/world_native_bridge_handler.go
+++ b/world_native_bridge_handler.go
@@ -2,7 +2,6 @@ package vhandler
 
 import (
 	"github.com/df-mc/dragonfly/server/block/cube"
-	"github.com/df-mc/dragonfly/server/event"
 	"github.com/df-mc/dragonfly/server/world"
 	"github.com/go-gl/mathgl/mgl64"
 )
@@ -15,62 +14,68 @@ type WorldNativeBridgeHandler struct {
 // Compile-time check to ensure that the WorldNativeBridgeHandler implements the WorldHandler interface.
 var _ world.Handler = &WorldNativeBridgeHandler{}
 
-func (h *WorldNativeBridgeHandler) HandleLiquidFlow(ctx *event.Context, from cube.Pos, into cube.Pos, liquid world.Liquid, replaced world.Block) {
+func (h *WorldNativeBridgeHandler) HandleLiquidFlow(ctx *world.Context, from cube.Pos, into cube.Pos, liquid world.Liquid, replaced world.Block) {
 	for _, handler := range h.h.liquidFlowHandlers {
-		handler.h(h.w, ctx, from, into, liquid, replaced)
+		handler.h(ctx, from, into, liquid, replaced)
 	}
 }
 
-func (h *WorldNativeBridgeHandler) HandleLiquidDecay(ctx *event.Context, pos cube.Pos, before world.Liquid, after world.Liquid) {
+func (h *WorldNativeBridgeHandler) HandleLiquidDecay(ctx *world.Context, pos cube.Pos, before world.Liquid, after world.Liquid) {
 	for _, handler := range h.h.liquidDecayHandlers {
-		handler.h(h.w, ctx, pos, before, after)
+		handler.h(ctx, pos, before, after)
 	}
 }
 
-func (h *WorldNativeBridgeHandler) HandleLiquidHarden(ctx *event.Context, hardenedPos cube.Pos, liquidHardened world.Block, otherLiquid world.Block, newBlock world.Block) {
+func (h *WorldNativeBridgeHandler) HandleLiquidHarden(ctx *world.Context, hardenedPos cube.Pos, liquidHardened world.Block, otherLiquid world.Block, newBlock world.Block) {
 	for _, handler := range h.h.liquidHardenHandlers {
-		handler.h(h.w, ctx, hardenedPos, liquidHardened, otherLiquid, newBlock)
+		handler.h(ctx, hardenedPos, liquidHardened, otherLiquid, newBlock)
 	}
 }
 
-func (h *WorldNativeBridgeHandler) HandleSound(ctx *event.Context, s world.Sound, pos mgl64.Vec3) {
+func (h *WorldNativeBridgeHandler) HandleSound(ctx *world.Context, s world.Sound, pos mgl64.Vec3) {
 	for _, handler := range h.h.soundHandlers {
-		handler.h(h.w, ctx, s, pos)
+		handler.h(ctx, s, pos)
 	}
 }
 
-func (h *WorldNativeBridgeHandler) HandleFireSpread(ctx *event.Context, from cube.Pos, to cube.Pos) {
+func (h *WorldNativeBridgeHandler) HandleFireSpread(ctx *world.Context, from cube.Pos, to cube.Pos) {
 	for _, handler := range h.h.fireSpreadHandlers {
-		handler.h(h.w, ctx, from, to)
+		handler.h(ctx, from, to)
 	}
 }
 
-func (h *WorldNativeBridgeHandler) HandleBlockBurn(ctx *event.Context, pos cube.Pos) {
+func (h *WorldNativeBridgeHandler) HandleBlockBurn(ctx *world.Context, pos cube.Pos) {
 	for _, handler := range h.h.blockBurnHandlers {
-		handler.h(h.w, ctx, pos)
+		handler.h(ctx, pos)
 	}
 }
 
-func (h *WorldNativeBridgeHandler) HandleCropTrample(ctx *event.Context, pos cube.Pos) {
+func (h *WorldNativeBridgeHandler) HandleCropTrample(ctx *world.Context, pos cube.Pos) {
 	for _, handler := range h.h.cropTrampleHandlers {
-		handler.h(h.w, ctx, pos)
+		handler.h(ctx, pos)
 	}
 }
 
-func (h *WorldNativeBridgeHandler) HandleEntitySpawn(e world.Entity) {
+func (h *WorldNativeBridgeHandler) HandleLeavesDecay(ctx *world.Context, pos cube.Pos) {
+	for _, handler := range h.h.leavesDecayHandlers {
+		handler.h(ctx, pos)
+	}
+}
+
+func (h *WorldNativeBridgeHandler) HandleEntitySpawn(tx *world.Tx, e world.Entity) {
 	for _, handler := range h.h.entitySpawnHandlers {
-		handler.h(h.w, e)
+		handler.h(tx, e)
 	}
 }
 
-func (h *WorldNativeBridgeHandler) HandleEntityDespawn(e world.Entity) {
+func (h *WorldNativeBridgeHandler) HandleEntityDespawn(tx *world.Tx, e world.Entity) {
 	for _, handler := range h.h.entityDespawnHandlers {
-		handler.h(h.w, e)
+		handler.h(tx, e)
 	}
 }
 
-func (h *WorldNativeBridgeHandler) HandleClose() {
+func (h *WorldNativeBridgeHandler) HandleClose(tx *world.Tx) {
 	for _, handler := range h.h.closeHandlers {
-		handler.h(h.w)
+		handler.h(tx)
 	}
 }