Commit Graph

2517 Commits

Author SHA1 Message Date
yhypno
bd7a1a2126 fix(inventory): enchanting table offers and lapis validation (#2374)
* fix(inventory): match applied enchantments with table preview

* fix(inventory): require lapis for enchanting purchases
2026-07-30 23:08:38 -04:00
ZlordHUN
a3b66be27b feat: Implement pillager outpost structures (#2470) 2026-07-30 14:27:00 +02:00
Maxime Chaffraix
b024c3ae3a fix(entity): apply knockback resistance to living entities (#2498)
* fix(entity): apply knockback resistance to living entities

Vanilla LivingEntity.knockback scales strength by 1.0 - KNOCKBACK_RESISTANCE,
but Pumpkin never applied it, so mobs with high resistance (iron golem,
warden, ravager) were knocked back like any other mob.

Scale both knockback paths by the victim's resistance: the base hit knockback
in LivingEntity, and the sprint/enchant bonus in handle_knockback, which now
takes the victim as &dyn EntityBase so it can read the attribute.

Fixes #1761

* docs(entity): clarify knockback resistance is not applied in apply_knockback

The previous note read as if every caller had to pre-scale strength. Ender
dragon knockback mirrors vanilla Entity.push, which ignores resistance, so
spell out which callers scale and which don't.
2026-07-30 14:25:36 +02:00
Mettwasser
98fd79b57e feat(plugin-api): add display impl for uuid (#2497) 2026-07-30 14:24:19 +02:00
Eshan I.
cbc8af5d2d fix(block): bleach fire coral blocks when they dry out (#2571)
get_dead_coral_block_type mapped FIRE_CORAL_BLOCK to itself rather than
to DEAD_FIRE_CORAL_BLOCK, so a fire coral block left out of water stayed
alive forever while the other four colours bleached normally. The two
sibling tables for fans and plants both map it correctly.

The same table feeds BlockMetadata::ids, so this also stops the block
being registered twice and registers DEAD_FIRE_CORAL_BLOCK, which was
missing from the list.
2026-07-30 14:22:40 +02:00
Eshan I.
fe0c442a02 fix(player): apply food exhaustion when attacking and mining (#2578)
Vanilla Player#attack ends its successful-hit branch with
causeFoodExhaustion(0.1F), and Block#playerDestroy calls
player.causeFoodExhaustion(0.005F) for every block destroyed.

Pumpkin never called add_exhaustion from either path: the only callers
were the Hunger status effect in entity/living.rs and jump/sprint
movement in entity/player.rs. Combat and mining were therefore free, so
the hunger bar was effectively cosmetic for a player who was not
sprinting.

Player::attack now adds 0.1 exhaustion at the end of the hit path,
after the damage_with_context early-return, so only hits that actually
deal damage cost hunger. The Java and Bedrock block-break handlers now
add MINE_BLOCK_EXHAUSTION (0.005) per block broken.

Mining exhaustion is gated exactly where vanilla gates
Block#playerDestroy: ServerPlayerGameMode#destroyBlock skips it in
creative and when the block was broken without a tool that can harvest
it, so the call sites reuse the existing can_harvest / block_drop
checks rather than adding new conditions. Creative and spectator
players are additionally covered by the existing abilities.invulnerable
guard in Player::add_exhaustion, which mirrors vanilla
Player#causeFoodExhaustion.

Limitation: swimming exhaustion (0.01 per metre) is still missing.
Player::progress_motion only implements the onGround branch of vanilla
ServerPlayer#checkMovementStatistics; adding the swimming and in-water
branches requires the whole else-if chain plus movement-state plumbing
(Player::is_swimming is itself still an inferred approximation carrying
a TODO), so it is deliberately left out of this change.
2026-07-30 14:21:39 +02:00
Eshan I.
0be7e49e52 fix: let console and RCON run /fill and /setworldspawn (#2583)
CommandSender::world() returns None for console and RCON, so the two
commands that call it via ok_or(InvalidRequirement) fail there while
/setblock at the same coordinates succeeds. Five other call sites had
each grown their own inline fallback to the first world, which is also
what vanilla does for server-console commands.

Add world_or_first(server) with that fallback and use it, and fold the
duplicated logic in setblock and teleport into it. world() is left
unchanged because it is part of the versioned WASM plugin ABI.
2026-07-30 14:20:02 +02:00
yhypno
35de5d4e89 fix(block): damage shears when carving pumpkins (#2644) 2026-07-30 14:14:57 +02:00
Hugo Planque
f29a762ee7 feat(block): implement bubble columns (#2633) 2026-07-30 14:14:20 +02:00
Giovanni Giordano
0fe896892f docs: document pumpkin-nbt (#2648) 2026-07-30 14:13:47 +02:00
Alexander Medvedev
a2263c55cc chore: update bug report template 2026-07-30 12:55:41 +02:00
Eshan I.
27d485a934 fix: four item interaction bugs (#2610)
Flint and steel and fire charge lit any block carrying a lit property,
because can_be_lit searched the property list by name rather than checking
the block. That covers furnaces, smokers, blast furnaces, redstone lamps,
redstone torches, redstone ore and every copper bulb. Redstone lamps have
no use handler so the click fell straight through, and furnaces were
reachable by sneaking, which skips the block use handler. Gate on the
campfire, candle and candle cake tags, matching the three canLight
predicates vanilla checks. The extinguished branch above it was dead, as
no block in the generated data has that property, so it is removed.

The hoe called set_block_state outside its changed guard, so a click that
tilled nothing still rewrote the block to its default state. On a grass
block under a snow layer that cleared snowy and turned the block green.
Vanilla returns PASS and touches nothing.

Bone meal on bamboo could never grow it: the air check read the topmost
bamboo block rather than the space above it, so it always returned on the
first iteration. It also rolled 1 to 3 where vanilla rolls 1 to 2, and
grew from the original position rather than the top stalk.

The axe could not strip crimson and warped stems and hyphae, or bamboo
blocks. Bamboo is not in the logs tag, so the axis copy is extended to
cover it or a sideways bamboo block would snap upright when stripped.
2026-07-30 12:35:29 +02:00
Rito
f2ca934a7b fix(plugin): read native plugin metadata through its LazyLock (#2561)
The native loader reads METADATA as a `*const PluginMetadata`, but since
#1675 gave PluginMetadata owned String and Vec fields, `#[plugin_impl]`
has to export it as a `LazyLock` — a const can't allocate. The loader was
therefore reinterpreting the LazyLock's internals as a PluginMetadata.

Every native plugin ends up with an empty name and version. That alone
puts the data folder at plugins/ instead of plugins/<name>/ and makes
Context::register_permission reject every node, since it validates against
the plugin's namespace. And when the garbage string length happens not to
be zero, cloning the metadata takes the server down with a multi-terabyte
allocation request, which is what #2434 reports.

Go through a `*const LazyLock<PluginMetadata>` and deref it, which forces
the lock before the metadata is read.
2026-07-30 12:01:27 +02:00
Demetrius Kanios
5cb537dcba plugin-api: Improve PluginInitError messages (#2647) 2026-07-30 10:18:32 +02:00
Andbix
2577cfa3c9 feat(server): support F3+2 tick debug sample chart (#2636) 2026-07-29 19:59:08 +02:00
Demetrius Kanios
ef325c459e plugin-api: Rework filesystem permissions and move data folders. (#2643) 2026-07-29 09:36:22 +02:00
Missing_Love
8db9c013b1 docs: add description for Redundancy in contributing guidelines (#2556)
* Add Redundancy description

Signed-off-by: Missing_Love <42416195+Q2297045667@users.noreply.github.com>

* Update

Signed-off-by: Missing_Love <42416195+Q2297045667@users.noreply.github.com>

---------

Signed-off-by: Missing_Love <42416195+Q2297045667@users.noreply.github.com>
2026-07-26 23:20:32 -04:00
Jamie Little
ad31ce9889 fix: correct sound packet position encoding (was multiplied by 8 twice) (#2440)
CSoundEffect::new() scales the position by * 8 to convert from
fixed-point. write_packet_data was applying * 8 a second time,
resulting in positions being multiplied by 64.

Add regression test asserting the encoded X/Y/Z are exactly
floor(input_pos * 8), preventing this bug from reappearing.
2026-07-26 23:06:00 -04:00
dorocha
5f127823ae feat(plugin-api): expose ItemStack, uuid, event and command arg types (#2526)
The item-stack, uuid, and event WIT modules are generated but were never
re-exported from the plugin API, so plugin authors could not name ItemStack
(needed to build GUI icons, /give, skulls) or construct a uuid. This adds them
to the public re-exports, plus EventHandler/FromIntoEvent and the command
Arg/ArgumentType/StringType helpers.

Revives the change from #2325 (closed unmerged).
2026-07-26 11:44:54 +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
necko
ce4f3cc1f1 docs: fix broken chunk loading image link in README (#2547)
Signed-off-by: necko <128916594+Necko1@users.noreply.github.com>
2026-07-26 11:39:10 +02:00
Alexander Medvedev
ac89bff1ca fix: from_legacy_string 2026-07-26 10:25:13 +02:00
Alexander Medvedev
faf8c50d80 chore(mappings): add 1.7 & 1.8 2026-07-25 16:48:20 +02:00
Alexander Medvedev
40d7ed052f feat: add more mappings 2026-07-25 12:38:52 +02:00
Alexander Medvedev
25ba4c6e40 feat: added some Love 💞 2026-07-25 12:08:59 +02:00
Alexander Medvedev
cba7578e28 feat: add Leash 2026-07-25 10:51:55 +02:00
BouncingElf10
0dfaf5d213 feat(block): Added more dispenser behaviors (#2495)
* feat(block): added DispenseContext and drop_item abstractions for dispenser behavior

* feat(block): added specific arrow dispenser behavior

* feat(block): added specific spawn dispenser behavior

* docs(block): added some comments to quickly spot missing dispenser behaviors

* fix: addressed PR review feedback
2026-07-25 09:36:10 +02:00
vyPal
56de61783a fix: use networking.java.online_mode for online mode detection (#2404) 2026-07-25 09:31:39 +02:00
TheDarkSword
2d7cf40761 feat: persist item components that were only set at runtime (#2426)
* feat: persist runtime-set item components

They serialized to nothing before; give the remaining ones a read/write so
their data survives a save/load. Predicate-based ones keep raw NBT for now.

* refactor: remove Cow where unnecessary

Copied it over from ItemModelImpl, but it makes no sense for base_color,
note_block_sound and tooltip_style: they're only ever built at runtime, so a
plain String is enough.
2026-07-25 09:29:46 +02:00
Maxime Chaffraix
64e9d97d7f fix(auth): don't require signatureRequired in texture profiles (#2499)
Third-party auth servers (drasl, Blessing Skin, littleskin.cn) don't send the
signatureRequired field in the hasJoined texture property, so parsing the
profile failed and the player was kicked. The field is unused, so default it
when missing.

fixes #301
2026-07-25 09:28:05 +02:00
Afalinx
0d443944a7 fix(redstone): use vanilla pressure plate detection bounds (#2439)
Replace full-block entity queries with vanilla's centered 14x4x14 pressure plate detection box. Share the bounds between normal and weighted pressure plates and cover the geometry with unit tests.
2026-07-24 19:22:19 +02:00
Redstone
6263b894ff fix(move_control): remove movement input reset while navigator owns movement (#2442) 2026-07-24 18:29:51 +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
MythicSorcerer
d529a6676a fix(egg): initialize git submodules during install (#2456)
* Fix egg: initialize git submodules during install

The Pumpkin repo uses pumpkin-plugin-wit as a git submodule, but the
install script only does 'git clone --depth 1' without --recurse-submodules.
Add 'git submodule update --init --recursive --depth 1' after checkout
so the WIT files required by bindgen!/wit_bindgen::generate are available.

* Potential fix for pull request finding
2026-07-24 18:16:57 +02:00
Megalith
f676bdd222 fix(protocol): remap particle IDs for older clients (#2451)
* feat(protocol): generate particle ID remap tables

Generate version-specific particle registry mappings from the existing ViaBackwards data for every supported Java protocol version.\n\nExpose the generated remapper through pumpkin-data and enable it for pumpkin-protocol so packet serializers can translate current registry IDs for older clients.

* fix(protocol): remap explosion particles for older clients

Translate the explosion particle registry ID for each client's negotiated Java version before serializing the explode packet.\n\nWithout this remap, 1.21.11 interpreted the 26.2 explosion-emitter ID as falling dust, consumed the following bytes as particle data, and disconnected with a decoder exception. Add packet-level coverage for both 1.21.11 and 26.2 encodings.

* fix(protocol): remap particle IDs for older clients

Level-particle packets and particle entity metadata still encoded raw 26.2 registry IDs, causing older clients to decode the wrong particle schema and disconnect. Route every active outbound particle path through the version remapper, preserve metadata payloads, and cover 1.21.11 and 26.2 encodings with regression tests.
2026-07-24 18:14:18 +02:00
Jamie Little
3ff3eeaf74 perf(world): bulk-build generated chunk palettes (#2492) 2026-07-24 17:02:29 +02:00
dongzh1
b04471e800 fix(command): gate tab-complete suggestions on command permissions (#2312)
`CommandDispatcher::find_suggestions` resolved the command tree and walked
its paths to produce server-side tab-complete suggestions without ever
checking the command's permission, unlike `dispatch`, which gates on
`self.permissions.get(key)` followed by `src.has_permission`.

Many legacy commands (e.g. pardon, deop, whitelist) register their
permission only in `self.permissions` and have no in-tree `Require` node.
Their argument consumers therefore leaked privileged data -- banned, op,
and whitelisted player names -- to unprivileged players through
tab-complete, even though those players could not execute the command.

Add the same permission gate used by `dispatch` after the command key is
resolved and before the tree is traversed: look up `self.permissions` for
the key and return an empty suggestion list if the permission is absent or
if the sender lacks it. This keeps suggestion visibility consistent with
execution authorization.
2026-07-24 16:36:39 +02:00
Alexander Medvedev
a956857209 readme: make vid loop 2026-07-24 12:40:59 +02:00
Alexander Medvedev
3103e97e18 ci: remove macos-15-intel 2026-07-24 12:31:57 +02:00
Alexander Medvedev
afbe839dea fix: https://github.com/Pumpkin-MC/Pumpkin/issues/2424 2026-07-20 11:42:20 +02:00
kedor
f4815f5c78 feat(wit): add enum packet support to wit (#2303)
* implementing the seen advancement packet and handling it

* adding the code generation of enum packet for wit

* typos fix and updating some packet

* adding wit

* ignore private enum

* ignore private enum

* fix packet mapping

* fix duplicate

* update wit

* remove time change
2026-07-20 10:58:28 +02:00
Mcxiaocaibug
5bc4e1bd67 fix(block): melt snow layers under high block light (#2419)
* fix(block): melt snow layers under high block light

Snow layers never melted because the block had no random_tick handler.
Mirror vanilla SnowLayerBlock.randomTick: on a random tick, remove the
layer when the block light level at its position exceeds 11 (e.g. from
a nearby torch).

Fixes #2179

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* style: apply rustfmt
2026-07-20 10:17:40 +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
712bb96d3e feat: Initial advancement triggers 2026-07-17 16:10:43 +02:00
Alexander Medvedev
55219f870f fix: https://github.com/Pumpkin-MC/Pumpkin/issues/2233 2026-07-16 19:56:53 +02:00
Alexander Medvedev
21e7f1418a feat: show credits on exiting end 2026-07-15 20:50:13 +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
Alexander Medvedev
06fa1db1d7 feat(command): add loot command 2026-07-14 18:45:02 +02:00
Alexander Medvedev
bb5ae5ab3c feat(command): add recipe command 2026-07-14 18:28:26 +02:00