Skip to content

Animals

There exists a range of animals in the world of Zanzarah, none of which is essential to gameplay. The only animal type you can call essential would be the Pixie, but it is not seen internally as an animal, so this wiki won't either. Also animals internally usually have three components:

  • The AnimalBase which is a reference used by the AnimalManager
  • The AnimalController which holds and controls the actor, its animations, the location of the animal
  • The AnimalBaseAI (mostly WaypointAI) which control its behaviour.

Every animal has at least one actor description file associated to it and an activation distance. Outside of this distance animals are not updated. Additionally animals use their trigger arguments (most have a speed parameter).

Link Type Actor file Name Activation Distance
[x] 0 a000sa00
a001sa00
Butterfly 120
[x] 1 a002sa01 Dragonfly 200
[x] 2 a003sa02
a005sa04
Brown bird
White? bird
400
3 unused type
[x] 4 a004sa03 Frog 300
[x] 5 a005sa04 Blue bird 5000
[x] 6 -/- Firefly 700
[x] 7 a006sa05
a007sa06
Red bug
green bug
120
[x] 8 -/- Collection fairy 700
[x] 9 a008sa07 Rabbit 300
[x] 10 a020sa20
a021sa20
Brown chicken
White chicken
500
[x] 11 u010s10m "Black pixie" 300

Butterfly

The butterfly chooses randomly with equal chances between his two actor files. The speed is stored in the ii2 argument (speed = ii2 * 0.001). It rotates in an 8 shape and normally does not check for collisions with the world. In almost all cases it first rotates clock-wise?, but with a very small chance (about 1 to 2^31) it rotates the other way around. This is most likely a bug by the programmer, as the original formula looks like this: randomFloat() <= 0.0

ButterflyAI

In Pseudo-code the AI update looks like this:

degreeDelta = timeDelta * 40
newDegrees = lastDegrees + degreeDelta
lastDegrees = newDegrees
if (newDegrees > 360) {
    degreeDelta -= (360 - degreeDelta)
    rotateDir *= -1
    lastDegrees = 0
}
rotateY(degreeDelta * rotateDir)
moveForward(speed * timeDelta)

Dragonfly

The dragonfly uses the WaypointAI with a max idle time of 4 and a speed of 5. It does not flee nor crawl.

Bird

If there is a single bird trigger in the scene, four bird slots are created for the whole scene. More triggers do not mean more birds. Birds are spawned when their slot is free and they follow a simple movement pattern. Between the two actor files are chosen randomly with equal distribution, their speed is fixed at 4.

BirdAI (implemented directly in their update function, not as AI class)

If they haven't spawned yet or are marked as spawnable, they may spawn each frame with a chance of 60% and run this code:

setLocationToTrigger()
v1 = Vector(
    triggerDir.X * -1,
    0,
    triggerDir.Y * -1)
move( normalize(v1) * 10 )

pitchSpeed = ii3 * 0.001
distanceLeft = (randomFloat()+0.5) * 50

if they are spawned their update code looks like this:

moveDistance = speed * timeDelta; // remember: speed is fixed at 4
newDistanceLeft = distanceLeft - moveDistance
if (newDistanceLeft > 0) {
    triggerDir.y += timeDelta * pitchSpeed
    setDirection(triggerDir)
    move( triggerDir * moveDistance )
}
else
    markAsSpawnable();

Frog

The frog has just one actor file, it uses the WaypointAI and moves with a speed of 5. It does not flee, but crawl in full cycles and idles at max 5 seconds.

BlueBird

The blue bird has just one actor file and uses a custom AI. It circles around a center point defined by moving ii2 * 0.01 units from the trigger in trigger direction. Its speed is ii3 * 0.001.

BlueBirdAI

moveSin = sin(timeDelta * speed)
moveCos = sin(timeDelta * speed)
deltaPos = pos - center
newPos = center + Vector(
    moveCos * deltaPos.X - moveSin * deltaPos.Z,
    pos.Y,
    moveSin * deltaPos.X + moveCos * deltaPos.Z)

setDirection( normalize( newPos - pos) )
setPosition( newPos )

Firefly

The firefly does not have an actor file, instead it uses the effect 4018. It is controlled by the WaypointAI. Its speed is set at spawn as randomFloat() * 3.0, as well as his max idle time randomFloat(). Also at start his max bounce height is set to ii2 * 0.5 and a start bounce is set as random integer value between 0 and maxBounce.

It uses an additional update functionality:

curBounce += timeDelta * 1000
if (curBounce > maxBounce) {
    curBounce = 0;
    maxBounce = randomFloat() * 600 + 400; // yes this overwrites the parameter ii2
}
moveUp( sin( curBounce * 2 * PI / maxBounce ) * 0.02)

Bug

The bug chooses randomly with equal distribution between his two actor files. It crawls at a fixed speed of 0.2 according to the WaypointAI. It does not flee.

CollectionFairy

The collection fairy is the only animal type, that can not be put in a scene, as in "it will not spawn if put into a scene file". It is spawned automatically based on the unused fairies of the player and the CollectionWizform triggers, which only occur in London. It uses its own AI and is not influenced by any trigger arguments. The fairy type and thus its actor file is set upon spawn, the frequency at which the fairy bounces is also set at spawn to randomFloat() * 40 + 60.

CollectionFairyAI

posOffset = Vector(
    0.1 * cos(allTime * 0.0033333),
    0.02 * cos(allTime / bounceFreq),
    0.1 * sin(allTime * 0.0033333))
dirToPlayer = normalize( playerPos - triggerPos )

setPosition( triggerPos - dirToPlayer + posOffset );
lookAt(playerPos)

Rabbit

Rabbits only have one actor file, they crawl at a speed of 2.1 in full cycles lead by the WaypointAI, whilst idling at max 5 seconds. They do not flee from the player.

Chicken

Chicken have two actor files, chosen by their trigger argument ii2. They use the WaypointAI and are the only one using this AI, which do flee from the player. They crawl at a speed of 2.1 and idle at max 6 seconds. Furthermore they are placed at a random animal waypoint around their actual waypoint, but not at those whose distance is greater than 500.

Black pixie

Before starting: the name "Black Pixie" may not be the internal name. Internal names are not found yet and this name may be highly inaccurate. Maybe some day one of the original developers will tell us more about it. The black pixie only has a single actor file, it uses the WaypointAI and crawls at a speed of 2.1 in full cycles. It idles at max 5 seconds.

WaypointAI

Last but not least, the WaypointAI shall be described. It is the most used animal AI in the game, but also has some specialized behaviour for different animals.

TODO