liuweireign / tectonicus

Automatically exported from code.google.com/p/tectonicus
0 stars 0 forks source link

Plugin system for complex mods #7

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Certain mods (eg, IndustrialCraft2, RedPower2, etc) have blocks that are 
currently impossible to render. Eg, IndustrialCraft2's machines are cubes, but 
they have a different texture on each side, while the pipes, tubes and cables 
of all mods are basically 3d redstone (they join up to other like blocks in 3 
dimensions).

There are two approaches I see to fix this:

1. Add a bunch of new block types to enable their representation in 
customBlocks.xml, or

2. Create specific modules for these mods that does the right thing so no 
customBlocks.xml modification is necessary.

I think #2 is a good solution, because it requires very little effort on the 
end-user's side. Here is how I would implement it:

1. Plugins can either be built in, or external. I don't know how this type of 
stuff works in Java, but the plugins will all implement a common interface (eg, 
IPlugin).

2. In the main config file, we add a new section, <mods>, which subsections for 
each of the supported mods (<IndustrialCraft>, <RedPower>, etc). In these 
places, we configure the requisite data (path to config files for obtaining 
blockIds, path to jars for obtaining textures, etc)

3. Each detected plugin is asked to read from the config, and enable themselves 
if necessary.

4. After Teconicus parses defaultBlocks.xml, but before parsing 
customBlocks.xml, it asks active plugins to register their own set of blocks.

5. Each plugin will have its own set of BlockTypes that it needs to represent 
its own blocks (eg, IC2CableBlockType, IC2MachineBlockType)

6. Assuming all goes well, the rendering can proceed as normal.

Assuming you guys agree that this plan is good, I am ready to start 
implementing it (at least the framework, I don't know how well I can implement 
each of the custom models for rendering, but it's a start :)

Original issue reported on code.google.com by caron.m...@gmail.com on 1 May 2012 at 1:24

GoogleCodeExporter commented 9 years ago
I'm sorry, I meant to mark this as "Enhancement", but I forgot and now I can't 
edit it :(

Original comment by caron.m...@gmail.com on 1 May 2012 at 1:25

GoogleCodeExporter commented 9 years ago
I don't have any experience with these mods but i understand the issues.  I was 
thinking about allowing  custom blocks to have their geometry defined in the 
xml. Would be easier to implement the mods that way than with a native Java 
plug in.

Original comment by sambened...@gmail.com on 1 May 2012 at 8:06

GoogleCodeExporter commented 9 years ago
The problem with having blocks-as-plugins is that it's very hard to change the 
code without breaking everyone's plugins. Minecraft's mod support being a prime 
example.

When I was originally thinking about this I was thinking about letting 
customblocks.xml include links to external model files for individual blocks. 
That would be better than hand-writing the block geometry like we do now, and 
makes custom blocks easier.

Where I got stuck was deciding what model format to use - unfortunately 
minecraft doesn't have one so we can't use that. Most professional modeling 
tools are pricey and/or don't let you control tex coords as precicely as we'd 
need.

Perhaps there may be a minecraft-specific modeling tool we can use for this?

Original comment by orangytang on 1 May 2012 at 10:02

GoogleCodeExporter commented 9 years ago
I would like to mention that the issue I'm trying to address is more than just 
modelling non-cube blocks. It's more about determining how to render blocks 
whose state is not fully captured by the blockId+data pair. This is an 
open-ended problem, but mainly manifests itself in two ways:

1. Blocks that depend on their neighbours. Eg, redstone, cables, etc. (see the 
attached screenshot). To properly render these blocks, you need to examine 
their 26 neighbours to see if they connect in some way. Certain blocks only 
connect to like blocks (red stone), other blocks connect to an entire set of 
other blocks (IndustrialCraft wires), still others only connect in certain 
situations/contextually (BuildCraft pipes).

Describing these relationships in XML would be possible, sure, but each 
individual block would require a page of XML, and were it up to me, I wouldn't 
bother.

2. Blocks whose state is in a Tile Entity (eg, Signs, IndustrialCraft machines, 
BuildCraft tanks). Unlike #1, I doubt that trying to describe this in XML is 
possible. And, how is the average user supposed to find this stuff out anyway? 
The Minecraft Wiki is the only one that even bothers trying to document this 
Tile Entity structures, but mods have 10 times as many and 0 documentation.

I'm sure there are cases I haven't even thought of, as well.

Even if it were feasible to describe all this stuff in customBlocks.xml, why 
would you want to make every single person who uses these very popular and very 
common mods reverse engineer them to figure out what data values and ids 
they're supposed to use, what model they have to use, etc etc. Tectonicus is 
the only mapping program that even /tries/ to have mod support, so I would be 
incredibly happy if it weren't half-assed. And, I am willing to help in 
full-assing this thing :)

Regarding breaking plugins, I don't think fear of breaking compatibility is a 
good reason not to have it. Minecraft's mod support being a prime example ;) 
Besides, the plugins don't need to be external, and they don't need to be 
written by third parties. They could be part of Tectonicus, and just separated 
from the core for organizational purposes.

In summary, I think the modelling part of this is orthogonal to the actual 
problem, which is that supporting these mods requires Tectonicus to be smarter 
than it currently is.

Original comment by caron.m...@gmail.com on 1 May 2012 at 10:28

Attachments:

GoogleCodeExporter commented 9 years ago
It was never intended for users to make their own customblocks.xml - it was 
always intended that mod authors would create it and share it for their users. 
Unfortunately no-one seems interested which is why it's not really been worked 
on. And most mod authors are (for some crazy reason) not very helpful with 
giving out info about what ids their mod actually uses.

From an end-user point of view, I don't think it matters if they get a custom 
blocks xml file, or a custom blocks jar / plugin.  I do agree that the more 
complicated blocks require more complicated logic though.

If (for the sake of argument) we ignore compatibility and authoring issues, 
Tectonicus wouldn't need much to support user-pluggable blocks since the 
BlockType gets us most of the way. I'd probably go with plugins provided as 
compiled java classes in a jar, containing new BlockType classes. Changes 
needed would be:

1. Add plugin jars to the classpath somehow (either at runtime (URLClassloader 
tricks?)) or make the user do it at the command line.
2. Some kind of plugin descriptor that lists fully-qualified names of classes 
that implement BlockType, and a shorthand name to use when referring to it in 
customblocks.xml
3. Load the plugin descriptor into some kind of BlockTypeLibrary with a 
Map<String, Class>
4. Use the BlockType library when parsing customblocks.xml, create new block 
types by reflection as needed and let the newly created block type parse the 
xml.

Then the rendering proceeds as normal, and should be fast as we're just using 
regular bytecode rather than any scripting language or what-not.

Thoughts?

Original comment by orangytang on 1 May 2012 at 10:46

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
Zekaonar, please make a new issue for this so we don't clog up this one.

And if you could attach to it a small example world with those blocks in it, 
and the config.xml you're currently using as well that'd be very helpful.

Original comment by orangytang on 1 May 2012 at 11:01

GoogleCodeExporter commented 9 years ago
I could suggest a solution to at least a part of a problem.

Approach 3: Scrap most of all the special blocks that have been created so far 
and introduce one generic "special block" with robust, descriptive syntax.
Just look, what you have now:
"Solid" - a block with the same texture on all sides. Fine.
"Water" - well... okay. It requires some special treatment. (Strangely enough, 
"Lava" is a solid block...)
But then it becoming worse with every next pick.
Why not introduce a <Custom /> block with some generic attributes, like 
front/back/left/right/side/top/bottom ? That would solve a problem with 99% of 
cubic blocks.

With some more convoluted syntax (definition of width, height and offset in 
1/16'th of a block), you could describe RP2's sliced blocks (easy).

Original comment by anrdae...@freemail.ru on 2 May 2012 at 1:15

GoogleCodeExporter commented 9 years ago
@anrdea... That's a great idea, I look forward to typing out all 32000+ 
microblocks!

@orangytang That's pretty close to what I was thinking of.

One addition I would suggest is the ability to point the plugin at the mod's 
config file (eg, .minecraft/config/IC2.cfg) so that it can read the ids 
directly. That way, additions to customBlocks.xml wouldn't even be necessary. 
But, this is not a priority, all things considered.

Unless you have any objections, I wouldn't mind getting started on whipping up 
a quick proof-of-concept.

Original comment by caron.m...@gmail.com on 2 May 2012 at 11:34

GoogleCodeExporter commented 9 years ago
anrdaemon: Most of the different kinds of block address subtle differences 
between the blocks. Water for example requires special handling because of the 
transparency and depth fogging. Similarly most block types make tradeoffs 
between rendering speed and flexibility. If we built everything out of a 
general purpose, highly configurable <Custom/> block the rendering time would 
be huge.

I do agree that we could have a few more custom block types to make mod support 
more useful. DataSolid is a step in the right direction but we probably need a 
block that can have specified textures on all sides.

caron.mike: I think plugins should be a self-contained jar, and free to define 
their block list however they want. Then we can make a 'base' plugin with all 
the standard minecraft blocks which reads from baseBlocks.xml and a 
user-provided customBlocks.xml, and an IC2 plugin may read from an IC2.cfg 
file. Does that sound reasonable?

Original comment by orangytang on 3 May 2012 at 4:51

GoogleCodeExporter commented 9 years ago
As I said earlier, I started implementing this. It wasn't actually that 
difficult get it going. I've attached the patch for tectonicus, however you 
need a plugin to test it properly.

As such, I've set up a repo for the plugins, which is located here: 
https://github.com/pkmnfrk/tectonicus-mods

To test the plugin, you need to do the following things:
1. Check out the plugin project
2. Copy Tectonicus-x.yz.jar to lib/ (must have been compiled with the patch 
applied)
3. Download IndustrialCraft client 
(http://wiki.industrial-craft.net/index.php?title=Download#Download_IC.C2.B2_for
_Minecraft.C2.A01.2.5) and stick that in test/
4. Make sure test/config.xml is pointing at the correct jar file name (in case 
IC2 releases a new version)
5. Run 'ant clean-build test'
6. The map will render to test/map/ and has a single Iron Furnace placed.

As of right now, the plugin is capable of:
 - Reading a configuration node from config.xml
 - Adding blocks to the block registry
 - Supplying its own set of textures (eg, from a mod's jar)
 - Supplying its own kinds of BlockTypes

To do:
 - Allow Tectonicus to query what kinds of BlockTypes it supports, for use in customBlocks.xml
 - Allow plugins to add more debug output a la Maps and their like.
 - Allow plugins to read Tile Entities that it cares about.

Things I'm not sure about:
 - Plugins currently have to publish a list of capabilities, but this is probably not necessary

Suggestions, criticisms, etc are welcome!

Original comment by caron.m...@gmail.com on 4 May 2012 at 11:52

Attachments:

GoogleCodeExporter commented 9 years ago
I've only had time to quickly glace through it, but it looks like it has 
potential.

Really not keen on the global state you've introduced, but I'm sure that can be 
removed. Will try and have a more detailed look later.

Original comment by orangytang on 5 May 2012 at 10:38

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
@caron, if that was a sarcasm, then fine.
But if not, then you don't need to TYPE all the 500+ microblocks, at all. This 
could easily be automated. Perhaps, automated on a rendering level, so that you 
don't need to type anything at all.

@orangytang: Let me elaborate for a bit: I'm not for "high customizability".
I'm for necessary and sufficient costomizability.

I don't know, if you can get block orientation from the map directly at all 
times (sad me)... but if you do, then dividing blocks into a few classes and 
creating sufficient attribute set to descibe 99% of them would be enough.

Say, for example, a Wooden Log block requires one texture for top/bottom, and 
one for sides.

A cauldron/crucibles/pistons have same texture on sides, but different top and 
different bottom.

Furnace/Dispenser have different face/top/bottom textures. Which requires 
knowing it's facing to describe properly...

There's not much variety, really.

Original comment by anrdae...@freemail.ru on 9 May 2012 at 8:57

GoogleCodeExporter commented 9 years ago
So I was going to tweek this and integrate it myself, but then I found out I 
still don't have any spare time. So mike I've given you commit access to the 
Tectonicus project. Feel free to integrate what you've got and we'll refine it 
from there.

Original comment by orangytang on 10 May 2012 at 12:11

GoogleCodeExporter commented 9 years ago
@orangytang: Ha ha, time, who has that these days?

I meant to actually respond to your concerns the other day, but, you know, 
work/life/etc.

The only reason I made the plugin list global was because I couldn't figure out 
a good way to inject the list into all the places it needed to go. I'm open to 
suggestions about a good place to stick it (eg on a configuration object that 
is already passed around everywhere that I didn't notice).

Anyway, thanks! I will look in to merging this in on the weekend.

@anrdaemon: Yes, that was sarcasm. But anyway, I've since discovered that 
microblocks are even more complicated than I thought. Each minecraft block can 
have up to 6 (or even more, I didn't experiment a lot) microblocks in it, all 
of different sizes, shapes and types. I have not dared investigate how Eloraam 
managed to pull this off. It is possible that she is the only one capable of 
understanding it properly :)

Ignoring the problematic microblocks, the reason that there are so many types 
of blocks is not because orangytang enjoys copying and pasting blocks, but 
because each block is, in fact, different. Caundrons and piston (heads) are 
complex models. Piston bodies are different shapes depending on state. Chests 
are not perfect prisims, and they do not occupy the entire block. Etc, etc.

With a few exceptions (Double slabs, for example), there is very little 
redundancy in the set of block types.

Original comment by caron.m...@gmail.com on 10 May 2012 at 12:56

GoogleCodeExporter commented 9 years ago
Speaking of amount of microblocks in one block worth of space, my number is 
"15". The frame of 12 blocks by each edge, and 3 pillars crossing inside. So, 
yes, it's complicated. But setting complication aside, and looking into 
technical details, all of the (500+?) microblocks could be described with the 
same code, as they are (re)using the textures of the parent block. And they are 
all "simple" blocks.
It's essentially down to writing the right render code once. A big task in 
itself, I could imagine, but honestly... It's probably the only one such mod, 
that have this level of effect on Minecraft, both visual and technical. Eloraam 
is simply genius...

Original comment by anrdae...@freemail.ru on 10 May 2012 at 10:08

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
Tectonicus is being moved over to GitHub here: 
https://github.com/tectonicus/tectonicus

I have imported this issue into the new GitHub project issue tracker: 
https://github.com/tectonicus/tectonicus/issues/7

Original comment by skoeven on 28 Aug 2014 at 3:59