-
-
Notifications
You must be signed in to change notification settings - Fork 140
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reworking Worlds management (introducing GameWorld & GameMode) #408
Conversation
I would like to be able to specify multiple shems in each world, so I am for this change. The only thing that I do not like, is method plugin.getWorlds(), as it returns WorldManager, not worlds, so it is counter-intuitive. |
@@ -23,7 +24,7 @@ public BlockEndDragon(BentoBox plugin) { | |||
*/ | |||
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) | |||
public boolean onDragonSpawn(CreatureSpawnEvent e) { | |||
if (!e.getEntityType().equals(EntityType.ENDER_DRAGON) || plugin.getIWM().isDragonSpawn(e.getEntity().getWorld())) { | |||
if (!e.getEntityType().equals(EntityType.ENDER_DRAGON) || plugin.getWorlds().getGameWorld(e.getEntity().getWorld()).map(gameWorld -> gameWorld.getSettings().isDragonSpawn()).orElse(false)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a bit "too much" there. How could we make this API call less big?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One way is to create new method in BentoBox plugin
plugin.getGameWorld(World) { return this.worldManager.getGameWorld(World); }
Another good nanosecond optimization is to create new variable in this method
if (!e.getEntityType().equals(EntityType.ENDER_DRAGON))
{
World world = e.getEntity().getWorld();
if (plugin.getGameWorld(world).map(gameWorld -> gameWorld.getSettings().isDragonSpawn()).orElse(false))) { // do staff }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if the plugin.getGameWorld(World) { return this.worldManager.getGameWorld(World); }
method would be a good idea.
In regards of the variable - that's a no, I think. That'd definitely make the condition look "lighter" but it'll mainly create this unnecessary variable at each call.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So internal variable is an optimization, as it avoid multiple calls for .getEntity().getWorld()
Its small, but in some cases a necessary optimization, to avoid unnecessary method calls.
So it improves performance over memory usage.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not an optimization. getEntity().getWorld()
are just getters that return a value that is part of the object - there is no calculations done there.
What I could do, however, is providing a method to directly access the GameSettings of a GameWorld...
@Poslovitch Thanks for this. It takes a big man to be subjective and say "I'm not sure about this". I'm on holiday now so I'll take a look at this and give you my thoughts. Thanks again! |
This will load all schems in an add-on's schem folder if it exists and associate them with this world set (overworld, nether and end). Schems can be named anything, but the partner nether or end worlds must be pre-fixed with "nether-" or "end-" in the filename. Additional schems can be added by the admin into the schem folder, or they can be stored in the jar file of the add-on. Both are supported. No changes are required to current add-ons. I.e., there is no API breakage here, but I would like to rename the SchemsManager method loadIslands(World world) to be loadSchems(World world) in the future. Related issues/PR: #104 #207 #378 #408
@Poslovitch Thanks again for the work. Just looking this, although you mentioned the current API is:
that is not actually correct - the current API is:
This is because Location already contains the World so it's not required to have it as a parameter. Unfortunately, the new API now requires the world parameter no matter what:
Also, the code above will require a null check on "getGameWold(World)" and getIslandAt(Location) because there may not be a game world in world, e.g., it could be another world on the server.and there may not be an island here. So that's two checks. With the current API, the returning Optional can be used quickly and easily for any world. So, in regards to making the API cleaner, this is not a step in the right direction and the current API is actually about as small as you can get I think... Just stepping back a bit - having a GameWorld class is not bad, but I don't think we have to have to put an IslandManager in each one. Indeed, keeping the IslandManager (by the way, it could be renamed to be WorldManager if you like) global makes sense because any Location given is a unique keys to identifying islands. Throughout the code, often we have queries for locations, flags or worlds and we just want to ask "is there an island there?" or "is there a setting for this world" and get a result. This can be done easily with a global Island/World Manager. Where a GameWorld class might be useful is to clean up the world, worldSettings and schematics registration in an add-on. Right now, an add-on registers a world with BentoBox using this method:
And then is registers schematics with BentoBox using:
One thing I do like about the new GameWorld class is that you can register both the world and schems in one go and also it forces an add-on that makes worlds to supply schems, which it must do otherwise no islands can ever be made. So, perhaps we can do something around that. In terms of enabling multiple schems, please have a look at #412. This uses the current API and just expands the current approach. I wrote it to see if there were any blockers or optimizations that the current API was limiting. I thought I might hit one, but in the end it went pretty much straightforward. The current UI is just text based (no GUI), but both the /island create and /island reset commands allow the addition of a schem name to them and they check the permission. |
Okay, thanks for the reviews @tastybento and @BONNe. I get the point with this API not making things simpler. That's what I was afraid of. We can consider this PR as declined. |
Related to #378.
Introducing the rework
Although the current "Worlds management" is working fine, it suffers a few downsides:
What is the purpose of this rework ?
Instead of having Worlds as parameters for most of the methods in IslandsManager, I wanted to make us "select the World we want to interact with first". I don't know how to clearly express myself, but here's a "comparison" between the current API and the one I'm working one.
Current API:
Which is like:
from all the islands that are currently managed, get the one from this world at this location.
New API (pseudo-code):
Well...
In facts, when I've started this rework almost a month ago, it seemed to be the best idea ever. But now, I'm unsure.
Is this all worth this big change?
I definitely need some feedback about this one.