-
-
Notifications
You must be signed in to change notification settings - Fork 57
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
basic structure setup and entitytype documentation
- Loading branch information
1 parent
41f583b
commit a9937e3
Showing
9 changed files
with
164 additions
and
116 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
--- | ||
sidebar_position: 5 | ||
--- | ||
# Attributes | ||
|
||
TODO |
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,12 @@ | ||
--- | ||
sidebar_position: 2 | ||
--- | ||
# Data and Networking | ||
|
||
TODO | ||
|
||
## Custom Network Messages | ||
|
||
Of course, you can also always opt to use a custom packet to send information. Please refer to the [Networking articles][networking] for more information. | ||
|
||
[networking]: ../networking/index.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 |
---|---|---|
@@ -1,134 +1,173 @@ | ||
--- | ||
sidebar_position: 1 | ||
--- | ||
# Entities | ||
|
||
Entities are actors that can interact with the world in a variety of ways. Entities comprise mobs, projectiles, rideable objects, and even players. Each entity is comprised of multiple systems that may not seem understandable at first glance. This section will breakdown some of the key components related to constructing an entity and making it behave as the modder intends. | ||
Entities are in-world objects that can interact with the world in a variety of ways. Common example include mobs, projectiles, rideable objects, and even players. Each entity consists of multiple systems that may not seem understandable at first glance. This section will break down some of the key components related to constructing an entity and making it behave as the modder intends. | ||
|
||
## A Quick Summary | ||
## Terminology | ||
|
||
Entities, in their simplest and most trivial form, are made up of four parts: | ||
A simple entity is made up of three parts: | ||
|
||
- The [`EntityType` registry object][entitytype] | ||
- The default properties that all entities have | ||
- An [`Entity` subclass][entity] | ||
- The logic to execute when this entity ticks or is interacted with | ||
- An [`EntityRenderer` subclass][entityrenderer] | ||
- How the entity is rendered in-game | ||
- A [summoning method][summon] | ||
- How the entity is spanwed into a level | ||
- The [`Entity`][entity] subclass, which holds most of our entity's logic | ||
- The [`EntityType`][type], which is [registered][registration] and holds some common properties, and | ||
- The [`EntityRenderer`][renderer], which is responsible for displaying the entity in-game | ||
|
||
An entity may require more parts depending on the subclass of `Entity` and `EntityRenderer` used (e.g., [`LivingEntity` or `Mob`][living]). | ||
More complex entities may require more parts. For example, many of the more complex `EntityRenderer`s use an underlying `EntityModel` instance. Or, a naturally spawning entity will need some sort of [spawn mechanism][spawning]. | ||
|
||
:::warning | ||
The simplest and most trivial entity does absolutely nothing. Most users will only need to extend a subclass of `Entity` and `EntityRenderer`. However, understanding the underlying principles is necessary to more effectively create entities and avoid hard to diagnose bugs. | ||
::: | ||
|
||
## `EntityType`: The Grounding Principle | ||
## `EntityType` | ||
|
||
An `EntityType` is the singleton that defines what an entity is. Multiple entities within the world can be associated with one `EntityType`. The `EntityType` also links an [`EntityRenderer`][entityrenderer] to its corresponding `Entity` class. It also defines default properties that all entities with this type has. The `EntityType` must be [registered]. | ||
The relationship between `EntityType`s and `Entity`s is similar to that of [`Item`s][item] and [`ItemStack`s][itemstack]. Like `Item`s, `EntityType`s are singletons that are registered to their corresponding registry (the entity type registry) and hold some values common to all entities of that type, while `Entity`s, like `ItemStack`s, are "instances" of that singleton type that hold data specific to that one entity instance. However, the key difference here is that most of the behavior is not defined in the singleton `EntityType`, but rather in the instantiated `Entity` class itself. | ||
|
||
An `EntityType` can be constructed via `EntityType.Builder#of`. This method takes in two parameters: an `EntityType.EntityFactory` that [constructs a default `Entity` instance][entity], and a [`MobCategory`][mobcategory] indicating the entity type. The `EntityType` can be built via `EntityType.Builder#build` by passing in `null` as the argument. | ||
|
||
:::info | ||
The `String` in the `build` method represents the registry name of the `EntityType` and is used when dealing with data fixers. The reason we pass in `null` is that data fixers go unused in mod development. If a value is passed in, then Vanilla's data fixer will continually throw a warning when loading the game as there is no definition within an applicable schema. | ||
::: | ||
Let's create our `EntityType` registry and register an `EntityType` for it, assuming we have a class `MyEntity` that extends `Entity` (see [below][entity] for more information). All methods on `EntityType.Builder`, except for the `#build` call at the end, are optional. | ||
|
||
```java | ||
// For some entity | ||
public class ExampleEntity extends Entity { | ||
|
||
// This is the constructor definition for use in 'EntityType.EntityFactory' | ||
public ExampleEntity(EntityType<? extends ExampleEntity> type, Level level) { | ||
super(type, level); | ||
// ... | ||
} | ||
|
||
// ... | ||
} | ||
|
||
// In some class that holds registry objects | ||
public static final DeferredRegister<EntityType<?>> REGISTRAR = DeferredRegister.create(Registries.ENTITY_TYPE, MOD_ID); | ||
|
||
public static final DeferredHolder<EntityType<?>, EntityType<ExampleEntity>> EXAMPLE_ENITTY = REGISTRAR.register( | ||
"example_entity", | ||
() -> EntityType.Builder.of( | ||
ExampleEntity::new // The constructor definition, | ||
MobCategory.MISC // Category for entities that do not generally extend 'Mob' | ||
).build(null) // String value goes unused | ||
public static final DeferredRegister<EntityType<?>> ENTITY_TYPES = | ||
DeferredRegister.create(Registries.ENTITY_TYPE, ExampleMod.MOD_ID); | ||
|
||
public static final Supplier<EntityType<MyEntity>> MY_ENTITY = ENTITY_TYPES.register( | ||
"my_entity", | ||
// The entity type, created using a builder. | ||
() -> EntityType.Builder.of( | ||
// An EntityType.EntityFactory<T>, where T is the entity class used - MyEntity in this case. | ||
// You can think of it as a BiFunction<EntityType<T>, Level, T>. | ||
// This is commonly a reference to the entity constructor. | ||
MyEntity::new, | ||
// The MobCategory our entity uses. This is mainly relevant for spawning. | ||
// See below for more information. | ||
MobCategory.MISC | ||
) | ||
// The width and height, in blocks. The width is used in both horizontal directions. | ||
// This also means that non-square footprints are not supported. Default is 0.6f and 1.8f. | ||
.sized(1.0f, 1.0f) | ||
// The spawn dimensions. This is used by mobs that spawn in varying sizes. | ||
// In vanilla, these are only slimes and magma cubes, both of which use 4.0f. | ||
.spawnDimensionsScale(4.0f) | ||
// The eye height, in blocks from the bottom of the size. Defaults to height * 0.85. | ||
// This must be called after #sized to have an effect. | ||
.eyeHeight(0.5f) | ||
// Disables the entity being summonable via /summon. | ||
.noSummon() | ||
// Prevents the entity from being saved to disk. | ||
.noSave() | ||
// Makes the entity fire immune. | ||
.fireImmune() | ||
// Makes the entity immune to damage from a certain block. Vanilla uses this to make | ||
// foxes immune to sweet berry bushes, withers and wither skeletons immune to wither roses, | ||
// and polar bears, snow golems and strays immune to powder snow. | ||
.immuneTo(Blocks.POWDER_SNOW) | ||
// Disables a rule in the spawn handler that limits the distance at which entities can spawn. | ||
// This means that no matter the distance to the player, this entity can spawn. | ||
// Vanilla enables this for pillagers and shulkers. | ||
.canSpawnFarFromPlayer() | ||
// The range in which the entity is kept loaded by the client, in chunks. | ||
// Vanilla values for this vary, but it's often something around 8 or 10. Defaults to 5. | ||
.clientTrackingRange(8) | ||
// How often update packets are sent for this entity, in once every x ticks. This is set to higher values | ||
// for entities that have predictable movement patterns, for example projectiles. Defaults to 3. | ||
.updateInterval(10) | ||
// Build the entity type. The parameter is a string used for datafixing; mods generally | ||
// do not utilize this and can safely pass null here instead. | ||
.build(null) | ||
); | ||
``` | ||
|
||
:::note | ||
The builder contains many methods that will be further discussed in other sections to help with understanding. An example for applying each to an `EntityType` will be provided there. | ||
:::warning | ||
Sometimes, there may be generic bounds errors with the entity type and the entity constructor. If this happens, the easiest solution is often to use an explicit generic type for `EntityType.Builder#of`, like so: | ||
|
||
```java | ||
() -> EntityType.Builder.<MyEntity>of(...) | ||
``` | ||
::: | ||
|
||
## Everything Revolves Around `Entity` | ||
### `MobCategory` | ||
|
||
The `Entity` class is the base containing the logic that the entity executes when ticked or interacted with. The `Entity` constructor takes in two parameters: the `EntityType` of the entity, and the `Level` the entity is spawned in. This constructor is passed into the `EntityType` builder to spawn entities on both the server and the client. | ||
TODO | ||
|
||
```java | ||
public class ExampleEntity extends Entity { | ||
## The Entity Class | ||
|
||
// This is the constructor definition for use in 'EntityType.EntityFactory' | ||
public ExampleEntity(EntityType<? extends ExampleEntity> type, Level level) { | ||
To begin, we create an `Entity` subclass. Alongside a constructor, `Entity` (which is an abstract class) defines three required methods that we are required to implement. These will be explained in the [Data and Networking article][data], in order to not further bloat this article. | ||
|
||
```java | ||
public class MyEntity extends Entity { | ||
// We inherit this constructor without the bound on the generic wildcard. | ||
// The bound is needed for registration below, so we add it here. | ||
public MyEntity(EntityType<? extends MyEntity> type, Level level) { | ||
super(type, level); | ||
// ... | ||
} | ||
|
||
// See the Data and Networking article for information about these methods. | ||
@Override | ||
protected void readAdditionalSaveData(CompoundTag compoundTag) {} | ||
|
||
@Override | ||
protected void addAdditionalSaveData(CompoundTag compoundTag) {} | ||
|
||
@Override | ||
protected void defineSynchedData(SynchedEntityData.Builder builder) {} | ||
} | ||
``` | ||
|
||
If the entity will be spawned manually rather than by the game, then additional constructors can be added to spawn the entity. These constructors usually hardcode the entity type to whatever is attempting to be spawned. | ||
:::info | ||
While `Entity` can be extended directly, it often makes sense to use one of its many subclasses as a base instead. See the [entity class hierarchy][hierarchy] for more information. | ||
::: | ||
|
||
```java | ||
public class ExampleEntity extends Entity { | ||
If required (e.g. because you're spawning entities from code), you can also add custom constructors. These generally hardcode the entity type as a reference to the registered object, like so: | ||
|
||
public ExampleEntity(Level level, double x, double y, double z) { | ||
// Delegates to the factory constructor | ||
this(EXAMPLE_ENITTY.value(), level); | ||
this.setPos(x, y, z); | ||
} | ||
```java | ||
public MyEntity(Level level, double x, double y, double z) { | ||
// Delegates to the factory constructor, using the EntityType we registered before. | ||
this(MY_ENTITY.get(), level); | ||
this.setPos(x, y, z); | ||
} | ||
``` | ||
|
||
### To Pick or Not to Pick | ||
And now, we are free to do basically whatever we want with our entity. The following subsections will display a variety of common entity use cases. | ||
|
||
TODO | ||
### Data Storage on Entities | ||
|
||
### Entity Dimensions | ||
_See [Entities/Data and Networking][data]._ | ||
|
||
TODO | ||
### Rendering | ||
|
||
### Entity Attachments | ||
_See [Entities/Entity Renderers][renderer]._ | ||
|
||
TODO | ||
### Spawning | ||
|
||
### Reading and Writing Data | ||
If we now boot up the game now and enter a world, we have exactly one way of spawning: through the `/summon` command (assuming `EntityType.Builder#noSummon` was not called). | ||
|
||
TODO | ||
Obviously, we want to add our entities some other way. The easiest way to do so is through the `LevelWriter#addFreshEntity` method. This method simply accepts an `Entity` instance and adds it to the world, like so: | ||
|
||
### Synchronizing to the Client | ||
```java | ||
// In some method that has a level available | ||
MyEntity entity = new MyEntity(level, 100.0, 200.0, 300.0); | ||
level.addFreshEntity(entity); | ||
``` | ||
|
||
TODO (Move to its own page) | ||
For more complex spawn behavior, please refer to the [Spawning article][spawning]. | ||
|
||
## Summoning an Entity | ||
### Ticking Entities | ||
|
||
TODO | ||
|
||
### `LevelWriter#addFreshEntity` | ||
### Picking Entities | ||
|
||
TODO | ||
|
||
### `SpawnerData` | ||
### Entity Attachments | ||
|
||
TODO | ||
|
||
#### `MobSpawnCost` | ||
## Entity Class Hierarchy | ||
|
||
TODO | ||
|
||
[entitytype]: #entitytype-the-grounding-principle | ||
[entity]: #everything-revolves-around-entity | ||
[entityrenderer]: ./renderer.md | ||
[summon]: #summoning-an-entity | ||
[registered]: ../concepts/registries.md#methods-for-registering | ||
<!-- Replace with living entity docs --> | ||
[living]: # | ||
[mobcategory]: # | ||
[data]: data.md | ||
[entity]: #the-entity-class | ||
[hierarchy]: #entity-class-hierarchy | ||
[item]: ../items/index.md | ||
[itemstack]: ../items/index.md#itemstacks | ||
[registration]: ../concepts/registries.md#methods-for-registering | ||
[renderer]: renderer.md | ||
[spawning]: spawning.md | ||
[type]: #entitytype |
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,6 @@ | ||
--- | ||
sidebar_position: 4 | ||
--- | ||
# Living Entities, Mobs & Players | ||
|
||
TODO |
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,6 @@ | ||
--- | ||
sidebar_position: 3 | ||
--- | ||
# Projectiles | ||
|
||
TODO |
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 |
---|---|---|
@@ -1,3 +1,6 @@ | ||
--- | ||
sidebar_position: 6 | ||
--- | ||
# Entity Renderers | ||
|
||
TODO |
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,6 @@ | ||
--- | ||
sidebar_position: 7 | ||
--- | ||
# Spawning Entities | ||
|
||
TODO |
This file was deleted.
Oops, something went wrong.
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