Gameplay Handles
Gameplay handles provide a thread-safe interface for interacting with entities, players, and world objects within the runtime.
In this section
Related section pages:
Accessing Players
Use ctx.Gameplay() for authoritative mutations. Players can be retrieved by name, ID, XUID, UUID, or the session-backed identity known to the server.
playerHandle, ok := ctx.Gameplay().Players().ByName("Steve")if !ok { return fmt.Errorf("player not found")}target, ok := ctx.Gameplay().Players().Resolve("Steve") // ID, name, XUID, or UUID_ = target_ = ok_, err := playerHandle.Inventory().Give(item.New("diamond_sword"). Enchant(item.Sharpness(5)). NameTag("Arena Blade"). Stack())worldHandle, ok := ctx.Gameplay().Worlds().ByName("Hub")if !ok { return fmt.Errorf("world not found")}container := worldHandle.ContainerAt(world.Pos{X: 10, Y: 64, Z: 10}, 27)_, err = container.Give(item.New("diamond").Count(8).Stack())Inventory
PlayerHandle.Inventory() gives access to inventory mutations that sync back to the Bedrock client.
inv := playerHandle.Inventory()_, err := inv.Give(item.New("diamond_sword"). Enchant(item.Sharpness(5)). NameTag("Arena Blade"). Lore("Bound to the arena"). Stack())_, err = inv.Move(0, 1, 1)_, err = inv.Swap(1, 2)err = inv.SetHeldSlot(1)err = inv.Resync()World And Entities
World handles expose block placement, block breaking, spatial player queries, entity queries, containers, and mob spawning.
worldHandle, ok := ctx.Gameplay().Worlds().ByName("Hub")if !ok { return fmt.Errorf("world not found")}pos := world.Pos{X: 10, Y: 64, Z: 10}err := worldHandle.SetBlock(pos, block.New("chest").String("minecraft:cardinal_direction", "north").Block())placed, err := playerHandle.PlaceBlock(pos, block.New("stone").Block())broken, err := worldHandle.BreakBlock(playerHandle.ID(), pos, item.New("diamond_pickaxe").Stack())nearby := worldHandle.NearestPlayers(entity.Position{X: 10, Y: 64, Z: 10}, 16, 5)zombies := worldHandle.EntitiesByType("minecraft:zombie")container := worldHandle.ContainerAt(pos, 27)_, err = container.Give(item.New("diamond").Count(8).Stack())err = container.OpenFor(playerHandle.ID())err = container.Resync()_ = placed_ = broken_ = nearby_ = zombiesmob, err := worldHandle.SpawnMob(entity.Zombie().At(12, 65, 10).Health(20))err = mob.SetNameTag("Training Zombie")_, err = mob.AddEffect(effect.New("strength").Seconds(10))err = mob.Damage(1, "training")EntityHandle also exposes Teleport, SetTransform, SetProperty, RemoveEffect, ClearEffects, and Despawn.
Motion And Network
SetMotion and Knockback mutate server-owned entity velocity and sync metadata; no custom player subclass is required.
motion, ok := playerHandle.Motion()_ = motion_ = okerr := playerHandle.SetMotion(entity.Motion{X: 0.2, Y: 0.42, Z: 0})_, err = playerHandle.Knockback(entity.Position{X: 0, Y: 64, Z: 0}, 0.4, 0.36)network, ok := playerHandle.Network()locale, _ := playerHandle.Locale()device, _ := playerHandle.Device()skinProfile, _ := playerHandle.SkinProfile()skin, err := playerHandle.Skin()_, err = playerHandle.SetSkin(skin)_ = network_ = ok_ = locale_ = device_ = skinProfile_ = skinSkinProfile() returns a lightweight skin summary. Skin() returns a cloned server-owned skin snapshot. SetSkin() stores the new skin in core and broadcasts a typed play.player_skin runtime message to viewers, so plugins do not need raw PlayerSkin packets.
Kits And Scoreboards
Armor, offhand, cursor, and crafting handles are named server-side containers. ClearAllInventories clears supported containers and requests a resync.
err := playerHandle.ClearAllInventories()err = playerHandle.Armor().Set(0, item.New("diamond_helmet").Stack())err = playerHandle.Offhand().Set(0, item.New("shield").Stack())err = playerHandle.Cursor().Clear()board := playerHandle.Scoreboard()err = board.SetTitle("Duel")err = board.SetLines("Map: nodebuff", "Ping: 20ms")err = board.SetLine(1, "Ping: 18ms")err = board.Remove()Nearby Queries And World Effects
World handles can query nearby entities and players, then emit sounds, particles, and level events through server-owned effects.
entities := worldHandle.NearbyEntities(entity.Position{X: 0, Y: 64, Z: 0}, 12, 10)players := worldHandle.PlayersNear(entity.Position{X: 0, Y: 64, Z: 0}, 12, 5)err := worldHandle.AddSound(entity.Position{X: 0, Y: 64, Z: 0}, gameplay.SoundEffect{Type: 1})err = worldHandle.AddParticle(entity.Position{X: 0, Y: 64, Z: 0}, gameplay.ParticleEffect{Type: 2001})err = worldHandle.LevelEvent(entity.Position{X: 0, Y: 64, Z: 0}, gameplay.LevelEvent{Type: 2001})_ = entities_ = playersItems, Projectiles, And Templates
Projectile item specs expose force, cooldown, projectile type, and hit hook metadata. Template copying prepares arena instances asynchronously; dynamic world registration stays server-owned.
err := ctx.Items().Alias("mace", "minecraft:stick")ctx.Items().SetCooldown(playerHandle.ID(), "pearl", 20)ready := ctx.Items().Ready(playerHandle.ID(), "pearl")_ = readyspec := content.DefineProjectileItem("practice:fireball"). MaxCount(16). Cooldown(20). ThrowForce(1.5). Projectile("practice:fireball_projectile"). Spec()_, err = ctx.RegisterItem(spec)ctx.WorldTemplates().Copy(ctx, plugin.WorldTemplateCopyRequest{ TemplatePath: "worlds/templates/duel", TargetPath: "worlds/arenas/duel-1", WorldID: "duel-1",}, func(result plugin.WorldTemplateResult) { if result.Err != nil { ctx.Logger().Warn("arena copy failed", "err", result.Err) }})