Skip to content

Commit 1fe8435

Browse files
committed
Started actual docs
1 parent 62ab159 commit 1fe8435

16 files changed

Lines changed: 829 additions & 144 deletions

.vitepress/config.mjs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ function buildSidebar() {
120120
}
121121

122122
// Prepend a home link
123-
sidebar.unshift({ text: 'home', link: '/azimuth' });
123+
sidebar.unshift({ text: 'home', link: '/' });
124124
return sidebar;
125125
}
126126

@@ -132,17 +132,17 @@ function basenameWithoutExt(fullPath) {
132132
const sidebar = buildSidebar();
133133

134134
export default defineConfig({
135-
title: "Azimuth Docs",
135+
title: "Azimuth",
136136
description: "Documentation of the Azimuth library",
137137
themeConfig: {
138138
nav: [
139-
{ text: 'home', link: '/azimuth' },
139+
{ text: 'home', link: '/' },
140140
],
141141

142142
sidebar: sidebar,
143143

144144
socialLinks: [
145-
{ icon: 'github', link: 'https://github.com/vuejs/vitepress' }
145+
{ icon: 'github', link: 'https://github.com/Industrialists-Of-Create/AzimuthDocs' }
146146
]
147147
},
148148
srcDir: 'docs',

docs/Advancements/Advancements.md

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
# Advancements
2+
3+
Azimuth provides a Create-compatible advancement system that closely mirrors how Create handles its own advancements internally. The goal is to let addon authors define and award advancements without having to wire up all the boilerplate themselves and, importantly, without needing to know Create's internals.
4+
5+
There are three main classes involved:
6+
7+
| Class | Role |
8+
| --- | --- |
9+
| `AzimuthAdvancementProvider` | Central registry for a mod's advancements. Handles datagen and lang generation. |
10+
| `AzimuthAdvancement` | A single advancement definition icon, title, description, trigger, parent. |
11+
| `AzimuthAdvancementBehaviour` | A `BlockEntityBehaviour` for tracking and awarding advancements from block entities. |
12+
13+
14+
## Setting up `AzimuthAdvancementProvider`
15+
16+
Create one static `AzimuthAdvancementProvider` for your mod and define all your advancements on it:
17+
18+
```java
19+
public class MyAdvancements {
20+
21+
public static final AzimuthAdvancementProvider PROVIDER =
22+
new AzimuthAdvancementProvider(MyMod.MOD_ID, "My Mod Advancements");
23+
24+
public static final AzimuthAdvancement ROOT = PROVIDER.create("root", b -> b
25+
.icon(MyItems.MY_ITEM)
26+
.title("My Mod")
27+
.description("Get started with My Mod.")
28+
.after(() -> AllAdvancements.ROOT) // display inside the Create tab omit to create a new advancement tab
29+
.awardedForFree() // immediately award when the player first joins
30+
.special(AzimuthAdvancement.TaskType.SILENT)
31+
);
32+
33+
public static final AzimuthAdvancement FIRST_CRAFT = PROVIDER.create("first_craft", b -> b
34+
.icon(MyItems.MY_ITEM)
35+
.title("First Steps")
36+
.description("Craft your first widget.")
37+
.after(ROOT)
38+
.whenItemCollected(MyItems.MY_ITEM)
39+
);
40+
}
41+
```
42+
43+
Then wire it into datagen. Call `register()` during common mod init, then hook `provideLang` and `dataProvider` into your datagen event:
44+
45+
```java
46+
// In your mod class or init method
47+
MyAdvancements.PROVIDER.register();
48+
49+
// In your GatherDataEvent handler
50+
public static void gatherData(final GatherDataEvent event) {
51+
final PackOutput output = event.getGenerator().getPackOutput();
52+
final CompletableFuture<HolderLookup.Provider> lookupProvider = event.getLookupProvider();
53+
54+
YourMod.REGISTRATE.addDataGenerator(ProviderType.LANG, provider -> {
55+
final BiConsumer<String, String> langConsumer = provider::add;
56+
MyAdvancements.PROVIDER.provideLang(langConsumer);
57+
});
58+
59+
event.getGenerator().addProvider(
60+
event.includeServer(),
61+
MyAdvancements.PROVIDER.dataProvider(output, lookupProvider)
62+
);
63+
}
64+
```
65+
66+
67+
## Advancement builder options
68+
69+
The builder passed to `PROVIDER.create(...)` supports the following:
70+
71+
### Icon
72+
73+
```java
74+
.icon(MyItems.MY_ITEM) // ItemProviderEntry<?, ?>
75+
.icon(Items.IRON_INGOT) // ItemLike
76+
.icon(new ItemStack(Items.BOOK)) // ItemStack, for NBT-specific icons
77+
```
78+
79+
### Title and description
80+
81+
```java
82+
.title("My Advancement Title")
83+
.description("A short description shown in the advancement screen.")
84+
```
85+
86+
Lang keys are automatically generated as `advancement.<modid>.<id>` and `advancement.<modid>.<id>.desc`.
87+
88+
### Parent
89+
90+
Chain advancements by passing the parent definition:
91+
92+
```java
93+
.after(ROOT) // AzimuthAdvancement
94+
.after(AllAdvancements.ANDESITE_ALLOY) // CreateAdvancement
95+
.after(ResourceLocation.fromNamespaceAndPath(...)) // raw ResourceLocation
96+
```
97+
98+
Leave out `.after(...)` entirely for the root advancement of your tree (its background texture is expected at `textures/gui/advancements.png` in your mod namespace).
99+
100+
### Task type
101+
102+
```java
103+
.special(AzimuthAdvancement.TaskType.NORMAL) // default
104+
```
105+
106+
| Type | Toast | Announce | Hidden |
107+
| --- | --- | --- | --- |
108+
| `SILENT` | No | No | No |
109+
| `NORMAL` | Yes | No | No |
110+
| `NOISY` | Yes | Yes | No |
111+
| `EXPERT` | Yes | Yes | No |
112+
| `SECRET` | Yes | Yes | Yes |
113+
114+
`SECRET` also appends a "Hidden Advancement" suffix to the description automatically.
115+
116+
### Triggers
117+
118+
If you want the advancement to be awarded by a game event (rather than manually), use one of the built-in trigger helpers:
119+
120+
```java
121+
.whenBlockPlaced(MyBlocks.MY_BLOCK.get()) // placed a specific block
122+
.whenItemCollected(MyItems.MY_ITEM) // item entered inventory
123+
.whenItemCollected(MyTags.Items.MY_TAG) // tag variant
124+
.whenIconCollected() // shorthand for the icon item
125+
.awardedForFree() // always awarded (useful for roots)
126+
.externalTrigger(myCriterion) // raw Criterion<?> for anything else
127+
```
128+
129+
If none of these are called, a built-in `SimpleCreateTrigger` is created automatically. You can then award the advancement manually (see below).
130+
131+
132+
## Awarding advancements manually
133+
134+
If the advancement uses the built-in trigger (no `.whenX` call), award it directly:
135+
136+
```java
137+
MyAdvancements.FIRST_CRAFT.awardTo(player);
138+
```
139+
140+
You can also check whether a player already has it:
141+
142+
```java
143+
if (!MyAdvancements.FIRST_CRAFT.isAlreadyAwardedTo(player)) {
144+
// do something
145+
}
146+
```
147+
148+
`awardTo` will throw `UnsupportedOperationException` if the advancement uses an external trigger.
149+
150+
151+
## `AzimuthAdvancementBehaviour`
152+
153+
If you want a block entity to track a player and award advancements when they interact with it, add `AzimuthAdvancementBehaviour` to its behaviour list:
154+
155+
```java
156+
@Override
157+
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
158+
super.addBehaviours(behaviours);
159+
AzimuthAdvancementBehaviour.create(behaviours, this,
160+
MyAdvancements.FIRST_CRAFT,
161+
MyAdvancements.ANOTHER_ONE
162+
);
163+
}
164+
```
165+
166+
Using the static `create` method (rather than constructing directly) means that if multiple callers add the behaviour, they'll merge into a single instance rather than duplicate.
167+
168+
### Tracking the player
169+
170+
Call `setPlacedBy` from your block's `setPlacedBy` override to register the player who placed it:
171+
172+
```java
173+
@Override
174+
public void setPlacedBy(Level level, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) {
175+
super.setPlacedBy(level, pos, state, placer, stack);
176+
AzimuthAdvancementBehaviour.setPlacedBy(level, pos, placer);
177+
}
178+
```
179+
180+
Fake players are ignored automatically.
181+
182+
### Awarding from the behaviour
183+
184+
```java
185+
// Award if the player is within maxDistance blocks
186+
behaviour.awardPlayerIfNear(MyAdvancements.FIRST_CRAFT, 8);
187+
188+
// Award unconditionally
189+
behaviour.awardPlayer(MyAdvancements.FIRST_CRAFT);
190+
```
191+
192+
Or use the static shorthand if you only have a position:
193+
194+
```java
195+
AzimuthAdvancementBehaviour.tryAward(level, pos, MyAdvancements.FIRST_CRAFT);
196+
```
197+
198+
Already-awarded advancements are pruned from the behaviour's tracked set automatically. Once all tracked advancements for a player have been awarded, the player reference is cleared.

docs/Getting Started.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Getting Started
2+
3+
Azimuth is a Create addon library focused on making it easier to extend the functionality of Create.
4+
5+
## Adding Azimuth to your project
6+
7+
Add the following to your `build.gradle` dependencies block, replacing `<version>` with the version you want to target, [the latest production-ready version is available here](https://modrinth.com/project/azimuth-api/settings/versions):
8+
9+
```groovy
10+
dependencies {
11+
implementation "com.cake.azimuth:azimuth:<version>"
12+
}
13+
```
14+
15+
You may also need to declare Azimuth as a required dependency in your `neoforge.mods.toml`:
16+
17+
```toml
18+
[[dependencies.yourmodid]]
19+
modId = "azimuth"
20+
type = "required"
21+
versionRange = "[<version>,)"
22+
ordering = "AFTER"
23+
side = "BOTH"
24+
```
25+
26+
Azimuth doesn't require any explicit initialisation on your part just depend on it and start using the APIs.
27+
28+
## What's available
29+
30+
### Super Block Entity Behaviours
31+
32+
An expanded version of Create's `BlockEntityBehaviour` that can do significantly more, in effort to replicate features that would typically take new block entity types. All of which is composable on a single `SmartBlockEntity`. You can also *inject* behaviours onto block entities you don't own, without touching their source, making simple soft-compatability easy.
33+
34+
[Super Block Entity Behaviours](./Super Behaviours/Super Behaviours.md)
35+
36+
### Advancements
37+
38+
A thin wrapper around Create's internal advancement machinery. Define advancements in the same style Create uses, generate the required data, and award them from anywhere including from a block entity via `AzimuthAdvancementBehaviour`.
39+
40+
[Advancements](./Advancements/Advancements.md)
41+
42+
### Outlines
43+
44+
Extra outline types built on top of Catnip's outliner. Particularly handy for ponders.
45+
46+
[Outlines](./Outlines/Outlines.md)

docs/Outlines/Outlines.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Outlines
2+
3+
Azimuth adds extra outline types built on top of Catnip's `LineOutline`. These are particularly useful in ponders, where animated visual cues help guide the player's attention.
4+
5+
## `ExpandingLineOutline`
6+
7+
A `LineOutline` that animates from its midpoint outward, expanding to full length over a configurable number of ticks. The expansion uses an ease-out cubic curve, so it decelerates naturally as it reaches full size.
8+
9+
```java
10+
ExpandingLineOutline outline = new ExpandingLineOutline();
11+
outline
12+
.set(start, end) // Vec3 start and end points
13+
.setGrowingTicks(10) // how many ticks the expansion takes
14+
.setGrowingTicksElapsed(0); // tick counter increment each tick to drive the animation
15+
```
16+
17+
Call `tickGrowingTicksElapsed()` each tick to advance the animation. Once elapsed reaches `growingTicks`, the outline stays at full size.
18+
19+
20+
## `ExpandingLineOutlineInstruction`
21+
22+
A ready-to-use Ponder `TickingInstruction` that wraps `ExpandingLineOutline`. Just add it to your scene and it handles everything.
23+
24+
```java
25+
scene.addInstruction(new ExpandingLineOutlineInstruction(
26+
PonderPalette.WHITE, // color palette
27+
new Vec3(0.5, 1.0, 0.5), // start point
28+
new Vec3(2.5, 1.0, 0.5), // end point
29+
40, // total duration in ticks
30+
10 // growing ticks how long the expand animation takes
31+
));
32+
33+
// Optionally specify line width (defaults to 1/16):
34+
scene.addInstruction(new ExpandingLineOutlineInstruction(
35+
PonderPalette.WHITE,
36+
new Vec3(0.5, 1.0, 0.5),
37+
new Vec3(2.5, 1.0, 0.5),
38+
40,
39+
10,
40+
1 / 8f // custom line width
41+
));
42+
```
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Extension Reference
2+
3+
Extensions are marker interfaces that opt a `SuperBlockEntityBehaviour` into additional systems. They're picked up lazily and cached per block entity, so behaviours that don't implement a given extension have zero impact on that system's cost.
4+
5+
For more about `SuperBlockEntityBehaviour`s, see [Super Block Entity Behaviours](./Super Behaviours.md).
6+
7+
| Extension | Description |
8+
| --- | --- |
9+
| [`KineticBehaviourExtension`](./Kinetic Extension.md) | Adds propagation positions and rotation transfer overrides for kinetic networks. |
10+
| [`RenderedBehaviourExtension`](./Rendered Extension.md) | Adds behaviour-level BER rendering, optional Flywheel visuals, and optional render bounds expansion. |
11+
| [`ItemRequirementBehaviourExtension`](./Item Requirement Extension.md) | Adds per-behaviour item requirements to schematic requirement flows. |
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# ItemRequirementBehaviourExtension
2+
3+
`ItemRequirementBehaviourExtension` lets a behaviour contribute item requirements to Create's schematic placement flow. Implement this if your behaviour places or represents items that should be listed when a player is deploying a schematic containing this block.
4+
5+
For an overview of all extensions, see [Super Block Entity Behaviours](./Super Behaviours.md#extensions).
6+
7+
## Implementing
8+
9+
```java
10+
public class MyBehaviour extends SuperBlockEntityBehaviour
11+
implements ItemRequirementBehaviourExtension {
12+
13+
public static final BehaviourType<MyBehaviour> TYPE = new BehaviourType<>();
14+
15+
public MyBehaviour(SmartBlockEntity be) {
16+
super(be);
17+
}
18+
19+
@Override
20+
public BehaviourType<?> getType() {
21+
return TYPE;
22+
}
23+
24+
@Override
25+
public ItemRequirement getRequiredItems(BlockState state) {
26+
return new ItemRequirement(
27+
ItemRequirement.ItemUseType.CONSUME,
28+
List.of(new ItemRequirement.StackRequirement(
29+
new ItemStack(MyItems.MY_ITEM.get()),
30+
ItemRequirement.ItemUseType.CONSUME
31+
))
32+
);
33+
}
34+
}
35+
```
36+
37+
Return `ItemRequirement.NONE` if no items are required in the current state, or `ItemRequirement.INVALID` if the structure cannot be placed at all.

0 commit comments

Comments
 (0)