Getting started

Jozufozu 2021-12-23 13:17:25 -08:00
commit 4273579b17

127
Your-First-Instance.md Normal file

@ -0,0 +1,127 @@
This wiki is a work in progress! Hopefully it can lead you in the right direction.
Start by creating an empty subclass of `TileEntityInstance`, and build it up from there.
```java
public class MyBlockInstance extends TileEntityInstance<MyBlockEntity> {
public MyBlockInstance(MaterialManager materialManager, MyBlockEntity tile) {
super(materialManager, tile);
}
@Override
public void remove() {
// You'll be doing some cleanup here later.
}
}
```
And you have to register the `Instance` with Flywheel, so might as well get that out of the way now.
```java
public class MyInstances {
public static void init() {
InstancedRenderRegistry r = InstancedRenderRegistry.getInstance();
r.tile(MyBlockEntityTypes.MY_BLOCK_ENTITY)
.setSkipRender(true) // Completely skip the BlockEntityRenderer.
.factory(MyBlockInstance::new); // Use our TileEntityInstance instead.
}
}
```
And be sure to call `MyInstances.init()` somewhere!
But, let's get back to the fun stuff. As it currently stands, our Instance does nothing but sit there and take up
memory. So, you might ask, how can I get it to render something?
In Flywheel, `TileEntityInstance`s don't *technically* render models on their own. Instead, they ask the
`MaterialManager` to create a parameterized *instance* of a model. The `TileEntityInstance` is then free to change the
parameters, and Flywheel takes care of the rest, ensuring that your copy of the model is rendered in the right place,
with the right light, etc.
So let's have your Instance ask the MaterialManager for a copy of some bricks, because why not?
```java
public class MyBlockInstance extends TileEntityInstance<MyBlockEntity> {
private final ModelData model;
public MyBlockInstance(MaterialManager materialManager, MyBlockEntity tile) {
super(materialManager, tile);
model = materialManager.defaultSolid()
.material(Materials.TRANSFORMED)
.getModel(Blocks.BRICKS.defaultBlockState()) // Feel free to use a different blockstate!
.createInstance();
// translate the model to make it appear at your BlockEntity
model.loadIdentity()
.translate(getInstancePosition());
}
...
}
```
And now that you've acquired resources, you have to make sure to clean up after yourself!
```java
public class MyBlockInstance extends TileEntityInstance<MyBlockEntity> {
...
@Override
public void remove() {
model.delete();
}
}
```
If you don't call `InstanceData#delete()`, all the models you ask for will be left behind when
your block entity is broken.
If you were to launch your game and place down your tile entity now, you'd see bricks, but they'd be very dark!
That's because you never tell Flywheel how to light the bricks!
In Flywheel, there's no need to query block and sky light every frame (like what's done for BlockEntityRenderers).
Instead, light data can be stored in the `ModelData`, and updated as necessary. Flywheel already does most of the
heavy lifting here, it's just on you to make sure you update your parameters when Flywheel detects a light update.
You do this by overriding (drum roll...) `#updateLight`.
```java
public class MyBlockInstance extends TileEntityInstance<MyBlockEntity> {
...
@Override
public void updateLight() {
relight(getWorldPosition(), model);
}
}
```
`relight(...)` is a helper method that takes a BlockPos and a series of model parameters, and updates the parameters
with the light data at the given position.
And so now your class looks like this:
```java
import com.jozufozu.flywheel.core.materials.model.ModelData;
public class MyBlockInstance extends TileEntityInstance<MyBlockEntity> {
private final ModelData model;
public MyBlockInstance(MaterialManager materialManager, MyBlockEntity tile) {
super(materialManager, tile);
model = materialManager.defaultSolid()
.material(Materials.TRANSFORMED)
.getModel(Blocks.BRICKS.defaultBlockState())
.createInstance();
model.loadIdentity()
.translate(getInstancePosition());
}
@Override
public void remove() {
model.delete();
}
@Override
public void updateLight() {
relight(getWorldPosition(), model);
}
}
```