Jump to content

[1.15.2] Questions regarding dynamically-generated GUIs


Blazer Nitrox

Recommended Posts

Okay, so admittedly this is a really complex thing I'm trying to do, but I figure I'd learn some things along the way, so I decided to give it a shot.

My goal is to recreate something like a skill tree in Minecraft. Specifically, my inspiration comes from the Passive Skill Tree in Path of Exile. I definitely do NOT expect to replicate the kind of complexity they've got, as the skill tree has evolved over the course of many years.
I've (mostly) figured out my implementation for the skill tree, and now I need to have a GUI allowing the player to actually allocate their skill points. This, unfortunately, seems to be much harder than the tree implementation itself, while also being extremely important to using the tree (I suppose I could implement the whole thing using commands, but I'm going to have to create a GUI at some point so I might as well ask now).

Currently, I'm trying to future-proof by using a custom registry for my SkillNodes. While this will allow me to easily add nodes programmatically (and will allow other mods to expand upon the skill tree), it also means that I have no way of knowing what nodes will need to be drawn to the tree at compile time, so I have to dynamically generate the GUI. I likewise have no way of knowing what positions I will need to draw the nodes' textures at, which means I won't know until runtime how long I will need to make the paths between each node.


So, here are my questions:
1.  I expect I will need to take advantage of Minecraft's built-in texture stitching, that way I don't have to rebind the texture every time I draw a node. Near as I can tell, there is no built-in GUI TextureAtlas, so I would need to create my own. How would I go about doing that, and would it need to be registered somewhere in order to still fire TextureStitchEvents?
2a.  Since I also don't know each node's position until runtime, I will need to dynamically draw the paths between them, which means I won't know the lengths of each path and therefore can't just draw a texture 1:1 between each node.

2b. I would like to make the paths straight lines between each node, which means I could potentially be dealing with diagonals as well. Can  `Screen` handle either of these scenarios, or would I need to directly access OpenGL?

 

This situation is something I'm not very experienced with at all, so please bear with me. I'll probably be asking several more questions to make sure I understand what I need to do here.

And as I said, I know I'm probably biting off more than I can chew, but I find that I learn best by bodging a solution together at first and then rewriting it with the knowledge I gained.

 

 

Link to comment
Share on other sites

43 minutes ago, Blazer Nitrox said:

While this will allow me to easily add nodes programmatically (and will allow other mods to expand upon the skill tree), it also means that I have no way of knowing what nodes will need to be drawn to the tree at compile time, so I have to dynamically generate the GUI. I likewise have no way of knowing what positions I will need to draw the nodes' textures at, which means I won't know until runtime how long I will need to make the paths between each node.

You could specify the position of the node as part of its data, which should be part of the instance you use as the registry entry, and draw each node according to its position data. This allows you (as well as other mods that use your mod) to have more control over where the newly added nodes should appear. This also circumvents the "dynamically position the node and draw line between" problem.

 

43 minutes ago, Blazer Nitrox said:

2a.  Since I also don't know each node's position until runtime, I will need to dynamically draw the paths between them, which means I won't know the lengths of each path and therefore can't just draw a texture 1:1 between each node.

2b. I would like to make the paths straight lines between each node, which means I could potentially be dealing with diagonals as well. Can  `Screen` handle either of these scenarios, or would I need to directly access OpenGL?

Directly using OpenGL should be the easier approach, as it has more flexibility (and Screen uses OpenGL anyways). Create a texture of a line and scale/rotate it to point it to other nodes. Some trigonometry will be needed.

Edited by DavidM

Some tips:

Spoiler

Modder Support:

Spoiler

1. Do not follow tutorials on YouTube, especially TechnoVision (previously called Loremaster) and HarryTalks, due to their promotion of bad practice and usage of outdated code.

2. Always post your code.

3. Never copy and paste code. You won't learn anything from doing that.

4. 

Quote

Programming via Eclipse's hotfixes will get you nowhere

5. Learn to use your IDE, especially the debugger.

6.

Quote

The "picture that's worth 1000 words" only works if there's an obvious problem or a freehand red circle around it.

Support & Bug Reports:

Spoiler

1. Read the EAQ before asking for help. Remember to provide the appropriate log(s).

2. Versions below 1.11 are no longer supported due to their age. Update to a modern version of Minecraft to receive support.

 

 

Link to comment
Share on other sites

29 minutes ago, DavidM said:

You could specify the position of the node as part of its data, which should be part of the instance you use as the registry entry, and draw each node according to its position data. This allows you (as well as other mods that use your mod) to have more control over where the newly added nodes should appear. This also circumvents the "dynamically position the node and draw line between" problem.

That's what I'm doing, sorry I didn't make that clear. As part of the node's data I've got the position and the resource location for the appropriate texture. My main concern was that since I won't know where the node will be located until it gets registered I can't just include the path as part of the background texture, so I would have to dynamically draw it.

 

32 minutes ago, DavidM said:

Directly using OpenGL should be the easier approach, as it has more flexibility (and Screen uses OpenGL anyways). Create a texture of a line and scale/rotate it to point it to other nodes. Some trigonometry will be needed.

I suspected this would be the case, but thanks for confirming it. I assume I can still use Screen for a convenient way to access the GUI, and then override the various rendering methods in order to actually draw what I need?

Side note: how did you code-ify `Screen`?

Link to comment
Share on other sites

Okay, I did some poking around with AtlasTexture, and I think I figured out how to do what I need to. I'm going to record it here for future generations, and as a second post because it just doesn't make sense to me to combine this with the above, since they're mostly unrelated (and the separation will help identify this as me explaining what I think I need to do).

 

AtlasTexture texture = new AtlasTexture(new ResourceLocation(MODID, "atlas"));
Stream<ResourceLocation> stream = list.stream(); //We get a stream of all of the textures we want, probably using Collection#stream()
SheetData data = texture.func_229220_a_((IResourceManager) Minecraft.getInstance().getTextureManager(), stream, Minecraft.getInstance().getProfiler(), 0); //Last argument is mipmap level, we use 0
map.upload(data);

So, first I must actually create a new AtlasTexture, passing in a ResourceLocation which will act as a registry name.
Then, to actually generate the stitched texture, I must call AtlasTexture#func229220_a_. It seems I should pass in Minecraft.getInstance().getTextureManager() (which I can do because I'm specifically doing this on Dist.CLIENT) for the first argument, a Stream containing the ResourceLocation's of all of the textures I want to stitch (so this will be done after all of the nodes are registered, no surprise there), an IProfiler (whatever that is, it seems to be used to track the progress of the texture stitching), and an integer mipmapping level (I would assume I'd use either 0 or 1, since I won't need mipmapping for a GUI I don't think). I would capture the output of this and pass it to AtlasTexture#upload, which would actually create the texture information I would then use for drawing. At this point, the AtlasTexture is ready for use.

 

if (!RenderSystem.isOnRenderThread()) {
	RenderSystem.recordRenderCall(() -> {
		manager.func_229263_a(texture.func_229223_g_(), texture);
      	texture.func_229148_d_();
	});
} else {
	textureManager.func_229263_a(texture.func_229223_g_(), texture);
  	texture.func_229148_d();
}

When we first start drawing, we have to bind the texture. First, we must ensure we are actually on the rendering thread, and ask the rendering thread to do it if we aren't. Then we call TextureManager#func_229263_a, which takes two arguments, a ResourceLocation we want to use as a key for our AtlasTexture and the AtlasTexture itself.  We can cheat the first argument here by calling AtlasTexture#func_229223_g_, which is essentially getRegistryName. This will set up our texture so it's ready to be bound to OpenGL (the above is ripped directly from TextureManager#bindTexture). We then call Texture#func229148_d, which actually binds the texture.

 

((I would provide a code example, except that Screen doesn't seem to provide any way to draw textures using UV coordinates which is all TextureAtlasSprite provides, and directly drawing via OpenGL requires calling Tessellator to get a BufferBuilder, and none of the methods in BufferBuilder (or, for that matter, Screen) have been deobfuscated yet.))

 

Now, in order to draw a texture from the Atlas onto the GUI, we call AtlasTexture#getSprite and pass in the key for the particular texture we want. That returns a TextureAtlasSprite, which contains the coordinates of our texture on the Atlas in absolute pixels as well as the relative min/max UV coordinates of our texture. Asking OpenGL to draw the part of the texture from min UV to max UV will draw our chosen texture and only that texture.

Link to comment
Share on other sites

Few things to add:

1. You might want to check out SpriteUploader.

2. Check out AbstractGui::blit. It is the built-in method of rendering sprites with UV coords.

3. You won't need to check on for the rendering thread if you are rendering in the Screen code (in the appropriate method).

 

On an irrelevant note, almost everything in BufferBuilder as well as AtlasTexture (and a few other mentioned classes) has been deobfuscated on recent MCP mappings. You should consider updating your mappings if you find them obfuscated on your setup.

  • Like 1
  • Thanks 1

Some tips:

Spoiler

Modder Support:

Spoiler

1. Do not follow tutorials on YouTube, especially TechnoVision (previously called Loremaster) and HarryTalks, due to their promotion of bad practice and usage of outdated code.

2. Always post your code.

3. Never copy and paste code. You won't learn anything from doing that.

4. 

Quote

Programming via Eclipse's hotfixes will get you nowhere

5. Learn to use your IDE, especially the debugger.

6.

Quote

The "picture that's worth 1000 words" only works if there's an obvious problem or a freehand red circle around it.

Support & Bug Reports:

Spoiler

1. Read the EAQ before asking for help. Remember to provide the appropriate log(s).

2. Versions below 1.11 are no longer supported due to their age. Update to a modern version of Minecraft to receive support.

 

 

Link to comment
Share on other sites

9 hours ago, DavidM said:

Few things to add:

1. You might want to check out SpriteUploader.

2. Check out AbstractGui::blit. It is the built-in method of rendering sprites with UV coords.

3. You won't need to check on for the rendering thread if you are rendering in the Screen code (in the appropriate method).

 

On an irrelevant note, almost everything in BufferBuilder as well as AtlasTexture (and a few other mentioned classes) has been deobfuscated on recent MCP mappings. You should consider updating your mappings if you find them obfuscated on your setup.

Oh, hey! In the process of updating my MCP mappings I noticed that for some reason Forge was claiming it was 1.15 (and downloading Minecraft 1.15), but it was using the 1.14 MCP mappings, so I had no idea that AbstractGui#blit had a version which took a TextureAtlasSprite.

 

So SpriteUploader seems to do exactly what I was originally expecting, with the added bonus of being able to be called whenever the resource engine reloads. That is very useful, although SpriteUploader#getSprite is set to protected, limiting its use pretty drasically IMHO. I assume the idea is that I would ask it to bind the texture atlas and then access the atlas directly from there.

 

As far as checking the rendering thread, I figured that the relevant methods would always be called on the rendering thread, but since bindTexture does it I figured it wouldn't hurt.

 

All of this has been extremely helpful, thanks a bunch!

Link to comment
Share on other sites

Might also be worth looking at how vanilla handles the Advancements screen.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Okay, having taken a bit to mess around with everything, I think I understand how I need to go about this. I did notice that SpriteUploader doesn't seem to have any markers for being called on reload, is there some way I should be registering it with the resource manager, or does it take care of that itself somewhere that I'm not seeing? There certainly doesn't appear to be any events I can attach to for registration or to manually call reload(), nor does TextureManager provide any such functionality.

Edited by Blazer Nitrox
Minor correction in wording
Link to comment
Share on other sites

What stops you from knowing a node's position at runtime? Try to separate the concept of a node to anything related to your skill tree.

 

If you can calculate/determine what skills a player knows at any time from player capabilities, access it from the GUI. Determine a pre-determined layout of the tree, like where a node will go (the physical node, not the skills attached to it) and where to draw arrows pointing to it. For example, if you have 40 skills in the tree, you could set up a lookup array of size 40 to determine if a node representing a particular skill should be drawn or not. This is the background layer. And in the foreground, overlay your skill name, description, etc over their respective positions. Then within the various mouse action methods, access this array whether it should detect player hovers/clicks there or not.

 

This is something similar I've done, if a player doesn't want to have the third row for example, the node and the arrows pointing to it aren't drawn. Notice that some concessions needed to be made, like the length of the names (I've formatted the string so it's inside the node, but anything longer will make the text go over the boundary). But if I wanted to, I could even vary the size of each node and have a lookup table that tells me how large a certain node needs to be for a certain skill name.

 

Edit: All a node should be is a quad with a texture, nothing more. You shouldn't need to register anything as David said

 

image.png.0ed0a18e21ed9ac582756a83bf9dbe71.png

Edited by Turtledove
Link to comment
Share on other sites

6 minutes ago, Turtledove said:

What stops you from knowing a node's position at runtime? Try to separate the concept of a node to anything related to your skill tree.

 

If you can calculate/determine what skills a player knows at any time from player capabilities, access it from the GUI. Determine a pre-determined layout of the tree, like where a node will go (the physical node, not the skills attached to it) and where to draw arrows pointing to it. For example, if you have 40 skills in the tree, you could set up a lookup array of size 40 to determine if a node representing a particular skill should be drawn or not. This is the background layer. And in the foreground, overlay your skill name, description, etc over their respective positions. Then within the various mouse action methods, access this array whether it should detect player hovers/clicks there or not.

 

This is something similar I've done, if a player doesn't want to have the third row for example, the node and the arrows pointing to it aren't drawn. Notice that some concessions needed to be made, like the length of the names (I've formatted the string so it's inside the node, but anything longer will make the text go over the boundary). But if I wanted to, I could even vary the size of each node and have a lookup table that tells me how large a certain node needs to be for a certain skill name.

 

image.png.0ed0a18e21ed9ac582756a83bf9dbe71.png

Under normal circumstances I would have done it that way, however I know that over time I'm going to be adding nodes to the tree (and potentially letting other mods add nodes to the tree as well), so I want to be able to programmatically add the nodes to the tree, meaning I won't know their textures or positions until they are registered. While it does mean I have to do more work in building the screen, theoretically it will also allow me to simply register a new node without having to modify the tree itself. It would also potentially allow me to create a tool later on which allows me to visually build the tree out and then simply export it as a JSON which the mod could then load, although it'll be a looong time before I pursue that route.

Link to comment
Share on other sites

5 minutes ago, Blazer Nitrox said:

so I want to be able to programmatically add the nodes to the tree, meaning I won't know their textures or positions until they are registered

Again, look at the advancements screen. It positions every advancement dynamically based on the advancements found during resource loading and they never overlap or have lines cross.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

43 minutes ago, Turtledove said:

Edit: All a node should be is a quad with a texture, nothing more. You shouldn't need to register anything as David said

OP wants to use the registry system for skill tree nodes so that he can manage the skill categories easier later on as well as allow other mods to add theirs. The nodes only manages how the tree is displayed; OP uses the registry system for the skill categories, not the actual icon (which can be stored in the registry entry for simplicity given that there is a one-to-one mapping for all of the categories).

 

 

Some tips:

Spoiler

Modder Support:

Spoiler

1. Do not follow tutorials on YouTube, especially TechnoVision (previously called Loremaster) and HarryTalks, due to their promotion of bad practice and usage of outdated code.

2. Always post your code.

3. Never copy and paste code. You won't learn anything from doing that.

4. 

Quote

Programming via Eclipse's hotfixes will get you nowhere

5. Learn to use your IDE, especially the debugger.

6.

Quote

The "picture that's worth 1000 words" only works if there's an obvious problem or a freehand red circle around it.

Support & Bug Reports:

Spoiler

1. Read the EAQ before asking for help. Remember to provide the appropriate log(s).

2. Versions below 1.11 are no longer supported due to their age. Update to a modern version of Minecraft to receive support.

 

 

Link to comment
Share on other sites

@Draco18s I took another look at the advancements screen and realized I was a complete moron lol. I had been avoiding doing a proper parent/child hierarchy because I want the player to be able to loop around the tree like so:

image.png.ac79200ae962b137e563f795d48e9f31.png

(excuse the terrible quality, I threw this together in like 2 minutes in Paint because I didn't feel like waiting for GIMP to load)

At the time, I had thought that a parent/child hierarchy wouldn't be capable of this because the last node in the sequence (top right) wouldn't have it's parent node active, and so it would think that it couldn't be activated. And I only just now realized that when the player tries to activate the node I could just... check if any child nodes are activated as well.
 

All of this is to say that I've been a miserable fool who wasted his time because his solution was only half-baked. Nice.

Edited by Blazer Nitrox
Link to comment
Share on other sites

34 minutes ago, Blazer Nitrox said:

I had thought that a parent/child hierarchy wouldn't be capable of this because the last node in the sequence (top right) wouldn't have it's parent node active, and so it would think that it couldn't be activated. And I only just now realized that when the player tries to activate the node I could just... check if any child nodes are activated as well.

If your tree is not a tree (as in data structure; in your case it resembles a graph), then there is no need to separate the parent and child. Instead of keeping track of parent and children, create a set for all other connect nodes (given that direction does not matter in your skill graph).

Edited by DavidM

Some tips:

Spoiler

Modder Support:

Spoiler

1. Do not follow tutorials on YouTube, especially TechnoVision (previously called Loremaster) and HarryTalks, due to their promotion of bad practice and usage of outdated code.

2. Always post your code.

3. Never copy and paste code. You won't learn anything from doing that.

4. 

Quote

Programming via Eclipse's hotfixes will get you nowhere

5. Learn to use your IDE, especially the debugger.

6.

Quote

The "picture that's worth 1000 words" only works if there's an obvious problem or a freehand red circle around it.

Support & Bug Reports:

Spoiler

1. Read the EAQ before asking for help. Remember to provide the appropriate log(s).

2. Versions below 1.11 are no longer supported due to their age. Update to a modern version of Minecraft to receive support.

 

 

Link to comment
Share on other sites

2 minutes ago, DavidM said:

If your tree is not a tree (as in data structure; in your case it resembles a graph), then there is no need to separate the parent and child. Instead of keeping track of parent and children, create a set for all other connect nodes.

Right, and that's how I've been doing it. I think you actually might have touched on the underlying problem... data structures have always kind of confused me for some reason, and I think part of the problem is in some ways I'm still thinking of this as a tree when in reality what I need is a graph, just with a pseudo-root node.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Dalam dunia perjudian online yang berkembang pesat, mencari platform yang dapat memberikan kemenangan maksimal dan hasil terbaik adalah impian setiap penjudi. OLXTOTO, dengan bangga, mempersembahkan dirinya sebagai jawaban atas pencarian itu. Sebagai platform terbesar untuk kemenangan maksimal dan hasil optimal, OLXTOTO telah menciptakan gelombang besar di komunitas perjudian online. Satu dari banyak keunggulan yang dimiliki OLXTOTO adalah koleksi permainan yang luas dan beragam. Dari togel hingga slot online, dari live casino hingga permainan kartu klasik, OLXTOTO memiliki sesuatu untuk setiap pemain. Dibangun dengan teknologi terkini dan dikembangkan oleh para ahli industri, setiap permainan di platform ini dirancang untuk memberikan pengalaman yang tak tertandingi bagi para penjudi. Namun, keunggulan OLXTOTO tidak hanya terletak pada variasi permainan yang mereka tawarkan. Mereka juga menonjol karena komitmen mereka terhadap keamanan dan keadilan. Dengan sistem keamanan tingkat tinggi dan proses audit yang ketat, OLXTOTO memastikan bahwa setiap putaran permainan berjalan dengan adil dan transparan. Para pemain dapat merasa aman dan yakin bahwa pengalaman berjudi mereka di OLXTOTO tidak akan terganggu oleh masalah keamanan atau keadilan. Tak hanya itu, OLXTOTO juga terkenal karena layanan pelanggan yang luar biasa. Tim dukungan mereka selalu siap sedia untuk membantu para pemain dengan segala pertanyaan atau masalah yang mereka hadapi. Dengan respon cepat dan solusi yang efisien, OLXTOTO memastikan bahwa pengalaman berjudi para pemain tetap mulus dan menyenangkan. Dengan semua fitur dan keunggulan yang ditawarkannya, tidak mengherankan bahwa OLXTOTO telah menjadi pilihan utama bagi jutaan penjudi online di seluruh dunia. Jika Anda mencari platform yang dapat memberikan kemenangan maksimal dan hasil optimal, tidak perlu mencari lebih jauh dari OLXTOTO. Bergabunglah dengan OLXTOTO hari ini dan mulailah petualangan Anda menuju kemenangan besar dan hasil terbaik!
    • Selamat datang di OLXTOTO, situs slot gacor terpanas yang sedang booming di industri perjudian online. Jika Anda mencari pengalaman bermain yang luar biasa, maka OLXTOTO adalah tempat yang tepat untuk Anda. Dapatkan sensasi tidak biasa dengan variasi slot online terlengkap dan peluang memenangkan jackpot slot maxwin yang sering. Di sini, Anda akan merasakan keseruan yang luar biasa dalam bermain judi slot. DAFTAR OLXTOTO DISINI LOGIN OLXTOTO DISINI AKUN PRO OLXTOTO DISINI   Jackpot Slot Maxwin Sering Untuk Peluang Besar Di OLXTOTO, kami tidak hanya memberikan hadiah slot biasa, tapi juga memberikan kesempatan kepada pemain untuk memenangkan jackpot slot maxwin yang sering. Dengan demikian, Anda dapat meraih keberuntungan besar dan memenangkan ribuan rupiah sebagai hadiah jackpot slot maxwin kami. Jackpot slot maxwin merupakan peluang besar bagi para pemain judi slot untuk meraih keuntungan yang lebih besar. Dalam permainan kami, Anda tidak harus terpaku pada kemenangan biasa saja. Kami hadir dengan jackpot slot maxwin yang sering, sehingga Anda memiliki peluang yang lebih besar untuk meraih kemenangan besar dengan hadiah yang menggiurkan. Dalam permainan judi slot, pengalaman bermain bukan hanya tentang keseruan dan hiburan semata. Kami memahami bahwa para pemain juga menginginkan kesempatan untuk meraih keberuntungan besar. Oleh karena itu, OLXTOTO hadir dengan jackpot slot maxwin yang sering untuk memberikan peluang besar kepada para pemain kami. Peluang Besar Menang Jackpot Slot Maxwin Peluang menang jackpot slot maxwin di OLXTOTO sangatlah besar. Anda tidak perlu khawatir tentang batasan atau pembatasan dalam meraih jackpot tersebut. Kami ingin memberikan kesempatan kepada semua pemain kami untuk merasakan sensasi menang dalam jumlah yang luar biasa. Jackpot slot maxwin kami dibuka untuk semua pemain judi slot di OLXTOTO. Anda memiliki peluang yang sama dengan pemain lainnya untuk memenangkan hadiah jackpot yang besar. Kami percaya bahwa semua orang memiliki kesempatan untuk meraih keberuntungan besar, dan itulah mengapa kami menyediakan jackpot slot maxwin yang sering untuk memenuhi harapan dan keinginan Anda.   Kesimpulan OLXTOTO adalah situs slot gacor terbaik yang memberikan pengalaman bermain judi slot online yang tak terlupakan. Dengan variasi slot online terlengkap dan peluang memenangkan jackpot slot maxwin yang sering, OLXTOTO menjadi pilihan terbaik bagi para pemain yang mencari kesenangan dan kemenangan besar dalam perjudian online. Di samping itu, OLXTOTO juga menawarkan layanan pelanggan yang ramah dan responsif, siap membantu setiap pemain dalam mengatasi masalah teknis atau pertanyaan seputar perjudian online. Kami menjaga integritas game dan memberikan lingkungan bermain yang adil serta menjalankan kebijakan perlindungan pelanggan yang cermat. Bergabunglah dengan OLXTOTO sekarang dan nikmati pengalaman bermain slot online yang luar biasa. Jadilah bagian dari komunitas perjudian yang mengagumkan ini dan raih kesempatan untuk meraih kemenangan besar. Dapatkan akses mudah dan praktis ke situs OLXTOTO dan rasakan sensasi bermain judi slot yang tak terlupakan.  
    • OLXTOTO: Platform Maxwin dan Gacor Terbesar Sepanjang Masa Di dunia perjudian online yang begitu kompetitif, mencari platform yang dapat memberikan kemenangan maksimal (Maxwin) dan hasil terbaik (Gacor) adalah prioritas bagi para penjudi yang cerdas. Dalam upaya ini, OLXTOTO telah muncul sebagai pemain kunci yang mengubah lanskap perjudian online dengan menawarkan pengalaman tanpa tandingan.     Sejak diluncurkan, OLXTOTO telah menjadi sorotan industri perjudian online. Dikenal sebagai "Platform Maxwin dan Gacor Terbesar Sepanjang Masa", OLXTOTO telah menarik perhatian pemain dari seluruh dunia dengan reputasinya yang solid dan kinerja yang luar biasa. Salah satu fitur utama yang membedakan OLXTOTO dari pesaingnya adalah komitmen mereka untuk memberikan pengalaman berjudi yang unik dan memuaskan. Dengan koleksi game yang luas dan beragam, termasuk togel, slot online, live casino, dan banyak lagi, OLXTOTO menawarkan sesuatu untuk semua orang. Dibangun dengan teknologi terkini dan didukung oleh tim ahli yang berdedikasi, platform ini memastikan bahwa setiap pengalaman berjudi di OLXTOTO tidak hanya menghibur, tetapi juga menguntungkan. Namun, keunggulan OLXTOTO tidak hanya terletak pada permainan yang mereka tawarkan. Mereka juga terkenal karena keamanan dan keadilan yang mereka berikan kepada para pemain mereka. Dengan sistem keamanan tingkat tinggi dan audit rutin yang dilakukan oleh otoritas regulasi independen, para pemain dapat yakin bahwa setiap putaran permainan di OLXTOTO adalah adil dan transparan. Tidak hanya itu, OLXTOTO juga dikenal karena layanan pelanggan yang luar biasa. Dengan tim dukungan yang ramah dan responsif, para pemain dapat yakin bahwa setiap pertanyaan atau masalah mereka akan ditangani dengan cepat dan efisien. Dengan semua fitur dan keunggulan yang ditawarkannya, tidak mengherankan bahwa OLXTOTO telah menjadi platform pilihan bagi para penjudi online yang mencari kemenangan maksimal dan hasil terbaik. Jadi, jika Anda ingin bergabung dengan jutaan pemain yang telah merasakan keajaiban OLXTOTO, jangan ragu untuk mendaftar dan mulai bermain hari ini!  
    • OLXTOTO adalah bandar slot yang terkenal dan terpercaya di Indonesia. Mereka menawarkan berbagai jenis permainan slot yang menarik dan menghibur. Dengan tampilan yang menarik dan grafis yang berkualitas tinggi, pemain akan merasa seperti berada di kasino sungguhan. OLXTOTO juga menyediakan layanan pelanggan yang ramah dan responsif, siap membantu pemain dengan segala pertanyaan atau masalah yang mereka hadapi. Daftar =  https://surkale.me/Olxtotodotcom1
    • DAFTAR & LOGIN BIGO4D   Bigo4D adalah situs slot online yang populer dan menarik perhatian banyak pemain slot di Indonesia. Dengan berbagai game slot yang unik dan menarik, Bigo4D menjadi tempat yang ideal untuk pemula dan pahlawan slot yang berpengalaman. Dalam artikel ini, kami akan membahas tentang Bigo4D sebagai situs slot terbesar dan menarik yang saat ini banyak dijajaki oleh pemain slot online.
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.