Overview
The component system provides:
- Per-entity state storage
- Handle-based subsystem integration
- NBT persistence
- Goal registration tracking
Component Structure
Each entity with an attached EcologyComponent contains:
| Field | Type | Purpose |
|---|---|---|
| Profile reference | EcologyProfile | Current behavior configuration |
| Handle tags | Map<String, CompoundTag> | Per-handle NBT data |
| Goals registered | boolean | Prevents double goal registration |
| Generation | int | Reload generation counter |
Accessing Components
From Entity
EcologyComponent component = ((EcologyAccess) entity).getComponent();Reading Handle Data
CompoundTag hungerTag = component.getHandleTag("hunger");
float currentHunger = hungerTag.getFloat("current");Writing Handle Data
CompoundTag tag = component.getOrCreateHandleTag("hunger");
tag.putFloat("current", newHungerValue);
tag.putLong("last_update", world.getGameTime());Handle Tags
Each handle stores its state in a separate CompoundTag under the handle’s ID:
BetterEcology
- hunger
- current: 75.0
- max: 100.0
- last_damage_tick: 12345
- condition
- value: 80.0
- wool
- wool_stage: 3
- wool_quality: 0.75Lifecycle
Attachment
Components are attached via MobEcologyMixin during entity initialization.
Goal Registration
Goals are registered once per entity:
if (!component.areGoalsRegistered()) {
EcologyHooks.onRegisterGoals(mob);
component.setGoalsRegistered(true);
}Ticking
Components are ticked via the mixin hook:
EcologyHooks.onTick(mob);Persistence
NBT data is saved and loaded via mixin hooks:
// Save
EcologyHooks.onSave(mob, compoundTag);
// Load
EcologyHooks.onLoad(mob, compoundTag);Generation Counter
The generation counter tracks reload events:
- On
/reload,EcologyProfileRegistry.reload()increments generation - Components compare their generation with registry generation
- Stale components refresh their profile reference
This ensures entities pick up configuration changes without requiring respawn.
Common Handle Tags
Hunger Handle
CompoundTag hunger = component.getHandleTag("hunger");
// Fields: current, max, decay_rate, last_damage_tickCondition Handle
CompoundTag condition = component.getHandleTag("condition");
// Fields: value, last_updateSocial Handle
CompoundTag social = component.getHandleTag("social");
// Fields: loneliness, last_social_tickAge Handle
CompoundTag age = component.getHandleTag("age");
// Fields: age_ticks, is_adultThread Safety
- All state stored in NBT tags per-entity
- No shared static state between entities
- Component system provides thread-safe access
Performance
- Component access is O(1) via entity attachment
- Handle tags are lazily created
- No allocation during normal tick operations
See Also
Last updated on