Commit Graph

640 Commits

Author SHA1 Message Date
Alexander Medvedev
a2263c55cc chore: update bug report template 2026-07-30 12:55:41 +02:00
Maxime Chaffraix
8a2075779b fix(worldgen): give the stronghold room chest a block entity (#2543)
The chest in the stronghold square room was placed as a bare block state,
so no chest block entity was ever created for it. Opening a chest and
resolving a double chest both go through `get_block_entity`, so the chest
could neither be opened nor paired with a chest placed next to it.

Use the existing `add_chest` helper, which writes the block state and the
matching block entity with a loot table, as the nether fortress corridors
already do. Vanilla `StrongholdPieces$RoomCrossing` uses
`chests/stronghold_crossing` at the same position.
2026-07-26 11:39:46 +02:00
Jamie Little
7552eff6b2 feat: data-driven mob spawn equipment system with vanilla-accurate gear (#2454)
Implements the full vanilla Minecraft 26.2 mob equipment system, giving
mobs weapons, armor, enchantments, and loot-pickup flags at spawn.

Added:

- Data-driven EQUIPMENT_REGISTRY mapping 13 mob types (zombie, husk,
  zombie_villager, drowned, zombified_piglin, skeleton, stray, bogged,
  wither_skeleton, piglin, pillager, vindicator) to their weapon and
  armor configurations, all verified against decompiled vanilla sources.

- Exact vanilla RegionalDifficulty formula from DifficultyInstance.java:
  computes effective_difficulty and special_multiplier from base
  difficulty, game time, chunk inhabited time, and moon phase. When
  special_multiplier is 0.0 (fresh Normal/Easy worlds), equipment,
  enchantments, and loot-pickup flags are suppressed, matching vanilla.

- Vanilla-accurate armor selection: random base tier (0-2) with up to 3
  upgrade attempts at 10.87% each, partial armor break chance (10% on
  Hard, 25% otherwise). Higher difficulty produces fewer pieces.

- Weighted enchantment selection with exclusive-set conflict resolution
  and cost-based level determination. Curated flat pools per equipment
  category (melee/trident/bow/crossbow/fishing_rod/head/chest/legs/feet).

- Per-slot equipment drop chances (0.085 default) with looting bonus
  (+lootingLevel * 0.01 per vanilla EnchantmentHelper).

- Exact vanilla drop durability formula from Mob.dropCustomDeathLoot:
  damage = maxDamage - random(1 + random(max(maxDamage-3, 1))).

- CAN_PICK_UP_LOOT mob flag (bit 3, value 8) set probabilistically at
  55% * special_multiplier.

- Guard against empty equipment packets in send_equipment_changes to
  prevent client decode crashes.

- Chunk inhabited_time tracking in world tick for difficulty scaling.

Integration: equip_mob_on_spawn is called from the blanket
EntityBase::init_data_tracker impl, so every mob type automatically
participates. New mobs are added by inserting a MobEquipmentDef into
the EQUIPMENT_REGISTRY with their weapon/armor config.

cargo check: passes / cargo clippy (pedantic): 0 warnings / cargo fmt: clean
2026-07-24 18:20:49 +02:00
Jamie Little
3ff3eeaf74 perf(world): bulk-build generated chunk palettes (#2492) 2026-07-24 17:02:29 +02:00
Alexander Medvedev
3103e97e18 ci: remove macos-15-intel 2026-07-24 12:31:57 +02:00
Alexander Medvedev
e0117ab559 perf: ditch serde because its slower
i rather trade performance and compile time over convenience
2026-07-19 18:07:37 +02:00
Alexander Medvedev
55219f870f fix: https://github.com/Pumpkin-MC/Pumpkin/issues/2233 2026-07-16 19:56:53 +02:00
Alexander Medvedev
c7be511fbc chore: some more chunk gen work 2026-07-15 19:02:31 +02:00
Alexander Medvedev
37bed1c8b5 feat(command): add fillbiome command 2026-07-14 19:19:03 +02:00
Mcxiaocaibug
1f38ba8054 feat(pumpkin): add /save-all, /save-off and /save-on commands (#2394)
Implements the three vanilla save-control commands (tracked in #15):

- /save-all saves all online players' data and advancements, then
  requests a chunk save from every world's chunk scheduler. It works
  even while autosaving is disabled, matching Vanilla.
- /save-off disables periodic autosaving via a new save_enabled flag
  on Level; running it again fails with commands.save.alreadyOff.
- /save-on re-enables autosaving; running it again fails with
  commands.save.alreadyOn.
2026-07-13 17:40:23 +02:00
Alexander Medvedev
ea7ee250fe fix: clippy 2026-07-13 13:14:00 +02:00
Alexander Medvedev
b1b2a31c49 fix: vanilla level.dat loading 2026-07-13 12:53:33 +02:00
TheDarkSword
1ca089df17 perf(generation): speed up chunk generation(#2335)
* perf(generation): cache computed structure starts

set_structure_references runs for every chunk and, for each nearby structure
candidate, recomputed the structure's placement from scratch. For jigsaw
structures (villages, ancient cities, ...) that means re-running the full
jigsaw expansion for every chunk whose references overlap the structure -- the
same start recomputed many times over.

A structure's placement depends only on its start chunk and the world seed (the
surface-height estimate it uses is position-independent and min_y is constant
per dimension), so memoize it in GlobalStructureCache and reuse it. In the
bench, structure references drop from ~342us to ~105us.

* perf(lighting): use a fast hasher in the generation light engine

The BFS light propagator's visited/shadow_cache/pending_updates maps were
aliased to std HashSet/HashMap (SipHash) despite being named "Fast". They are
probed on every neighbour of every propagated block, so the hash function
dominates. Point the aliases at rustc-hash's FxHash (already a dependency).

Lighting generation drops from ~65ms to ~36ms and full chunk generation from
~103ms to ~68ms in the bench, with identical output.

* perf(lighting): propagate light through storage, not a shadow cache

The BFS light propagator kept a hashed shadow cache of in-flight light values
plus a per-chunk batched write buffer, layered on top of the light storage. The
storage is itself a fast array lookup, so the extra hashing and buffering cost
more than they saved. Read and write it directly and treat it as the single
source of truth.

Lighting generation drops from ~36ms to ~22ms and full chunk generation from
~68ms to ~52ms, output unchanged (all pumpkin-world tests, including the
fixed-seed ancient-city parity test, still pass).

---------

Co-authored-by: Alexander Medvedev <lilalexmed@proton.me>
2026-07-11 18:46:29 +02:00
TheDarkSword
a4af4269fb fix: sky light propagation hanging on unloaded chunks (#2334)
* fix(lighting): stop sky light updates from looping on unloaded chunks

The sky light propagation could spin forever when a light update happened
next to a chunk that wasn't loaded. Writes to an unloaded chunk are dropped
silently and reads come back as 0, so the "this neighbor is darker than us"
check stayed true on every pass and the same position kept getting queued
again. In practice this hangs a tick thread when a block is broken near the
edge of the loaded area.

Skip neighbors whose chunk isn't loaded in both the increase and decrease
passes, matching how the border of loaded chunks already behaves: light
doesn't bleed into chunks that aren't there yet.

* Use Level::is_chunk_loaded for the unloaded-chunk guard
2026-07-09 20:59:38 +02:00
Alexander Medvedev
47fe060665 fix: rust 1.97 lints 2026-07-09 20:39:01 +02:00
Alexander Medvedev
339d9dde5b feat: add bedrock biome mappings 2026-07-08 17:30:55 +02:00
BitForge
adbc8e2b6a fix: prevent capacity overflow crash (#2348)
* fix: prevent capacity overflow crash when flying with elytra or in creative mode

The NoiseBasedCountPlacementModifier::get_count() can return negative i32
values when foliage noise sampling produces negative results at certain
world coordinates. The previous code cast this negative i32 directly to
usize, causing an integer wrap to ~18 quintillion, which triggered a
capacity overflow panic in Vec allocation during chunk feature generation.

This aligns with vanilla Minecraft behavior which also clamps the count
to a minimum of 0 before using it.

Closes #2345

* Hi
2026-07-07 15:53:11 +02:00
ChocoDev
da2401d07d feat: aquifer sample and top material in cave carver (#2242)
* sin/cos util

* 4 nieghbor check

* formating

* air helper

* carver wrapper

* fmt

* clippy

* clipp2

* remove local y

* out of bound guard

* fluid tick

* surface rule

* wire up

* math correct

* start fix

* bring back xoroshiro oops

* scheduler guard

* simplify test

* clean test

* comment

* crash fix

* clippy

* clippy

* i hate you codex

* sin cos

* im stupid f32
2026-07-05 15:55:43 +02:00
Alexander Medvedev
5d117b3213 fix: ci in release 2026-07-03 19:26:17 +02:00
Alexander Medvedev
a9f69fea01 chore: enforce clippy lints in pumpkin-world 2026-07-03 18:51:47 +02:00
PigTurtle
7bfc6a6737 refactor(data) BlockId and BlockStateId wrapper types (#2328)
* refactor: less manual BlockMetadata impls

* refactor: added BlockId type

BlockId is a wrapper for u16: it is valid for any u16 that is the id of a Block.
- Changed the Block.id field type to BlockId
- added named BlockId constants
- BlockMetadata::ids() now returns Box<[BlockId]>
- adjusted pumpkin-macros to use BlockId constants
- fixed some methods that were comparing blockstate ids or item ids (u16) against block ids (previously u16)

TODO: check if unsafe blocks can be removed; The compiler might understand that BlockId is always a valid index into mappings::TYPE_FROM_RAW_ID

* refactor: added BlockStateId type

A BlockStateId is a safe wrapper around the numerical index of a BlockState in pumpkin-data. They help avoiding validity checks (outside of IO and, currently, plugins), and make it easier for other contributors to reason about what they're comparing; BlockStateIds, BlockIds or Item ids (still u16).
pumpkin-data::BlockStateId replaces RawBlockState and BlockStateId from pumpkin-world.

- added the BlockStateId wrapper type
- made (almost; plugins) every function interacting with block states or block state ids use the wrapper type
- changed codegen logic to create/work with BlockStateIds
- made ChunkPalette parsing check BlockStateId validity (pumpkin-world::chunk::format::ChunkSectionBlockStates)

TODO: check if unsafe blocks can be removed; The compiler might understand that BlockStateId is always a valid index into mappings::BLOCK_ID_FROM_STATE_ID and mappings::STATE_FROM_STATE_ID

* refactor: imports
changed every use pumpkin_world::BlockStateId to pumpkin_data::BlockStateId

* refactor: Block- & BlockStateId

finishing touches;
- rebased on latest mater
- ensure there are no bound checks on Block(State)Id conversions, making them extremely cheap
  - this required unsafe std::hint::assert_unchecked annotations because the compiler is (occasionally) stupid
  - on debug builds the bound checks still exist because of ub_checks (see rust unstable book for the feature of the same name)
- added Safety notes to hopefully prevent anyone from enabling the creation of invalid Block(State)Ids in the future

- fixed a benchmark
2026-07-01 18:05:05 +02:00
ZlordHUN
395c4aa36b feat(generation): implement ancient city jigsaw structures (#2329) 2026-07-01 09:11:47 +02:00
dongzh1
af712b714e fix(pumpkin-world): correct inverted liquid_block_count (#2316)
BlockPalette::liquid_block_count() returned the inverse of what it
should: the Homogeneous arm returned 0 when the section was liquid and
the full VOLUME (4096) when it was not, and the Heterogeneous arm summed
the counts of non-liquid blocks (filtering on !is_liquid).

Flip both arms to actually count liquid blocks, mirroring the correct
sibling non_air_block_count(): Homogeneous yields VOLUME when the single
block is liquid (0 otherwise) and Heterogeneous filters on is_liquid.

This value is sent to clients as the fluid count in chunk data
(MC 26.1+), so the inversion reported wrong fluid counts to players.
2026-06-30 19:23:17 +02:00
ZlordHUN
5eb7cc0e81 feat: Add Overworld Fossil Generation (#2319) 2026-06-30 19:08:44 +02:00
Alexander Medvedev
7ff990c468 fix: bedrock crafting 2026-06-29 21:20:40 +02:00
Alexander Medvedev
8c5d6dc405 fix: bedrock SActorEvent packet 2026-06-28 13:26:32 +02:00
Alexander Medvedev
1dbfb75ecc fix: end spawning 2026-06-27 14:57:40 +02:00
Alexander Medvedev
322b7af6ae chore: made tnt explosion bit faster 2026-06-26 21:43:00 +02:00
Alexander Medvedev
23e7992b2d Port to 26.2 2026-06-20 20:07:31 +02:00
Alexander Medvedev
8634d8740f fix: nether/end 2026-06-13 22:44:29 +02:00
Alexander Medvedev
68bae5899e feat: add stats 2026-06-12 20:55:29 +02:00
Alexander Medvedev
b4a652c68c fix: ci 2026-06-12 06:58:14 +02:00
Alexander Medvedev
acb295b250 fix: ci/test 2026-06-11 23:02:42 +02:00
Alexander Medvedev
5b8eab0f56 feat: initial village support 2026-06-10 23:07:10 +02:00
ChocoDev
636331ead3 chore update world generation benchmark (#2216)
* benchmark

* clippy
2026-06-09 16:01:40 +02:00
shaches
1f63fae486 fix(world): handle unsupported custom anvil compression (#2217) 2026-06-04 10:24:36 +02:00
shaches
440d222f8a fix: stale proto chunk generation tasks (#2214) 2026-06-04 10:18:24 +02:00
Alexander Medvedev
3629f43dcc fix: disable cave carver for now
fixes some issues
2026-05-23 16:36:08 +02:00
Alexander Medvedev
3303bb7b97 chore(net): change get_string to get_str
changed return value from `String` to `Box<str>` which is smaller and makes more sense since we don't mutate packet data

String — 24 bytes (ptr + len + capacity)
Box<str> — 16 bytes (ptr + len)
2026-05-23 11:21:53 +02:00
Nicolai Van der Storm
c7ab629947 fix: serialization fix wich resulted in void/air chunks (#2177)
* Fix chunk save/load corruption and generation stage progression

- Fix serde rename mismatch: ChunkSectionNBT now uses PascalCase
  to match serialization, restoring block_states and biomes on load.
- Correct generation stage order: Biomes before StructureStart,
  add missing Carvers stage.
- Add stage guards in Cache::advance to avoid re-running completed
  stages, preventing assertion panics.
- Set ProtoChunk::stage from saved ChunkStatus in from_chunk_data,
  ensuring loaded chunks start at correct stage.

* using propper asserts instead of silent skips

* using StagedChunkEnum::Empty instead of None
2026-05-23 09:29:00 +02:00
Alexander Medvedev
4aa78496dd fix: forgot to decompress pump files 2026-05-22 23:03:15 +02:00
Alexander Medvedev
2fcc9bcf4a chore: enforce some more clippy lints
pumpkin contributors will love me :cap:
2026-05-20 22:27:54 +02:00
Alexander Medvedev
330a68054f chore: replace String with ConfiguredFeatures enum 2026-05-19 20:19:46 +02:00
Alexander Medvedev
c7a9d5935a chore: replace String with PlacedFeatures enum 2026-05-19 20:08:58 +02:00
Greened
21b5967fc8 fix: layer snow on ice (#2152) 2026-05-18 20:34:12 +02:00
Alexander Medvedev
7467195821 fix: test 2026-05-17 17:27:26 +02:00
Alexander Medvedev
d3d13323b2 fix: don't store empty chunks
should be fixed
2026-05-17 13:47:34 +02:00
Greened
60ad62bbf1 feat: implement coral plants, coral fans and fix coral feature (#2025)
* feat: implement coral plants, coral fans and fix coral feature

* fix: clippy warnings

* fix: dead coral fans

* chore: restructure

* fix: clippy warning

* fix: resolve changes

---------

Signed-off-by: Greened <108997309+GreenedDev@users.noreply.github.com>
2026-05-17 09:49:54 +02:00
Alexander Medvedev
5aafff35e8 feat: add bedrock forms 2026-05-15 18:24:28 +02:00
RB007
b2b10f3323 feat: chest loot tables (#2084)
* feat: add vanilla chest loot table json files

* feat: codegen and chest loot logic

Co-authored-by: Copilot <copilot@github.com>

* fix: monster_room loot chests

* fix: nether_fortress loot chests

* fix: shuffle item stacks and fmt/clippy

Co-authored-by: Copilot <copilot@github.com>

---------

Signed-off-by: Alexander Medvedev <lilalexmed@proton.me>
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Alexander Medvedev <lilalexmed@proton.me>
2026-05-15 08:43:51 +02:00