RFC Dimensions support and new Level+Dimensions API

Discussion in 'Contributing & RFCs' started by dktapps, Dec 13, 2016.

?

Which design do you think should be used to implement dimensions into PocketMine?

  1. Level with Dimensions

  2. Level with SubLevels

  3. Can't decide either way

Results are only viewable after voting.
  1. dktapps

    dktapps Administrator Staff Member PMMP Team

    Messages:
    764
    GitHub:
    dktapps
    Opening

    It's long past time PocketMine-MP got support for dimensions. While there are nice simple dirty ways to do this, such as that implemented in Genisys currently, these aren't scalable at all. Can you have more than one Nether? Nope. Can you automatically load PC Nethers? Nope. So dump that idea in the bin where it belongs, along with Genisys itself.

    The design I am working on is aimed at PocketMine-MP 1.6.2, as indicated in https://github.com/pmmp/PocketMine-MP/issues/149.

    Basic goals:
    • Load, travel to, work in and save dimensions from PC world formats, and also PE once we get LevelDB to work with php7.
    • Be able to have per-world dimensions. Portals in world A's Overworld will take you to world A's Nether or End.
    More advanced goals:
    • Provide a clean, easy-to-use API for plugin developers to add their own custom dimensions and modify the behaviours of existing ones.
    Design
    After a lot of planning and discussion, it became clear that there were two distinct ways this could be done, which will be described below. It is absolutely critical that we get this right, as such an upgrade could be dramatically breaking for backwards compatibility, and it needs to be worth the time and effort.

    Approach 1: Level as a Dimension Manager, with an array of Dimensions
    This was the design I initially opted for. Most things Level would be refactored out into a Dimension class, which all dimensions would then extend. Level would then be a manager of an array of Dimensions, with some basic methods for worldwide stuff like time management.

    This would allow stripping a lot of things out of Level into Dimension, which would draw a distinct line between what should be handled globally in the Level, and what should be handled locally in the Dimensions.

    Such a design would look something like this:
    • Level (with basic global methods like setTime(), getName(), blah)
      • Overworld dimension
      • Nether dimension
      • The End dimension
      • Custom dimensions
    In a class-based hierarchy:
    Code:
    Level (with basic global methods for handling time etc)
     - Dimension[]
       - Dimension (overworld)
       - Dimension (nether)
       - Dimension (the end)
       - Dimension (custom dimensions)
    
    This design I believe is the cleanest way to do this, since it conforms with the way vanilla Minecraft handles dimensions.

    However, such a design would be potentially extremely breaking to backwards compatibility and would be a very large amount of work to complete. The majority of Level functionality would need to be refactored out into Dimensions, which would break near enough every plugin that does anything remotely to do with Levels. Which is a hell of a lot of broken plugins.

    I started to wonder if this was overkill just for a slightly cleaner design when similar things can be achieved with the design laid out below.

    Approach 2: Level with sub levels
    This design came to mind after realizing the design above would be a very large task, and is similar to the design originally suggested at https://github.com/PocketMine/PocketMine-MP/issues/3149 of having recursive levels. This involves having a regular Level as it is now, but with child levels (Nether, End, custom dimensions) which would extend the Level class.

    This would be much easier to implement, and much less breaking for backwards compatibility. However, I don't think it is a good approach because it blurs the line between Dimensions and Levels. A Level is not a Dimension. However, with this design they could be treated that way to reduce the amount of changes needed to PocketMine and to keep breaking API modifications to a minimum. This may be beneficial to those who will still want to use older plugins which depend on Level functionality.

    This design would look something like:
    • Level as Overworld
      • Nether sublevel
      • The End sublevel
      • Custom dimension sublevels
    In a class hierarchy:
    Code:
    Level (overworld)
     - SubLevel[] (dimensions)
       - SubLevel (nether)
       - SubLevel (the end)
       - SubLevel (custom dimensions)
    
    Summary
    What this ultimately comes down to is whether to refactor everything out to separate Levels and Dimensions, or whether to make them as one. Is it worth breaking lots of plugins for the sake of separating the two?

    I'm very much torn on this and totally unable to decide. Let's see what the community thinks.
     
    Last edited: Dec 14, 2016
  2. robske_110 (Tim)

    robske_110 (Tim) Wither Skeleton Poggit Reviewer

    Messages:
    1,373
    GitHub:
    robske110
    ~WIP post, sent because of *need sleep*~
    I am for the Approach1, while understanding that this may break some plugins. (Very vague expressed) I don't think it is an overkill in any way, otherwise Mojang would have managed to design something right :eek:! But anyways, as MCPE/PC also use this approach, i think we also should follow it. It will be much nicer to work with this afterwards and it may resolve many issues that may come up during the sublevel approach. To be continued...
    E1: And of course Dylan has the right to finally decide this, because he will do the work (dimensions are much work) and he will get the blame, if any....
     
    dktapps likes this.
  3. XenialDan

    XenialDan Baby Zombie

    Messages:
    137
    GitHub:
    thebigsmilexd
    I am for the level(s) with dimensions. It would support the vanilla format. And due to me implementing as many vanilla features as possible and pc compatibility (for example gamerules | blocks), i support this and you fully with that. If you need help by a 'noob', contact me.
     
    dktapps likes this.
  4. Dinokiller

    Dinokiller Spider Jockey

    Messages:
    35
    My understanding of this is that for every level you get all the dimensions created with it. Why not just have each Level have it's own set dimension type? If memory serves I'm fairly sure that's how Bukkit did it.
     
  5. robske_110 (Tim)

    robske_110 (Tim) Wither Skeleton Poggit Reviewer

    Messages:
    1,373
    GitHub:
    robske110
    Yea, it is how bukkit did it and it turned out to be f(d)ucking annoying. To have 3 world folders for one world.
     
    XenialDan and dktapps like this.
  6. dktapps

    dktapps Administrator Staff Member PMMP Team

    Messages:
    764
    GitHub:
    dktapps
    PocketMine is already way too much "copy from Bukkit" and look at the mess that's resulted from doing so.
     
  7. Dinokiller

    Dinokiller Spider Jockey

    Messages:
    35
    I'm talking like having a method such as Level::getDimensionType(). That doesn't mean you need "world_the_end" and "world_nether" and "world" worlds for every world you have.
     
  8. dktapps

    dktapps Administrator Staff Member PMMP Team

    Messages:
    764
    GitHub:
    dktapps
    The world saves aren't the issue; the actual code structure is the problem. World saves will be formatted the way PC saves are, regardless of which approach we choose. It's a question of whether to separate Dimensions and Levels, or whether to squash them into one.
     
  9. Dinokiller

    Dinokiller Spider Jockey

    Messages:
    35
    I know world saves aren't the issue. Read my post again you silly man. :p
     
    dktapps likes this.
  10. Sandertv

    Sandertv Skeleton Poggit Reviewer

    Messages:
    800
    GitHub:
    Sandertv
    It's quite a hard decision to make, but I too would vote for the first approach. It's quite tempting to go for the second approach, as it will give more time to implement other features, but it would be the best for later times to go for the first approach. So... That's what I'm going for.
     
  11. AryToNeX

    AryToNeX Creeper

    Messages:
    1
    GitHub:
    arytonex
    What if you guys manage levels and dimensions the way MCPC server softwares (Bukkit/Spigot) do?
    • world
    • world_nether
    • world_the_end
    • world_custom
    I think it'll be much easier and in line with Bukkit/Spigot world importing.
     
  12. dktapps

    dktapps Administrator Staff Member PMMP Team

    Messages:
    764
    GitHub:
    dktapps
     
  13. dktapps

    dktapps Administrator Staff Member PMMP Team

    Messages:
    764
    GitHub:
    dktapps
    This is the second, easier method I laid out above. I don't like it because it makes Dimensions and Levels the same thing, but it is undeniably simpler to implement and less BC breaking, which is why I'm giving it consideration.

    I don't know if it is worth making a potentially huge BC break for the purposes of a slightly nicer design, especially when there is a much simpler way to do it.
     
  14. aliuly

    aliuly Silverfish

    Messages:
    23
    GitHub:
    alejandroliu
    I think the first approach is the cleanest. However since it breaks backward compatibility it should be slated for a major API version bump (i.e. API v3).

    The pragmatic approach would be to implement the Level/Sublevel method for now, and replace it for the Level/Dimension when there is a major PocketMine-MP rewrite.
     
    archie426, dktapps and Magicode like this.
  15. dktapps

    dktapps Administrator Staff Member PMMP Team

    Messages:
    764
    GitHub:
    dktapps
    This is a sensible suggestion; however I wonder if it is worth delaying such an upgrade. Quick support now, mess clean up later?
     
    Magicode likes this.
  16. Magicode

    Magicode Baby Zombie

    Messages:
    189
    GitHub:
    magicode1
    Well, it may be good to just break compatibility now, since PMMP doesn't even have an official plugin 'list' yet. If you get this upgraded before Poggit releases, then plugins on the list won't be confusingly outdated when it does get upgraded.
     
    dktapps and Sandertv like this.
  17. SOFe

    SOFe Administrator Staff Member PMMP Team Poggit Admin

    Messages:
    1,933
    GitHub:
    sof3
    There won't be a problem with Poggit. I will make sure outdated plugins are clearly labelled.
    Don't get ourselves trapped in the past forever. Many things need to be broken to be improved anyway, so let's break everything once rather than breaking something every time.
     
  18. dktapps

    dktapps Administrator Staff Member PMMP Team

    Messages:
    764
    GitHub:
    dktapps
    My objection to doing what @aliuly suggested is the differences in API that would result. Say I write plugin A that depends on API 2.2 with Sublevel-style dimensions API, and then API 3.0 rolls around with a proper dimensions implementation, and I have to rewrite plugin A for that: is it worth doing it twice? I don't think so. I think whichever we decide on is what we should stick with, because changing it later will double the work and the confusion. So I quote this, albeit from a different perspective.
     
  19. Thunder33345

    Thunder33345 Moderator Staff Member

    Messages:
    2,159
    GitHub:
    Thunder33345
    I am thinking of
    using a link/group approach
    Code:
    worldfolder
    - world1
    -- dimension overworld, link ID 1
    - endworld
    -- dimension end, link ID 1
    - nether1
    -- dimension nether, link ID 1
    - custom world
    -- dimension custom, link1
    - custom world2
    -- dimension customid2
    
    link and dimension will be stored inside of level.dat
    linkID would be needed for the portal to work and it will be optional so in if there multiple targeted dimension with same link id
    Code:
    - world; dimension overworld, link ID 1
    - nether1; dimension nether, link ID 1
    - nether2; dimension nether, link ID 1
    
    in example of that, it would not work as if same with no nether ware present
    i think these ware all the possible concern if using that kind of structure
    as a after thought: time etc would cram into every world means every world can have it's own time

    I understand on one ask for more ways to do it and it is a of 1,2,3 not tell us how you would do it if you ware me but here goes nothing

    EDIT: fixed spoiler formatting
     
  20. XenialDan

    XenialDan Baby Zombie

    Messages:
    137
    GitHub:
    thebigsmilexd
    (Re-read the thread please lol)
    So then, what about adding a Dimensions class instead?
    (btw, some cores have Level::getDimension, ClearSky returns the value from the level.dat)
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.