kyrptonaught / customportalapi

Developer Api for creating custom portals to any dimension
MIT License
63 stars 22 forks source link

[Tech Question] Sync between client and server upon moving to other dimensions #44

Open Azagwen opened 2 years ago

Azagwen commented 2 years ago

This isn't an issue, but more a Technical Question.

I wanted to use your Portal API for a mod of mine, but unfortunately the API does not really match the type of portal I wanted to make. But then I wanted to ask you guys a question, since you've already tempered with dimension teleporting a lot and managed to make it work.

How does one sync client and server after teleportation? When I teleport the player, weither it's using vanilla methods or yours, my destination world either doesn't load and I fall in the void, or parts of the previous world stay loaded (entities notably), or my player entity enters a loop of being re-created indefinitely while still partly in the previous world (which results in a soft-lock utlimately).

Because of that, I wanted to look at how this API does it to see, but I don't really know what part of it I should look at, so I thought asking directly would be better. Hoping to see a response, and cheers for your great work!

aleck099 commented 2 years ago

The source code of Minecraft is really hard to read.

kyrptonaught commented 2 years ago

CPA does nothing special at all to sync the client, It just uses the minecraft method of teleporting while injecting a custom Teleport Target. Assuming you've taken a look here? Line 42, entity:moveToWorld is the actual vanilla tp method. Adding to this, Line 43-47 helped with some issues of players falling into the void or though blocks after TPing. Though if your dim takes a long time to sync and load, this can only help so much

Have you attempted to use a CPA portal to teleport there? It's possible it could be an issue with your dim. We had a similar issue in the aether, not quite sure what the exact solution was though.

What features of the portals are missing for the type of portal you'd like? It's possible it could still be done with the API. You can use custom portal shapes, and custom forms of activating the portal

Azagwen commented 2 years ago

CPA does nothing special at all to sync the client, It just uses the minecraft method of teleporting while injecting a custom Teleport Target. Assuming you've taken a look here? Line 42, entity:moveToWorld is the actual vanilla tp method. Adding to this, Line 43-47 helped with some issues of players falling into the void or though blocks after TPing. Though if your dim takes a long time to sync and load, this can only help so much

Have you attempted to use a CPA portal to teleport there? It's possible it could be an issue with your dim. We had a similar issue in the aether, not quite sure what the exact solution was though.

What features of the portals are missing for the type of portal you'd like? It's possible it could still be done with the API. You can use custom portal shapes, and custom forms of activating the portal

Thanks for the reply! I did manage to get to my dimensions using CPA actually, and it loaded quite fast, as so far my dim is just a test void, which is why I first thought I might have missed something and decided to ask here. But I never managed to get there without a full CPA portal, except through commands.

My first intuition was to copy the end portal code to derive from it, which uses the moveToWorld method you mentioned, which didn't work. Then I tried to use CPA's methods while modifying it slightly to fit my needs, but no luck with that either

One thing I did notice was that if my dim had been previously loaded manually it would tend to sometimes work (?)

As for the full portal, what I'm trying to do was originally a frame-less one, which later turned into one with a offset position from its frame, and a different trigger than the ones CPA allows. The actual portal blocks being one block below the frame's upper half, and the full frame being 2 blocks tall (one farmland ring + a fully grown crop ring on top of it which would trigger the portal upon fully growing).

The closest CPA can get to this is a flat portal made of farmlands afaik 🤔

I also don't know if it's possible to create a portal with CPA that doesn't spawn a return portal on the other end? Or ones that don't have a frame at all (either player crafted or a fully custom activation process) ?

kyrptonaught commented 2 years ago

Can you post an image showing the design of the portal? It may be doable, or potentially support could be added. One thing to note though, CPA stores the portal data in a hash map using a block as the key. Thus every portal is required to have a unique frame block. BUT there's nothing to say the frame block has to be used in the portal.

CPA can use custom Frame-testers. Here and here.

CPA also has completely custom ignition sources that can be triggered however you'd like.

If you'd like, I could probably show you an example

Azagwen commented 2 years ago

Can you post an image showing the design of the portal? It may be doable, or potentially support could be added. One thing to note though, CPA stores the portal data in a hash map using a block as the key. Thus every portal is required to have a unique frame block. BUT there's nothing to say the frame block has to be used in the portal.

The portal would look like this, as I tried to describe, a fully grown crop ring, with its required supporting farmland, the portal blocks spawning inside of the farmland ring (which results in a 2x5x2 frame in the end + the lack of player-initiated ignition source): image

CPA can use custom Frame-testers. Here and here.

CPA also has completely custom ignition sources that can be triggered however you'd like.

I hadn't noticed that, thanks for letting me know! :o I will probably toy with these whenever I get free time

If you'd like, I could probably show you an example

If you're willing to, that would be welcome! Especially examples of more "unconventional" portals (frame-less portals, weird frame shapes, disconnected frames and portal scenarios...). Could also help anyone else who hasn't noticed these features existed 🤔

aleck099 commented 2 years ago

I also don't know if it's possible to create a portal with CPA that doesn't spawn a return portal on the other end? Or ones that don't have a frame at all (either player crafted or a fully custom activation process) ?

I do want to know this!

kyrptonaught commented 2 years ago

I've got this just about working with only minor changes to CPA(Mostly just non privating some things).

https://github.com/kyrptonaught/exampleCPAPortals

https://user-images.githubusercontent.com/3196164/149461018-255de084-e3f0-42ec-a14d-d4a2156c45da.mp4

kyrptonaught commented 2 years ago

I also don't know if it's possible to create a portal with CPA that doesn't spawn a return portal on the other end? Or ones that don't have a frame at all (either player crafted or a fully custom activation process) ?

I do want to know this!

I'm not sure if this is possible without a frame. CPA "links" the connection between portals and stores it, rather than just searching for a valid frame upon tping like vanilla. This helps slightly with lag, but more importantly this helps with guaranteeing certain portals will always link together. Ever gone into the nether in one portal and came out another? These links are stored by their frames, and the link is only created upon the initial TP. So TPing and not placing a frame will essentially neuter the initial portal. Manually creating a portal on the other side will not link back to the original.

This could be implemented though, I just haven't gotten around to it

aleck099 commented 2 years ago

Thanks a lot! And we know that moveToWorld only works for overworld, nether and the_end since 1.18. Passing custom world to it results in nothing. Then how can we teleport entities to another world except using /execute in xxx run tp x y z? ServerPlayerEntity seems to have a method named teleportToWorld, but Entity doesn't have.

kyrptonaught commented 2 years ago

Thanks a lot! And we know that moveToWorld only works for overworld, nether and the_end since 1.18. Passing custom world to it results in nothing. Then how can we teleport entities to another world except using /execute in xxx run tp x y z? ServerPlayerEntity seems to have a method named teleportToWorld, but Entity doesn't have.

The issue here is actually getTeleportTarget in entity. This is where the coords for the destination are determined. It seems to just abort if we aren't going to the end or nether. CPA gets around this by just injecting and giving our own teleport target. See here lines 85 -110. This where we inject our custom target, and do some other things like prevent the end credits and the end platform from spawning. The custom teleport target is created here here

Azagwen commented 2 years ago

Thanks a lot! And we know that moveToWorld only works for overworld, nether and the_end since 1.18. Passing custom world to it results in nothing. Then how can we teleport entities to another world except using /execute in xxx run tp x y z? ServerPlayerEntity seems to have a method named teleportToWorld, but Entity doesn't have.

The issue here is actually getTeleportTarget in entity. This is where the coords for the destination are determined. It seems to just abort if we aren't going to the end or nether. CPA gets around this by just injecting and giving our own teleport target. See here lines 85 -110. This where we inject our custom target, and do some other things like prevent the end credits and the end platform from spawning. The custom teleport target is created here here

So that might be why weird stuff happens when using moveToWorld alone?

Azagwen commented 2 years ago

I've got this just about working with only minor changes to CPA(Mostly just non privating some things).

https://github.com/kyrptonaught/exampleCPAPortals

https://user-images.githubusercontent.com/3196164/149461018-255de084-e3f0-42ec-a14d-d4a2156c45da.mp4

That looks incredible! Makes me want to try and make more unconventional portals with CPA from this example, to see how far it can go 👀