HyperScript
Docs

Scripts

Ready-made scripts. Copy one or download it, put the file in plugins/HyperScript/scripts, and it is live. The notes at the top of each script say what it does and what to change.

How to use a script from this page
  1. Check the version. Each script shows the HyperScript version it needs. /hyperscript version shows yours.
  2. Download it, or copy it into a new file whose name ends in .hs.
  3. Put the file in plugins/HyperScript/scripts/. A subfolder is fine. With hot reloading on it is loaded at once; otherwise run /hyperscript reload.
  4. Change the settings. Open the file and edit the options: block at the top: prefixes, waiting times, permissions. Save, and the change is live.
  5. Give out the permissions the script lists, with your permissions plugin.

If a script does not load, the error names the file and the line. /hyperscript check <file> reads a script and reports mistakes without loading it. Two scripts that add the same command do not break each other, but only one of them gets the command.

ChatPrefixes.hs

# ==============================================================
#  ChatPrefixes.hs - a prefix in front of everybody's chat
# ==============================================================
#
# Requires: 1.7.35
# Author: HyperScript Team
# Tags: chat, prefix, ranks, server template
#
# Every chat message gets the player's prefix in front of it:
# their rank from Ranks.hs, or one you gave them yourself.
#
# /prefix set <player> <text>   give a player a prefix of their own
# /prefix clear <player>        back to the prefix of their rank
#
# Notes
#  - How a message looks is "format" below. %{_prefix}% is the
#    prefix, and %player.name% and %event.message% are filled
#    in for each message.
#  - A player's prefix is, in this order: one given with
#    /prefix set, the one of their rank (Ranks.hs keeps it as
#    {%player%.rank_prefix}), and "default" if there is neither.
#    Without Ranks.hs everybody has "default" until you give
#    them one.
#  - "server_tag" puts your server's name in front of every
#    message as well, for a network where chat is shared.
#  - /prefix needs the permission "prefix.admin". A prefix may
#    have colours: "&6&lKING".
#  - Use one script for how chat looks. Another that sets the
#    chat format as well would fight this one over it.

options:
    name: "MY SERVER"
    prefix: "&8[&bPrefix&8] "
    # How a chat message looks.
    format: "%{_prefix}% &f%player.name%&8: &7%event.message%"
    # The prefix of a player who has none.
    default: "&7PLAYER"
    # Put the server's name in front of every message too.
    server_tag: false

# The prefix a player has: their own, their rank's, or the default.
local function prefix_of({_who}):
    if {%{_who}%.chat_prefix} is set:
        return {%{_who}%.chat_prefix}
    if {%{_who}%.rank_prefix} is set:
        return {%{_who}%.rank_prefix}
    return "{@default}"

on player chat:
    set {_prefix} to prefix_of(player)
    if {@server_tag} is true:
        set {_prefix} to "&8[&f{@name}&8] %{_prefix}%"
    set chat format to "{@format}"

command /prefix [action] [target] [text]:
    description: Give a player a chat prefix of their own
    permission: "prefix.admin"
    usage: "&cUse /prefix set <player> <text> or /prefix clear <player>"
    tab complete:
        set arg.1 to "set", "clear"
        set arg.2 to server.players
    trigger:
        if arg.2 is not set:
            send "{@prefix}&cUse /prefix set <player> <text> or /prefix clear <player>"
            stop
        if arg.2 is not a player:
            send "{@prefix}&c%arg.2% is not online."
            stop
        if arg.1 is "set":
            if arg.3 is not set:
                send "{@prefix}&cSay what: /prefix set %arg.2% <text>"
                stop
            set {%arg.2%.chat_prefix} to arg.3
            send "{@prefix}&f%arg.2% &7now has the prefix %arg.3%&7."
            stop
        if arg.1 is "clear":
            delete {%arg.2%.chat_prefix}
            set {_now} to prefix_of(arg.2)
            send "{@prefix}&f%arg.2% &7has the prefix %{_now}% &7again."
            stop
        send "{@prefix}&cUse /prefix set <player> <text> or /prefix clear <player>"

DeathMessages.hs

# ==============================================================
#  DeathMessages.hs - death messages that do not take it seriously
# ==============================================================
#
# Requires: 1.7.3
# Author: HyperScript Team
# Tags: death, messages, chat, funny, server template
#
# Instead of "Steve fell from a high place" everybody sees one
# of a handful of lines for that kind of death, picked at random
# each time: falling, burning, drowning, blowing up, the void,
# lightning, being squashed, cactus, potions, freezing, mobs,
# and being killed by another player.
#
# /deaths    how often you have died
#
# Notes
#  - The lines are in the functions below, one function for each
#    kind of death. Add your own, take some out, or leave one:
#    with one line it is always that line. %player.name% is
#    whoever died, and %{_killer}% in slain() is who did it.
#  - A death that fits none of the kinds gets a line from
#    other().
#  - "sign" is what stands in front of every line.
#  - Put false after "show_deaths" to say nothing at all when
#    somebody dies.
#  - With "tell_place" the player who died is told where it
#    happened, and nobody else is.
#  - With "count_deaths" deaths are counted, in
#    {%player%.deaths}, and whoever died is told which one that
#    was. Every "milestone" deaths, everybody is.
#  - Changing death messages needs a Paper server.

options:
    name: "MY SERVER"
    # What stands in front of every death message.
    sign: "&8[&cRIP&8] "
    show_deaths: true
    # Tell whoever died where it happened. Only they see it.
    tell_place: true
    # Count deaths, tell whoever died which one it was, and let them ask with /deaths.
    count_deaths: true
    # Everybody is told when somebody's deaths get to a multiple of this. 0 never tells.
    milestone: 50

# Killed by another player.
local function slain({_killer}):
    return ["&f%player.name% &7got absolutely folded by &c%{_killer}%&7.", \
            "&c%{_killer}% &7sent &f%player.name% &7back to the lobby of life.", \
            "&f%player.name% &7brought fists to a &c%{_killer}% &7fight.", \
            "&c%{_killer}% &7deleted &f%player.name%&7. No refunds.", \
            "&f%player.name% &7was turned into loot by &c%{_killer}%&7.", \
            "&7Somebody check on &f%player.name%&7. &c%{_killer}% &7did not hold back.", \
            "&f%player.name% &7lost a staring contest with &c%{_killer}%&7's sword.", \
            "&c%{_killer}% &7pressed the off switch on &f%player.name%&7.", \
            "&f%player.name% &7was an easy win for &c%{_killer}%&7.", \
            "&c%{_killer}% &7taught &f%player.name% &7a lesson. The lesson was pain.", \
            "&f%player.name% &7picked a fight with &c%{_killer}% &7and regretted it at once.", \
            "&7Thank you for your items, &f%player.name%&7. Signed, &c%{_killer}%&7."]

# Fell too far.
local function fell():
    return ["&f%player.name% &7forgot that gravity is always on.", \
            "&f%player.name% &7believed they could fly. They could not.", \
            "&f%player.name% &7found the ground. Quickly.", \
            "&f%player.name% &7skipped the stairs.", \
            "&7The floor says hi, &f%player.name%&7.", \
            "&f%player.name% &7tried the water bucket trick without the bucket.", \
            "&f%player.name% &7took the fast way down.", \
            "&f%player.name% &7misjudged that jump by a lot.", \
            "&7Ten out of ten for the dive, &f%player.name%&7. Zero for the landing.", \
            "&f%player.name% &7left their legs at the bottom."]

# Lava and fire.
local function burned():
    return ["&f%player.name% &7is now extra crispy.", \
            "&f%player.name% &7thought the lava was orange juice.", \
            "&f%player.name% &7went for a swim in the wrong liquid.", \
            "&7Medium rare: &f%player.name%&7.", \
            "&f%player.name% &7found out that fire is hot.", \
            "&f%player.name% &7became a campfire story.", \
            "&f%player.name% &7is toast. Actual toast.", \
            "&f%player.name% &7stood a little too close to the grill.", \
            "&7Somebody bring a bucket for &f%player.name%&7. Too late.", \
            "&f%player.name% &7tested whether the floor was lava. It was."]

# Ran out of air.
local function drowned():
    return ["&f%player.name% &7forgot how to breathe.", \
            "&f%player.name% &7tried to become a fish.", \
            "&f%player.name% &7stayed down there to look at one more thing.", \
            "&7Blub. &f%player.name% &7is with the squid now.", \
            "&f%player.name% &7held their breath for almost long enough.", \
            "&f%player.name% &7found out that the bubbles mean something.", \
            "&f%player.name% &7went looking for Atlantis. It is not there."]

# Creepers, TNT and everything else that goes boom.
local function exploded():
    return ["&f%player.name% &7went out with a bang.", \
            "&f%player.name% &7hugged a creeper. It hugged back.", \
            "&f%player.name% &7is now in several places at once.", \
            "&7Tssss... &f%player.name% &7did not hear it coming.", \
            "&f%player.name% &7stood next to the TNT to see what it does.", \
            "&f%player.name% &7was redecorated across the landscape.", \
            "&7Boom. &f%player.name% &7is confetti now."]

# Fell out of the world.
local function into_void():
    return ["&f%player.name% &7fell out of the world. Impressive.", \
            "&f%player.name% &7went looking for the bottom. There is none.", \
            "&7The void now owns everything &f%player.name% &7was carrying.", \
            "&f%player.name% &7is still falling, somewhere.", \
            "&f%player.name% &7stepped off the edge of the map."]

# Struck by lightning.
local function struck():
    return ["&f%player.name% &7was picked out by the sky itself.", \
            "&f%player.name% &7held the trident up in a storm.", \
            "&7One in a million, &f%player.name%&7. Unlucky.", \
            "&f%player.name% &7is fully charged."]

# Stuck in a block, under an anvil or sand, or in a crowd that was too big.
local function squashed():
    return ["&f%player.name% &7is now two blocks wide and none high.", \
            "&f%player.name% &7became part of the wall.", \
            "&f%player.name% &7did not look up.", \
            "&7It got a bit tight for &f%player.name%&7.", \
            "&f%player.name% &7was flattened. Paper thin."]

# Cactus, berry bushes and thorns.
local function pricked():
    return ["&f%player.name% &7hugged a cactus.", \
            "&f%player.name% &7lost to a plant.", \
            "&f%player.name% &7found out what the spikes are for.", \
            "&7Ouch. &f%player.name% &7got the point."]

# Potions, poison, the wither effect and dragon's breath.
local function by_magic():
    return ["&f%player.name% &7drank the wrong bottle.", \
            "&f%player.name% &7was magicked out of existence.", \
            "&f%player.name% &7withered away.", \
            "&7That potion was not for drinking, &f%player.name%&7.", \
            "&f%player.name% &7angered somebody with a wand."]

# Powder snow.
local function froze():
    return ["&f%player.name% &7is an ice cube now.", \
            "&f%player.name% &7chilled a little too hard.", \
            "&f%player.name% &7forgot their leather boots."]

# Killed by a mob, an arrow or anything else alive that is not a player.
local function by_mob():
    return ["&f%player.name% &7lost a fight with the local wildlife.", \
            "&f%player.name% &7was not the main character after all.", \
            "&7The mobs send their regards, &f%player.name%&7.", \
            "&f%player.name% &7got bullied by something with no brain.", \
            "&f%player.name% &7should have slept last night.", \
            "&f%player.name% &7forgot to light up the place.", \
            "&f%player.name% &7was outplayed by a monster.", \
            "&7Something in the dark says thanks for the items, &f%player.name%&7.", \
            "&f%player.name% &7ran, but not fast enough."]

# Nothing to eat.
local function starved():
    return ["&f%player.name% &7forgot that food exists.", \
            "&f%player.name% &7was too busy to eat. For a week.", \
            "&f%player.name% &7had a whole inventory and no bread in it.", \
            "&7The stomach of &f%player.name% &7has filed a complaint."]

# Everything else.
local function other():
    return ["&f%player.name% &7died. Nobody is quite sure how.", \
            "&f%player.name% &7has left this mortal block.", \
            "&7Press F for &f%player.name%&7.", \
            "&f%player.name% &7respawned with fewer items and more regret.", \
            "&f%player.name% &7speedran dying.", \
            "&7Skill issue, &f%player.name%&7.", \
            "&f%player.name% &7ran out of hearts.", \
            "&f%player.name% &7is taking a short break from being alive.", \
            "&7And that was the end of &f%player.name%&7. For now."]

on player death:
    if {@count_deaths} is true:
        add 1 to {%player%.deaths}
    if {@show_deaths} is false:
        hide death message
        stop
    set {_cause} to event.cause
    set {_lines} to other()
    if killer is set:
        set {_killer} to event.killer
        set {_lines} to slain({_killer})
    else if {_cause} is "FALL" or {_cause} is "FLY_INTO_WALL":
        set {_lines} to fell()
    else if {_cause} is "LAVA" or {_cause} is "FIRE" or {_cause} is "FIRE_TICK" or {_cause} is "HOT_FLOOR":
        set {_lines} to burned()
    else if {_cause} is "DROWNING":
        set {_lines} to drowned()
    else if {_cause} is "ENTITY_EXPLOSION" or {_cause} is "BLOCK_EXPLOSION":
        set {_lines} to exploded()
    else if {_cause} is "VOID":
        set {_lines} to into_void()
    else if {_cause} is "LIGHTNING":
        set {_lines} to struck()
    else if {_cause} is "SUFFOCATION" or {_cause} is "FALLING_BLOCK" or {_cause} is "CRAMMING":
        set {_lines} to squashed()
    else if {_cause} is "CONTACT" or {_cause} is "THORNS":
        set {_lines} to pricked()
    else if {_cause} is "MAGIC" or {_cause} is "POISON" or {_cause} is "WITHER" or {_cause} is "DRAGON_BREATH":
        set {_lines} to by_magic()
    else if {_cause} is "FREEZE":
        set {_lines} to froze()
    else if {_cause} is "ENTITY_ATTACK" or {_cause} is "ENTITY_SWEEP_ATTACK" or {_cause} is "PROJECTILE" or {_cause} is "SONIC_BOOM":
        set {_lines} to by_mob()
    else if {_cause} is "STARVATION":
        set {_lines} to starved()
    set {_line} to random item of {_lines}
    set death message to "{@sign}%{_line}%"
    if {@tell_place} is true:
        set {_x} to round(x of event's location)
        set {_y} to round(y of event's location)
        set {_z} to round(z of event's location)
        send "&7You died at &f%{_x}%, %{_y}%, %{_z}%&7 on &f{@name}&7."
    if {@count_deaths} is true:
        set {_deaths} to {%player%.deaths}
        send "&7That was death number &f%{_deaths}%&7."
        if {@milestone} > 0:
            # A whole number of milestones: 50, 100, 150 and so on.
            set {_times} to {_deaths} / {@milestone}
            if {_times} is round({_times}):
                broadcast "{@sign}&f%player.name% &7has now died &c%{_deaths}% &7times. A round of applause."

command /deaths:
    description: How often you have died
    trigger:
        set {_deaths} to {%player%.deaths}
        if {_deaths} is not set:
            send "&7You have not died yet. &8(Or nobody was counting.)"
            stop
        send "&7You have died &f%{_deaths}% &7times on &f{@name}&7."

JoinMessages.hs

# ==============================================================
#  JoinMessages.hs - join and leave messages with some wit
# ==============================================================
#
# Requires: 1.7.3
# Author: HyperScript Team
# Tags: join, leave, quit, messages, welcome, server template
#
# Instead of "Steve joined the game" everybody sees one of a
# handful of lines, picked at random each time. Leaving has its
# own. Whoever joins is welcomed, with a title if you like, and
# told how long they were away; somebody new to the server is
# announced to all, with which player of the server they are.
#
# Notes
#  - The lines are in joins() and leaves() below. Add your own,
#    take some out, or leave one: with one line it is always
#    that line. %player.name% is the player.
#  - The welcome is "welcome" in the options, shown only to the
#    player who joined. In it and in "first_join", %{_server}% is
#    your server's name and %{_address}% its address, as "name"
#    and "address" say them.
#  - "first_join" is what everybody sees when somebody joins
#    for the very first time, in place of a line from joins().
#    %{_number}% in it is which player of the server they are,
#    counted from when this script was installed. "first_tip"
#    is said to the new player alone.
#  - "welcome_back" is said to somebody who has been here
#    before; %{_away}% is how long they were gone.
#  - With "show_title" the player who joined gets "title" and
#    "subtitle" in the middle of the screen.
#  - With "play_sound" everybody hears "sound" when somebody
#    joins. It is the game's name for a sound.
#  - Put false after "show_joins" or "show_leaves" to say
#    nothing at all when somebody comes or goes.

options:
    name: "MY SERVER"
    address: "play.example.com"
    # What stands in front of the lines for joining and leaving.
    join_sign: "&8[&a+&8] "
    leave_sign: "&8[&c-&8] "
    # Shown to the player who joined, and only to them.
    welcome: "&7Welcome to &6&l%{_server}%&7! &8(%{_address}%)"
    # Shown after it to somebody who has been here before.
    welcome_back: "&7Good to see you again. You were away for &f%{_away}%&7."
    # Shown to everybody when somebody joins for the first time.
    first_join: "&d&lNEW! &f%player.name% &7just joined &6%{_server}% &7for the first time, as player &f#%{_number}%&7. Say hi!"
    # Shown after the welcome to somebody who is new, and only to them.
    first_tip: "&7New here? Have a look around, and ask in chat if you are stuck."
    # In the middle of the screen of the player who joined.
    title: "&6&l%{_server}%"
    subtitle: "&7Welcome, &f%player.name%&7!"
    # What everybody hears when somebody joins.
    sound: "block.note_block.pling"
    show_joins: true
    show_leaves: true
    show_welcome: true
    show_title: true
    play_sound: false

# The lines for somebody joining. One is picked at random.
local function joins():
    return ["&f%player.name% &7hopped in!", \
            "&f%player.name% &7has entered the chat.", \
            "&7A wild &f%player.name% &7appeared!", \
            "&f%player.name% &7just slid into the server.", \
            "&7Look who it is: &f%player.name%&7!", \
            "&f%player.name% &7joined. Hide your diamonds.", \
            "&7Everybody act normal, &f%player.name% &7is here.", \
            "&f%player.name% &7spawned in with questionable intentions.", \
            "&f%player.name% &7is here. The party can start.", \
            "&7Roll out the red carpet for &f%player.name%&7.", \
            "&f%player.name% &7logged in. Productivity is over.", \
            "&7Quick, look busy: &f%player.name% &7just joined.", \
            "&f%player.name% &7fell out of the sky and landed here.", \
            "&7It is a bird, it is a plane, it is &f%player.name%&7!", \
            "&f%player.name% &7has come to mine and chew bubblegum.", \
            "&7Somebody left the door open and &f%player.name% &7walked in."]

# The lines for somebody leaving.
local function leaves():
    return ["&f%player.name% &7dipped!", \
            "&f%player.name% &7has left the building.", \
            "&f%player.name% &7rage quit. Probably.", \
            "&7Poof! &f%player.name% &7is gone.", \
            "&f%player.name% &7went to touch grass.", \
            "&f%player.name% &7vanished into thin air.", \
            "&7And just like that, &f%player.name% &7was gone.", \
            "&f%player.name% &7logged off to get snacks.", \
            "&f%player.name% &7has gone to bed. Maybe.", \
            "&7Bye, &f%player.name%&7. The chests are safe again.", \
            "&f%player.name% &7pulled the plug.", \
            "&f%player.name% &7heard their mum calling.", \
            "&7One fewer: &f%player.name% &7is off.", \
            "&f%player.name% &7left to do their homework. Sure.", \
            "&f%player.name% &7walked off into the sunset.", \
            "&7See you next time, &f%player.name%&7."]

on player join:
    set {_server} to "{@name}"
    set {_address} to "{@address}"
    # Somebody this script has not seen before is new to the server.
    set {_new} to false
    if {%player%.seen_before} is not set:
        set {_new} to true
        add 1 to {joinmessages.players}
    set {_number} to {joinmessages.players}
    if {@show_joins} is true:
        if {_new} is true:
            set join message to "{@first_join}"
        else:
            set {_line} to random item of joins()
            set join message to "{@join_sign}%{_line}%"
    else:
        hide join message
    set {%player%.seen_before} to true
    if {@show_welcome} is true:
        send "{@welcome}"
        if {_new} is true:
            send "{@first_tip}"
        else if {%player%.last_left} is set:
            set {_away} to time since {%player%.last_left}
            send "{@welcome_back}"
    if {@show_title} is true:
        send title "{@title}" with subtitle "{@subtitle}" to player
    if {@play_sound} is true:
        play sound "{@sound}" for all players

on player quit:
    set {%player%.last_left} to now
    if {@show_leaves} is true:
        set {_line} to random item of leaves()
        set quit message to "{@leave_sign}%{_line}%"
    else:
        hide quit message

Quests.hs

# ==============================================================
#  Quests.hs - quests with a menu that shows how far you are
# ==============================================================
#
# Requires: 1.7.64
# Author: HyperScript Team
# Tags: quests, menu, gui, rewards, daily, weekly
#
# Eleven quests to start a server with, and a menu to take them
# from. HyperScript counts what players do and keeps it across
# restarts; this script only says what the quests are, what
# they give, and how the menu looks.
#
# /quests       open the menu: click a quest to start it
# /questtop     the ten players who have done the most quests
# /queststop    give up the quests you are on
#
# The quests
#  - Miner          break 50 stone
#  - Lumberjack     break 30 oak logs
#  - Farmer         break 40 wheat
#  - Builder        place 128 blocks of any kind
#  - Hunter         kill 10 zombies
#  - Baker          craft 16 bread
#  - Fisher         catch 10 things with a rod
#  - Saver          have 1000 coins
#  - Daily walk     walk 500 blocks, once a day
#  - Speed run      walk 300 blocks within 2 minutes, once an hour
#  - Weekly slayer  kill 100 creatures, once a week
#
# Notes
#  - To change a quest, change its "goal:" and "reward:". A goal
#    is  break, place, kill or craft  with a number and a name,
#    fish 5,  walk 500 blocks,  reach 1000 {coins}  for a
#    variable, or  do 3  for one your own scripts count with
#    "advance quest".
#  - To add one, copy a quest block, give it another name, and
#    add its name and an item for it in the menu below, on a
#    line like the others.
#  - Rewards are coins in {%player%.coins}, and a few items. Use
#    your own variable if yours is called something else.
#  - "repeat: daily" lets a quest be done again each day, and
#    "time limit:" gives it an end. Take the line out for a
#    quest that is done once, or that may take as long as it
#    takes.
#  - "max_active" is how many quests a player may be on at once.
#  - Whoever finishes a quest hears a sound and sees a title.
#    With "announce" everybody is told when somebody has done 5,
#    10, 25, 50 or 100 of them.
#  - How many quests a player has done is kept in
#    {%player%.quests_done}, for your own scripts to read.

options:
    title: "&8Quests"
    # How many quests a player may be on at the same time.
    max_active: 3
    # Tell everybody when somebody has done 5, 10, 25, 50 or 100 quests.
    announce: true
    reward_miner: 100
    reward_lumberjack: 80
    reward_farmer: 80
    reward_builder: 120
    reward_hunter: 150
    reward_baker: 60
    reward_fisher: 120
    reward_walk: 40
    reward_speed: 75
    reward_slayer: 500

quest "Miner":
    goal: break 50 stone
    reward:
        add {@reward_miner} to {%player%.coins}
        send "&a&lQuest done! &7Miner: &6+{@reward_miner} coins"

quest "Lumberjack":
    goal: break 30 oak log
    reward:
        add {@reward_lumberjack} to {%player%.coins}
        send "&a&lQuest done! &7Lumberjack: &6+{@reward_lumberjack} coins"

quest "Farmer":
    goal: break 40 wheat
    reward:
        add {@reward_farmer} to {%player%.coins}
        give 5 emerald to player
        send "&a&lQuest done! &7Farmer: &6+{@reward_farmer} coins &7and 5 emeralds"

quest "Builder":
    goal: place 128 any
    reward:
        add {@reward_builder} to {%player%.coins}
        send "&a&lQuest done! &7Builder: &6+{@reward_builder} coins"

quest "Hunter":
    goal: kill 10 zombie
    reward:
        add {@reward_hunter} to {%player%.coins}
        send "&a&lQuest done! &7Hunter: &6+{@reward_hunter} coins"

quest "Baker":
    goal: craft 16 bread
    reward:
        add {@reward_baker} to {%player%.coins}
        send "&a&lQuest done! &7Baker: &6+{@reward_baker} coins"

quest "Fisher":
    goal: fish 10
    reward:
        add {@reward_fisher} to {%player%.coins}
        send "&a&lQuest done! &7Fisher: &6+{@reward_fisher} coins"

# Done when the player's coins get to a thousand; the other quests are how to get there.
quest "Saver":
    goal: reach 1000 {coins}
    reward:
        give 3 diamond to player
        send "&a&lQuest done! &7Saver: &b3 diamonds"

quest "Daily walk":
    goal: walk 500 blocks
    repeat: daily
    reward:
        add {@reward_walk} to {%player%.coins}
        send "&a&lQuest done! &7Daily walk: &6+{@reward_walk} coins. &7Come back tomorrow."

# Against the clock: when the two minutes are up it has to be started again.
quest "Speed run":
    goal: walk 300 blocks
    time limit: 2 minutes
    repeat: 1 hour
    reward:
        add {@reward_speed} to {%player%.coins}
        send "&a&lQuest done! &7Speed run: &6+{@reward_speed} coins. &7Again in an hour."

quest "Weekly slayer":
    goal: kill 100 any
    repeat: weekly
    reward:
        add {@reward_slayer} to {%player%.coins}
        give 1 golden apple to player
        send "&a&lQuest done! &7Weekly slayer: &6+{@reward_slayer} coins &7and a golden apple"

# What a quest's button says under its name: how far the player is, or what to do next.
local function quest_lore({_quest}):
    set {_state} to quest state {_quest}
    set {_goal} to quest goal {_quest}
    if {_state} is "active":
        set {_done} to quest progress {_quest}
        set {_bar} to bar of {_done} out of {_goal}
        return "&7%{_done}% of %{_goal}%|%{_bar}%"
    if {_state} is "done":
        return "&aDone"
    return "&eClick to start|&7Goal: %{_goal}%"

local function quest_clicked({_quest}):
    set {_state} to quest state {_quest}
    if {_state} is "none":
        set {_mine} to active quests
        if size of {_mine} >= {@max_active}:
            send "&cYou are on {@max_active} quests already. &7Finish one first, or give them up with /queststop."
            stop
        start quest {_quest}
        send "&eQuest started: &f%{_quest}%"
    else if {_state} is "active":
        send "&7You are already on &f%{_quest}%&7."
    else:
        send "&7You have done &f%{_quest}%&7."

# What the book in the menu says: how the player is doing altogether.
local function quest_stats():
    set {_done} to {%player%.quests_done}
    if {_done} is not set:
        set {_done} to 0
    set {_coins} to {%player%.coins}
    if {_coins} is not set:
        set {_coins} to 0
    set {_mine} to active quests
    return "&7Quests done: &f%{_done}%|&7On right now: &f%size of {_mine}% &7of {@max_active}|&7Coins: &6%{_coins}%"

local function quest_top():
    send "&6Most quests done"
    set {_place} to 0
    for each {_name} in top 10 players by {quests_done}:
        add 1 to {_place}
        send "&e#%{_place}% &f%{_name}% &7- %{%{_name}%.quests_done}%"
    if {_place} is 0:
        send "&7Nobody has finished a quest yet."

local function quest_give_up():
    set {_mine} to active quests
    if size of {_mine} is 0:
        send "&7You are not on any quest."
        stop
    for each {_quest} in {_mine}:
        stop quest {_quest}
    send "&7You gave up &f%size of {_mine}% &7quests. What was counted for them is gone."

command /quests:
    description: Open the quest menu
    players only:
    trigger:
        open gui with title {@title} with 5 rows for player:
            border with "black_stained_glass_pane"
            refresh every 2 seconds
            slot 11 is "iron_pickaxe" named "&6Miner" lore quest_lore("Miner"):
                quest_clicked("Miner")
                refresh gui
            slot 12 is "oak_log" named "&6Lumberjack" lore quest_lore("Lumberjack"):
                quest_clicked("Lumberjack")
                refresh gui
            slot 13 is "wheat" named "&6Farmer" lore quest_lore("Farmer"):
                quest_clicked("Farmer")
                refresh gui
            slot 14 is "bricks" named "&6Builder" lore quest_lore("Builder"):
                quest_clicked("Builder")
                refresh gui
            slot 15 is "rotten_flesh" named "&6Hunter" lore quest_lore("Hunter"):
                quest_clicked("Hunter")
                refresh gui
            slot 16 is "bread" named "&6Baker" lore quest_lore("Baker"):
                quest_clicked("Baker")
                refresh gui
            slot 17 is "fishing_rod" named "&6Fisher" lore quest_lore("Fisher"):
                quest_clicked("Fisher")
                refresh gui
            slot 21 is "gold_ingot" named "&6Saver" lore quest_lore("Saver"):
                quest_clicked("Saver")
                refresh gui
            slot 22 is "leather_boots" named "&bDaily walk" lore quest_lore("Daily walk"):
                quest_clicked("Daily walk")
                refresh gui
            slot 24 is "clock" named "&bSpeed run &7(2 minutes)" lore quest_lore("Speed run"):
                quest_clicked("Speed run")
                refresh gui
            slot 25 is "diamond_sword" named "&dWeekly slayer" lore quest_lore("Weekly slayer"):
                quest_clicked("Weekly slayer")
                refresh gui
            slot 30 is "book" named "&eYour quests" lore quest_stats()
            slot 32 is "gold_block" named "&eTop 10" lore "&7Who has done the most quests":
                close gui
                quest_top()
            slot 34 is "barrier" named "&cGive up" lore "&7Stop the quests you are on":
                quest_give_up()
                refresh gui

command /questtop:
    description: The ten players who have done the most quests
    trigger:
        quest_top()

command /queststop:
    description: Give up the quests you are on
    players only:
    trigger:
        quest_give_up()

on quest progress:
    send action bar "&6%{_quest}% &7%{_progress}% of %{_goal}%" to player

on quest complete:
    add 1 to {%player%.quests_done}
    set {_done} to {%player%.quests_done}
    play sound "entity.player.levelup" for player
    send title "&6Quest done!" with subtitle "&f%{_quest}%" to player
    if {@announce} is true:
        if {_done} is 5 or {_done} is 10 or {_done} is 25 or {_done} is 50 or {_done} is 100:
            broadcast "&6%player.name% &7has finished &f%{_done}% &7quests!"

Ranks.hs

# ==============================================================
#  Ranks.hs - ranks you give with /rank
# ==============================================================
#
# Requires: 1.7.35
# Author: HyperScript Team
# Tags: ranks, permissions, admin, server template
#
# Ranks without a permissions plugin. A rank is a name, how it
# is shown, and a permission that goes with it, so the sidebar,
# the tab list and the chat prefixes all know who is what.
#
# /rank                       your own rank
# /rank list                  the ranks there are
# /rank info <player>         somebody's rank
# /rank set <player> <rank>   give a rank
# /rank remove <player>       back to the lowest rank
#
# Notes
#  - The ranks are in ranks() below, from the lowest to the
#    highest, and how each is shown is in shown(). Add one in
#    both places; the first in ranks() is what a new player is.
#  - A player with the rank "vip" gets the permission
#    "rank.vip", and loses the one of the rank they had. Give
#    your other plugins and scripts that permission to check.
#  - How a rank is shown is kept as {%player%.rank_prefix},
#    which ChatPrefixes.hs puts in front of chat messages.
#  - Giving and taking ranks needs the permission "ranks.admin".
#  - Tab offers what comes next: the actions, then the players
#    who are online, then the ranks.
#  - The player has to be online to be given a rank.
#  - With a permissions plugin such as LuckPerms, use that for
#    ranks instead: it does far more than this.

options:
    name: "MY SERVER"
    prefix: "&8[&6Ranks&8] "
    # Tell everybody when somebody is given a rank.
    announce: true

# The ranks, from the lowest to the highest.
local function ranks():
    return ["player", "vip", "mod", "admin", "owner"]

# How a rank is shown in chat and in lists.
local function shown({_rank}):
    if {_rank} is "owner":
        return "&4&lOWNER"
    if {_rank} is "admin":
        return "&c&lADMIN"
    if {_rank} is "mod":
        return "&9&lMOD"
    if {_rank} is "vip":
        return "&6&lVIP"
    return "&7PLAYER"

# Gives a player a rank: what is kept about it, and the permission that goes with it.
local function give_rank({_who}, {_rank}):
    for each {_other} in ranks():
        permission {_who} remove "rank.%{_other}%"
    set {%{_who}%.rank} to {_rank}
    set {%{_who}%.rank_prefix} to shown({_rank})
    permission {_who} add "rank.%{_rank}%"

on player join:
    # A new player is the lowest rank, and everybody's rank is put in place again.
    set {_lowest} to item 1 of ranks()
    if {%player%.rank} is not set:
        set {%player%.rank} to {_lowest}
    set {%player%.rank_prefix} to shown({%player%.rank})

command /rank [action] [target] [rank]:
    description: See and give ranks
    usage: "&cUse /rank, /rank list, /rank info <player>, /rank set <player> <rank> or /rank remove <player>"
    # What Tab offers: the actions, then a player for those that take one, then the ranks for "set".
    tab complete:
        set arg.1 to "list", "info", "set", "remove"
        if arg.1 is "info" or arg.1 is "set" or arg.1 is "remove":
            set arg.2 to server.players
        if arg.1 is "set":
            set arg.3 to ranks()
    trigger:
        set {_lowest} to item 1 of ranks()
        if arg.1 is not set:
            if player is not set:
                send "{@prefix}&cSay whose: /rank info <player>"
                stop
            set {_mine} to shown({%player%.rank})
            send "{@prefix}&7Your rank on &f{@name}&7 is %{_mine}%&7."
            stop
        if arg.1 is "list":
            send "{@prefix}&7The ranks of &f{@name}&7, lowest first:"
            for each {_rank} in ranks():
                set {_looks} to shown({_rank})
                send " &8- &f%{_rank}% &8(%{_looks}%&8)"
            stop
        if arg.1 is "info":
            if arg.2 is not set:
                send "{@prefix}&cSay whose: /rank info <player>"
                stop
            if arg.2 is not a player:
                send "{@prefix}&c%arg.2% is not online."
                stop
            set {_theirs} to shown({%arg.2%.rank})
            send "{@prefix}&f%arg.2% &7is %{_theirs}%&7."
            stop
        if arg.1 is "set" or arg.1 is "remove":
            if player is set:
                if player does not have permission "ranks.admin":
                    send "{@prefix}&cYou may not change ranks."
                    stop
            if arg.2 is not set:
                send "{@prefix}&cSay whom: /rank %arg.1% <player>"
                stop
            if arg.2 is not a player:
                send "{@prefix}&c%arg.2% is not online."
                stop
            set {_new} to {_lowest}
            if arg.1 is "set":
                if arg.3 is not set:
                    send "{@prefix}&cSay which rank: /rank set %arg.2% <rank>. &7/rank list shows them."
                    stop
                if not (ranks() contains arg.3):
                    send "{@prefix}&cThere is no rank called %arg.3%. &7/rank list shows the ones there are."
                    stop
                set {_new} to lowercase arg.3
            give_rank(arg.2, {_new})
            set {_looks} to shown({_new})
            send "{@prefix}&f%arg.2% &7is now %{_looks}%&7."
            if {@announce} is true:
                broadcast "{@prefix}&f%arg.2% &7is now %{_looks}%&7!"
            stop
        send "{@prefix}&cUse /rank, /rank list, /rank info <player>, /rank set <player> <rank> or /rank remove <player>"

SetupServer.hs

# ==============================================================
#  SetupServer.hs - sets a new server up with one command
# ==============================================================
#
# Requires: 1.7.38
# Author: HyperScript Team
# Tags: setup, install, server template, admin
#
# /setupserver    install the scripts chosen below and give
#                 them your server's name and address
# /updateserver   fetch the newest version of every script the
#                 setup installed
#
# Run it once on a new server. It asks whether the scripts that
# are there should go first, fetches the ones chosen below from
# the HyperScript website into a folder of their own,
# scripts/ServerSetup, asks you in chat what your server is
# called and what its address is, and writes both into the
# options of what it installed. On the way it asks whether you
# want the extras as well: quests with a /quests menu.
#
# Notes
#  - What is installed is chosen in "options:" below. Put false
#    after one to leave it out.
#  - It always asks first whether every other script should be
#    taken out. Say n and nothing is taken out: the new scripts
#    are installed beside what you have. Scripts that are taken
#    out are not destroyed: they are moved to plugins/
#    HyperScript/removed-scripts, from where they can be put
#    back.
#  - Extras are not installed unless you say y when it asks:
#    Quests.hs, eleven quests and a /quests menu. Anything but
#    y leaves it out, and it can be added later by running
#    /setupserver again or with /hs install Quests. It needs
#    HyperScript 1.7.64 or newer. Put false after "AskQuests"
#    and the question is not asked at all.
#  - The answers you type are not shown to other players.
#  - /setupserver is for server operators only, and the server
#    needs to reach the HyperScript website.
#  - It can be run again: a script that is installed already is
#    left as it is and only given the new name and address.
#  - /updateserver looks at every script in the setup's folder
#    and fetches the ones the website has a newer text of. What
#    you set in their "options:" stays as you set it. Anything
#    else you changed in a file is not carried over: the file as
#    it was is kept beside the new one, as <name>.hs.old.
#  - The scripts go into scripts/ServerSetup, so they stay apart
#    from your own. "folder" below names it. One of them that
#    is in the scripts folder itself from an earlier setup is
#    taken out, so that it does not run twice.

options:
    # The folder inside the scripts folder that the scripts are put in.
    folder: "ServerSetup"
    InstallSidebar: true # The sidebar that shows people stats about the server on the right of the screen
    InstallTablist: true # A header, a footer and ranks for the list players see when they hold Tab
    InstallRanks: true # Ranks you give with /rank set, which the sidebar, the tab list and chat all show
    InstallChatPrefixes: true # Everybody's rank in front of what they say in chat
    InstallJoinMessages: true # Random join and leave messages, and a welcome for whoever joins
    InstallDeathMessages: true # Death messages that do not take it seriously, a different one each time
    InstallWorldsManager: true # /world to make, visit and remove worlds
    # Extras: /setupserver asks about each of these before it installs anything. false never asks.
    AskQuests: true # Eleven quests and a /quests menu that shows how far everybody is

command /setupserver:
    description: Set this server up with a sidebar, a tab list, ranks, chat prefixes, join and death messages, /world, and quests if you want them
    permission: op
    players only: true
    trigger:
        send "&3[Setup] &2Setting up the server..."
        # What can be installed: what /hs install is told, and the file it becomes.
        set {_ids} to []
        set {_wanted} to []
        set {_plain} to []
        if {@InstallSidebar} is true:
            append "Sidebar" to {_ids}
            append "{@folder}/Sidebar.hs" to {_wanted}
            append "Sidebar.hs" to {_plain}
        if {@InstallTablist} is true:
            append "TabList" to {_ids}
            append "{@folder}/TabList.hs" to {_wanted}
            append "TabList.hs" to {_plain}
        if {@InstallRanks} is true:
            append "Ranks" to {_ids}
            append "{@folder}/Ranks.hs" to {_wanted}
            append "Ranks.hs" to {_plain}
        if {@InstallChatPrefixes} is true:
            append "ChatPrefixes" to {_ids}
            append "{@folder}/ChatPrefixes.hs" to {_wanted}
            append "ChatPrefixes.hs" to {_plain}
        if {@InstallJoinMessages} is true:
            append "JoinMessages" to {_ids}
            append "{@folder}/JoinMessages.hs" to {_wanted}
            append "JoinMessages.hs" to {_plain}
        if {@InstallDeathMessages} is true:
            append "DeathMessages" to {_ids}
            append "{@folder}/DeathMessages.hs" to {_wanted}
            append "DeathMessages.hs" to {_plain}
        if {@InstallWorldsManager} is true:
            append "WorldsManager" to {_ids}
            append "{@folder}/WorldsManager.hs" to {_wanted}
            append "WorldsManager.hs" to {_plain}
        set {_needed} to size of {_ids}
        set {_done} to 0

        ask player "&3[Setup] &2Should all other scripts be taken out first? &7(y/n, n keeps them)" into {_confirmation} for at most 60 seconds
        if {_confirmation} is not set:
            send "&3[Setup] &cTimed out: the time to reply ran out."
            stop
        if {_confirmation} == "y":
            send "&3[Setup] &2Yes selected. Taking out the other scripts..."
            set {_removed} to 0
            for each {_script} in all scripts:
                if {_script} is not this script:
                    delete script {_script}
                    add 1 to {_removed}
            send "&3[Setup] &2Took out %{_removed}% scripts. &7They are kept in plugins/HyperScript/removed-scripts."
        else if {_confirmation} == "n":
            send "&3[Setup] &2No selected. Your scripts stay; the new ones are installed beside them."
        else:
            send "&3[Setup] &cThat was neither: say y or n."
            stop

        # The extras: asked about one by one, and left out unless the answer is y.
        set {_quests} to false
        if {@AskQuests} is true:
            ask player "&3[Setup] &2Install the extra &fQuests&2 as well? &7(y/n: eleven quests and a /quests menu)" into {_answer} for at most 60 seconds
            if {_answer} == "y":
                set {_quests} to true
                append "Quests" to {_ids}
                append "{@folder}/Quests.hs" to {_wanted}
                append "Quests.hs" to {_plain}
                send "&3[Setup] &2Yes selected. Quests will be installed."
            else if {_answer} is not set:
                send "&3[Setup] &7No answer, so Quests is left out."
            else:
                send "&3[Setup] &2Quests is left out. &7/hs install Quests adds it later."
        set {_needed} to size of {_ids}
        if {_needed} == 0:
            send "&3[Setup] &cNothing is chosen in the options of this script, so there is nothing to install."
            stop

        # One that an earlier setup left in the scripts folder itself would run beside the new one.
        for each {_file} in {_plain}:
            if script {_file} exists:
                delete script {_file}
                send "&3[Setup] &7%{_file}% was in the scripts folder itself and was taken out; it now lives in {@folder}."

        send "&3[Setup] &2Fetching %{_needed}% scripts into scripts/{@folder}..."
        # All of them are asked for at once; this waits until they are there, ten seconds at most.
        for each {_id} in {_ids}:
            execute console command "hs install %{_id}% {@folder}"
        loop 20 times:
            set {_done} to 0
            for each {_file} in {_wanted}:
                if script {_file} exists:
                    add 1 to {_done}
            if {_done} >= {_needed}:
                break
            wait 10 ticks

        send "&3[Setup] &2Fetched %{_done}%/%{_needed}%. Reloading..."
        execute console command "hs reload"
        wait 1 second

        # Which of them are there now: one that could not be fetched is said so, not passed over.
        set {_installed} to []
        for each {_file} in {_wanted}:
            if script {_file} exists:
                append {_file} to {_installed}
            else:
                send "&3[Setup] &c%{_file}% is not there. &7Is the website reachable? Try /hs install again later."
        if size of {_installed} == 0:
            send "&3[Setup] &cNothing was installed, so there is nothing to set up."
            stop

        ask player "&3[Setup] &2What is your server called?" into {_servername} for at most 60 seconds
        if {_servername} is not set:
            send "&3[Setup] &cTimed out. &7The scripts are installed; run /setupserver again to name the server."
            stop
        ask player "&3[Setup] &2What is its address? &7(say none if it has none yet)" into {_address} for at most 60 seconds
        if {_address} is not set:
            set {_address} to "none"

        # Every script that was installed and has a name or an address among its options gets yours.
        for each {_file} in {_installed}:
            if option "name" of script {_file} is set:
                set option "name" of script {_file} to {_servername}
            if {_address} is not "none":
                if option "address" of script {_file} is set:
                    set option "address" of script {_file} to {_address}

        execute console command "hs reload"
        send "&3[Setup] &2Setup finished! &7%size of {_installed}% scripts are running for &f%{_servername}%&7."
        if {@InstallRanks} is true:
            send "&3[Setup] &7Give yourself a rank with &f/rank set %player.name% owner&7."
        if {_quests} is true:
            if script "{@folder}/Quests.hs" exists:
                send "&3[Setup] &7Players take quests from the menu of &f/quests&7."

command /updateserver:
    description: Fetch the newest version of every script the setup installed
    permission: op
    trigger:
        # Everything the setup can install; the ones that are in its folder are the ones to update.
        set {_ids} to []
        for each {_id} in ["Sidebar", "TabList", "Ranks", "ChatPrefixes", "JoinMessages", "DeathMessages", "WorldsManager", "Quests"]:
            if script "{@folder}/%{_id}%.hs" exists:
                append {_id} to {_ids}
        set {_needed} to size of {_ids}
        if {_needed} == 0:
            send "&3[Setup] &cThere is nothing in scripts/{@folder} to update. &7Run /setupserver first."
            stop
        send "&3[Setup] &2Asking the website about %{_needed}% scripts..."
        # Installing a script that is there fetches a newer one, and keeps what its options are set to.
        for each {_id} in {_ids}:
            execute console command "hs install %{_id}% {@folder}"
        wait 5 seconds
        execute console command "hs reload"
        send "&3[Setup] &2Done. &7The console says which scripts were newer. Your options were kept, and the files as they were are beside the new ones as <name>.hs.old."

TabList.hs

# ==============================================================
#  TabList.hs - a header, a footer and ranks for the tab list
# ==============================================================
#
# Requires: 1.7.3
# Author: HyperScript Team
# Tags: tab list, tablist, header, footer, ranks, server template
#
# The list players see when they hold Tab: your server's name
# on top in changing colours, a line about the server below
# it, the player count, their ping, the TPS and the time
# underneath, and every name with its rank in front.
#
# Notes
#  - Everything to set is in "options:" below: the name, the
#    line under it, the address, the colours, how often it is
#    redrawn, and which parts of the footer are shown. Put
#    false after a "show_" option to take that part out.
#  - "refresh" is how often it is redrawn. "title_speed" is how
#    long each colour of the title stays.
#  - The rank in front of a name is the one Ranks.hs gives
#    with /rank set, shown the way Ranks.hs shows it: the same
#    rank the sidebar and the chat prefixes show. It is kept
#    as {%player%.rank_prefix}. Without Ranks.hs names are
#    written in "no_rank" below, with nothing in front.
#  - Everything is drawn again every "refresh", so a rank given
#    while a player is online shows a moment later, and there
#    is no command to learn.
#  - Minecraft sorts the list by name. A script cannot change
#    the order, only what is written.

options:
    # The name on top, the line under it, and the address at the bottom.
    name: "MY SERVER"
    line: "&7Survival &8| &7Minigames &8| &7Events"
    address: "play.example.com"
    # How often it is redrawn, and how long one colour of the title stays.
    refresh: 10 ticks
    title_speed: 10 ticks
    # The colours of the footer: what a part is called, and its value.
    label: "&f"
    value: "&a"
    # Which parts of the footer are shown, and whether names get their rank.
    show_online: true
    show_ping: true
    show_tps: true
    show_time: false
    show_address: true
    show_ranks: true
    # The colour of a name, and what stands in front of one that has no rank.
    name_colour: "&f"
    no_rank: "&7"

# The title, one colour after the other.
local function title():
    set {_frames} to ["&6&l{@name}", "&e&l{@name}", "&f&l{@name}", "&e&l{@name}"]
    set {_count} to size of {_frames}
    set {_frame} to ({temp.tablist.frame} % {_count}) + 1
    return item {_frame} of {_frames}

# What stands in front of a name: the player's rank, as Ranks.hs shows it.
local function rank():
    if {%player%.rank_prefix} is set:
        set {_shown} to {%player%.rank_prefix}
        return "%{_shown}% {@name_colour}"
    return {@no_rank}

local function header():
    set {_title} to title()
    return "\n%{_title}%\n{@line}\n"

# The footer: one line of numbers with a bar between them, and one with the time and the address.
local function footer():
    set {_parts} to []
    if {@show_online} is true:
        append "{@label}Online: {@value}%server.online_players%&7/%server.max_players%" to {_parts}
    if {@show_ping} is true:
        append "{@label}Ping: &b%player.ping% ms" to {_parts}
    if {@show_tps} is true:
        set {_tps} to round(server.tps)
        append "{@label}TPS: {@value}%{_tps}%" to {_parts}
    set {_last} to []
    if {@show_time} is true:
        set {_time} to now formatted as "HH:mm"
        append "&8%{_time}%" to {_last}
    if {@show_address} is true:
        append "&e{@address}" to {_last}
    set {_first} to join {_parts} with "  &8|  "
    set {_second} to join {_last} with "  "
    return "\n%{_first}%\n%{_second}%\n"

local function show_tab():
    set tab header of player to header()
    set tab footer of player to footer()
    if {@show_ranks} is true:
        set {_rank} to rank()
        set tab name of player to "%{_rank}%%player.name%"

# One step of the title for everybody, so that every tab list changes together.
every {@title_speed}:
    add 1 to {temp.tablist.frame}

every {@refresh} for all players:
    show_tab()

on player join:
    show_tab()

WorldsManager.hs

# ==============================================================
#  WorldsManager.hs - make, visit and remove worlds with /world
# ==============================================================
#
# Requires: 1.7.50
# Author: HyperScript Team
# Tags: worlds, world, teleport, admin, server template
#
# /world                      what /world can do
# /world list                 every world, and who is in it
# /world create <name> [kind] make a world: normal, flat, void,
#                             amplified, nether or end
# /world tp <name> [player]   go to a world, or send somebody
# /world delete <name>        remove a world for good
# /world load <name>          bring a world into memory
# /world unload <name>        let go of a world, files stay
# /world setspawn             the world's spawn is where you stand
# /world info [name]          what kind of place a world is
# /world rule <rule> <value>  change a game rule of your world
# /world time <time>          day, noon, night, midnight
# /world weather <weather>    clear, rain or thunder
# /world difficulty <level>   peaceful, easy, normal or hard
#
# Notes
#  - Everything is for whoever has the permission in "admin";
#    with "everyone_may_visit" every player may use
#    /world tp and /world list.
#  - A world is made the moment you ask, which makes the server
#    stand still for a few seconds. Do it when it is quiet.
#  - Only worlds made with /world create (or by another script)
#    can be deleted. The worlds the server came with are safe.
#  - /world delete asks you to say it twice. What is deleted is
#    gone: there is no way back but a backup of your own.
#  - Players in a world that is unloaded or deleted are sent to
#    the main world first.
#  - /world tp waits "wait" seconds and is called off if you
#    move, unless you have the admin permission. Put 0 to go at
#    once. Nobody is sent while they are in a fight.
#  - A world keeps its name, kind and spawn across restarts.

options:
    name: "MY SERVER"
    # What stands in front of every message.
    sign: "&8[&bWorlds&8] "
    # The permission for everything but visiting.
    admin: "worlds.admin"
    # true lets every player use /world tp and /world list.
    everyone_may_visit: false
    # Seconds a player stands still before /world tp takes them. 0 for none.
    wait: 3
    # The world nobody may unload or delete, whatever it is called on your server.
    main_world: "world"

function kinds():
    return ["normal", "flat", "void", "amplified", "nether", "end"]

function may_visit({_who}):
    if {@everyone_may_visit} is true:
        return true
    return {_who} has permission "{@admin}"

function help({_who}):
    send "{@sign}&7What /world can do:" to {_who}
    send "&b/world list &8- &7every world" to {_who}
    send "&b/world tp <name> [player] &8- &7go to a world" to {_who}
    if {_who} has permission "{@admin}":
        send "&b/world create <name> [kind] &8- &7normal, flat, void, amplified, nether, end" to {_who}
        send "&b/world delete <name> &8- &7remove a world for good" to {_who}
        send "&b/world load <name> &8/ &bunload <name>" to {_who}
        send "&b/world setspawn &8- &7the spawn is where you stand" to {_who}
        send "&b/world info [name] &8- &7about a world" to {_who}
        send "&b/world rule <rule> <value> &8- &7a game rule of your world" to {_who}
        send "&b/world time <day|noon|night|midnight>" to {_who}
        send "&b/world weather <clear|rain|thunder>" to {_who}
        send "&b/world difficulty <peaceful|easy|normal|hard>" to {_who}

command /world [action] [first] [second]:
    description: Make, visit and remove worlds
    aliases: /worlds, /wm
    tab complete: ["list", "tp", "create", "delete", "load", "unload", "setspawn", "info", "rule", "time", "weather", "difficulty"]
    tab complete 2: server.worlds
    trigger:
        if arg.1 is not set:
            help(player)
            stop
        set {_action} to lowercase arg.1

        # ---- list
        if {_action} is "list":
            if may_visit(player) is false:
                send "{@sign}&cYou may not do that."
                stop
            send "{@sign}&7Worlds:"
            for each {_world} in server.worlds:
                set {_inside} to 0
                for each {_name} in server.players:
                    if world of location of {_name} is {_world}:
                        add 1 to {_inside}
                send "&a%{_world}% &8- &7%{_inside}% player(s)"
            for each {_world} in created worlds:
                if {_world} is not in server.worlds:
                    send "&8%{_world}% &8- &7not loaded &8(/world load %{_world}%)"
            stop

        # ---- tp
        if {_action} is "tp" or {_action} is "teleport" or {_action} is "go":
            if may_visit(player) is false:
                send "{@sign}&cYou may not do that."
                stop
            if arg.2 is not set:
                send "{@sign}&7Use &b/world tp <name> [player]"
                stop
            if arg.2 is not in server.worlds:
                if world arg.2 exists:
                    send "{@sign}&7%arg.2% is not loaded. &b/world load %arg.2%"
                else:
                    send "{@sign}&cThere is no world called %arg.2%."
                stop
            if arg.3 is set:
                if player does not have permission "{@admin}":
                    send "{@sign}&cYou may only send yourself."
                    stop
                if arg.3 is not online:
                    send "{@sign}&c%arg.3% is not here."
                    stop
                teleport arg.3 to spawn of world arg.2
                send "{@sign}&7You were sent to &b%arg.2%&7." to arg.3
                send "{@sign}&7%arg.3% was sent to &b%arg.2%&7."
                stop
            if player has permission "{@admin}" or {@wait} is 0:
                teleport player to spawn of world arg.2
                send "{@sign}&7Welcome to &b%arg.2%&7."
                stop
            if player is in combat:
                send "{@sign}&cNot while you are fighting."
                stop
            teleport player to spawn of world arg.2 after {@wait} seconds unless they move
            stop

        # ---- everything below is for admins
        if player does not have permission "{@admin}":
            send "{@sign}&cYou may not do that."
            stop

        if {_action} is "create" or {_action} is "new":
            if arg.2 is not set:
                send "{@sign}&7Use &b/world create <name> [kind]"
                send "&7Kinds: &f%kinds()%"
                stop
            if world arg.2 exists:
                send "{@sign}&cThere is a world called %arg.2% already."
                stop
            set {_kind} to "normal"
            if arg.3 is set:
                set {_kind} to lowercase arg.3
            if {_kind} is not in kinds():
                send "{@sign}&c%{_kind}% is not a kind of world. &7Kinds: &f%kinds()%"
                stop
            send "{@sign}&7Making &b%arg.2% &7(%{_kind}%). The server stands still for a moment..."
            wait 1 second
            if {_kind} is "flat":
                create world arg.2 flat
            else if {_kind} is "void":
                create world arg.2 void
            else if {_kind} is "amplified":
                create world arg.2 amplified
            else if {_kind} is "nether":
                create world arg.2 nether
            else if {_kind} is "end":
                create world arg.2 end
            else:
                create world arg.2
            set {worlds.kind.%arg.2%} to {_kind}
            send "{@sign}&aDone. &b/world tp %arg.2% &7takes you there."
            stop

        if {_action} is "delete" or {_action} is "remove":
            if arg.2 is not set:
                send "{@sign}&7Use &b/world delete <name>"
                stop
            if arg.2 is "{@main_world}":
                send "{@sign}&cThe main world cannot be deleted."
                stop
            if arg.2 is not in created worlds:
                send "{@sign}&c%arg.2% was not made with /world create, so it is left alone."
                stop
            set {_ask} to "delete %arg.2%"
            if {%player%.worlds_sure} is not {_ask}:
                set {%player%.worlds_sure} to {_ask}
                send "{@sign}&cThis deletes &f%arg.2% &cand everything built in it, for good."
                send "&7Say &b/world delete %arg.2% &7once more to do it."
                stop
            delete {%player%.worlds_sure}
            delete world arg.2
            delete {worlds.kind.%arg.2%}
            send "{@sign}&7%arg.2% is gone."
            stop

        if {_action} is "load":
            if arg.2 is not set:
                send "{@sign}&7Use &b/world load <name>"
                stop
            if world arg.2 exists is false:
                send "{@sign}&cThere is no world called %arg.2%."
                stop
            send "{@sign}&7Loading &b%arg.2%&7..."
            load world arg.2
            send "{@sign}&aLoaded."
            stop

        if {_action} is "unload":
            if arg.2 is not set:
                send "{@sign}&7Use &b/world unload <name>"
                stop
            if arg.2 is "{@main_world}":
                send "{@sign}&cThe main world cannot be unloaded."
                stop
            if arg.2 is not in server.worlds:
                send "{@sign}&c%arg.2% is not loaded."
                stop
            unload world arg.2
            send "{@sign}&7%arg.2% is unloaded. Its files are still there."
            stop

        if {_action} is "setspawn":
            set {_here} to world of player's location
            set spawn of world {_here} to player's location
            send "{@sign}&aThe spawn of %{_here}% is where you stand."
            stop

        if {_action} is "info":
            set {_which} to world of player's location
            if arg.2 is set:
                set {_which} to arg.2
            if {_which} is not in server.worlds:
                send "{@sign}&c%{_which}% is not loaded."
                stop
            set {_inside} to []
            for each {_name} in server.players:
                if world of location of {_name} is {_which}:
                    append {_name} to {_inside}
            send "{@sign}&b%{_which}%"
            if {worlds.kind.%{_which}%} is set:
                send "&7Kind: &f%{worlds.kind.%{_which}%}%"
            send "&7Spawn: &f%spawn of world {_which}%"
            send "&7Difficulty: &f%difficulty of world {_which}%"
            send "&7Players: &f%size of {_inside}%"
            if size of {_inside} > 0:
                send "&7%{_inside}%"
            stop

        if {_action} is "rule" or {_action} is "gamerule":
            if arg.3 is not set:
                send "{@sign}&7Use &b/world rule <rule> <value>&7, such as &b/world rule keepInventory true"
                stop
            set {_here} to world of player's location
            set gamerule arg.2 of world {_here} to arg.3
            send "{@sign}&7%arg.2% is now &f%gamerule arg.2 of world {_here}% &7in %{_here}%."
            stop

        if {_action} is "time":
            set {_here} to world of player's location
            set {_ticks} to parse arg.2 as number
            if arg.2 is "day":
                set {_ticks} to 1000
            else if arg.2 is "noon":
                set {_ticks} to 6000
            else if arg.2 is "night":
                set {_ticks} to 13000
            else if arg.2 is "midnight":
                set {_ticks} to 18000
            if {_ticks} is not set:
                send "{@sign}&7Use &b/world time <day|noon|night|midnight>"
                stop
            set time in world {_here} to {_ticks}
            send "{@sign}&7It is %arg.2% in %{_here}%."
            stop

        if {_action} is "weather":
            if arg.2 is not in ["clear", "rain", "thunder"]:
                send "{@sign}&7Use &b/world weather <clear|rain|thunder>"
                stop
            set {_here} to world of player's location
            set weather in world {_here} to arg.2
            send "{@sign}&7The weather in %{_here}% is %arg.2%."
            stop

        if {_action} is "difficulty":
            if arg.2 is not in ["peaceful", "easy", "normal", "hard"]:
                send "{@sign}&7Use &b/world difficulty <peaceful|easy|normal|hard>"
                stop
            set {_here} to world of player's location
            set difficulty of world {_here} to arg.2
            send "{@sign}&7%{_here}% is now %arg.2%."
            stop

        help(player)

Looking for more? People who use HyperScript share theirs under User-made scripts.