Fauna procedural en Godot 4: conejos, ciervos y mariposas que no cuestan nada
Mariposas, conejos, ciervos y gaviotas alrededor del jugador, colocados con una semilla fija y sin física. La primera versión costaba 8 ms por fotograma; así bajó a 2,1.

Después de llenar Gotic de pueblos, la isla seguía pareciendo un decorado: mucha hierba y ningún bicho. El mod Fauna de la isla pone vida alrededor del jugador sin pedirle nada: mariposas sobre la hierba, conejos en el prado, ciervos en el linde del bosque y una bandada de gaviotas dando vueltas sobre el trozo de costa más cercano (la portada está tomada desde el agua, junto a la playa de salida).
Si llegas corriendo, conejos y ciervos huyen. Si vas andando despacio, te dejan acercarte y puedes acariciarlos con R (o USAR). Con el mod de día y noche, de noche las mariposas se convierten en luciérnagas y las gaviotas se van; con el del tiempo, cuando llueve no vuela ninguna.
Cómo está hecho
Ningún animal tiene cuerpo físico. Todo se pega al suelo leyendo la altura de la isla (Island.height_at) y se coloca cerca del jugador con un azar de semilla fija: el mismo sitio da la misma colocación llegues cuando llegues, y las pruebas lo pueden repetir. Hay topes fijos: 24 mariposas, 3 conejos, 2 ciervos y 5 gaviotas. Lo que se aleja más de 110 m reaparece cerca.
Cada especie tiene su regla de dónde puede estar: los conejos en hierba abierta, los ciervos en el linde del bosque, y ninguno en la arena, el agua, la nieve, las laderas fuertes ni dentro de los claros de otros mods (pueblos, ruinas, el corral). Las 24 mariposas son un solo MultiMesh: una única llamada de dibujo.
La parte de acercarse sin asustar son tres líneas. Si vas más despacio que andando, la distancia a la que se asustan se queda en un cuarto (2 m en vez de 8 para el conejo, 3,75 en vez de 15 para el ciervo):
var calm: bool = world.player.ground_speed() < CALM_SPEED
var scare := (RABBIT_SCARE if rabbit else DEER_SCARE) * (CALM_FACTOR if calm else 1.0)
var speed := RABBIT_SPEED if rabbit else DEER_SPEED
Al huir corren 2,5 s; si el siguiente paso cae en el agua o en un barranco, giran.
Más tarde, para el bestiario, la fauna aprendió a contar qué está haciendo cada animal (quieto, huyendo, acariciado), la gaviota a planear 1,6 s de cada 9 y la mariposa a posarse con las alas abiertas 2,6 s de cada 11, para que tengan un momento que fotografiar.
Lo que salió mal
- 8 ms por fotograma por buscar sitio. En la playa no hay hierba, así que las 24 mariposas, con 40 intentos cada una, volvían a buscar sitio en cada fotograma. Medido sin ventana con todo el juego vivo: 10,8 ms por fotograma. Ahora lo que no encuentra sitio espera 3 s entre búsquedas (una prueba vigila que el azar no avance en 10 fotogramas seguidos) y, de paso, solo se animan los pueblos cercanos: 2,1 ms. Peor aún: el commit de la fauna se hizo con la suite cortada por su tope de tiempo, sin llegar a PRUEBAS OK. El siguiente lo arregló y lo dijo.
- Mariposas pegadas al jugador. Las que no tenían hierba cerca se escondían bajo tierra, pero el vuelo las subía a 40 cm del suelo… junto al jugador. En los pueblos revoloteaban todas a tu alrededor. Lo vio una captura, no una prueba; ahora hay prueba.
- Un conejo que huía desde debajo de ti. Un animal que no encontraba sitio huía desde debajo del jugador; lo vio una prueba. Ahora se esconde bajo tierra y vuelve a buscar sitio cada pocos segundos.
- El
MultiMeshmiente sin ventana. En las pruebas sin pantalla,get_instance_transformdevuelve siempre la identidad. El mod guarda aparte dónde está cada mariposa y las pruebas leen eso. - El bestiario reventaba al dibujar la ficha del conejo con la fauna instalada, porque ninguna prueba abría la pestaña con los dos mods. Ahora cada especie puede traer su propio modelo.
Mirando el prado con fauna, una captura costó 471 llamadas de dibujo.
Lo que falta por comprobar
No se ha medido en el móvil, y tampoco cuánto cuesta ese mismo encuadre del prado sin fauna, así que no sé cuánto de esas 471 llamadas es suyo. Y en el bestiario, la gaviota solo dio 3 estrellas con la mejor lente y la fauna congelada en el fotograma del disparo: con un jugador real, sin medir.