Skip to content

Commands supported vs vanilla

Ramjet has a complete Brigadier-compatible command engine: a port of com.mojang.brigadier 1.3.11 and vanilla’s net.minecraft.commands, the full vanilla 26.3 command tree as data (a dedicated server’s tree, vanilla feature set), all 62 argument types, tab-completion suggestions and the Commands packet the client uses for syntax colouring. It is verified against the real vanilla dispatcher with a differential oracle (accept/reject, error messages and cursor positions on tens of thousands of generated lines).

On top of it the gameplay executors are ported command by command from vanilla’s net.minecraft.server.commands.*. A command path that is not yet implemented answers “not implemented yet”. These stubs are tracked exactly: the explorer marks each one in red, and the counts on this page come from the same list.

Pick a command: the tree shows literals, typed arguments, which nodes run, and which executable paths are still stubs (red). Usage lines lists every runnable form. The data is derived from the vanilla command report (data/vanilla/reports/commands.json) and the stub list above, on every build.

1383 of 1424 executable paths of the vanilla tree have a real executor (97%); 41 are still stubs. Select a command to see its tree and which paths are missing.

/give

permission: gamemasters · 2 executable paths · 100% implemented

Loading ...

The notes below record what each area needed when it was planned. For the current status of each command, use the explorer above: its red entries are the stubs.

Estimates are for one engineer who knows the module, tests included.

area commands missing estimate
functions & datapacks /function, /schedule, /return, execute if function, execute run function, the tick / load function tags .mcfunction parser (comments, $ macros with with <source>), function registry from the datapack (data/<ns>/function/), vanilla’s ExecutionContext queue with frames (return, maxCommandChainLength is already enforced by CommandQuota), scheduled functions saved in data/minecraft/scheduled_events.dat, /reload of the datapack registries (loot, recipes, tags, predicates: today they are loaded once at startup) 3 - 4 days (parser + macros 1, execution + return 1, schedule + tags 0.5, reload / datapack list-enable 1 - 1.5)
advancements /advancement (done, T9: advancement/command.cpp, all feedback keys and names checked against AdvancementCommands; tests in advancement_session_test.cpp) (done) the advancement tree, criteria triggers (inventory_changed, location, …) hooked into the game, advancements/<uuid>.json per player, ClientboundUpdateAdvancements, advancement= in selectors, recipe unlocking is separate (crafting module) 4 - 5 days
/forceload implemented (gamecmd/cmd_forceload.cpp, forceload.hpp): forced chunk set per dimension = ChunkProvider::acquire tickets, saved as dimensions/<ns>/<path>/data/minecraft/chunk_tickets.dat (vanilla 26.3 format tickets[{chunk_pos: int[2], type: minecraft:forced, level: 31}], checked against a real vanilla server’s file; the old chunks.dat is gone), all feedback strings checked against vanilla’s output the forced chunks are loaded but not part of the block / random ticking set (LevelRuntime builds it from the players’ chunks only): needs a LevelRuntime::set_forced_chunks hook 0.5 day for the ticking hook
/locate poi done (batch 10 audit A): every POI type and the three POI tags, PoiManager.find_closest_with_type within 256 blocks over the loaded sections nothing none
/ride 2 vehicles / passengers (no riding in the mobs module) 1 day with mobs
/compute and /data modify ... compute: providers conditional, number_dispatcher (int and float) and environment_attribute the providers answer a generic command failure (command.failed); the other 50-odd provider types are ported in compute.cpp the predicate test of a LootItemCondition (loot:: should expose test_condition(id or json, LootContext), the Cond::test of loot/engine.hpp) and the attribute values of a dimension / biome (EnvironmentAttributes) 1 day
/fetchprofile name / id (done, online players only) the Mojang session-server lookup (GameProfileRepository, user cache) for profiles that are not online 0.5 day
/waypoint locator bar (done: waypoints.cpp, see “Waypoints”) mobs as transmitters (LivingEntity with WAYPOINT_TRANSMIT_RANGE), firstTick, the team remake on a team change is a per-tick icon compare 0.5 day
/test 41 the GameTest framework (test instances, structures, batches) 3+ days, probably out of scope
/debug start stop, /jfr, /perf done (batch 15, cmd_profiling.cpp) the JFR recording itself (there is no JVM recorder: /jfr answers vanilla’s failure messages) n/a

Smaller gaps inside the implemented commands:

  • Scoreboard criteria: the self updating ones (health, food, air, armor, xp, level, deathCount, playerKillCount, totalKillCount, teamkill.*, killedByTeam.*, the statistic criteria) are live (StatsService::tick, the death / kill hooks; see docs/agents/advancements-stats.md). Checked in T9: the read-only set (health, food, air, armor, xp, level) matches vanilla’s ObjectiveCriteria readonly flag. Team rules: the collision rule is applied to boats and minecarts (team_can_push), friendly fire to every player damage path, mobs skip allies (mobs::is_allied_entities). The team packets carry the nametag visibility, the collision rule and the color (the client applies them). Still not applied: LivingEntity.pushEntities between living entities (not ported at all), the illager / Vex ally rules.
  • Items: item_input.cpp writes the codec forms of damage / max_damage / max_stack_size / repair_cost / unbreakable / glider / creative_slot_lock / intangible_projectile / rarity / map_id / ominous_bottle_amplifier / base_color / note_block_sound / custom_name / item_name / lore / enchantments / stored_enchantments / dyed_color / custom_data / block_entity_data / fireworks / firework_explosion / potion_contents (potion, custom_color, custom_effects, custom_name); any other component of item[...] is arguments.item.malformed. item_predicate tests existence and damage only; /item modify / modifiers need datapack item_modifier entries (the vanilla datapack has none), inline JSON loot modifiers / tables ({...}) are refused. Slots: enderchest.N, player.cursor (the open menu’s carried stack) and player.crafting.N resolve; horse / donkey / llama inventories have no container in mobs yet (set_open_mount_inventory is never installed). /item replace writes without canPlaceItem like vanilla’s Container.getSlot; /loot insert and Slot.may_place (menus) consult Container.can_place_item.
  • Items: the components listed in docs/agents/item-components.md (“Component values from NBT”) can be written from SNBT, pot_decorations and tooltip_display included (T9); the ones listed there as refused (teleport_randomly, …) cannot. /item modify takes inline loot functions ({type: "minecraft:set_count", ...}, the loot tables’ parser; the vanilla datapack has no item_modifier files) and the slot range / group / empty sources and the transforms limit_slots (the first N slots), filtered (item_filter, the ItemPredicate codec tested by item_codec_matches) and contents (the container or bundle_contents component of each stack, written back into that stack: a write re-reads the components of the chain first, and a bundle slot refuses a stack that is not bundleable or would take the contents past weight 1, as BundleContents.Mutable.setItem; a replace past the stored size of a container does not append like GrowableMutableContainer). A source over 100000 slots on one target is refused. The source is evaluated per target, as vanilla does. execute if|unless items|slots (cmd_slots.cpp count_items_or_slots, declared in gamecmd/slot_sources.hpp) gives the ExecuteCommand counts (summed counts of the matching stacks, or the slot count). No ender chest / cursor / crafting grid / horse inventory slots. Container.canPlaceItem is not consulted (the result slot of a furnace accepts items).
  • Entities: mobs exist in the overworld only (non-player /tp across dimensions answers commands.teleport.invalidPosition); /data merge entity on a player is refused like vanilla, on mobs it goes through MobService::mob_apply_nbt (the keys the mobs module reads); entity_to_nbt for players duplicates Services::save_player (should call it); execute on owner|leasher|vehicle|controller|origin|passengers have no relation to follow (only target and attacker are real).
  • execute store: store result|success bossbar and the data targets work.
  • World border: block entities outside the border do not tick (Level::within_world_border, LevelChunk.isTicking), natural spawning needs the chunk inside (NaturalSpawner::can_spawn_entities_in_chunk). Vanilla has no other ticking limit (Level.isInWorldBounds is the build / placement limit). The damage outside is dealt by WorldBorders::tick (players only, as in vanilla) instead of the living tick.
  • Block entities: signs, banners, skulls, spawners, command blocks, jukeboxes … are blockentity::RawBlockEntity objects (their saved NBT), so /setblock ...{...}, /clone, /data get|merge block work on them; a changed entity is sent to the players (ClientboundBlockEntityData, docs/agents/blockentity.md). Their gameplay is not there.
  • /tick: tick query prints the vanilla percentiles of the engine’s tick metrics; tick sprint is implemented by ecs::TickRateManager.
  • /swing sends the packet to every player of the dimension (the tracker’s queue_packet is private); the server-side swing progress of players is not advanced. /posteffect keeps the list in the PostEffects component, saved as post_effects in the player file and sent at join, respawn and a dimension change (S8; Session::send_post_effects, test gamecmd_slots_test.cpp “posteffect: the shaders are sent again with the respawn”).
  • /place: a feature is generated into a FeatureWorld over the 3x3 chunks around the target (LiveFeatureSession), so whatever reaches beyond them is clipped (bone meal has the same limit). Structures and templates run one session per chunk of their box (batch 12, batch 13). Inline features (/place feature {...}) answer commands.place.feature.failed. Template entities are spawned (batch 13). Structure starts are generated for the chunk of the position without the placement rule (StructureGenerator::generate_start, like Structure.generate). /place jigsaw runs jigsaw_generate_pool (the addPieces of structure_jigsaw.cpp with the target as the anchor jigsaw, MaxDistance 128, no projection) and places the pieces with the position as the reference (place_pieces_in_chunk).
  • /spectate: the checks and messages of SpectateCommand; the camera (snap, resets, tracking) is documented in docs/agents/spectator.md.
  • /waypoint: transmitters are the players (mobs transmit nothing here); the locator bar is in “Waypoints” below.
  • /dialog: the dialog is sent inline (ClientboundShowDialog, registry flag 0) even for a datapack dialog that vanilla sends by id. Datapack dialogs are converted from JSON to the network NBT (json_to_tag: fractional numbers are floats, booleans are bytes).
  • /fetchprofile: name / id resolve against the players that are online (case-insensitive name); no session-server lookup. The copy-as-text link of the head is an empty component (no sprite components in text::Component).
  • /locate biome: DimensionGenerator::find_closest_biome3d replays ServerLevel.findClosestBiome3d (the spiral of BlockPos.spiralAround, Mth.outFromOrigin heights, BiomeFiller::noise_biome_chained). A biome that is not there costs a full scan of the 6400 block square at every sample height.
  • /setidletimeout: the value is stored (GameServer::player_idle_timeout); the idle kick itself is not implemented.

Vanilla commands require a permission level (all, moderators 1, gamemasters 2, admins 3, owners 4), shown per command in the explorer. op-permission-level (default 4) is the level /op grants; operators come from ops.json exactly as in vanilla. Fine-grained per-node permissions for plugins and vanilla commands are part of Plugin API v1 (permissions). The enforce_vanilla_nodes setting in ramjet.toml decides whether the per-node table applies to vanilla commands; by default (warn) the operator level decides and differences are logged.

Plugins add nodes to this same tree (Plugin API v1, see commands): they appear in the client’s command tree, complete on the server and respect permissions. A plugin also sees each command a player runs through PlayerCommandEvent, and can rewrite it.