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.
Explore the vanilla command tree
Section titled “Explore the vanilla command tree”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% implementedLoading ...
What is missing and what it takes
Section titled “What is missing and what it takes”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; seedocs/agents/advancements-stats.md). Checked in T9: the read-only set (health, food, air, armor, xp, level) matches vanilla’sObjectiveCriteriareadonly 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.pushEntitiesbetween living entities (not ported at all), the illager / Vex ally rules. - Items:
item_input.cppwrites 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 ofitem[...]isarguments.item.malformed.item_predicatetests existence anddamageonly;/item modify/ modifiers need datapackitem_modifierentries (the vanilla datapack has none), inline JSON loot modifiers / tables ({...}) are refused. Slots:enderchest.N,player.cursor(the open menu’s carried stack) andplayer.crafting.Nresolve; horse / donkey / llama inventories have no container in mobs yet (set_open_mount_inventoryis never installed)./item replacewrites withoutcanPlaceItemlike vanilla’sContainer.getSlot;/loot insertandSlot.may_place(menus) consultContainer.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 modifytakes inline loot functions ({type: "minecraft:set_count", ...}, the loot tables’ parser; the vanilla datapack has noitem_modifierfiles) and the slot range / group / empty sources and the transformslimit_slots(the first N slots),filtered(item_filter, the ItemPredicate codec tested byitem_codec_matches) andcontents(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, asBundleContents.Mutable.setItem; areplacepast the stored size of a container does not append likeGrowableMutableContainer). 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.cppcount_items_or_slots, declared ingamecmd/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.canPlaceItemis not consulted (the result slot of a furnace accepts items). - Entities: mobs exist in the overworld only (non-player
/tpacross dimensions answerscommands.teleport.invalidPosition);/data merge entityon a player is refused like vanilla, on mobs it goes throughMobService::mob_apply_nbt(the keys the mobs module reads);entity_to_nbtfor players duplicatesServices::save_player(should call it);execute on owner|leasher|vehicle|controller|origin|passengershave no relation to follow (onlytargetandattackerare real). execute store:store result|success bossbarand 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.isInWorldBoundsis the build / placement limit). The damage outside is dealt byWorldBorders::tick(players only, as in vanilla) instead of the living tick. - Block entities: signs, banners, skulls, spawners, command blocks, jukeboxes … are
blockentity::RawBlockEntityobjects (their saved NBT), so/setblock ...{...},/clone,/data get|merge blockwork on them; a changed entity is sent to the players (ClientboundBlockEntityData, docs/agents/blockentity.md). Their gameplay is not there. /tick:tick queryprints the vanilla percentiles of the engine’s tick metrics;tick sprintis implemented byecs::TickRateManager./swingsends the packet to every player of the dimension (the tracker’squeue_packetis private); the server-side swing progress of players is not advanced./posteffectkeeps the list in thePostEffectscomponent, saved aspost_effectsin the player file and sent at join, respawn and a dimension change (S8;Session::send_post_effects, testgamecmd_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 {...}) answercommands.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, likeStructure.generate)./place jigsawrunsjigsaw_generate_pool(the addPieces ofstructure_jigsaw.cppwith thetargetas 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 ofSpectateCommand; 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 intext::Component)./locate biome:DimensionGenerator::find_closest_biome3dreplaysServerLevel.findClosestBiome3d(the spiral ofBlockPos.spiralAround,Mth.outFromOriginheights,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.
Operators and permission levels
Section titled “Operators and permission levels”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.
Plugin commands
Section titled “Plugin commands”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.