Description
/piss mod
This mod adds the /piss command, which triggers the player to urinate. The effect is visible to all players (everything is handled on the server; there is almost no client-side code).
Features
- Type the command
/pissto start urinating. - Hold down
Shiftto stop it early. - Typing
/pissagain also stops the current urination. - The stream moves in the direction of the player’s line of sight and reacts to collisions with blocks.
- The stream reacts to entities: when it hits a target, it stops on the target, and the visual trail moves with it for a short time.
- Urination automatically stops after about 5 seconds, as well as when the player dies or leaves the game.
- The effect is processed on the server and is visible to other players.
How the Projectile Works (Every Server Tick)
Parabola, not physics. Launch point — the player’s hips (
player.position().add(0, 0.8, 0)), initial velocity — in the direction of the player’s gaze (player.getLookAngle(), velocity ~0.5–0.7), gravity ~0.05/tick². We sample the parabolic trajectory at ~12 points with a large step size—the jet’s cubes are sparsely distributed.Glass blocks instead of particles. The jet is a
Display.BlockDisplaypool containing a full block of yellow glass (Panes.GLASS_BLOCK, scale ~0.13, no rotation—the transformation is global and static), with one block per visible point on the parabola. Every tick, the pool is adjusted to the number of points, and the entities move (setPos) rather than being recreated;setPosRotInterpolationDuration(4)smooths and slows down the movement on the client. Particles are not used.Hit point. Using the same parabolic segments—
level.clip(new ClipContext(from, to, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, player))for blocks, plusProjectileUtil.getEntityHitResult(...)for entities (the segment is clipped by the block hit, and the player itself andDisplayentities of the jet stream are excluded from the predicate). First hit = landing point; we do not sample the parabola further.Ghost block (puddle). At the point of impact, spawn a
Display.BlockDisplaywith a flat panel (NOT a cross-shaped one):YELLOW_STAINED_GLASS_PANEwith both opposite sides set totrue, facing the player (rotated around the Y-axis by-yRot). The world is NOT modified; by definition, display entities have no collisions.- Fade-in interpolation: upon spawn, duration is 12 ticks; one tick later — the target transformation is “lower and wider” (scale.y → ~0.15). If this is set at the spawn tick, the client will receive both states in a single packet and will not animate them.
- After 12 ticks (0.6 s) —
entity.discard(). A new puddle is spawned every 4 ticks (GHOST_INTERVAL). - Hitting an entity: the puddle “sticks” — it remembers the target and the offset from its position, and reposition itself behind it every tick (
setPosRotInterpolationDuration(2)for smoothness).
Stopping the stream: timer (100 ticks = 5 s), repeated
/piss(toggle), Shift (player.isShiftKeyDown()on the server—no client-side keybind required), death, logout, or dimension change. The command does not send any messages to chat or the action bar.


