-
-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
8 changed files
with
258 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
doc/architecture/decision/001-multi-loader-architecture.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# 1. Multi-loader architecture | ||
|
||
Date: 2021-12-21 | ||
|
||
## Status | ||
|
||
Accepted | ||
|
||
## Context | ||
|
||
A big reason for rewriting Refined Storage is to have support for multiple modloaders. Therefore, the architecture | ||
should support this design goal in a maintainable way. | ||
|
||
## Decision | ||
|
||
Refined Storage 2 will have a modular structure with a module per modloader. | ||
|
||
There will be a common module, and most code should reside in there. The modloader specific (platform) modules should be | ||
reserved | ||
for platform specific functionality, like registration, networking, etc. | ||
|
||
The module naming follows the standard of `refinedstorage2-platform-{name}`. | ||
|
||
## Consequences | ||
|
||
Thanks to the modular structure, it will be easier to separate modloader specific code and Minecraft code. | ||
|
||
Apart from the structural benefits, it will be easier to maintain support for different modloaders as opposed to working | ||
with multiple Git branches and rebasing (or copying code over). | ||
|
||
The build system will become more complicated, as the common module needs to be "loaded" into the specific modloader ( | ||
platform) | ||
modules. | ||
|
||
It will also be harder to update the mod to a newer Minecraft version if not all our supported modloaders are upgraded | ||
yet. However, in that case we can probably disable the specific platform module in the build system. | ||
|
||
## References | ||
|
||
- https://github.com/refinedmods/refinedstorage2/issues/64 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# 2. API modules | ||
|
||
Date: 2021-08-21 | ||
|
||
## Status | ||
|
||
Accepted | ||
|
||
## Context | ||
|
||
Most of the business logic in Refined Storage 1 is interweaved with Minecraft specific code. | ||
|
||
This makes it harder to write unit tests and to maintain the codebase. | ||
|
||
Along with the negative impact on testability, this makes our business logic prone to changes in Minecraft. Ideally, our | ||
business logic shouldn't change due to a Minecraft update. | ||
|
||
## Decision | ||
|
||
Refined Storage 2 will have multiple API modules that have no dependency on Minecraft whatsoever. | ||
These modules can depend on each other, but the dependency chain should be logical. | ||
|
||
These API modules can be consumed by platform modules (to bundle them) [[1]](#1) and addon developers. | ||
|
||
The platform modules [[1]](#1) are responsible for integrating the modules with Minecraft, by implementing interfaces on | ||
their end that the API modules can use. | ||
|
||
The API modules have the name `refinedstorage2-{name}-api`. | ||
|
||
## Consequences | ||
|
||
Using multiple API modules ties in nicely with our modular structure for platform modules [[1]](#1). | ||
|
||
It will be difficult to integrate these modules with Minecraft code, so designing them should be done thoughtfully. | ||
|
||
It will be easier to maintain and unit test these modules as they have no dependency on Minecraft. | ||
|
||
## References | ||
|
||
- <a id="1">[1]</a> See [1. Multi-loader architecture](001-multi-loader-architecture.md) | ||
- https://github.com/refinedmods/refinedstorage2/commit/42cd440dfa227673be88917193a5327285d85f47 | ||
- https://github.com/refinedmods/refinedstorage2/commit/a3fce1c12bc5e1d06db4441a78b9edc56852f2bc | ||
- https://github.com/refinedmods/refinedstorage2/commit/d46fba9bed46edaa3c7ed57fc780b10d724c4a2c | ||
- https://github.com/refinedmods/refinedstorage2/commit/5b798047e9573e787e071e14fe7de122218389f9 | ||
- https://github.com/refinedmods/refinedstorage2/commit/66416a25f0c32127c94aed265c5e62a2b4374f31 | ||
- https://github.com/refinedmods/refinedstorage2/commit/bcf3324b71ea837fb044b051b8d5bb9c9e108028 | ||
- https://github.com/refinedmods/refinedstorage2/commit/1b86e4364561160ceda9a62f6f5e10298d989791 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# 3. The platform API module | ||
|
||
Date: 2021-12-29 | ||
|
||
## Status | ||
|
||
Accepted | ||
|
||
## Context | ||
|
||
Now that we have platform modules (one for each modloader, and a common module) [[1]](#1) and API | ||
modules [[2]](#2), we still need a way for addons to integrate with the mod. | ||
|
||
Doing so via the common module would be detrimental as it would expose too much code to addons (just like it did in | ||
Refined Storage 1). | ||
|
||
## Decision | ||
|
||
Refined Storage 2 will have a modloader-neutral (just like the common module) platform API module which addon mods can | ||
use to integrate with Refined Storage. | ||
|
||
Moreover, Refined Storage 2 itself will use this platform API module. | ||
|
||
The module is named `refinedstorage2-platform-api`. | ||
|
||
## Consequences | ||
|
||
By offering a dedicated platform API module we can much more tightly control API surface. | ||
|
||
The platform API module is platform-neutral so addons can decide what modloader they target. Moreover, it saves us time | ||
because we don't have to maintain different platform APIs per modloader. | ||
|
||
However, if addon mods want to support multiple modloaders, they'll have to create their own abstractions. | ||
|
||
## References | ||
|
||
- <a id="1">[1]</a> See [1. Multi-loader architecture](001-multi-loader-architecture.md) | ||
- <a id="2">[1]</a> See [2. API modules](002-api-modules.md) | ||
- https://github.com/refinedmods/refinedstorage2/commit/64e97fd170185d3d55a60879db7fca2134ae6dd0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# 4. Coverage requirements | ||
|
||
Date: 2021-12-22 | ||
|
||
## Status | ||
|
||
Accepted | ||
|
||
## Context | ||
|
||
Since we are writing more unit tests with our API modules [[1]](#1) we need to establish code coverage requirements. | ||
|
||
## Decision | ||
|
||
We will differentiate between platform modules [[2]](#2) and API modules [[1]](#1). The reason for this is that it's difficult to test | ||
Minecraft code properly. | ||
|
||
Luckily, since our most important (business-logic) code resides in the API modules [[1]](#1) we can put | ||
our testing focus there and establish coverage requirements. | ||
|
||
However, sometimes it is still advised to write a test for platform code, even if there are no coverage requirements for | ||
it. For that reason, the `refinedstorage2-platform-test` module exists, to provide helpers to deal with Minecraft code. | ||
|
||
## Consequences | ||
|
||
For API modules, this means that: | ||
|
||
- Minimum 80% code coverage | ||
- Minimum 90% mutation coverage | ||
|
||
For platform modules, this means that: | ||
|
||
- No code coverage requirement | ||
- No mutation coverage requirement | ||
|
||
These requirements will be enforced by SonarQube and Pitest. | ||
|
||
## References | ||
|
||
- <a id="1">[1]</a> See [2. API modules](002-api-modules.md) | ||
- <a id="2">[2]</a> See [1. Multi-loader architecture](001-multi-loader-architecture.md) | ||
- https://github.com/refinedmods/refinedstorage2/issues/115 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# 5. Unit testing | ||
|
||
Date: 2020-10-24 | ||
|
||
## Status | ||
|
||
Accepted | ||
|
||
## Context | ||
|
||
The coverage requirements [[1]](#1) for the API modules [[2]](#2) state that we need unit test coverage. Hence, we need | ||
to clarify what "unit" in unit test means. | ||
|
||
The API modules in Refined Storage 2 are already disconnected from reality (Minecraft), so we need unit tests that | ||
closely mimick real situations and assert real behavior if we want to get any value out of them. | ||
|
||
This eliminates the definition that most | ||
people have of unit tests, which is to test "a single method" and to mock dependencies of the class of that method. | ||
|
||
## Decision | ||
|
||
Refined Storage 2 unit testing will follow a behavior driven approach, where "unit" in unit test means "unit of | ||
behavior" and not "unit of method". | ||
|
||
## Consequences | ||
|
||
A unit test should verify behavior and not make assumptions about internal code structure, therefore most use of mocking | ||
is not allowed. This will make our test suite stronger and less prone to breakage. | ||
|
||
Our tests will not break due to a refactoring. | ||
|
||
This doesn't mean that we are suddenly "integration testing", just because we decide to not mock dependencies of | ||
classes. Integration testing will happen in the platform modules [[3]](#3) as Minecraft game tests. | ||
|
||
## References | ||
|
||
- <a id="1">[1]</a> See [4. Coverage requirements](004-coverage-requirements.md) | ||
- <a id="2">[2]</a> See [2. API modules](002-api-modules.md) | ||
- <a id="3">[3]</a> See [1. Multi-loader architecture](001-multi-loader-architecture.md) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# 6. No persistent networks | ||
|
||
Date: 2021-05-24 | ||
|
||
## Status | ||
|
||
Accepted | ||
|
||
## Context | ||
|
||
Networks and network nodes were persisted seperately in Refined Storage 1. | ||
|
||
This caused a lot of problems, because there was a disconnect between the real state of the world and the persisted | ||
file. | ||
|
||
Most of the time, this didn't lead to any problems, but it quickly failed with block moving mods or mods that worked | ||
with block entities in non-conventional ways. | ||
|
||
## Decision | ||
|
||
Networks cannot be persisted in Refined Storage 2. They need to be loaded in memory. | ||
|
||
Network nodes cannot be persisted in Refined Storage 2. All persistent data should be stored on corresponding the block | ||
entity. | ||
|
||
## Consequences | ||
|
||
It will no longer be possible to persist global network data, since there are no persistent networks. | ||
|
||
This means that some persistent components like resource trackers (when has what been changed in het network?) need to | ||
be stored on the storage itself. | ||
|
||
Since networks are no longer persisted and built ad-hoc, it should make the mod more robust. Also, it allows to have | ||
multiple entry-points to a network. | ||
|
||
For network nodes, storing everything on the block entity should simplify the code a lot. There is simply no need for | ||
decoupling the storage part, and just causes friction like in Refined Storage 1. | ||
|
||
## References | ||
|
||
- https://github.com/refinedmods/refinedstorage2/commit/df8f881c1c300e1cb6f02a8ac3f03aa163f634db |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters