Skip to Content

Overview

AttributeValue
Health6 HP (3 hearts)
MovementFlying (AmbientCreature)
Activity PatternNocturnal (active 12000-23000 ticks)
Social TypeColonial roosting
MetabolismReduced (0.3x when resting, 0.5x when active)

Behaviors

Nocturnal Activity

Implementation: BatMixin

Bats follow a strict day/night activity cycle based on Minecraft time.

Activity Schedule:

Time (ticks)PeriodBehavior
0-12000DayResting (roosting)
12000-13500DuskActive (emergence)
13500-23000NightActive (foraging)
23000-24000Pre-dawnSeeking shelter

Configuration Constants:

private static final long DAY_START = 0; private static final long DUSK_START = 12000; private static final long NIGHT_START = 13500; private static final long NIGHT_END = 23000; private static final long DAY_CYCLE = 24000;

Roosting Behavior

Bats cluster on ceilings and in dark spaces during the day.

Roost Location Requirements:

  • Solid block above (cave ceiling)
  • Light level below 8
  • Either condition is sufficient for resting

Roost Preferences:

  • Ceilings of caves
  • Dark enclosed spaces
  • Protected from weather

Metabolism System

Bats have reduced metabolism compared to other animals.

Metabolism Multipliers:

StateHunger DecayThirst Decay
Resting0.3x default0.3x default
Active0.5x default0.5x default

Auto-Hydration

Bats automatically restore thirst when in contact with water.

Hydration Details:

  • Triggers when in water or rain
  • Restores at 0.5x normal drinking rate
  • Gradual restoration while exposed

Light Response

Light LevelBehavior
0-7Comfortable, can rest
8+Too bright, seeks darker area

Integration

Mixin Implementation

Bats are AmbientCreature (not PathfinderMob), so they cannot use standard pathfinding goals. Instead, all behaviors are implemented via mixin injection:

@Mixin(Bat.class) public abstract class BatMixin { @Shadow public abstract boolean isResting(); @Shadow public abstract void setResting(boolean resting); @Inject(method = "<init>", at = @At("TAIL")) private void betterEcology$initEcology(EntityType<?> entityType, Level level, CallbackInfo ci) { Bat bat = (Bat) (Object) this; AnimalNeeds.initializeIfNeeded(bat); } @Inject(method = "customServerAiStep", at = @At("TAIL")) private void betterEcology$tickNeeds(CallbackInfo ci) { Bat bat = (Bat) (Object) this; // Handle nocturnal activity patterns betterEcology$updateNocturnalBehavior(bat); // Decay hunger and thirst with metabolism multiplier float metabolismMultiplier = this.isResting() ? 0.3f : 0.5f; AnimalNeeds.decayHunger(bat, AnimalThresholds.DEFAULT_HUNGER_DECAY * metabolismMultiplier); AnimalNeeds.decayThirst(bat, AnimalThresholds.DEFAULT_THIRST_DECAY * metabolismMultiplier); } }

Nocturnal Behavior Logic

private boolean betterEcology$shouldBatRest(long timeOfDay) { // Day time: 0-12000 ticks (bat should rest) if (timeOfDay >= DAY_START && timeOfDay < DUSK_START) { return true; } // Dusk and night: 12000-23000 ticks (bat should be active) if (timeOfDay >= DUSK_START && timeOfDay < NIGHT_END) { return false; } // Pre-dawn: 23000-24000 ticks (bat seeks shelter) return true; }

Rest Location Check

private boolean betterEcology$canRestAtCurrentLocation(Bat bat) { BlockPos batPos = bat.blockPosition(); BlockPos abovePos = batPos.above(); // Check for solid ceiling boolean hasCeilingAbove = bat.level().getBlockState(abovePos).isSolid(); // Check if dark enough (light level < 8) int lightLevel = bat.level().getMaxLocalRawBrightness(batPos); boolean isDarkEnough = lightLevel < 8; // Can rest if ceiling above OR dark enough return hasCeilingAbove || isDarkEnough; }

NBT Data

Bat ecology state is stored in the standard ecology component:

/data get entity @e[type=bat,limit=1] better-ecology

Expected output:

{ "hunger": 75.0, "thirst": 80.0, "last_damage_tick": 0 }

Configuration

ConstantValuePurpose
Activity check interval20 ticksHow often to check time of day
Resting metabolism0.3xHunger/thirst decay when resting
Active metabolism0.5xHunger/thirst decay when active
Light threshold8Maximum light level for resting

Scientific Basis

Emergence Timing

Based on research showing bat emergence is triggered by declining light levels rather than absolute time. Most bat species emerge within a narrow window after sunset, with timing influenced by ambient light intensity.

Roosting Behavior

Based on observations of bat colony behavior and roost site selection. Bats prefer dark, enclosed spaces with overhead cover for daytime roosting. Temperature regulation and predator avoidance drive roost selection.

Reduced Metabolism

Based on research showing bats have evolved lower metabolic rates compared to similar-sized mammals. This adaptation allows them to survive on relatively limited food resources and explains their use of torpor/hibernation.

Colonial Behavior

Based on observations that many bat species roost in groups for thermoregulation and social benefits. Colonial roosting provides warmth sharing and may facilitate information exchange about food sources.

Predation Avoidance

Based on research on bat timing to avoid diurnal predators. By restricting activity to darkness, bats reduce predation risk from visual predators like hawks and owls.

Technical Notes

AmbientCreature Limitations

Bats extend AmbientCreature rather than PathfinderMob, which means:

  • No goal selector available
  • Cannot use pathfinding-based goals
  • All behavior logic must be in mixins
  • Limited AI capabilities compared to other animals

This is why bat behaviors are simpler than other animals and rely on direct state manipulation rather than goal-based AI.

See Also

Last updated on