[OSRS/RS3] Rest system
Posted: Fri Mar 06, 2026 5:37 pm
[Release] RS3 Rest System Snippet
Today I’m releasing a small snippet that adds the RS3-style Rest System to your server.
This allows players to sit down and regenerate their run energy faster, similar to the mechanic seen in modern RuneScape.
This was written for the Rune-unique base but can be modified for any other base.
Features
• RS3-style resting animation
• Faster run energy regeneration while resting
• Automatically stops when the player moves or performs another action
• Lightweight snippet – easy to implement into most sources
Preview / Example Code
How it Works
When a player activates the rest option, their character will sit down and begin restoring run energy at an increased rate.
The rest state will automatically cancel if the player moves, attacks, or performs another action.
Usage
Simply integrate the snippet into your player or energy handling system and call the rest method when the player activates the rest option.
Notes
This is just a basic snippet and may require small adjustments depending on your source.
Credits
• ROGUE#8231
If you have improvements or questions feel free to reply to the thread.
Today I’m releasing a small snippet that adds the RS3-style Rest System to your server.
This allows players to sit down and regenerate their run energy faster, similar to the mechanic seen in modern RuneScape.
This was written for the Rune-unique base but can be modified for any other base.
Features
• RS3-style resting animation
• Faster run energy regeneration while resting
• Automatically stops when the player moves or performs another action
• Lightweight snippet – easy to implement into most sources
Preview / Example Code
Code: You must be registered to view this Link
package com.zenyte.game.content;
import com.zenyte.game.packet.in.ClientProtEvent;
import com.zenyte.game.task.WorldTask;
import com.zenyte.game.task.WorldTasksManager;
import com.zenyte.game.world.entity.masks.Animation;
import com.zenyte.game.world.entity.player.LogLevel;
import com.zenyte.game.world.entity.player.Player;
import com.zenyte.game.world.entity.player.container.impl.equipment.EquipmentSlot;
/**
* Rest system (RS3-style).
* Author: Rogue#8231
*/
public class RestHandler implements ClientProtEvent {
// Rest animations
// Male resting animations
// Male resting animations
private static final Animation REST_MALE_1 = new Animation(7186); // sit / relaxed
private static final Animation REST_MALE_2 = new Animation(7211); // laying / resting
private static final Animation REST_MALE_3 = new Animation(1351); // sit looking down (idle)
private static final Animation REST_MALE_4 = new Animation(1352); // sit thinking / resting
// Female resting animations
private static final Animation REST_FEMALE_1 = new Animation(7186); // sit / relaxed
private static final Animation REST_FEMALE_2 = new Animation(7211); // laying / resting
private static final Animation REST_FEMALE_3 = new Animation(1351); // sit looking down
private static final Animation REST_FEMALE_4 = new Animation(1352); // sit thinking
// Regen multipliers
private static final double ENERGY_MULTIPLIER = 3.6; // ~3.6x faster
private static final int HP_INTERVAL = 6; // every 6 seconds (10x faster)
/**
* Starts resting.
*/
public static void startRest(Player player) {
if (player.isDead() || player.getHitpoints() <= 0) {
player.sendMessage("You can't rest right now.");
return;
}
if (!canRest(player)) {
player.sendMessage("You cannot rest at this moment.");
return;
}
if (isResting(player)) {
player.sendMessage("You are already resting.");
return;
}
// Reset idle if the entity is a player
if (player instanceof Player p) {
IdleHandler.resetIdle(p);//cameron added for the throne idle system
p.getTemporaryAttributes().put("last_action", System.currentTimeMillis());
}
player.getTemporaryAttributes().put("resting", true);
player.sendMessage("You begin to rest...");
// Start animation cycle
cycleAnimations(player);
// Start regen task using WorldTask
WorldTasksManager.schedule(new WorldTask() {
@Override
public void run() {
if (!isResting(player)) {
stop(); // properly stops this task
return;
}
// Restore run energy faster
if (player.getVariables().getRunEnergy() < 100) {
int baseRestore = 1 + (player.getSkills().getLevel(16) / 6); // agility effect
int restore = (int) Math.ceil(baseRestore * ENERGY_MULTIPLIER);
int current = (int) player.getVariables().getRunEnergy();
int restored = Math.min(100, current + restore);
player.getVariables().setRunEnergy(restored);
}
// Restore HP every 6 seconds
player.setHitpoints(Math.min(player.getMaxHitpoints(),
player.getHitpoints() + Math.max(1, player.getMaxHitpoints() / 100)));
}
}, 0, 1); // initial delay 0 ticks, repeat every 1 tick
}
/**
* Stops resting.
*/
public static void stopRest(Player player) {
if (!isResting(player)) return;
player.getTemporaryAttributes().remove("resting");
player.setAnimation(Animation.STOP);
player.sendMessage("You stop resting.");
}
/**
* Cycles the resting animations.
*/
private static void cycleAnimations(Player player) {
WorldTasksManager.schedule(new WorldTask() {
private int tick = 0;
@Override
public void run() {
if (!isResting(player)) {
stop();
return;
}
if (player.getAppearance().isMale()) {
switch (tick % 4) {
case 0: player.setAnimation(REST_MALE_1); break;
case 1: player.setAnimation(REST_MALE_2); break;
case 2: player.setAnimation(REST_MALE_3); break;
case 3: player.setAnimation(REST_MALE_4); break;
}
} else {
switch (tick % 4) {
case 0: player.setAnimation(REST_FEMALE_1); break;
case 1: player.setAnimation(REST_FEMALE_2); break;
case 2: player.setAnimation(REST_FEMALE_3); break;
case 3: player.setAnimation(REST_FEMALE_4); break;
}
}
tick++;
}
}, 0, 20); // cycle every ~12 seconds
}
/**
* Checks if the player is allowed is transformed.
*/
public static boolean isTransformed(Player player) {
return player.getAppearance().getNpcId() != -1;
}
/**
* Checks if a player is currently holding a banner.
*/
public static boolean hasBanner(Player player) {
// Check weapon slot
int weaponId = player.getEquipment().getId(EquipmentSlot.WEAPON.getSlot());
if (weaponId == 20225 || weaponId == 20226) { // banner ids.
return true;
}
return false;
}
/**
* Checks if a player can actually rest.
*/
private static boolean canRest(Player player) {
if (player.getToxins().isPoisoned()) {
return false;
}
if (player.isUnderCombat()) {
return false;
}
if (isTransformed(player)) {
return false;
}
if (hasBanner(player)) {
return false;
}
if (player.getArea().isWildernessArea(player)) {
return false;
}
return true;
}
/**
* Checks if a player is currently resting.
*/
public static boolean isResting(Player player) {
return (Boolean) player.getTemporaryAttributes().getOrDefault("resting", false);
}
@Override
public void handle(Player player) {
RestHandler.startRest(player);
}
@Override
public LogLevel level() {
return LogLevel.INFO;
}
}
When a player activates the rest option, their character will sit down and begin restoring run energy at an increased rate.
The rest state will automatically cancel if the player moves, attacks, or performs another action.
Usage
Simply integrate the snippet into your player or energy handling system and call the rest method when the player activates the rest option.
Notes
This is just a basic snippet and may require small adjustments depending on your source.
Credits
• ROGUE#8231
If you have improvements or questions feel free to reply to the thread.