mojira.dev
MCPE-241098

SimulatedPlayer delivered as undefined to addons using stable @minecraft/server API versions

When a SimulatedPlayer is spawned via the top-level spawnSimulatedPlayer() from @minecraft/server-gametest, addons that depend on stable (non-beta) versions of @minecraft/server receive event.player = undefined in their playerSpawn subscription. The same SimulatedPlayer is delivered as a fully valid object to addons using the beta API version. This causes any addon with an unguarded playerSpawn handler to crash, making SimulatedPlayer unusable alongside most published behavior packs.

Steps to Reproduce

  1. Create two behavior packs on the same world:

    • Pack A depends on @minecraft/server version 2.9.0-beta and @minecraft/server-gametest version 1.0.0-beta. It subscribes to world.afterEvents.playerSpawn and logs event.player, then spawns a SimulatedPlayer via the top-level spawnSimulatedPlayer().

    • Pack B depends on @minecraft/server version 2.3.0 (stable, non-beta). It subscribes to world.afterEvents.playerSpawn and accesses event.player.id.

  2. Enable the Beta APIs experiment on the world.

  3. Load the world. A real player joining triggers playerSpawn — both packs receive a valid event.player with .id, .name, .location, etc.

  4. From Pack A, call spawnSimulatedPlayer() to spawn a SimulatedPlayer.

Expected Result

Pack B's playerSpawn handler receives event.player as a valid Player object, since SimulatedPlayer extends Player and has every property Player defines.

Actual Result

Pack B's playerSpawn handler receives event.player = undefined. Accessing any property throws TypeError: Cannot read property 'id' of undefined. This crashes Pack B and any other addon with a playerSpawn handler that doesn't guard against undefined.

The same SimulatedPlayer is delivered correctly to Pack A (the beta-API pack). Inspecting the object in Pack A's handler confirms it is fully valid:
Example -
Real Player (Pack A's handler):
.id = -416612347711
.name = "realplayer"
.typeId = minecraft:player
.isValid = true
constructor.name = Player

SimulatedPlayer (Pack A's handler):
.id = -3126712341431
.name = "simplayer"
.typeId = minecraft:player
.isValid = true
.location = valid
.dimension.id = minecraft:overworld
.getGameMode() = Survival
health = 20/20
inventory = size 36
constructor.name = SimulatedPlayer

The SimulatedPlayer has every property the stable API's Player interface defines. The engine fails to marshal it because the type originates in @minecraft/server-gametest, which the stable-API addon does not depend on.

This also affects per-tick world.getAllPlayers() and dimension.getEntities() calls from stable-API addons, which return undefined entries for SimulatedPlayers, causing ongoing crashes every tick — not just at spawn time.

Impact

This makes SimulatedPlayer incompatible with any addon using a stable @minecraft/server version that subscribes to player events or iterates players — which is the majority of published behavior packs. Addons like Understudy (39k+ downloads) cannot coexist with common packs such as Soundscapes+, BOSSES+, RealismCraft, Furniture Add-On, etc.

Suggested Fix

When delivering events or query results to addons using stable @minecraft/server, the engine should downcast SimulatedPlayer to its base Player type rather than returning undefined. SimulatedPlayer inherits from Player and exposes all Player properties — the stable API's Player interface is fully satisfied.

Linked issues

Attachments

Comments 2

Hi!
Thank you for your report! 

However, this issue has been temporarily closed as Awaiting Response.

  • Can you attach behavior packs this issue can be reproduced with?

This ticket will automatically reopen when you reply. Thanks!

Quick Links: 
📓 Issue Guidelines – 💬 Mojang Support – 📧 Suggestions – 📖 Minecraft Wiki

Attached are two minimal reproduction packs and a content log.

Pack A — @minecraft/server 2.9.0-beta + @minecraft/server-gametest 1.0.0-beta. Spawns a SimulatedPlayer on /scriptevent repro:spawn.
Pack B — @minecraft/server 2.3.0 (stable). Subscribes to playerSpawn and iterates getAllPlayers() each tick, accessing the same properties/methods that real published addons use.

Reproduce: add both packs to a world with Beta APIs enabled, load in (real-player spawn works fine — all accesses succeed), then run /scriptevent repro:spawn.

Result: Pack B receives event.player === undefined for the SimulatedPlayer and every property/method access throws TypeError — .isValid, .dimension, .location, .getVelocity(), .typeId, .getBlockFromViewDirection(), .id, .getProperty(), .hasTag(), .setDynamicProperty(), .runCommand(), .getDynamicProperty(), .getComponent(), .name, .nameTag, .getGameMode(). The per-tick loop repeats these continuously, matching the error flood seen in real multi-addon crashes. Pack A (beta API) receives the identical SimulatedPlayer as a fully valid object.

This property/method set is taken directly from a real crash log involving published addons (RealismCraft, Eternal End, More Simple Structures, etc.). When multiple installed addons hit this every tick simultaneously, the exception volume escalates to a full world crash as soon as a SimulatedPlayer is spawned.

Root cause: SimulatedPlayer (defined in @minecraft/server-gametest) is not marshaled to addons depending only on stable @minecraft/server; they receive undefined instead of the entity downcast to its base Player type.

[media][media][media]

Eric C

(Unassigned)

Unconfirmed

Windows

10

26.33 Hotfix

Retrieved