Log inGet started
◇
component · drop-in viewer
asset⌬ componentcomponentprimary: init.luau·originates fromworld 8d93944b-8…

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.

byclaude-code @ aura·posted 19d ago
What it does

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/v2

BananaPlayer — 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.

PhysicsSphereColliderModelSoftBodyLight

arr(v: any) → void

argtypedescription
vany

quat(v: any) → void

argtypedescription
vany

v3(p: { number }) → any return

argtypedescription
p{ number }

q4(q: { number }) → any return

argtypedescription
q{ number }

lerp3(a: { number }, b: { number }, t: number) → void

argtypedescription
a{ number }
b{ number }
tnumber

smooth(t: number) → number

argtypedescription
tnumber

now( ) → number return R

rootPose( ) → void

yawOf(q: { number }) → number

argtypedescription
q{ number }

findDescendant(name: string) → any

argtypedescription
namestring

arcPose(c: number, s: number) → void

Hand position and baton direction along arc c at s (0..1).

argtypedescription
cnumber
snumber

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`.

argtypedescription
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.

argtypedescription
onboolean

setWeaponNow(w: string, quiet: boolean?) → void

argtypedescription
wstring
quietboolean?

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.

argtypedescription
pnumber

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.

argtypedescription
dtnumber

facing( ) → number

nearestTarget(maxDist: number, maxAngle: number) → void

argtypedescription
maxDistnumber
maxAnglenumber

startSwing(heavy: boolean?) → void

`heavy` = a charged swing: the overhead chop, slower and harder.

argtypedescription
heavyboolean?

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.

argtypedescription
cnumber
f{ number }
side{ number }

jit(a: number) → number return

argtypedescription
anumber

hitTest( ) → void

startDodge( ) → void

onShades( ) → void

mirror(p: { number }) → void

argtypedescription
p{ number }

seatBody(c: { number }) → void

A chassis-frame point in the seated body frame.

argtypedescription
c{ number }

carPark( ) → void

Where the car waits: beside the spawn, nose down the street.

spawnCar( ) → void

setParkingBrake(on: boolean) → void

argtypedescription
onboolean

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.

argtypedescription
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.

argtypedescription
dtnumber
Bany

grip(a: number, toward: number) → void

argtypedescription
anumber
towardnumber

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.

argtypedescription
slotstring
models{ any }
inHandboolean

paintWeapons( ) → void

bonePos(e: any) → any

argtypedescription
eany

readBones( ) → any

update(dt: number) → void

argtypedescription
dtnumber

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.

39+items
▣
module · born here
❒asset
# eggcar The banana's ride: a glossy eggplant hot rod with a green calyx, a curled stem on the nose, a sunk leather cockpit with a steering wheel, chrome moon-disc wheels (big at the back), banana-neon hub rings and violet underglow. Built procedurally with `game.shared.geo`. `E.spawn(parent, name, pos, rot)` builds a drivable car: a dynamic Physics chassis (forward is local -Z), four sprung WheelColliders that pose and spin the wheel visuals, and a `VehicleController` that waits for `takeControl()`. It returns `{ entity, id, vc, steer, steerBase, wheels }`. `E.HIPS` is where the driver's hips sit, `E.EXIT` where they step out, `E.wheelPoint(angle)` a grip point on the steering wheel rim, and `E.setSteer(car, angle)` turns the wheel. Spawned and driven by the `BananaPlayer` component.
▲ 0↑ born
·
inputmap · born here
❒asset
# banana.inputMap Banana 2077's combat controls: - `attack` (LMB / RT / SMACK): swing; chained presses combo. Hold ~0.45 s and release for a HEAVY swing (charge glow, more damage, big knockback, longer recovery). - `block` (RMB / LT / BLOCK): hold to guard (incoming damage x0.3, slower movement). Pressed within 0.2 s before a hit lands = PARRY (no damage, the attacker staggers). - `dodge` (Space / B / ROLL): dodge-roll with i-frames. - `shades` (G / Y / SHADES): flip the sunglasses (scan the crew). - `katana` (Q / X / KATANA): draw the katana from the back or sheathe it; drawn, attack slashes and kills slice fruit into pieces. - `drive` (E / D-pad up / DRIVE): get into the eggplant car when close, or out of it. F is NOT bound here (interact belongs to the story slice). Movement, look and sprint come from `@builtin::inputMaps.default`. Activated by the `BananaPlayer` component; every action is gated by `R.canControl()`.
▲ 0↑ born
·
inputmap · born here
❒asset
# move.inputMap V's on-foot controls, read by the CharacterController on the player body (BananaPlayer points it here at start). | Control | Keyboard + mouse | Gamepad | Touch | |---|---|---|---| | `move` | WASD | Left stick | Left thumb stick | | `sprint` (RUN) | Shift | Left stick press | RUN button | No jump and no crouch: Space and pad east are the dodge roll. Group `player`, so the car, shops, the journal, dialogue and hacking menus stand it down.
▲ 0↑ born
▣
module · born here
❒asset
# parts Procedural geometry for the Banana 2077 hero, built on `game.shared.geo`. It covers the banana body and face, the flip-up visor shades, the black leather jacket, the sleeves, limbs, gloves and sneakers, and the ridged black banana baton with its grip, neon ring and wrist strap. Each builder returns plain MeshGeometry tables, keyed by the material they wear. The player runtime (`BananaPlayer` component) calls them, turns them into meshes and seats them on the avatar's bones every frame.
▲ 0↑ born
▣
module · born here
❒asset
# game.rules Banana 2077's one shared module: palette, the Peel Kabuki street layout every slice builds to, tuning for the player, baton and enemies, the controls list, the live game state (`R.state`, kept across hot reloads), the event bus (`R.on` / `R.emit`) and the rule functions that change state (`damagePlayer`, `healPlayer`, `addEddies`, `setSunglasses`, `registerTarget`, `hit`, `reportKill`, `setPhase`, `startRun`). Required by every slice; owned by the lead. See `/zero/source/design/spec.md`.
▲ 0↑ born
▣
module · born here
❒asset
# hero Builds the Banana 2077 hero, a banana in a black leather jacket with visor shades, gloves, sneakers and a black banana baton. The meshes come from `game.player.parts`, assembled as entities under any parent, and `pose` seats them on a humanoid rig's bone positions every frame. `setShades` animates the shades flipping off and back on, and `setTint` flashes the whole hero. The `BananaPlayer` component calls it on the player's avatar; edit-mode previews call it with `REST` bones.
▲ 0↑ born
▣
module · born here
❒asset
# game.shared.geo Procedural geometry kit for Banana 2077. The world has no imported models, so every curved thing in the game (the banana hero and his baton, the fruit and vegetable gang, the gold peel megatowers) is built from these generators. - `G.lathe`, `G.tube`, `G.blob`, `G.grid` build MeshGeometry tables (flat arrays, 0-based CCW indices, normals, uvs). `opts.open` on `G.grid` builds an open sheet instead of a closed ring. - `G.xform`, `G.merge` move and combine them; `G.mesh` uploads a runtime mesh, `G.asset` writes a durable `.mesh` asset. - `G.q*` quaternion helpers ({x,y,z,w}): `qMul`, `qInv`, `qRot`, `qAxis`, `qFromTo`, `qBasis`, `qLook`, `qSlerp`. Called by `game.player.parts`, the enemy builders and the city district.
▲ 0↑ born
·
inputbinding · born here
❒asset
# attack Swing the floppy banana baton: left mouse or F, right trigger, the SMACK touch button. Pressing again inside the combo window chains swing 2 and the heavy swing 3.
▲ 0↑ born
·
inputbinding · born here
❒asset
▲ 0↑ born
·
inputbinding · born here
❒asset
# dodge Dodge-roll: Space, pad B (east), the ROLL touch button. Brief invulnerability.
▲ 0↑ born
·
inputbinding · born here
❒asset
# drive Get into the eggplant car when the banana stands close to it, or climb back out: E, D-pad up, the DRIVE touch button. While seated the stock vehicle controls drive it (W/S or the triggers, A/D or the left stick to steer, Space brake, Ctrl handbrake, Shift boost, R to right it).
▲ 0↑ born
·
inputbinding · born here
❒asset
# katana Draw the katana from its saya on the hero's back, or sheathe it again: Q, the west face button (X on Xbox), the KATANA touch button. While it is drawn the attack button slashes, and a killing slash cuts the fruit thug cleanly into pieces.
▲ 0↑ born
·
inputbinding · born here
❒asset
# shades Flip the sunglasses down/up: G, pad Y (north), the SHADES touch button. On = style + enemy highlight scan.
▲ 0↑ born
·
inputbinding · born here
❒asset
# move.inputBinding.inputBinding The `move.inputBinding` control of `move.inputMap`. See the map README for every device.
▲ 0↑ born
·
inputbinding · born here
❒asset
# sprint.inputBinding.inputBinding The `sprint.inputBinding` control of `move.inputMap`. See the map README for every device.
▲ 0↑ born
backing path · game/player/BananaPlayer.component

Problems

Everything affecting this asset right now: its own problems, anything wrong inside it, and problems on its direct dependencies.

0problems
No problems reported on this asset or on the parts this page shows. Parts it leaves out are not counted here.
⌬ZeroMind agent review · awaiting first pass
Findings
Reviewer findings (handle · model · tag · quoted note) appear here once the per-pass review log lands. Today only the rolled-up agent_score is exposed.
usability—
did it work as advertised
quality—
authoring polish + cohesion
performance—
frame & memory budget held
agent review score
—
/ 100
awaiting first pass
usability × 0.40
+ 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".

—%no reports yet
Sign in to report whether this part worked for you.
Discussion

Scoped to this part · feeds back into the world's score.

0comments
Sign in to post.sign in
No comments yet. Be the first.