diff --git a/v0.1/advancement.wit b/v0.1/advancement.wit new file mode 100644 index 0000000..f298593 --- /dev/null +++ b/v0.1/advancement.wit @@ -0,0 +1,41 @@ +package pumpkin:plugin@0.1.0; + +interface advancement { + use text.{text-component}; + + /// Frame type for an advancement. + enum frame-type { + task, + challenge, + goal, + } + + /// Display information for an advancement. + record advancement-display { + title: text-component, + description: text-component, + frame: frame-type, + show-toast: bool, + hidden: bool, + announce-to-chat: bool, + background: option, + x: f32, + y: f32, + } + + /// Detailed information about an advancement. + record advancement-info { + id: string, + parent-id: option, + criteria: list, + display: option, + } + + /// Represents progress of an advancement for a player. + record advancement-progress { + advancement-id: string, + done: bool, + awarded-criteria: list, + remaining-criteria: list, + } +} diff --git a/v0.1/block-entity.wit b/v0.1/block-entity.wit index b626005..583ab3f 100644 --- a/v0.1/block-entity.wit +++ b/v0.1/block-entity.wit @@ -1,5 +1,5 @@ interface block-entity { - use common.{block-pos}; + use common.{block-pos, nbt-tree}; use item-stack.{item-stack}; resource block-entity { @@ -8,6 +8,15 @@ interface block-entity { get-id: func() -> u32; is-dirty: func() -> bool; clear-dirty: func(); + + /// Sets a namespaced custom data value on this block entity. + set-custom-data: func(namespace: string, key: string, value: nbt-tree); + /// Returns a namespaced custom data value from this block entity, if set. + get-custom-data: func(namespace: string, key: string) -> option; + /// Removes a namespaced custom data value from this block entity. + remove-custom-data: func(namespace: string, key: string); + /// Returns whether this block entity has a namespaced custom data value. + has-custom-data: func(namespace: string, key: string) -> bool; } resource container-block-entity { diff --git a/v0.1/common.wit b/v0.1/common.wit index 282a219..f76aec1 100644 --- a/v0.1/common.wit +++ b/v0.1/common.wit @@ -4,6 +4,34 @@ interface common { /// @deprecated Use the text-component resource from the text interface instead. type raw-text-component = list; + /// Represents one entry in an NBT compound tag. + record nbt-entry { + key: string, + value: u32, + } + + /// Represents a Minecraft NBT tag tree. + record nbt-tree { + root: u32, + tags: list, + } + + /// Represents a Minecraft NBT tag. + variant nbt-tag { + byte(s8), + short(s16), + int(s32), + long(s64), + float(f32), + double(f64), + byte-array(list), + string-tag(string), + list-tag(list), + compound(list), + int-array(list), + long-array(list), + } + /// A position in the world grid (integers). record block-pos { x: s32, diff --git a/v0.1/damage-types.wit b/v0.1/damage-types.wit new file mode 100644 index 0000000..7acebb9 --- /dev/null +++ b/v0.1/damage-types.wit @@ -0,0 +1,57 @@ +package pumpkin:plugin@0.1.0; + +interface damage-types { + enum damage-type { + arrow, + bad-respawn-point, + cactus, + campfire, + cramming, + dragon-breath, + drown, + dry-out, + ender-pearl, + explosion, + fall, + falling-anvil, + falling-block, + falling-stalactite, + fireball, + fireworks, + fly-into-wall, + freeze, + generic, + generic-kill, + hot-floor, + in-fire, + in-wall, + indirect-magic, + lava, + lightning-bolt, + mace-smash, + magic, + mob-attack, + mob-attack-no-aggro, + mob-projectile, + on-fire, + out-of-world, + outside-border, + player-attack, + player-explosion, + sonic-boom, + spear, + spit, + stalagmite, + starve, + sting, + sulfur-cube-hot, + sweet-berry-bush, + thorns, + thrown, + trident, + unattributed-fireball, + wind-charge, + wither, + wither-skull, + } +} diff --git a/v0.1/display.wit b/v0.1/display.wit new file mode 100644 index 0000000..db5db52 --- /dev/null +++ b/v0.1/display.wit @@ -0,0 +1,171 @@ +interface display { + use %world.{entity}; + use text.{text-component}; + use item-stack.{item-stack}; + use uuid.{uuid}; + + /// Billboard rendering constraints for display entities. + enum billboard-mode { + fixed, + vertical, + horizontal, + center, + } + + /// Item display transformation modes for item display entities. + enum item-display-mode { + none, + thirdperson-lefthand, + thirdperson-righthand, + firstperson-lefthand, + firstperson-righthand, + head, + gui, + ground, + fixed, + } + + /// Text alignment options for text display entities. + enum text-alignment { + center, + left, + right, + } + + /// 3D single-precision vector. + record vector3f { + x: f32, + y: f32, + z: f32, + } + + /// Single-precision quaternion representing a 3D rotation. + record quaternionf { + x: f32, + y: f32, + z: f32, + w: f32, + } + + /// Transformation (translation, scale, left and right rotations) for display entities. + record display-transformation { + translation: vector3f, + scale: vector3f, + left-rotation: quaternionf, + right-rotation: quaternionf, + } + + /// Common base resource for all display entities. + resource display-entity { + from-entity: static func(entity: borrow) -> option; + get-entity: func() -> entity; + + get-transformation: func() -> display-transformation; + set-transformation: func(transformation: display-transformation); + + get-interpolation-duration: func() -> s32; + set-interpolation-duration: func(duration: s32); + + get-interpolation-start: func() -> s32; + set-interpolation-start: func(delta-ticks: s32); + + get-teleport-duration: func() -> s32; + set-teleport-duration: func(duration: s32); + + get-billboard: func() -> billboard-mode; + set-billboard: func(mode: billboard-mode); + + get-view-range: func() -> f32; + set-view-range: func(range: f32); + + get-shadow-radius: func() -> f32; + set-shadow-radius: func(radius: f32); + + get-shadow-strength: func() -> f32; + set-shadow-strength: func(strength: f32); + + get-display-width: func() -> f32; + set-display-width: func(width: f32); + + get-display-height: func() -> f32; + set-display-height: func(height: f32); + + get-glow-color-override: func() -> s32; + set-glow-color-override: func(color: s32); + + get-brightness: func() -> s32; + set-brightness: func(brightness: s32); + } + + /// Resource specifically for Block Display entities. + resource block-display-entity { + from-entity: static func(entity: borrow) -> option; + get-display: func() -> display-entity; + get-entity: func() -> entity; + + get-block-state-id: func() -> u16; + set-block-state-id: func(state-id: u16); + } + + /// Resource specifically for Item Display entities. + resource item-display-entity { + from-entity: static func(entity: borrow) -> option; + get-display: func() -> display-entity; + get-entity: func() -> entity; + + get-item: func() -> option; + set-item: func(item: option); + + get-item-display-mode: func() -> item-display-mode; + set-item-display-mode: func(mode: item-display-mode); + } + + /// Resource specifically for Text Display entities. + resource text-display-entity { + from-entity: static func(entity: borrow) -> option; + get-display: func() -> display-entity; + get-entity: func() -> entity; + + get-text: func() -> text-component; + set-text: func(text: text-component); + + get-line-width: func() -> s32; + set-line-width: func(width: s32); + + get-background: func() -> s32; + set-background: func(color: s32); + + get-text-opacity: func() -> s8; + set-text-opacity: func(opacity: s8); + + get-shadow: func() -> bool; + set-shadow: func(shadow: bool); + + get-see-through: func() -> bool; + set-see-through: func(see-through: bool); + + get-default-background: func() -> bool; + set-default-background: func(default-background: bool); + + get-alignment: func() -> text-alignment; + set-alignment: func(alignment: text-alignment); + } + + /// Resource specifically for Interaction entities. + resource interaction-entity { + from-entity: static func(entity: borrow) -> option; + get-entity: func() -> entity; + + get-width: func() -> f32; + set-width: func(width: f32); + + get-height: func() -> f32; + set-height: func(height: f32); + + get-response: func() -> bool; + set-response: func(response: bool); + + get-last-attacker: func() -> option; + get-last-interaction: func() -> option; + } +} diff --git a/v0.1/enchantments.wit b/v0.1/enchantments.wit index 21ab4c9..51d602e 100644 --- a/v0.1/enchantments.wit +++ b/v0.1/enchantments.wit @@ -1,6 +1,24 @@ package pumpkin:plugin@0.1.0; interface enchantments { + use text.{text-component}; + + /// Equipment slot where an enchantment is active. + enum attribute-modifier-slot { + any, + main-hand, + off-hand, + hand, + feet, + legs, + chest, + head, + armor, + body, + saddle, + } + + /// Vanilla enchantments enum. enum enchantment { aqua-affinity, bane-of-arthropods, @@ -46,4 +64,39 @@ interface enchantments { vanishing-curse, wind-burst, } + + /// Represents a custom enchantment definition. + record custom-enchantment { + /// Unique identifier for the enchantment (e.g. "my_plugin:lifesteal"). + id: string, + /// Description or display name of the enchantment. + description: text-component, + /// Maximum level of the enchantment (e.g. 1..=10). + max-level: u32, + /// Base anvil repair/combination cost multiplier. + anvil-cost: u32, + /// Tag or item pattern for supported items (e.g. "#minecraft:enchantable/weapon"). + supported-items: string, + /// Weight / rarity of the enchantment (higher = more common, default 5). + weight: u32, + /// Equipment slots where this enchantment is active. + slots: list, + /// List of exclusive/conflicting enchantment IDs. + exclusive-set: list, + } + + /// Global manager for registering and querying custom enchantments. + resource enchantment-manager { + /// Registers a new custom enchantment with the server. + register-enchantment: func(enchantment: custom-enchantment) -> result<_, string>; + + /// Gets an enchantment definition by its ID. + get-enchantment: func(id: string) -> option; + + /// Checks if an enchantment ID is registered. + has-enchantment: func(id: string) -> bool; + + /// Returns all registered custom enchantment IDs. + get-all-enchantment-ids: func() -> list; + } } diff --git a/v0.1/event.wit b/v0.1/event.wit index 8fc36dc..3dd3e3c 100644 --- a/v0.1/event.wit +++ b/v0.1/event.wit @@ -2,6 +2,8 @@ interface event { use common.{block-pos, game-mode, hand, position, click-type}; use item-stack.{item-stack}; use enchantments.{enchantment}; + use damage-types.{damage-type}; + use screens.{screen}; use player.{player}; use text.{text-component}; use %world.{%world}; @@ -208,7 +210,7 @@ interface event { record inventory-click-event-data { player: player, - window-type: option, + window-type: option, click-type: click-type, slot: s16, raw-slot: s16, @@ -220,7 +222,7 @@ interface event { record inventory-close-event-data { player: player, - window-type: option + window-type: option } record block-redstone-event-data { @@ -387,7 +389,7 @@ interface event { record entity-damage-event-data { entity-id: s32, damage: f32, - cause: string, + damage-type: damage-type, cancelled: bool } diff --git a/v0.1/game-rules.wit b/v0.1/game-rules.wit new file mode 100644 index 0000000..0ac2b9d --- /dev/null +++ b/v0.1/game-rules.wit @@ -0,0 +1,69 @@ +package pumpkin:plugin@0.1.0; + +interface game-rules { + enum game-rule { + advance-time, + advance-weather, + allow-entering-nether-using-portals, + block-drops, + block-explosion-drop-decay, + command-block-output, + command-blocks-work, + drowning-damage, + elytra-movement-check, + ender-pearls-vanish-on-death, + entity-drops, + fall-damage, + fire-damage, + fire-spread-radius-around-player, + forgive-dead-players, + freeze-damage, + global-sound-events, + immediate-respawn, + keep-inventory, + lava-source-conversion, + limited-crafting, + locator-bar, + log-admin-commands, + max-block-modifications, + max-command-forks, + max-command-sequence-length, + max-entity-cramming, + max-minecart-speed, + max-snow-accumulation-height, + mob-drops, + mob-explosion-drop-decay, + mob-griefing, + natural-health-regeneration, + player-movement-check, + players-nether-portal-creative-delay, + players-nether-portal-default-delay, + players-sleeping-percentage, + projectiles-can-break-blocks, + pvp, + raids, + random-tick-speed, + reduced-debug-info, + respawn-radius, + send-command-feedback, + show-advancement-messages, + show-death-messages, + spawn-mobs, + spawn-monsters, + spawn-patrols, + spawn-phantoms, + spawn-wandering-traders, + spawn-wardens, + spawner-blocks-work, + spectators-generate-chunks, + spread-vines, + tnt-explodes, + tnt-explosion-drop-decay, + universal-anger, + water-source-conversion, + } + variant game-rule-value { + int(s32), + %bool(bool), + } +} diff --git a/v0.1/gui.wit b/v0.1/gui.wit index 7e3cc4d..d82a4d7 100644 --- a/v0.1/gui.wit +++ b/v0.1/gui.wit @@ -2,42 +2,15 @@ interface gui { use text.{text-component}; use common.{click-type}; use item-stack.{item-stack}; - - enum gui-type { - generic-9x1, - generic-9x2, - generic-9x3, - generic-9x4, - generic-9x5, - generic-9x6, - generic-3x3, - crafter-3x3, - anvil, - beacon, - blast-furnace, - brewing-stand, - crafting, - enchantment, - furnace, - grindstone, - hopper, - lectern, - loom, - merchant, - shulker-box, - smithing, - smoker, - cartography-table, - stonecutter, - } + use screens.{screen}; resource gui { - constructor(%type: gui-type, title: text-component); + constructor(%type: screen, title: text-component); set-item: func(slot: u32, item: item-stack); get-item: func(slot: u32) -> option; /// Returns the type of this GUI. - get-type: func() -> gui-type; + get-type: func() -> screen; /// Returns the title of this GUI. get-title: func() -> text-component; diff --git a/v0.1/item-stack.wit b/v0.1/item-stack.wit index b89704f..a806cfb 100644 --- a/v0.1/item-stack.wit +++ b/v0.1/item-stack.wit @@ -9,6 +9,12 @@ interface item-stack { level: u32, } + /// Represents a custom enchantment and its level on an item stack. + record custom-enchantment-value { + enchantment-id: string, + level: u32, + } + /// Represents a data component and its serialized value. record data-component-value { component: data-component, @@ -16,33 +22,7 @@ interface item-stack { value: list, } - /// Represents one entry in an NBT compound tag. - record nbt-entry { - key: string, - value: u32, - } - - /// Represents a Minecraft NBT tag tree. - record nbt-tree { - root: u32, - tags: list, - } - - /// Represents a Minecraft NBT tag. - variant nbt-tag { - byte(s8), - short(s16), - int(s32), - long(s64), - float(f32), - double(f64), - byte-array(list), - string-tag(string), - list-tag(list), - compound(list), - int-array(list), - long-array(list), - } + use common.{nbt-entry, nbt-tree, nbt-tag}; resource item-stack { constructor(registry-key: string, count: u8); @@ -65,6 +45,17 @@ interface item-stack { /// Removes an enchantment from this item stack. remove-enchantment: func(enchantment: enchantment); + /// Returns all custom enchantments on this item stack. + get-custom-enchantments: func() -> list; + /// Adds a custom enchantment to this item stack. + add-custom-enchantment: func(enchantment-id: string, level: u32); + /// Removes a custom enchantment from this item stack. + remove-custom-enchantment: func(enchantment-id: string); + /// Returns the level of a custom enchantment on this item stack, if present. + get-custom-enchantment-level: func(enchantment-id: string) -> option; + /// Returns whether this item stack has a specific custom enchantment. + has-custom-enchantment: func(enchantment-id: string) -> bool; + /// Returns the lore of this item stack. get-lore: func() -> list; /// Sets the lore of this item stack. diff --git a/v0.1/player.wit b/v0.1/player.wit index 18ad39e..238ee00 100644 --- a/v0.1/player.wit +++ b/v0.1/player.wit @@ -13,6 +13,9 @@ interface player { use uuid.{uuid}; use status-effect.{status-effect-type, status-effect-instance}; use scoreboard.{scoreboard, bedrock-scoreboard}; + use advancement.{advancement-progress}; + use damage-types.{damage-type}; + use statistics.{statistic-category, custom-statistic}; /// Represents per-player weather condition overrides. enum player-weather { @@ -895,11 +898,33 @@ interface player { /// Heals the player by a specified amount. heal: func(amount: f32); - /// Deals damage to the player by a specified amount. - damage: func(amount: f32); + /// Deals damage to the player by a specified amount with a damage type. + damage: func(amount: f32, damage-type: damage-type); /// Kills the player instantly. kill: func(); + // Statistics + + /// Gets the value of a statistic for this player in the given category and ID. + get-statistic: func(category: statistic-category, stat-id: s32) -> s32; + /// Sets the value of a statistic for this player in the given category and ID. + set-statistic: func(category: statistic-category, stat-id: s32, value: s32); + /// Increments the value of a statistic for this player in the given category and ID. + increment-statistic: func(category: statistic-category, stat-id: s32, amount: s32); + + /// Gets the value of a custom statistic for this player. + get-custom-statistic: func(stat: custom-statistic) -> s32; + /// Sets the value of a custom statistic for this player. + set-custom-statistic: func(stat: custom-statistic, value: s32); + /// Increments the value of a custom statistic for this player. + increment-custom-statistic: func(stat: custom-statistic, amount: s32); + + /// Sends the player's updated statistics packet to the client. + send-stats: func(); + + /// Gets the team name that this player belongs to on their active scoreboard, if any. + get-team: func() -> option; + // Cooldowns /// Starts an item cooldown for a specific item group name. @@ -934,6 +959,17 @@ interface player { /// Sets the item in the specified inventory slot. set-inventory-item: func (slot: u8, stack: option); + // Ender Chest Inventory + + /// Returns the item in the specified ender chest slot (0-26). + get-ender-chest-item: func (slot: u8) -> option; + /// Sets the item in the specified ender chest slot (0-26). + set-ender-chest-item: func (slot: u8, stack: option); + /// Clears all items from the player's ender chest. + clear-ender-chest: func (); + /// Opens the player's ender chest inventory screen for them. + open-ender-chest: func (); + // Status /// Returns the player's current health. @@ -1055,6 +1091,39 @@ interface player { /// Launches a projectile from the player's eyes in their line of sight. launch-projectile: func(%type: projectile-type) -> option; + // Advancements + + /// Returns the progress of the specified advancement for this player, if the advancement exists. + get-advancement-progress: func(advancement-id: string) -> option; + + /// Awards a specific criterion of an advancement to the player. + /// Returns true if the criterion was successfully awarded (was not already completed). + award-advancement-criterion: func(advancement-id: string, criterion: string) -> bool; + + /// Revokes a specific criterion of an advancement from the player. + /// Returns true if the criterion was successfully revoked (was previously completed). + revoke-advancement-criterion: func(advancement-id: string, criterion: string) -> bool; + + /// Awards all criteria of the specified advancement to the player. + /// Returns true if any criterion was newly awarded. + award-advancement: func(advancement-id: string) -> bool; + + /// Revokes all criteria of the specified advancement from the player. + /// Returns true if any criterion was newly revoked. + revoke-advancement: func(advancement-id: string) -> bool; + + /// Checks whether the player has completed the specified advancement. + has-advancement: func(advancement-id: string) -> bool; + + /// Returns a list of all advancement IDs completed by this player. + get-completed-advancements: func() -> list; + + /// Returns the ID of the currently selected advancement tab for this player, if any. + get-selected-advancement-tab: func() -> option; + + /// Sets the selected advancement tab for this player (must be a root advancement ID). + set-selected-advancement-tab: func(tab-id: option); + /// Returns a Java-specific player handle, if the player is connected via Java Edition. /// /// This allows access to Java-exclusive features like sending specific packets diff --git a/v0.1/plugin.wit b/v0.1/plugin.wit index 194e527..e59b53e 100644 --- a/v0.1/plugin.wit +++ b/v0.1/plugin.wit @@ -8,7 +8,7 @@ world plugin { use event.{event}; use server.{server as server-instance}; use command.{command-sender, consumed-args, command-error}; - use %world.{entity}; + use %world.{entity, chunk-buffer, generation-phase}; use ipc.{plugin-id, ipc-message}; // --- Host-provided imports --- @@ -51,6 +51,22 @@ world plugin { import attributes; /// Provides player management. import player; + /// Provides advancement definitions and progress types. + import advancement; + /// Provides custom recipe registration and management. + import recipe; + /// Provides custom enchantment registration and management. + import enchantments; + /// Provides damage types. + import damage-types; + /// Provides screen / window types for GUIs and containers. + import screens; + /// Provides player statistics categories and types. + import statistics; + /// Provides Display and Interaction entities. + import display; + /// Provides game rules definitions and queries. + import game-rules; // --- Plugin-provided exports --- @@ -86,4 +102,7 @@ world plugin { export handle-ai-goal-start: func(goal-id: u32, server: server-instance, entity: entity); export handle-ai-goal-tick: func(goal-id: u32, server: server-instance, entity: entity); export handle-ai-goal-stop: func(goal-id: u32, server: server-instance, entity: entity); + + /// Dispatches a chunk generation phase to the plugin. + export handle-generate-phase: func(generator-id: u32, phase: generation-phase, chunk: chunk-buffer); } diff --git a/v0.1/recipe.wit b/v0.1/recipe.wit index 8cbe61e..960b889 100644 --- a/v0.1/recipe.wit +++ b/v0.1/recipe.wit @@ -1,12 +1,24 @@ interface recipe { use item-stack.{item-stack}; + /// Recipe category for the recipe book. + enum recipe-category { + building, + redstone, + equipment, + misc, + food, + blocks, + } + /// Represents an ingredient in a recipe. variant ingredient { - /// A specific item. + /// A specific item (e.g. "minecraft:diamond"). item(string), /// A tag group of items (e.g., "minecraft:logs"). tag(string), + /// One of multiple specific items. + one-of(list), } /// Represents a shaped crafting recipe. @@ -19,6 +31,10 @@ interface recipe { output: item-stack, /// The recipe group (optional). group: option, + /// The recipe category in the recipe book. + category: option, + /// Whether to show a toast notification when the recipe is unlocked. + show-notification: option, } /// Represents a shapeless crafting recipe. @@ -29,6 +45,8 @@ interface recipe { output: item-stack, /// The recipe group (optional). group: option, + /// The recipe category in the recipe book. + category: option, } /// Represents a cooking recipe (Smelting, Blasting, Smoking, Campfire). @@ -43,6 +61,8 @@ interface recipe { cooking-time: u32, /// The recipe group (optional). group: option, + /// The recipe category in the recipe book. + category: option, } /// Types of cooking stations. @@ -65,3 +85,4 @@ interface recipe { register-cooking: func(id: string, station-type: cooking-type, recipe: cooking-recipe); } } + diff --git a/v0.1/scoreboard.wit b/v0.1/scoreboard.wit index 7cba1b0..48c954a 100644 --- a/v0.1/scoreboard.wit +++ b/v0.1/scoreboard.wit @@ -73,6 +73,11 @@ interface scoreboard { add-player-to-team: func(team-name: string, player-name: string); remove-player-from-team: func(team-name: string, player-name: string); clear-team-players: func(team-name: string); + + get-teams: func() -> list; + get-team: func(name: string) -> option; + get-team-players: func(team-name: string) -> list; + get-player-team: func(player-name: string) -> option; } enum bedrock-sort-order { diff --git a/v0.1/screens.wit b/v0.1/screens.wit new file mode 100644 index 0000000..5369ee0 --- /dev/null +++ b/v0.1/screens.wit @@ -0,0 +1,31 @@ +package pumpkin:plugin@0.1.0; + +interface screens { + enum screen { + generic-9x1, + generic-9x2, + generic-9x3, + generic-9x4, + generic-9x5, + generic-9x6, + generic-3x3, + crafter-3x3, + anvil, + beacon, + blast-furnace, + brewing-stand, + crafting, + enchantment, + furnace, + grindstone, + hopper, + lectern, + loom, + merchant, + shulker-box, + smithing, + smoker, + cartography-table, + stonecutter, + } +} diff --git a/v0.1/server.wit b/v0.1/server.wit index a44408c..d4f9a7d 100644 --- a/v0.1/server.wit +++ b/v0.1/server.wit @@ -5,7 +5,9 @@ interface server { use text.{text-component}; use uuid.{uuid}; use recipe.{recipe-manager}; + use enchantments.{enchantment-manager, custom-enchantment}; use permission.{permission-level}; + use advancement.{advancement-info}; /// Represents an operator entry in the ops configuration. record op-entry { @@ -180,15 +182,31 @@ interface server { /// Returns a list of all worlds on this server. get-all-worlds: func() -> list<%world>; - /// Gets a world by its dimension name (e.g., "minecraft:overworld"). + /// Gets a world by its dimension name (e.g., "minecraft:overworld") or custom world name (e.g., "world", "arena_1"). get-world-by-name: func(name: string) -> option<%world>; + /// Checks if a world exists by name or dimension. + has-world: func(name: string) -> bool; + execute-command: func(command: string, sender: command-sender); /// Creates or loads a world by its name and dimension. /// If a world with the given name already exists, it will be returned. create-world: func(name: string, dimension: dimension) -> %world; + /// Unloads and saves a world by its name or dimension. + /// Returns an error if the world cannot be found, is the primary/default world, or still has players inside. + unload-world: func(name: string) -> result<_, string>; + + /// Saves all players, player advancements, and loaded worlds to disk. + save-all: func() -> result<_, string>; + + /// Returns a list of all online players in a specific world. + get-players-in-world: func(world-ref: %world) -> list; + + /// Returns the number of online players in a specific world. + get-player-count-in-world: func(world-ref: %world) -> u32; + /// Broadcasts a system chat message to all players. broadcast: func(message: string); @@ -236,5 +254,20 @@ interface server { /// Returns the global whitelist manager for querying and modifying the server whitelist. get-whitelist-manager: func() -> whitelist-manager; + + /// Returns detailed information about an advancement by its ID (e.g., "minecraft:story/mine_stone" or "story/mine_stone"). + get-advancement: func(id: string) -> option; + + /// Returns a list of all registered advancement IDs on the server. + get-all-advancement-ids: func() -> list; + + /// Returns the global enchantment manager for registering and querying custom enchantments. + get-enchantment-manager: func() -> enchantment-manager; + + /// Returns information about an enchantment by its ID (vanilla or custom). + get-enchantment: func(id: string) -> option; + + /// Returns a list of all registered enchantment IDs (custom and vanilla) on the server. + get-all-enchantment-ids: func() -> list; } } diff --git a/v0.1/statistics.wit b/v0.1/statistics.wit new file mode 100644 index 0000000..07222d5 --- /dev/null +++ b/v0.1/statistics.wit @@ -0,0 +1,94 @@ +package pumpkin:plugin@0.1.0; + +interface statistics { + enum statistic-category { + mined, + crafted, + used, + broken, + picked-up, + dropped, + killed, + killed-by, + custom, + } + enum custom-statistic { + leave-game, + play-time, + total-world-time, + time-since-death, + time-since-rest, + sneak-time, + walk-one-cm, + crouch-one-cm, + sprint-one-cm, + walk-on-water-one-cm, + fall-one-cm, + climb-one-cm, + fly-one-cm, + walk-under-water-one-cm, + minecart-one-cm, + boat-one-cm, + pig-one-cm, + happy-ghast-one-cm, + horse-one-cm, + aviate-one-cm, + swim-one-cm, + strider-one-cm, + nautilus-one-cm, + jump, + drop, + damage-dealt, + damage-dealt-absorbed, + damage-dealt-resisted, + damage-taken, + damage-blocked-by-shield, + damage-absorbed, + damage-resisted, + deaths, + mob-kills, + animals-bred, + player-kills, + fish-caught, + talked-to-villager, + traded-with-villager, + eat-cake-slice, + fill-cauldron, + use-cauldron, + clean-armor, + clean-banner, + clean-shulker-box, + interact-with-brewingstand, + interact-with-beacon, + inspect-dropper, + inspect-hopper, + inspect-dispenser, + play-noteblock, + tune-noteblock, + pot-flower, + trigger-trapped-chest, + open-enderchest, + enchant-item, + play-record, + interact-with-furnace, + interact-with-crafting-table, + open-chest, + sleep-in-bed, + open-shulker-box, + open-barrel, + interact-with-blast-furnace, + interact-with-smoker, + interact-with-lectern, + interact-with-campfire, + interact-with-cartography-table, + interact-with-loom, + interact-with-stonecutter, + bell-ring, + raid-trigger, + raid-win, + interact-with-anvil, + interact-with-grindstone, + target-hit, + interact-with-smithing-table, + } +} diff --git a/v0.1/world.wit b/v0.1/world.wit index 7682ffd..e1668d6 100644 --- a/v0.1/world.wit +++ b/v0.1/world.wit @@ -1,5 +1,5 @@ interface %world { - use common.{position, entity-pose, block-pos}; + use common.{position, entity-pose, block-pos, nbt-tree}; use block-entity.{block-entity, command-block-entity, block-entity-type}; use text.{text-component}; use scoreboard.{scoreboard}; @@ -9,6 +9,8 @@ interface %world { use biomes.{biome}; use attributes.{attribute, modifier-operation, attribute-modifier}; use item-stack.{item-stack}; + use damage-types.{damage-type}; + use game-rules.{game-rule, game-rule-value}; use uuid.{uuid}; @@ -232,7 +234,7 @@ interface %world { get-health: func() -> f32; set-health: func(health: f32); get-max-health: func() -> f32; - damage: func(amount: f32); + damage: func(amount: f32, damage-type: damage-type); is-dead: func() -> bool; get-absorption: func() -> f32; @@ -355,6 +357,15 @@ interface %world { /// Performs a raycast from the entity's eye position in its looking direction. raycast: func(max-distance: f64, fluid-handling: bool) -> option; + + /// Sets a namespaced custom data value on this entity. + set-custom-data: func(namespace: string, key: string, value: nbt-tree); + /// Returns a namespaced custom data value from this entity, if set. + get-custom-data: func(namespace: string, key: string) -> option; + /// Removes a namespaced custom data value from this entity. + remove-custom-data: func(namespace: string, key: string); + /// Returns whether this entity has a namespaced custom data value. + has-custom-data: func(namespace: string, key: string) -> bool; } /// Result of a raycast operation. @@ -403,6 +414,15 @@ interface %world { /// Gets the block light level at the specified position relative to the chunk. /// X and Z must be in the range [0, 15]. get-block-light: func(pos: block-pos) -> u8; + + /// Sets a namespaced custom data value on this chunk. + set-custom-data: func(namespace: string, key: string, value: nbt-tree); + /// Returns a namespaced custom data value from this chunk, if set. + get-custom-data: func(namespace: string, key: string) -> option; + /// Removes a namespaced custom data value from this chunk. + remove-custom-data: func(namespace: string, key: string); + /// Returns whether this chunk has a namespaced custom data value. + has-custom-data: func(namespace: string, key: string) -> bool; } /// Represents the boundaries of a world. @@ -556,6 +576,66 @@ interface %world { /// Restores a block entity from raw NBT bytes at the given position. /// The NBT must contain a valid "id" field (e.g. "minecraft:chest"). set-block-entity-nbt: func(pos: block-pos, nbt-data: list) -> result<_, string>; + + /// Returns the name of this world (e.g. "world", "world_nether", "arena_1"). + get-name: func() -> string; + + /// Saves all chunk data, block entities, and entities for this world to disk. + save: func() -> result<_, string>; + + /// Sets a custom chunk generator for this world using a registered generator ID. + set-chunk-generator: func(generator-id: u32); + + /// Sets a namespaced custom data value on this world. + set-custom-data: func(namespace: string, key: string, value: nbt-tree); + /// Returns a namespaced custom data value from this world, if set. + get-custom-data: func(namespace: string, key: string) -> option; + /// Removes a namespaced custom data value from this world. + remove-custom-data: func(namespace: string, key: string); + /// Returns whether this world has a namespaced custom data value. + has-custom-data: func(namespace: string, key: string) -> bool; + + /// Gets the value of a game rule in this world. + get-game-rule: func(rule: game-rule) -> game-rule-value; + /// Sets the value of a game rule in this world. + set-game-rule: func(rule: game-rule, value: game-rule-value); + } + + /// Generation phase for custom chunk generation. + enum generation-phase { + biomes, + noise, + surface, + features, + } + + /// Mutable chunk buffer representing a 16x16 column during custom world generation. + resource chunk-buffer { + /// Returns the chunk X coordinate. + get-x: func() -> s32; + /// Returns the chunk Z coordinate. + get-z: func() -> s32; + /// Returns the minimum Y coordinate for this world. + get-min-y: func() -> s32; + /// Returns the height of the chunk in blocks. + get-height: func() -> u32; + + /// Sets the block state ID at local coordinates (0..16, y, 0..16). + set-block-state-id: func(x: u8, y: s32, z: u8, state-id: u16); + /// Gets the block state ID at local coordinates (0..16, y, 0..16). + get-block-state-id: func(x: u8, y: s32, z: u8) -> u16; + + /// Fills an entire horizontal 16x16 layer at the given Y level with a block state ID. + fill-layer: func(y: s32, state-id: u16); + /// Fills a vertical column from min-y to max-y at local (x, z) with a block state ID. + fill-range: func(x: u8, min-y: s32, max-y: s32, z: u8, state-id: u16); + /// Fills a 3D cuboid with a block state ID. + fill-cuboid: func(min-x: u8, min-y: s32, min-z: u8, max-x: u8, max-y: s32, max-z: u8, state-id: u16); + + /// Sets the biome at local coordinates (0..16, y, 0..16). + set-biome: func(x: u8, y: s32, z: u8, biome: biome); + /// Fills the entire chunk with the given biome. + fill-biome: func(biome: biome); } /// Resolves a block name and optional properties to a block state ID.