How HSP Works
This page is a description of how HSP works, which is intended to help someone understand the internals of how HSP does what it does and help you troubleshoot any problems you might be having getting things working the way you want.
HSP hooks the Bukkit PlayerJoinEvent and PlayerRespawnEvent. It hooks some other stuff too, but these two do most of the work, as they cover the HSP "onJoin" event and "onDeath" event, which is what most people install HSP to get control over.
HSP works by allowing you to define strategy chains that you want it to try out when these events happen. What does it mean to "try out" a strategy? Basically not every strategy will always return a value. Let's look at an example:
events: onDeath: - homeLocalWorld - spawnLocalWorld - spawnDefaultWorld
Let's say you have 3 worlds: world, creative and skylands. With this setup, lets say a player dies in skylands. HSP hits the homeLocalWorld strategy you defined first and so it will check to see if they have a home set in skylands and if they do, it sends the player there, no other strategies are fired.
However, lets say they didn't have a home set in skylands. HSP moves on to the next strategy spawnLocalWorld. So if you have at some point done a /setspawn command while in skylands to setup an HSP spawn point there, HSP will find this spawn and send the player there. If you haven't done so, HSP will hit the last strategy spawnDefaultWorld which will send the player to the spawn on your default world (usually world, unless you change it in the config).
HSP allows you to use one of several data storage options, controlled via the config parameter core.storage (config options). You can use Bukkit ebeans which either writes to a SQLite database (plugins/HomeSpawnPlus/HomeSpawnPlus.db) or to MySQL, depending on how you have configured your bukkit.yml. The documentation available for Bukkit ebeans is sparse, but what little exists can be found here, which covers the basic setup. As long as you don't run into issues, this is usually good enough. If you do run into issues, I don't offer any help with that as debugging your database/ebeans setup is beyond the scope of HSP; I simply use the facility Bukkit provides (and fortunately 99% of the time it just works).
Your other option is to use the YAML back-end, which uses Bukkit's new YAML facility that provides some efficient caching of YAML files. For small to medium sized installations (in the few thousand home range), this is probably more than fine.
In any case, I will refer to the HSP database throughout the online documentation and when doing so, I am referring to the back-end of your choice, whether that's SQLite, MySQL or YAML, it's collectively known as the HSP database.
It's important to note that HSP keeps track of the spawns you setup in it's own database. Bukkit has a separate single spawn per map that Bukkit keeps track of as part of your world files. Using the HSP core.override_world option, you can keep these two in sync so that if you ever uninstall HSP, your spawns don't change. However, that obviously only works for the simple case where you've only defined a single spawn per world. HSP can keep track of multiple named spawns per world, which you can take advantage of in various strategies such as spawnNearest, spawnLocalRandom and spawnNamedSpawn.
HSP homes are also stored in HSP's database and are separate from the single Bukkit home per player/world that Bukkit saves in the map (Bukkit's homes are not used/referenced by HSP in any way).
HSP keeps track of two flags per home, a bed flag and a default flag. You can use or ignore these as you like, there are strategies and modes that can pay attention to these two flags to allow you to do different things. For example, most strategies use the default home on a given world (which can be the same as the bed home), so you can optionally enable the /setdefaulthome command for your players and allow them to change their default home, which could then change where they spawn at on death. Or, lets say you want players to only be able to respawn at a home set via bed, but you let them pay for /home to their other homes for a cost; that's also possible (an in fact, documented in Example 4).
For details about the many different options that are available for configuring "bed homes", please review the bedHomes page.
Per-permission and Per-world options
HSP has a number of options that can be enabled per-permisson and also per-world. The options that support this are events, cooldowns, warmups, costs and homeLimits. Check the config_defaults.yml file in your HomeSpawnPlus directory for examples of the syntax or you can view it online here.
HSP considers per-permission more specific than per-world. So what to do if you have a group creative that you want to do something special with on your creative world, but not on your regular world? Permission systems allow you to define permissions per-world, so you should give your players creative permissions only on the creative world, and then on the regular world, your per-world or default HSP policies will apply.
Per-permissions and groups; an example
A point most people get tripped up on is that they look at Bukkit permissions this way: they have a group they setup and then they have permissions that plugins define that they assign to those groups, such as hsp.command.home. In truth, permissions are just arbitrary strings that you or a plugin dev make up and Bukkit just checks to see if they are assigned to a given player (which your permission plugin probably allows you to conveniently organize into groups).
So as an example, let's say you want to setup per-permission costs for HSP. How do you assign costs for group A different from group B? HSP looks for whatever permissions you tell it to, so the answer is, however you want. Here are some examples:
# example1: "group.A" and "group.B". # you must assign the permission "group.A" to your group A using your permission system, same for group.B cost: permission: entry1: permissions: - group.A home: 500 entry2: permissions: - group.B home: 250 # example2: multiple groups per section, groups A&B pay 500, group C pays 250 and anyone # that isn't in one of those two groups pays 1000 (the default) cost: home: 1000 permission: entry1: permissions: - group.A - group.B home: 500 entry2: permissions: - group.C home: 250 # example3: use made-up permissions, assign "hsp.cost.1" to all groups/players you # want to have the 500 cost cost: permission: entry1: permissions: - hsp.cost.1 home: 500 entry2: permissions: - hsp.cost.2 home: 250
As you can see, HSP doesn't care what permission string you tell it to use, it just checks for whatever you tell it.
Beware permission system inheritance
One last important point is that HSP checks in the order you give it AND that most permission systems propagate permissions upwards through inherited groups. Let's look at a broken example:
events: onJoin: - spawnLocalSpawn permission: entry1: permissions: - group.Member onJoin: - homeLocalWorld - spawnNamedSpawn:member entry2: permissions: - group.VIP onJoin: - homeLocalWorld - spawnNamedSpawn:vip
While this is a perfectly valid HSP configuration, chances are it will not work like you expect. Why? Because you will assign your group.Member permission to your Member group and you will assign your group.VIP group to your VIP group. All seems good so far, except that most permissions systems propagate permissions upwards, so if your VIP group inherits your Member group, your VIP people will ALSO have the group.Member permission. Which in the above example, means HSP will hit entry1, check for group.Member, see that your VIP members have it and then spawn them at your "member" spawn.
So how do you fix it? Simple, put your VIP entry first. Your VIPs will hit it and spawn at their VIP spawn. Your Members will not hit it because they don't have the group.VIP permission so they will fall through to the next entry and then end up a their member spawn.