Description

Nomad Physics adds rigid-body physics to Hytale props. Drop a crate, knock over a stack of bricks, or grab something with the physgun and throw it across the room. Props fall, roll and collide with the world, with ode4j running the simulation on the server. Players don't need a separate client mod.
The core includes the physgun, gravity gun, a wooden crate and bricks in eight colours. Other plugins can use the same physics through PhysicsApi, including content packs such as bowling.
Try it on Nomad Arcade
Test out the physics system on the Nomad Arcade server. Join at arcade.nomad-labs.co:5521.
Getting started on your server

Install NomadPhysics.jar in your server's mods folder and restart the server. The jar includes its assets. Start in an open area and run these commands as a server operator:
/physics tool physgun
/physics tool gravgun
/physics demo crates
The tools have no crafting recipes. Give one to another player with /physics tool physgun --player=PlayerName or /physics tool gravgun --player=PlayerName. The recipient must be in the same world as the command.
Using the tools

These are the default mouse and Use-key bindings. If you've rebound your controls, use the corresponding Primary, Secondary or Use action.
Physgun
Use the physgun for placing and arranging props. It can carry heavy objects without the gravity gun's mass limit.
| Control | Action |
|---|---|
| Hold left click | Grab the prop under your crosshair and carry it where you aim. |
| Release left click | Let go of the prop. |
| Right click while carrying | Freeze the prop in place. |
| Right click a frozen prop while carrying nothing | Unfreeze it. Grabbing it with left click also unfreezes it. |
| F while carrying | Enter rotate mode, then look around to turn the prop. Press F again to resume carrying. |
| Crouch and look up or down while carrying | Adjust how far away you hold the prop. |
Gravity gun
Use the gravity gun to pull things close or launch them away.
| Control | Action |
|---|---|
| Right click a prop | Pull it toward you and hold it in front of you. |
| Right click again | Drop the held prop, or cancel a pull in progress. |
| Left click | Punt the prop you're holding or aiming at. |
The gravity gun has a shorter reach and a carry mass limit. An ordinary prop that's too heavy to lift can still receive a weaker shove. Creature and registered-owner targets are exempt from that carry mass check.
Block mode
With either gun equipped and nothing held, press F to toggle block mode. The HUD tells you whether it's on. In block mode, the gun can pull allowed blocks out of the world and move them as loose props. They snap back into the block grid when they settle; if no suitable space is available, they drop as an item.
Block pickup needs the tool's permission and nomadphysics.blocks. The server's Blocks.AllowTags and Blocks.DenyIds settings decide which block types can be picked up. Denied IDs take priority over allowed tags.
What works with physics?
| Object | What to expect |
|---|---|
| Physics props | Both guns can move them. The physgun can freeze and rotate them. |
| World blocks | Stay in the world until picked up in block mode. Only permitted block types can be removed. |
| Mobs and animals | Can be picked up when creature handling is enabled. Their AI pauses while physics controls them and resumes after release. Hard landings can hurt them if creature damage is enabled. |
| Props in water | Bodies configured with a buoyancy density can float. Bodies without buoyancy sink. |
| Other mods' entities | Their mod must register an integration before the guns can take control. Nomad Longships is one example; its integration decides which hulls can be picked up. |
If your favourite modded object misbehaves with this on, tell me and I'll do my best to sort it out. Point its author to the integration instructions below, too.
Permissions and configuration

Give players the permissions for the tools and actions you want them to use:
| Default permission | Allows |
|---|---|
nomadphysics.physgun |
Using the physgun. |
nomadphysics.gravitygun |
Using the gravity gun. |
nomadphysics.blocks |
Picking up world blocks with either tool. The tool's own permission is also required. |
nomadphysics.admin |
Passing the additional permission check on /physics tool to hand out tools. |
These nodes are configurable. They are separate from the server's command permissions, so keep administrative commands restricted through your normal permission setup.
The plugin creates config.json in its data directory on first startup. Stop the server before editing it, then restart to load your changes.
| Config section | What you can change |
|---|---|
Physgun |
Reach, minimum and maximum carry distance, distance adjustment and the permission node. |
GravityGun |
Reach, carry distance, MassCap, PuntSpeed, weaker shoves for heavy props and the permission node. |
Blocks |
Allowed tags, denied block IDs, mass, the per-player airborne-block limit and the permission node. |
Creatures |
Enable or disable creature pickup, adjust its limits, and turn landing damage on or off with Damage. |
Impact |
Damage and knockback from props hitting players. Set Enabled to false to disable that impact handling. |
Diagnostics |
Set this top-level flag to true when investigating a problem. It is off by default. |
Useful operator commands
| Command | Purpose |
|---|---|
/physics status |
Show the current world's physics state. |
/physics stats |
Inspect body counts, simulation cost and contacts. |
/physics holds |
List active holds and frozen props. |
/physics unfreeze all |
Unfreeze all tool-frozen props in the current world. |
/physics unfreeze PlayerName |
Unfreeze props frozen by that player. |
/physics blocks |
Inspect the block allowlist and airborne blocks. |
/physics creatures |
Inspect creature settings and active creature adoptions. |
/physics owners |
List registered mod integrations and their adopted entities. |
/physics joints |
List the current world's joints. |
/physics clear |
Clear the world's physics simulation, including props created by content packs. Use this to reset a test area, not as a routine cleanup command on an active game. |
For mod authors: using PhysicsApi

The Java API is for server plugins. Server owners can use the tools and commands above without writing code.
Add the dependency
Compile against the core and plugin API in NomadPhysics.jar. For a Gradle Kotlin build, put the jar in your project's libs directory and add:
dependencies {
compileOnly(files("libs/NomadPhysics.jar"))
}
Add this dependency entry to your plugin's manifest.json:
{
"Dependencies": {
"co.nomadlabs:NomadPhysics": "*"
}
}
Install Nomad Physics alongside your plugin on the server. Keep the dependency as compileOnly; bundling another copy of the physics classes into your jar can give your plugin a separate API holder.
Spawn, move and remove a prop
Create one PhysicsExample for the world you want to use, then call spawn with a body-centre position in a loaded area. This example spawns the vanilla Minecart model as a physics prop and pushes it along the world's X axis. Call clear when your feature is finished with it, while that world is still running.
import co.nomadlabs.physics.Quat;
import co.nomadlabs.physics.Vec3;
import co.nomadlabs.physics.plugin.api.BodyHandle;
import co.nomadlabs.physics.plugin.api.PhysicsApi;
import com.hypixel.hytale.server.core.universe.world.World;
public final class PhysicsExample {
private final World world;
private BodyHandle prop;
public PhysicsExample(World world) {
this.world = world;
}
public void spawn(Vec3 centre) {
world.execute(() -> {
PhysicsApi physics = PhysicsApi.get();
if (physics == null || prop != null) return;
prop = physics.spawnBody(world, "Minecart", centre, Quat.IDENTITY);
if (prop != null) {
physics.applyImpulse(prop, new Vec3(8, 0, 0), centre);
}
});
}
public void clear() {
world.execute(() -> {
PhysicsApi physics = PhysicsApi.get();
if (physics != null && prop != null) physics.removeBody(prop);
prop = null;
});
}
}
PhysicsApi.get() returns null before setup and after shutdown. spawnBody can return null when a model is unknown, the destination section is unloaded, or the world has reached its body cap. Query the cap with bodyCap() rather than hard-coding it.
Run simulation calls on the owning world's thread. world.execute(...) schedules the work there. Contact, impact and adoption callbacks already run on that thread; keep them short and avoid blocking I/O. Impulses use kg·m/s, and the application point is in world coordinates. Check bodyState(handle) before relying on a stored handle: it returns null after that body has gone.
More API features
| API | Use it for |
|---|---|
spawnBody(..., BodySpec) |
Choose mass, buoyancy, rolling resistance and other body settings. |
bodyState, entityOf, bodyOf |
Read a body's state or find the link between a physics body and its entity. |
spawnBlockBody |
Spawn a loose block that snaps back into the world when it settles. Its body handle expires when that happens. |
addContactListener / removeContactListener |
Receive body contact events. Register once and keep the same listener object for removal. |
addImpactListener / removeImpactListener |
Receive player-impact events separately from body contacts. |
addHinge, addSlider, addBall |
Join bodies to each other or to the world. Keep the returned joint handle and release it with removeJoint. |
adopt / release |
Temporarily give physics control of an existing entity, then hand it back. |
registerAdoptable / unregisterAdoptable |
Let the physics guns recognise and pick up entities owned by your mod. |
registerLiftOwner / unregisterLiftOwner |
Let a carry action move a multi-part object through a body chosen by your mod. |
registerMachine |
Register a machine that a content-pack item can place and pick up. |
Remove your listeners and registrations when your integration shuts down. Remove spawned bodies when your feature no longer needs them. For adopted entities, use release so their owner gets control back.
Make your own entities work with the guns
Implement AdoptableOwner and register it from your plugin's start() using NomadPhysicsPlugin.registerAdoptable("yourgroup:YourPlugin", owner). This registration is thread-safe and can happen before worlds exist. Use the same ID with unregisterAdoptable when your plugin shuts down.
| Callback | Your mod's job |
|---|---|
claims(store, entity) |
Return whether this is one of your entities. Keep this check cheap. |
describe(store, entity) |
Return an AdoptRequest with its shape and settings, or null to refuse pickup, for example while it's occupied or locked. |
onAdopt(store, entity) |
Pause your own movement or AI for this entity. Return false to cancel adoption. |
onRelease(store, entity, finalPose, reason) |
Resume your own behaviour from the final pose. Use the entity reference supplied here; a cached reference may have been replaced. |
AdoptRequest contains an AdoptShape and AdoptOptions. The shape describes positive box half-extents in blocks and the box centre's offset from the entity origin in entity-local coordinates. The options set mass, buoyancy, client collision and the thresholds for returning a settled entity. finalPose is the body's centre and orientation; the entity origin is finalPose.centre().minus(finalPose.rotation().rotate(pivotOffset)).
Release reasons are REST, OWNER_RECALLED, ENTITY_GONE and WORLD_CLOSED. The release callback fires once. For ENTITY_GONE, the entity reference may already be invalid, so check it before accessing components.
If physics support is optional for your mod, load its classes through the installed physics plugin's class loader and use a reflection proxy for AdoptableOwner. A null check on a directly imported PhysicsApi does not remove the jar dependency. The static registration methods on NomadPhysicsPlugin are available for that optional integration path too.






