Skip to content

Commit f9c66b2

Browse files
authored
Merge pull request #3 from EngineHub/feature/developer-docs
Add developer docs
2 parents 05fdf2c + b60739d commit f9c66b2

13 files changed

Lines changed: 308 additions & 1 deletion

source/api/concepts/actors.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Actors
2+
======
3+
4+
An ``Actor`` is anything that uses WorldEdit commands or certain APIs. Typically, an actor is a player, but they can
5+
also be a command block, the console, or perhaps an entity. As should be clear, an actor does not need a location
6+
in the world, although many actors also implement ``Locatable`` to provide this. A mod/plugin does not usually need
7+
to provide an actor to use the WorldEdit API, but actors may be provided in certain hooks such as
8+
``EditSessionEvent``, allowing for customization based on who/what an actor is.

source/api/concepts/adapters.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
Adapters
2+
========
3+
WorldEdit works across many Minecraft modding platforms. This implies that WorldEdit's API does not use any platform's
4+
API types, such as Bukkit's ``Player`` or Sponge's ``World``. Instead, WorldEdit has its own set of API types,
5+
and the platform-specific library (see :ref:`api-libraries`) contains an `adapter` class to turn the platform's
6+
API types into WorldEdit's API types, and vice versa. For example, you can turn an
7+
``org.bukkit.entity.Player`` into a ``com.sk89q.worldedit.entity.Player`` like so
8+
9+
.. code-block:: java
10+
11+
org.bukkit.entity.Player player = /* get a player */;
12+
Player wePlayer = BukkitAdapter.adapt(player);
13+
14+
Nearly every other WorldEdit type has a similar conversion from the platform type. These are best discovered by
15+
looking at the methods in the adapter classes in your IDE.

source/api/concepts/blocks.rst

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
Blocks
2+
======
3+
4+
Blocks are broken into two parts, `type` and `state`. These are represented by the ``BlockType`` and
5+
``BlockState`` classes. An example of block type is ``minecraft:oak_log``, and a state would be the
6+
combination of the type ``minecraft:oak_log`` and the `properties` ``[axis=y]``.
7+
8+
You can get a ``BlockState`` from a ``BlockType`` using either ``getDefaultState()`` or providing the
9+
correct property mappings to ``getState(Map)``.
10+
11+
For example, to get the state for ``minecraft:oak_log[axis=y]``
12+
13+
.. code-block:: java
14+
15+
BlockType oakLog = Objects.requireNonNull(BlockTypes.OAK_LOG);
16+
BlockState yFacingOakLog = oakLog.getState(ImmutableMap.of(
17+
oakLog.getProperty("axis"), "y"
18+
));
19+
System.err.println("State: " + yFacingOakLog);
20+
21+
22+
Some blocks include NBT_, and these are represented by the ``BaseBlock`` type.
23+
24+
You can get a ``BaseBlock`` from a ``BlockState`` using ``toBaseBlock(CompoundTag)``.
25+
26+
.. _NBT: https://minecraft.gamepedia.com/NBT_format
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Edit Sessions
2+
=============
3+
An ``EditSession`` handles the configuration for getting and placing blocks, entities, and biomes. It sets up the
4+
chain of extents to place blocks properly. It also handles turning on and off reorder mode, fast mode, and buffering.
5+
Every operation will use an ``EditSession`` at some point to ensure that block placement is done properly and quickly.
6+
7+
Edit sessions must be closed once all operations are complete, to ensure that block queues are flushed.
8+
They are not re-usable, and must be re-created for each individually operation.

source/api/concepts/extents.rst

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Extents
2+
=======
3+
4+
Extents form the backbone of WorldEdit's block manipulation. Extents are generally split into three categories:
5+
input, output, and both. Although extents provide and receive block and biome information, they are not always
6+
associated with a world / dimension.
7+
8+
Input extents are responsible for providing block and biome information for a given location. They do not provide
9+
a way to set blocks.
10+
11+
Output extents are responsible for receiving block and biome information for a given location. They do not provide
12+
a way to get blocks.
13+
14+
Most or all extents in WorldEdit implement both ``*Extent`` interfaces, typically through the ``Extent`` interface.
15+
``Extent`` instances also provide a minimum and maximum point, as well as entity manipulation methods.
16+
17+
Some examples of extents are worlds and clipboards. Many block placement features in WorldEdit - such as fast and
18+
reorder mode - are implemented using ``AbstractDelegateExtent`` and hooking into ``setBlock``.

source/api/concepts/index.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
API Concepts
2+
============
3+
4+
WorldEdit uses some simple concepts to create flexible operations. These concepts are detailed below, and should
5+
be read in the order provided, as later concepts sometimes reference earlier concepts.
6+
7+
.. toctree::
8+
:maxdepth: 2
9+
10+
actors
11+
blocks
12+
patterns-and-masks
13+
extents
14+
regions
15+
registries
16+
edit-sessions
17+
adapters
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
Patterns and Masks
2+
==================
3+
4+
Patterns and masks are the same as described in :doc:`/usage/general/patterns` and :doc:`/usage/general/masks`.
5+
The only difference is that they must be constructed via their respective classes, rather than from formatted strings.
6+
7+
A single block pattern can be represented using a ``BlockStateHolder``, such as ``BlockState`` and ``BaseBlock``.
8+
Other patterns types are fairly obvious from their names, such as ``TypeApplyingPattern`` or ``RandomStatePattern``.
9+
Use your IDE to find subclasses of ``Pattern``.
10+
11+
Masks are a slightly different story. Exact and fuzzy block `state` masks are done using ``BlockMask``, but you can
12+
also mask only over block `type` (``BlockTypeMask``) or only the `properties` (``BlockStateMask``).
13+
There are also some utility masks in the ``Masks`` class. Again, using your IDE to find ``Mask`` subclasses is
14+
recommended.

source/api/concepts/regions.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
Regions
2+
=======
3+
4+
WorldEdit uses regions to define where an operation works. A ``Region`` is a set of positions, potentially associated
5+
with a ``World``. There is no requirement that a region be fully continuous.
6+
7+
Regions implement ``Iterable<BlockVector3>``, meaning that the best way to get all the points of `any` region is to
8+
use a ``for-each`` loop, e.g. ``for (BlockVector3 point : region)``. In addition to this, there are convenience
9+
methods to retrieve the minimum, maximum, center, area, width, height, length, chunks, and cubic chunks.
10+
You can also easily ``expand()``, ``contract()``, and ``shift()`` regions, which work like the commands of the same
11+
name. Note that these methods `do not` change any blocks.
12+
13+
Creating a region is as simple as calling the appropriate constructor of the region you want. Typically you want a
14+
``CuboidRegion``, but there are other subclasses for each of the selection types in WorldEdit, or you can implement
15+
your own!
16+
17+
Some common region usages are the actor's selection and clipboard bounds.

source/api/concepts/registries.rst

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Registries
2+
==========
3+
4+
Almost everything in Minecraft uses the same format for identifying a particular type, such as ``minecraft:stone``.
5+
This is known as a `namespaced ID <https://minecraft.gamepedia.com/Namespaced_ID>`_ (see page for details).
6+
WorldEdit keeps some `registries` that allow access to blocks, items, biomes, entities, fluids, and more from the
7+
current Minecraft platform using their ID in a platform-independent way.
8+
9+
These registries are available on most classes named ``*Type``, such as ``BlockType`` and ``ItemType``.
10+
However, it is recommended to use the ``*Types`` classes instead, which either provide potentially-null constants
11+
or a ``get`` method for retrieving types that aren't built-in, such as modded blocks.
12+
13+
.. note::
14+
The constants on these registries may be ``null`` because the API does not change across Minecraft versions,
15+
and this means that some blocks won't exist on earlier Minecraft versions, or like in 1.13, were renamed
16+
from their ID in 1.12 and WorldEdit no longer recognizes the block properly. If you require a block, you should
17+
wrap the access to the constant in ``Objects.requireNonNull`` or a similar check to properly communicate that
18+
you do not expect the constant to be missing at runtime.

source/api/examples/clipboard.rst

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
Clipboard Examples
2+
==================
3+
4+
.. note::
5+
This documentation covers the API for using clipboards.
6+
See :doc:`/usage/clipboard` for in-game usage & explanations of what clipboards are.
7+
8+
Concepts used in these examples: :doc:`../concepts/regions`, :doc:`../concepts/edit-sessions`,
9+
:doc:`../concepts/extents`
10+
11+
Copying
12+
-------
13+
Copying is the most common way to create a clipboard. To do it, you'll need a ``Region``, a target ``Clipboard``,
14+
and an ``EditSession``. In this example we use a ``CuboidRegion`` and the standard ``BlockArrayClipboard``.
15+
Then, all you need to do is pass the parameters to the ``ForwardExtentCopy``, apply configuration (such as calling
16+
``setCopyingEntities(true))`` to copy entities), and call ``Operations.complete``.
17+
18+
.. code-block:: java
19+
20+
CuboidRegion region = new CuboidRegion(world, min, max);
21+
BlockArrayClipboard clipboard = new BlockArrayClipboard(region);
22+
23+
try (EditSession editSession = WorldEdit.getInstance().getEditSessionFactory().getEditSession(world, -1)) {
24+
ForwardExtentCopy forwardExtentCopy = new ForwardExtentCopy(
25+
editSession, region, clipboard, region.getMinimumPoint()
26+
);
27+
// configure here
28+
Operations.complete(forwardExtentCopy);
29+
}
30+
31+
You may want to :ref:`save <Saving>` the clipboard after this.
32+
33+
Pasting
34+
-------
35+
Pasting is the only way to move blocks from a ``Clipboard`` to another ``Extent``, typically a ``World``.
36+
To paste, you'll need a ``World``, an ``EditSession`` and a ``Clipboard``. Create a ``ClipboardHolder``
37+
with your clipboard, then get a ``PasteBuilder`` by calling ``createPaste`` with the ``EditSession``.
38+
Call ``.to`` to set the position at which you want to paste (this will be offset by the clipboard offset,
39+
see the clipboard page above for more information). Add any other configuration you want (masks, paste entities,
40+
paste biomes, etc.), and then call ``build()`` to get an operation. Complete the operation, and all the blocks
41+
will be pasted.
42+
43+
Full example:
44+
45+
.. code-block:: java
46+
47+
try (EditSession editSession = WorldEdit.getInstance().getEditSessionFactory().getEditSession(world, -1)) {
48+
Operation operation = new ClipboardHolder(clipboard)
49+
.createPaste(editSession)
50+
.to(BlockVector3.at(x, y, z))
51+
// configure here
52+
.build();
53+
Operations.complete(operation);
54+
}
55+
56+
You may want to :ref:`load <Loading>` a clipboard before this.
57+
58+
Schematic Examples
59+
==================
60+
This section deals with schematics, which are a related but distinct concept. Schematics
61+
specifically refer to a saved clipboard, not a clipboard in-memory.
62+
63+
.. _saving:
64+
65+
Saving
66+
------
67+
A ``Clipboard`` can be saved to disk very easily. All you need is a ``ClipboardFormat``, a ``Clipboard``, and an
68+
``OutputStream``. Then you can call ``getWriter`` on the format and ``write`` on the writer with
69+
your ``Clipboard``. Here's an example for saving a clipboard to file.
70+
71+
.. code-block:: java
72+
73+
File file = /* figure out where to save the clipboard */;
74+
75+
try (ClipboardWriter writer = BuiltInClipboardFormat.SPONGE_SCHEMATIC.getWriter(new FileOutputStream(file))) {
76+
writer.write(clipboard);
77+
}
78+
79+
.. _loading:
80+
81+
Loading
82+
-------
83+
Loading a ``Clipboard`` is nearly as simple. You can either force a specific ``ClipboardFormat``, or have WorldEdit
84+
discover the format of the schematic you want to load. The example does the latter. Then you can call ``getReader``
85+
on the format and ``read`` on the reader to get a ``Clipboard`` instance.
86+
87+
.. code-block:: java
88+
89+
Clipboard clipboard;
90+
91+
ClipboardFormat format = ClipboardFormats.findByFile(file);
92+
try (ClipboardReader reader = format.getReader(new FileInputStream(file))) {
93+
clipboard = reader.read();
94+
}
95+
/* use the clipboard here */

0 commit comments

Comments
 (0)