Modular Schematics
CiaranGruber opened this issue ยท 2 comments
Is your feature request related to a problem?
One of the biggest things I enjoy using Litematica for is creating things like redstone contraptions. Often there can be many different ways that you can modify a contraption/build. For example, in some hidden contraptions, you may want to have different modules depending on how you want to open the contraption (ie, maybe a simple redstone torch, or potentially just a simple lever sticking out of the ground). My suggestion is building in this module support into Litematica so these different modules could be selected by the person pasting the schematic depending on their needs and requirements
Additionally, this wouldn't just benefit redstone-users who want to add different modules but really any builder. For example, building a house, you can choose to either have a balcony or just a window, or for a full base, you can various different entrances and also different buildings depending on your needs.
Describe the solution you'd like
I've presented a few different solutions that may be used to solve the problem as one may be preferable depending on how Litematica has already been programmed. I've ordered them in what I believe is the least "disruptive" (aka fewest changes to the interface) at the start with the more fully featured solutions towards the bottom. Solution 3 I believe though is the best since it may actually be easier to implement plus it would be the cleanest and most fully-featured solution in my eyes.
For creation of the schematic
Solution 1 (Having different modules per sub-region):
The main idea of Solution 1 is to allow the various sub-regions within a schematic to have different versions. This would essentially mean that a sub-region could either select the only available module if nothing has been specified or select the "default" module specified by the player who created the schematic.
To add a module to a region, an "add module" button can be made available for each sub-region in the area editor, which would serve to save the existing sub-region selection as a module. Then to add another module, the player would change the blocks inside the selection and then press "add module" again. When pasting a schematic, these different versions could then be selected as described further below.
Solution 2 (Having different sub-regions in a single "module set"):
The idea of solution to is to have a module set that can be added in the Area Editor and where different sub-regions can be added for each module type. The main advantage of Solution 2 over Solution 1 is that unlike Solution 1, modules may vary in size as the sub-regions in a module set may be different sizes.
To create a module using Solution 2, it would function similar to Solution 1, however you would create a sub-region and then "save" it to an existing module set. To add more sub-regions to the module set, the player can simply create another sub-region selection and again save it to the module set.
Solution 3 (Multiple modules within a module-set each with differing sets of sub-regions):
This solution I believe is the most fully-featured/clean and may be easier to implement than the others due to the existing sub-region code not needing to be changed much in regards to different versions or overlap priority. This solution is quite similar to solution 2, where you would essentially be able to add multiple modules to a module-set, and each module could have its own set of sub-regions.
This would be done by creating a module set, a module and any necessary sub-regions via the Area Editor and then making the selections for each sub-region. To add a sub-region to a module, you can simply press the "Add Sub-region" button that would be present on each module in the set.
The benefit of this, is that - using the example of the balcony of a Minecraft house - the addition of fences below the balcony to add as "supports" could have their own sub-region so that if extra modules were created for the door for example, this would not be overwritten by the balcony module.
For all solutions, the first module in a sub-region/module set should be selected as default unless the player selects a different module to be the default version. Additionally, it is imperative that sub-regions/module-sets within a schematic can be ordered by the player in terms of priority. This is because the base schematic must be able to be overwritten by any modules in order to ensure that modules interacting with the base schematic region are shown correctly. To handle overlapping, the module-set that is highest in the list should overwrite any modules-sets below it within its region.
Also, to ensure things remain simple for beginner Litematica users, module-sets/advanced sub-regions should be available alongside the standard sub-regions. This ensures that for a beginner, the addition of module-sets/advanced sub-regions do not affect the learning curve or make things more complicated other than by potentially adding a few more buttons to the interface.
For pasting a schematic
When the schematic is initially pasted, the default module in a sub-region/module-set would be selected. To change modules, the player can configure the schematic placement and select the modules relevant for their purpose. Modules in a sub-region/module-set should only be able to be selected one at a time as being able to select multiple would likely just lead to confusion for users and would be unlikely to serve much purpose.
For the Material List and Schematic Verifier, this may also need to be reprogrammed if it is to work correctly with modules as any blocks in a module lower in priority need to be ignored if a higher-priority module overlaps with them.
Describe alternatives you've considered
The current alternative to this is creating multiple schematics for the base schematic and for each of the modules which may add a minor amount of bloat to the schematics folder when you have many different modules for many contraptions.
However the major con is related to pasting a schematic with multiple modules, as for each module, you will need to put it in the correct position plus any changes to the base schematic will need to be applied individually to each module making the whole process significantly more difficult. Additionally, due to the lack of ability to order schematic placements in order of priority, the base-schematic may easily overlap the modules instead of vice versa unless it is named accurately.
Additional context
By adding this, I would expect it to massively extend the capabilities of advanced Litematica users, while not needing to affect beginners in a significant way, however it may require a large update and effort to implement and so it may not be feasible for a while.
If this is seen to be a potential idea, I could describe it in further detail and maybe help out in development as well partially however I can see this advancing the possibilities for Litematica a lot and it could be really good if implemented properly.
I think the main challenge in implementing this will be the user interface and usability aspect - how can all this be exposed in a way that makes sense and is easy enough to use and get a good overview of what is happening. The way you describe it by clicking a button in the Area Editor to "add a module" is totally different from how the mod works currently. The area selection is just a collection of boxes, and it only starts to relate to a schematic when you create a task that takes in an area selection, and produces out a schematic file, and that happens at once in memory, after which the schematic is saved to file. This would either need there to be an on-going modular schematic save process, or it would need to read the schematic from file, append new stuff to it, and then write it back again. That latter has other complications such as needing to always make sure the file still actually contains all the expected stuff, and the user didn't change the file on disk etc. so I think the on-going save process would be a better and cleaner option.
For the schematic format itself, I think the only change needed would be a new tag that holds the modules/module sets information, and what sub-regions are mapped to which set. A sub-region is the smallest complete storage unit in the schematic, each sub-region basically being a box that stores all the data from the world. So any larger logical units would be a combination of one or more sub-regions.
The one thing that might be a bit awkward is the sub-region names, as they need to be unique, and if you have different module sets or modules, they might want to have separate sub-regions with the same name. I guess that could also just be stored in the module set mapping as the "final display name" for a given sub-region, but I wonder if module-based schematics should actually store (additional?) sub-regions in a different tag structure instead. Also I'm not sure if backwards compatibility should be a concern here, probably not? (ie. that you could still load these modular schematics in older versions of the mod without that module support, where just the default module/set would get loaded essentially from the old/current schematic data structure). If you were to edit such a schematic in the older mod versions, it would wipe all the module data anyway...
So all in all, this does sound like a nice idea that would bring a lot more capability to the mod, but it will definitely need some further thought to figure out how things should work.
As to "when", I don't know if you are aware of the situation with my client mod development (I've mentioned it repeatedly in the comments here and on CurseForge and on Discord etc. but no idea if you have happened to see any of those), but basically this would only come via the main development version from 1.12.2, and it would need to happen at some point after the current rewrites are done first. So not really any time soon, where "soon" is totally undefined as of right now.
Note: My suggestions below are assuming using Solution 3 as described above since I believe that would be the cleanest way to add it without convoluting the interface or the back-end.
Regarding the user interface, I was originally thinking it could work essentially as an extension to the Area Editor in that the module sets/modules could be shown to the user similar to a tree-view design. However, given the way you describe how Area Selection works, and also with further thought, I believe a couple extra GUIs may be simpler while also sticking to the existing Litematica GUI theme. I've made some mock-ups of what these GUIs could look like in the screenshots below that should help explain things.
In regards to how to effectively manage modules in the back-end, a simple and clean way could potentially be to treat each individual module as its own self-contained schematic purely for the purposes of data storage (functionally the whole thing should act as one full schematic). This is similar to how they would work in my mind as a modular schematic is really quite similar to multiple schematics just working in conjunction with each other by specifying overlap and having restrictions such as only having one module picked per module set and rotating as a group. From there, things like the Material List, etc, would just need to be modified to be able to handle these modular schematics correctly.
As you described, I would agree that the easiest way to manage the modules is with an ongoing schematic save progress. I imagine this could be done similar to how I believe area selections are managed with a temporary storage until the user decides to build the completed schematic. Similarly, storage for when a person leaves a server etc, could be done the same with a folder called schematic_builds
which would contain the information for that schematic for people to come back to. In that folder, I'd imagine each module set to again have its own folder and finally each module to have its own json
/litematic
file.
Also regarding the issue with sub-region names needing to be unique, I believe that with Solution 3 (having multiple modules in a module set) and having modules act similar to a self-contained schematic, the sub-regions should be able to functionally work similar as they do now, and so the way they are stored can be basically the same as they are currently.
In terms of backwards compatibility, there's a few ways I can think this could be managed. The first way is to potentially create a converter that can save a copy of the modular schematic but with either default modules or selected ones. Otherwise, a potential solution that may help to stop the module data being wiped is if the module data is saved in a separate file (with a different extension), however this may not be worth making the schematic files more convoluted. Alternatively, if this was too difficult though, it could simply be said that they aren't backwards compatible and potentially leave it up to the community to develop something if it's seen as necessary.
If you've added a flag in previous versions of Litematica that you can use to notify the user that newer modular schematics may break, then this flag could be activated. If not, it may be good to add a flag in the litematic
files for future updates where if the Litematica version is not above a certain value (dependent on what is used), it will come up with a warning to the user. This means if you have any other major rewrites in the future, it will notify players before breaking things. (Eg. Maybe a couple flags with minimum version
and recommended version
where minimum is where it simply can't load and recommended may break things)
Also, one thing I haven't explicitly mentioned (though I have shown in the pictures) is that I feel it would be important to ensure schematics can also be saved using the simple method of creating an area the same way you do currently and saving it. I feel by having both methods, this allows the feature of modules to be added without exposing anything overly complicated to a beginner, while keeping a fast way to create schematics. Also, if flags were added, these simple schematics could be backwards compatible with more versions.
I hadn't seen your comments however I understood that it would've been the case since often large updates like this may take a bit of time to even be started if they do end up being done at all so that's perfectly understandable. Hopefully though, this can be done eventually since I think it would make Litematica significantly more capable for the more advanced users and maybe encourage more sharing between players as it allows for different needs to be met