Skip to content

feat: possible second implementation of the new structure system - #24

Open
noone-075 wants to merge 14 commits into
WebMCDevelopment:mainfrom
noone-075:wait-for-it
Open

noone-075 wants to merge 14 commits into
WebMCDevelopment:mainfrom
noone-075:wait-for-it

Conversation

@noone-075

Copy link
Copy Markdown
Contributor
  • the old API is fully usable in api.structure.* but deprecated and mark for removal
  • the new API is located in api.structures.* and it would be the new way to create structures
  • the new API works with 2 types of structures: LocatedStructure and RelativeStructure
    • LocatedStructure is a structure that is generated at a specific location and it can be placed without specifying a location, it is already located
    • RelativeStructure is a structure that is generated relative to a location and it can be placed to any location, it is not located
  • each of them uses a PlacebleStructure (either LocatedPlacebleStructure or RelativePlacebleStructure) to build the structure and place it.
  • to make a new Structure, you need to extend either of them, and implement the build() method to return the correct type of PlacebleStructure
  • they use custom placeble blocks (LocatedBlock, RelativeBlock), they can also override the place function for custom behavior
  • then implementing the GenerableStructure interface is optional, it allows the structure to have the function needed to be generated in the world, if used by a chunk generator.

THIS IS NOT A FINAL IMPLEMENTATION, IT IS STILL IN DEVELOPMENT AND MAY CHANGE IN THE FUTURE.

- the old API is fully usable in api.structure.* but deprecated and mark for removal
- the new API is located in api.structures.* and it would be the new way to create structures
- the new API works with 2 types of structures: LocatedStructure and RelativeStructure
  - LocatedStructure is a structure that is generated at a specific location and it can be placed without specifying a location, it is already located
  - RelativeStructure is a structure that is generated relative to a location and it can be placed to any location, it is not located
- each of them uses a PlacebleStructure (either LocatedPlacebleStructure or RelativePlacebleStructure) to build the structure and place it.
- to make a new Structure, you need to extend either of them, and implement the build() method to return the correct type of PlacebleStructure
- they use custom placeble blocks (LocatedBlock, RelativeBlock), they can also override the place function for custom behavior
- then implementing the GenerableStructure interface is optional, it allows the structure to have the function needed to be generated in the world, if used by a chunk generator.

THIS IS NOT A FINAL IMPLEMENTATION, IT IS STILL IN DEVELOPMENT AND MAY CHANGE IN THE FUTURE.
@noone-075
noone-075 marked this pull request as ready for review September 5, 2026 17:30
@noone-075 noone-075 mentioned this pull request Sep 5, 2026
@colbster937 colbster937 self-assigned this Sep 5, 2026
@colbster937
colbster937 self-requested a review September 5, 2026 19:09

@colbster937 colbster937 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i have requested all the changes i want (i'll fix what i can). i would also like to keep the package the same as the old api as to keep it consistent (singular words, not plural).

Comment thread src/main/java/xyz/webmc/wlib/api/structures/blocks/LocatedBlock.java Outdated
Comment thread src/main/java/xyz/webmc/wlib/api/structures/blocks/RelativeBlock.java Outdated
Comment thread src/main/java/xyz/webmc/wlib/internal/structures/RickQRCodeTestStructure.java Outdated
Comment thread pom.xml Outdated
@colbster937
colbster937 self-requested a review September 5, 2026 19:33
@colbster937

Copy link
Copy Markdown
Member

it would also be a good idea to rename some classes (e.g. "Block") to not be the same as a bukkit class name, so they can be used in classes that already import bukkit classes

@noone-075

Copy link
Copy Markdown
Contributor Author

it would also be a good idea to rename some classes (e.g. "Block") to not be the same as a bukkit class name, so they can be used in classes that already import bukkit classes

What about, it might be redundant but: PlaceableBlock.

Comment thread src/main/java/xyz/webmc/wlib/api/structures/blocks/LocatedBlock.java Outdated
Comment thread src/main/java/xyz/webmc/wlib/api/structures/blocks/RelativeBlock.java Outdated
Comment thread src/main/java/xyz/webmc/wlib/api/structures/blocks/PlaceableBlock.java Outdated
Comment thread src/main/java/xyz/webmc/wlib/api/structure/GenerableStructure.java
Comment thread src/main/java/xyz/webmc/wlib/api/structures/LocatedStructure.java Outdated
Comment thread src/main/java/xyz/webmc/wlib/api/structures/LocatedStructure.java Outdated
Comment thread src/main/java/xyz/webmc/wlib/api/structure/AbsoluteStructure.java
Comment thread src/main/java/xyz/webmc/wlib/api/structures/blocks/RelativeBlock.java Outdated
Comment thread src/main/java/xyz/webmc/wlib/api/structures/blocks/RelativeBlock.java Outdated
Comment thread src/main/java/xyz/webmc/wlib/api/structures/placeable/PlaceableStructure.java Outdated
Comment thread src/main/java/xyz/webmc/wlib/api/structure/AbsoluteStructure.java
- introduce the new abstract structure base and instance registry
- update located/relative/placeable structure types
- remove legacy structure entry and align command/test usages
- added new exemple of structure
@noone-075

Copy link
Copy Markdown
Contributor Author

i think its finished tell me if it is then i wont change it until merge with upstream

Comment thread src/main/java/xyz/webmc/wlib/api/util/GenerableStructuresUtils.java
Comment thread src/main/java/xyz/webmc/wlib/api/structures/GenerableStructuresUtils.java Outdated
Comment thread src/main/java/xyz/webmc/wlib/api/structures/GenerableStructuresUtils.java Outdated
Comment thread src/main/java/xyz/webmc/wlib/api/structures/GenerableStructuresUtils.java Outdated
@colbster937

colbster937 commented Sep 9, 2026

Copy link
Copy Markdown
Member

i have requested all the changes i want (i'll fix what i can). i would also like to keep the package the same as the old api as to keep it consistent (singular words, not plural).

resurfacing this 4 day old comment

@colbster937

Copy link
Copy Markdown
Member

i have requested all the changes i want (i'll fix what i can). i would also like to keep the package the same as the old api as to keep it consistent (singular words, not plural).

resurfacing this 4 day old comment

resurfacing me resurfacing this comment 5 days ago

@noone-075

noone-075 commented Sep 14, 2026

Copy link
Copy Markdown
Contributor Author

i have requested all the changes i want (i'll fix what i can). i would also like to keep the package the same as the old api as to keep it consistent (singular words, not plural).

resurfacing this 4 day old comment

resurfacing me resurfacing this comment 5 days ago

the package is api.structure.* and internal.structure.*
i already fixed that
(did it directly in the merge)

@noone-075

Copy link
Copy Markdown
Contributor Author

notice im not done reorganizing but its near to be completed

@colbster937 colbster937 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry if this is coming off as rude, but what exactly is the usecase for this major refactor? i get the ability to use it in a chunkgenerator, but i also liked the simplicity of the previous impl. it was just an idea i came up with while walking to class and implemented it in a simple way so that it would be easy to use.

Comment on lines +51 to +53
if (material == null) {
return;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

flip the condition and dont return

Comment on lines +69 to +76
if (chunk instanceof org.bukkit.Chunk liveChunk) {
if (loc.getWorld() == liveChunk.getWorld()
&& loc.getBlockX() >> 4 == liveChunk.getX()
&& loc.getBlockZ() >> 4 == liveChunk.getZ()) {
this.place(loc);
}
return;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

flip the condition and dont return

}

protected void place(Location loc, Object chunk) {
if (chunk instanceof org.bukkit.Chunk liveChunk) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import the class, dont use the fqpn

Comment on lines +79 to +82
if (loc.getBlockX() >> 4 != builderChunk.x()
|| loc.getBlockZ() >> 4 != builderChunk.z()) {
return;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

flip the condition and dont return

Comment on lines +85 to +87
if (material == null) {
return;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

flip the condition and dont return

Comment on lines +70 to +77
public static BaseStructure getTestStructure(Class<?> clazz) {
for (BaseStructure structure : getStructures()) {
if (structure.getClass().equals(clazz)) {
return structure;
}
}

return null;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the point of the reflection method was to avoid repeating code like this

}

public static Set<String> getStructureNames() {
final Set<String> names = new HashSet<>();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be final

Comment thread .gitignore
/dependency-reduced-pom.xml No newline at end of file
/dependency-reduced-pom.xml

.vscode No newline at end of file

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.vscode should be with the existing directory ignores at the top

- id: vars
run: |
echo "JAVA=$(mvn help:evaluate -Dexpression=maven.compiler.release -q -DforceStdout)" >> "$GITHUB_OUTPUT"
echo "VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)" >> "$GITHUB_OUTPUT"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be "VERS", not "VERSION"

Comment on lines +95 to +114
public static void sendUnknownCommandMessage(CommandSender sender) {
boolean bool = true;

final Class<?> clazz = MirrorSafe.getClass("org.spigotmc.SpigotConfig");
if (clazz != null) {
final String msg = MirrorSafe.getFieldValue(clazz, "unknownCommandMessage");
if (msg != null) {
sender.sendMessage(msg);
bool = false;
}
}

if (bool) {
sender.sendMessage(ChatColor.RED + "Unknown command.");
}
}

public static void sendOnlyPlayersMessage(CommandSender sender) {
sender.sendMessage(ChatColor.RED + "This command can only be used by players.");
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

static methods go under instance methods

@noone-075

noone-075 commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

sorry if this is coming off as rude, but what exactly is the usecase for this major refactor? i get the ability to use it in a chunkgenerator, but i also liked the simplicity of the previous impl. it was just an idea i came up with while walking to class and implemented it in a simple way so that it would be easy to use.

the goals are:

  • being able to generate the structure depending on where it is located (AbsoluteStructure).
  • being able to create a structure that remains the same regardless of the location where it is placed (RelativeStructure), already existed.
  • being able to place it in ChunkGenerator.
  • having generation tools (GenerableStructure).

@colbster937

Copy link
Copy Markdown
Member

I don't get what you mean by the 1st, 2nd, and 3rd, can you elaborate?

@noone-075

Copy link
Copy Markdown
Contributor Author

look at CoordinateStructure in internal. this structure places black and white concrete depending on the position the structure was placed on (it encodes in binary the coords), im using the AbsoluteStructure to be able to change how the structure is generated, depending on the location, this allows for complex randomnized structure like in vanilla generation. while the RelativeStructure is more like a schematic of a structure you can place anywhere in the world. if you place it at 0,0 or at 10000,10000 it will be the exact same.
The number 3 is for automatic generation in the world, this allow to generate the structure chunk by chunk either when loading for the first time the chunk. or to generate it with a chunkGenerator.
MyStructure.place(CenterLocationOfTheStructure, ChunkToPlaceIn) should always place the same block at the same place this allow for custom generation for big structures that extend in multiple chunks

@colbster937

Copy link
Copy Markdown
Member

sorry, i meant 1st, 2nd, and 4th, not 3rd

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants