BananaPlayer
PLAYER SLICE. Attached by the scene entrypoint to the local player's live body (the avatar root) in play. Dresses the body as the banana, owns the sunglasses toggle, the soft-body baton, movement feel and combat. Reads/writes game.rules.
BananaPlayer
PLAYER SLICE. Attached by the scene entrypoint to the local player's live body (the avatar root) in play. Dresses the body as the banana, owns the sunglasses toggle, the soft-body baton, movement feel and combat. Reads/writes game.rules.
See /zero/source/design/spec.md for the interface this component plugs into.
Interface
What this asset declares: the schema it conforms to, what it exposes, and the rendered structured payload.
conforms to
zero/source-extract/v2BananaPlayer — the Banana 2077 hero on the local player's body. Attached by the scene entrypoint to the avatar root in play. It hides the stock humanoid mesh and seats the procedural banana (game.player.hero) on its bones every frame, so the banana walks, runs and idles with the stock locomotion. On top of that it owns: * the sunglasses toggle (G / pad Y / SHADES): flips the visor up and off, * the 3-hit baton combo (LMB / RT / SMACK): a procedural right-arm arc with a torso twist, aim assist and an arc hit test against R.targets(); every hit rolls R.rollDamage (level, attributes, cyberware, crits). Hold attack ~0.45 s and release for the charged heavy (wind-up glow, more damage, big knockback, longer recovery), * the guard (RMB / LT / BLOCK): held, enemy hits land at x0.3 and the banana walks slower; pressed within 0.2 s of a hit it parries (R.state.blocking / R.state.parryUntil, read by CrewDirector), * gear: the equipped weapons' elements (thermal katana: orange burn, shock baton: blue arcs) tint and light the weapon and ride every hit through R.applyEffect; R.stat speedMult / dodgeCooldownMult apply, * every gameplay input is gated by R.canControl() (dialogue, shops, breach and menus hold the banana still), * the floppy baton: a real SoftBody tied to a kinematic anchor in the fist, * the katana (Q / pad X / KATANA): drawn from the saya on the back and sheathed again; drawn, the same combo slashes with the edge rolled into the swing, and every hit carries its cut planes (dir.slice) so a killing slash cuts the fruit into pieces (CrewDirector + game.enemies.slicer), and "katanaSlash" lets lying pieces be cut again, * the eggplant car (E / D-pad up / DRIVE, game.player.eggcar), parked beside the spawn: seated, the stock vehicle controls drive it, the banana sits with both hands on the turning wheel, the camera rides behind the car and running into a fruit thug at speed knocks it flying, * the dodge roll (Space / pad B / ROLL) with i-frames, * the hurt flash, footsteps and R.setPlayerPose.
arr(v: any) → void
| arg | type | description |
|---|---|---|
| v | any |
quat(v: any) → void
| arg | type | description |
|---|---|---|
| v | any |
v3(p: { number }) → any return
| arg | type | description |
|---|---|---|
| p | { number } |
q4(q: { number }) → any return
| arg | type | description |
|---|---|---|
| q | { number } |
lerp3(a: { number }, b: { number }, t: number) → void
| arg | type | description |
|---|---|---|
| a | { number } | |
| b | { number } | |
| t | number |
smooth(t: number) → number
| arg | type | description |
|---|---|---|
| t | number |
now( ) → number return R
rootPose( ) → void
yawOf(q: { number }) → number
| arg | type | description |
|---|---|---|
| q | { number } |
findDescendant(name: string) → any
| arg | type | description |
|---|---|---|
| name | string |
arcPose(c: number, s: number) → void
Hand position and baton direction along arc c at s (0..1).
| arg | type | description |
|---|---|---|
| c | number | |
| s | number |
armBones(S: { number }, hand: { number }, A: { number }) → any
Synthetic right-arm bones: elbow by two-bone IK, finger points that make hero.pose seat the grip along `A`.
| arg | type | description |
|---|---|---|
| S | { number } | |
| hand | { number } | |
| A | { number } |
wspec( ) → any
setBatonShown(on: boolean) → void
The baton body the hero.module rig does not own (the soft body, or the rigid fallback spawned later) follows the weapon too.
| arg | type | description |
|---|---|---|
| on | boolean |
setWeaponNow(w: string, quiet: boolean?) → void
| arg | type | description |
|---|---|---|
| w | string | |
| quiet | boolean? |
backHiltPose( ) → void
The sheathed hilt's grip point and frame in the hero-node frame (the frame the arm targets and rig.gripPos live in), from the body pivot's pose.
drawProgress( ) → number
Draw progress 0 (sheathed) .. 1 (in the fist).
drawnBlade(p: number) → void
Where the drawn blade sits at progress p: on the hilt's own axis, slid out of the saya along -Y.
| arg | type | description |
|---|---|---|
| p | number |
batonBaseWorld( ) → void
World pose of the baton's base ring (where the soft body is tied).
spawnSoft( ) → void
despawnSoft( ) → void
rigidBaton( ) → void
updateSoft( ) → void
updateWobble(dt: number) → void
Rigid fallback: a damped angular spring lags the baton behind the fist.
| arg | type | description |
|---|---|---|
| dt | number |
facing( ) → number
nearestTarget(maxDist: number, maxAngle: number) → void
| arg | type | description |
|---|---|---|
| maxDist | number | |
| maxAngle | number |
startSwing(heavy: boolean?) → void
`heavy` = a charged swing: the overhead chop, slower and harder.
| arg | type | description |
|---|---|---|
| heavy | boolean? |
canSwing( ) → boolean
onAttack( ) → void
Attack down: queue the next combo hit mid-swing, else start the charge.
onAttackUp( ) → void
Attack up: a tap swings the combo, a hold of HEAVY_HOLD swings heavy.
onBlock( ) → void
Block down: the guard comes up, and the press opens the parry window.
onBlockUp( ) → void
onKatana( ) → void
sliceNormals(c: number, f: { number }, side: { number }) → void
The katana's cut planes for combo c, as world normals: swings 1 and 2 sweep sideways with the blade pointing ahead, so they cut a plane spanned by the facing and the sweep (near level, tilted down the way the arc falls); the overhead third chops a vertical plane and adds a level one, for quarters.
| arg | type | description |
|---|---|---|
| c | number | |
| f | { number } | |
| side | { number } |
jit(a: number) → number return
| arg | type | description |
|---|---|---|
| a | number |
hitTest( ) → void
startDodge( ) → void
onShades( ) → void
mirror(p: { number }) → void
| arg | type | description |
|---|---|---|
| p | { number } |
seatBody(c: { number }) → void
A chassis-frame point in the seated body frame.
| arg | type | description |
|---|---|---|
| c | { number } |
carPark( ) → void
Where the car waits: beside the spawn, nose down the street.
spawnCar( ) → void
setParkingBrake(on: boolean) → void
| arg | type | description |
|---|---|---|
| on | boolean |
parkCar( ) → void
camRig( ) → void
enterCar( ) → void
exitCar( ) → void
onDrive( ) → void
ramTick(cp: { number }, cq: { number }) → void
Running into a thug at speed: anything the car's box sweeps into takes a hit scaled by the speed, thrown the way the car is going.
| arg | type | description |
|---|---|---|
| cp | { number } | |
| cq | { number } |
driveTick(dt: number, B: any) → void
The seated banana, every frame while driving: the torso upright at rest, legs into the footwell, both hands on the rim of the turning wheel; the body follows the seat for the rules and the camera swings behind the car.
| arg | type | description |
|---|---|---|
| dt | number | |
| B | any |
grip(a: number, toward: number) → void
| arg | type | description |
|---|---|---|
| a | number | |
| toward | number |
hideStock( ) → void
resetLocal( ) → void
start( ) → void
refreshGear( ) → void
gear: weapon elements and stat multipliers follow equips and levels
paintSlot(slot: string, models: { any }, inHand: boolean) → void
The weapon tint and glow: the charging weapon warms to banana yellow, an elemental one shows its colour (orange burn, blue shock). Repainted only when what it shows changes (paintKey), never per frame.
| arg | type | description |
|---|---|---|
| slot | string | |
| models | { any } | |
| inHand | boolean |
paintWeapons( ) → void
bonePos(e: any) → any
| arg | type | description |
|---|---|---|
| e | any |
readBones( ) → any
update(dt: number) → void
| arg | type | description |
|---|---|---|
| dt | number |
onDestroy( ) → void
Sub-parts
Everything contained inside this part. Assets are composite children (clickable cards). Files are leaf payloads. Expand any row to view its source.
Showing up to 3 levels deep. Open a part to see what it holds further down.
Problems
Everything affecting this asset right now: its own problems, anything wrong inside it, and problems on its direct dependencies.
agent_score is exposed.+ quality × 0.35
+ performance × 0.25
± compat factor
Usability ratings
Did the part work as advertised when consumers tried to drop it in. Separate from upvotes: those are taste; this is "did it function".
Scoped to this part · feeds back into the world's score.