Pumpkin-Docs/docs/zh_cn/developer/entities/spawning-and-tracking.md
Alexander Medvedev 5c23b676ed feat: d binding
2026-09-17 09:23:24 +02:00

4.9 KiB

Spawning & Network Tracking

To maintain high tick rates with hundreds of active entities, Pumpkin utilizes a chunk-based entity tracking and streaming system.

Entities are held in chunk-level collections inside crates/pumpkin-world and synchronized across clients via edition-specific network packets.


The Spawning Pipeline

Spawning an entity involves creating an instance, allocating its network IDs, registering it with the world, and broadcasting spawn packets to chunk observers:

  1. Construct Entity Instance: Instantiate the specific entity struct (such as ZombieEntity, ArrowEntity, or ItemEntity) initialized with its starting world and spatial coordinates.
  2. Allocate Unique Network Identifiers: Assign an atomic 32-bit entity_id for network protocol packets and a 128-bit persistent UUID.
  3. Register in World & Chunk Map: Insert the entity into the world's entity storage and index it within its corresponding chunk coordinate entry.
  4. Query Chunk Observers: Look up all connected players within tracking range whose view distance includes the containing chunk.
  5. Broadcast Edition-Specific Spawn Packets: Transmit the relevant spawn and metadata packets tailored to each observing client's edition (Java or Bedrock).

Spawning via the World API

use std::sync::Arc;
use pumpkin_data::entity::EntityType;
use pumpkin_util::math::vector3::Vector3;
use crate::entity::Entity;
use crate::entity::mob::zombie::ZombieEntity;

// 1. Create base entity with target world and position
let position = Vector3::new(100.5, 64.0, -200.5);
let base_entity = Entity::new(world.clone(), position, &EntityType::ZOMBIE);

// 2. Wrap in specific entity implementation
let zombie = Arc::new(ZombieEntity::new(base_entity));

// 3. Register into the world
world.spawn_entity(zombie);

Network Packet Synchronization

When a player enters a chunk containing entities—or when an entity moves into an observed chunk—Pumpkin dispatches spawn packets tailored to the client's edition:

Java Edition Spawning

  1. CSpawnEntity: Declares the entity ID, UUID, entity type, position, and initial pitch/yaw.
  2. CSetEntityMetadata: Sends initial visual states (custom name tags, burning flags, baby/adult state).
  3. CEntityVelocity: Synchronizes initial momentum.
  4. CUpdateEntityRot & CHeadRot: Synchronizes head orientation independently from body yaw.

Bedrock Edition Spawning

  1. CAddActor: Declares the runtime ID, actor type identifier, position, rotation, and embedded SyncedActorDataList.
  2. CSetActorMotion: Sets initial velocity vector.

Movement & Position Synchronization

Transmitting absolute 64-bit coordinates every tick would congest network bandwidth. Instead, Pumpkin dynamically switches between compact relative delta updates and authoritative full synchronization based on movement distance:

Metric / Scenario Threshold Java Protocol Packet Bedrock Protocol Packet Bandwidth Impact
Incremental Movement \Delta < 8 blocks per tick CUpdateEntityPos / CUpdateEntityPosRot CMoveActorDelta Minimal (fixed-point byte deltas)
Teleport / Long Distance \Delta \ge 8 blocks or chunk warp CTeleportEntity / CEntityPositionSync CMoveActorAbsolute Full 64-bit float coordinate payload
Rotation Only Position unchanged CUpdateEntityRot & CHeadRot CMoveActorDelta (rot flags only) Minimal (byte angles)

1. Relative Delta Movement

If the entity moved less than 8 blocks in a single tick, Pumpkin sends delta packets using fixed-point encoded increments:

  • Java: CUpdateEntityPos (XYZ delta), CUpdateEntityRot (yaw/pitch delta), or CUpdateEntityPosRot (both).
  • Bedrock: CMoveActorDelta with bitflags indicating which coordinates changed (MOVE_ACTOR_DELTA_FLAG_HAS_X, HAS_Y, HAS_Z).

2. Full Position Synchronization

When an entity teleports, crosses chunk boundaries, or accumulates floating-point drift:

  • Java: Sends CEntityPositionSync containing absolute coordinates, velocities, and on-ground flags.
  • Bedrock: Sends CMoveActorAbsolute.

Passenger & Vehicle Mounting

When an entity mounts another entity (e.g., a player mounting a horse, boat, or minecart):

  • Java Edition: Sends CSetPassengers containing the vehicle's VarInt entity ID and an array of passenger entity IDs.
  • Bedrock Edition: Sends CSetActorLink defining the rider and vehicle runtime IDs and link type (Rider, Passenger).

Despawning & Entity Removal

When an entity dies, is removed from the world, or steps out of a player's tracking radius:

  • Java Edition: Sends CRemoveEntities with an array of entity IDs.
  • Bedrock Edition: Sends CRemoveActor with the entity's runtime ID.

The client immediately frees its local rendering and audio memory for the removed entity.