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

CrewDirector

The Rotten Crew and the people of Peel Kabuki. Attached by the scene entrypoint to `mount_enemies` in play.

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

CrewDirector

The Rotten Crew and the people of Peel Kabuki. Attached by the scene entrypoint to mount_enemies in play.

  • Spawns the 8 thugs (tomato, broccoli punk, pineapple bruiser) at R.layout.thugSpawns, and Don Aubergine at R.layout.bossSpawn on bossCue, with a drop-in landing.
  • Runs their AI: idle → chase → windup → strike → recover, plus flinch and death. Every third boss attack is a telegraphed ground slam with a shockwave.
  • Registers each enemy as a baton target with game.rules. A hit knocks back, flashes white, splatters juice in the enemy's colour, and reports the kill.
  • Drops banana-coin eddies and healing snacks that the player collects by walking over them.
  • While the sunglasses are on, outlines enemies within scan range.
  • A crowd of fruit civilians (crowd, 16 by default) walks both sidewalks and scatters from fights. Every other one (never the watermelon cop) carries a Neo-Tokyo light-up umbrella from game.enemies.crew (Crew.prop("umbrella")), its neon picked from UMBRELLAS, held in the right hand with the arm locked in place while the legs walk.
  • Hides distant characters, and puts everything back on reset.

Fields: cullDistance (metres), civilians (bool), crowd (how many civilians).

Interface

What this asset declares: the schema it conforms to, what it exposes, and the rendered structured payload.

conforms to

zero/source-extract/v2

strict

Text3DModelMeshColliderPhysics

q4(q: { number }) → any return

argtypedescription
q{ number }

qax(a: { number }, ang: number) → void

argtypedescription
a{ number }
angnumber

qm(a: { number }, b: { number }) → void

argtypedescription
a{ number }
b{ number }

now( ) → number return R

rnd(a: number, b: number) → number return a

argtypedescription
anumber
bnumber

smooth(t: number) → number

argtypedescription
tnumber

angDiff(a: number, b: number) → number

argtypedescription
anumber
bnumber

despawn(e: any) → void

argtypedescription
eany

groundY(x: number, z: number) → number

Walkable height of the street at (x, z): road, raised sidewalks, plaza.

argtypedescription
xnumber
znumber

clampPos(x: number, z: number) → void

argtypedescription
xnumber
znumber

armQ(roll: number, pitch: number, side: number) → any

side -1 = right arm, +1 = left arm; pitch swings the arm forward.

argtypedescription
rollnumber
pitchnumber
sidenumber

pose(c: any, P: any) → void

argtypedescription
cany
Pany

walkPose(c: any, speed: number, dt: number, P: any) → void

argtypedescription
cany
speednumber
dtnumber
Pany

idlePose(c: any, P: any, guard: boolean) → void

argtypedescription
cany
Pany
guardboolean

attackPose(c: any, P: any, k: number, phase: string) → void

Attack choreography; k runs 0..1 through each phase.

argtypedescription
cany
Pany
knumber
phasestring

setVisible(c: any, on: boolean) → void

argtypedescription
cany
onboolean

tint(c: any, k: number, col: { number }?) → void

argtypedescription
cany
knumber
col{ number }?

baseTint(c: any) → void

The tint a character rests at: orange while it burns, none otherwise.

argtypedescription
cany

outline(c: any, col: { number }?) → void

argtypedescription
cany
col{ number }?

newDrop(mat: string) → any

argtypedescription
matstring

takeDrop(mat: string) → any

argtypedescription
matstring

burst(mat: string, p: { number }, dx: number, dz: number, n: number, power: number, gy: number?) → void

`gy` pins the floor the drops land on (an encounter off the street); nil reads the street's own ground.

argtypedescription
matstring
p{ number }
dxnumber
dznumber
nnumber
powernumber
gynumber?

flames(x: number, y: number, z: number, n: number, spread: number) → void

Short-lived additive bits from the same drop pools: flames rise and wink out, sparks spit and fall. Neither leaves a splat.

argtypedescription
xnumber
ynumber
znumber
nnumber
spreadnumber

sparks(x: number, y: number, z: number, n: number, mat: string?) → void

argtypedescription
xnumber
ynumber
znumber
nnumber
matstring?

splat(mat: string, x: number, z: number, size: number, y: number?) → void

argtypedescription
matstring
xnumber
znumber
sizenumber
ynumber?

ringFx(mat: string, x: number, z: number, r0: number, r1: number, dur: number, y: number?) → any

argtypedescription
matstring
xnumber
znumber
r0number
r1number
durnumber
ynumber?

updateFx(dt: number) → void

argtypedescription
dtnumber

dropRing(fx: any) → void

argtypedescription
fxany

pop(x: number, y: number, z: number, content: string, height: number) → void

argtypedescription
xnumber
ynumber
znumber
contentstring
heightnumber

updatePops(dt: number) → void

argtypedescription
dtnumber

spawnDrop(kind: string, x: number, z: number, y: number, value: any, gy: number?) → void

argtypedescription
kindstring
xnumber
znumber
ynumber
valueany
gynumber?

updateDrops(dt: number) → void

argtypedescription
dtnumber

newChar(kind: string, x: number, z: number, yaw: number) → any

argtypedescription
kindstring
xnumber
znumber
yawnumber

scare(x: number, z: number, radius: number) → void

argtypedescription
xnumber
znumber
radiusnumber

spawnEnemy(kind: string, x: number, z: number, opts: any?) → any

opts (optional) = { level, enc (encounter record), gy (pinned floor y), ambient (a respawning street thug after the Don), yaw }

argtypedescription
kindstring
xnumber
znumber
optsany?

level( ) → void

hp( ) → void

maxHp( ) → void

position( ) → void

takeHit(damage: number, dir: any, heavy: boolean) → void

argtypedescription
damagenumber
dirany
heavyboolean

applyEffect(effect: string, params: any) → void

argtypedescription
effectstring
paramsany

ensureTag(c: any) → void

One Text3D billboard per enemy, hung off its root, made the first time it aggroes or is hurt. Its text changes only when a health segment does.

argtypedescription
cany

setTag(c: any) → void

argtypedescription
cany

showTag(c: any, on: boolean) → void

argtypedescription
cany
onboolean

clearTelegraph(c: any) → void

argtypedescription
cany

blankMesh( ) → any

newSlot(root: any) → any

argtypedescription
rootany

newShell( ) → any

warmShells( ) → void

One Model a frame until the pool holds SHELL_WARM shells of SLOT_WARM slots.

flushGrave(all: boolean) → void

argtypedescription
allboolean

freePiece(pc: any) → void

A piece goes back to the pool as an empty shell; its meshes are released once nothing draws them.

argtypedescription
pcany

bakeRig(rig: any) → void

A crew rig as it stands this frame: every Model's geometry in world space, merged per material.

argtypedescription
rigany

bakePiece(pc: any) → void

A lying piece's parts in world space, from its body's pose.

argtypedescription
pcany

hullProxy(parts: { any }) → any

The points a piece's convex hull needs, as a small mesh for the collider to wrap: the extremes on each axis and an even sample of the rest.

argtypedescription
parts{ any }

spawnPiece(parts: { any }, vel: { number }, cuts: number, juice: string) → any

One piece: a pooled shell at the parts' centre, a Model slot per material, and the shell's hidden hull proxy for the collider to follow.

argtypedescription
parts{ any }
vel{ number }
cutsnumber
juicestring

sliceCorpse(c: any, slice: any, dx: number, dz: number) → boolean

Cut a dying thug along the blade's planes; the rig goes and the pieces fly apart from the cut, carried on along the hit.

argtypedescription
cany
sliceany
dxnumber
dznumber

onSlash(e: any) → void

A katana slash through lying pieces cuts each again, through its centre.

argtypedescription
eany

updatePieces(dt: number) → void

argtypedescription
dtnumber

rollLoot( ) → string

What a thug leaves besides its eddies: usually junk, now and then a consumable, rarely a quickhack shard.

die(c: any, dx: number, dz: number, slice: any?) → void

argtypedescription
cany
dxnumber
dznumber
sliceany?

hurt(c: any, dmg: number, content: string, height: number) → void

Damage with no knockback or flinch: burn ticks, shocks.

argtypedescription
cany
dmgnumber
contentstring
heightnumber

takeHit(c: any, damage: number, dir: any, heavy: boolean) → void

argtypedescription
cany
damagenumber
dirany
heavyboolean

breakAttack(c: any) → void

argtypedescription
cany

applyEffect(c: any, effect: string, params: any) → void

R.applyEffect lands here: stun / burn / shock / reveal.

argtypedescription
cany
effectstring
paramsany

spawnBoss( ) → void

turnTo(c: any, target: number, rate: number, dt: number) → void

argtypedescription
cany
targetnumber
ratenumber
dtnumber

hitPlayer(c: any, amount: number, from: any, slam: boolean) → void

An enemy's blow meets V's guard. A parry (block pressed in the 0.2 s before the hit, facing the attacker) cancels it and staggers the attacker, slowing it and its mates nearby a moment; a held block takes 30%. A boss slam can be blocked but not parried.

argtypedescription
cany
amountnumber
fromany
slamboolean

leashed(c: any, pp: any) → boolean

Has V run far enough from an encounter that its crew gives up the chase?

argtypedescription
cany
ppany

updateEnemy(c: any, dt: number, playing: boolean, pp: any, active: boolean) → void

`active` = playing and no dialogue / shop / breach / menu holds V: the crew holds off (idle, no approach, no attacks) while it is false.

argtypedescription
cany
dtnumber
playingboolean
ppany
activeboolean

spawnCiv(kind: string, wp: number, along: number, umbrella: string?) → void

A civilian walking its own side's route, set down `along` (0..1) of the way from waypoint `wp` to the next one, with a light-up umbrella in its right hand when `umbrella` names the neon it glows in.

argtypedescription
kindstring
wpnumber
alongnumber
umbrellastring?

updateCiv(c: any, dt: number, pp: any) → void

argtypedescription
cany
dtnumber
ppany

separate(list: { any }, pp: any) → void

argtypedescription
list{ any }
ppany

refreshCars( ) → void

keepOutOfCars(list: { any }) → void

argtypedescription
list{ any }

encGround(x: number, z: number, y0: number) → number

The floor at (x, z): nil on the street itself (groundY reads it there), the first surface below y0 + 4 m otherwise.

argtypedescription
xnumber
znumber
y0number

encPoint(e: any, x: number, z: number) → void

Enemy positions are world x, z; a list written as offsets from `at` is read as offsets (only when the absolute point is nowhere near the fight).

argtypedescription
eany
xnumber
znumber

spawnEncounter(id: string, def: any) → void

argtypedescription
idstring
defany

dropEncounter(id: string) → void

argtypedescription
idstring

spawnAmbient(pp: any) → boolean

After the Don falls the 8 street thugs are gone for good; a few stragglers walk in from the crew's corners, out of V's sight, on a long timer.

argtypedescription
ppany

clearAll( ) → void

populate( ) → void

start( ) → void

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.

23+items
▣
module · born here
❒asset
# gangs.module Registers the gangs beyond the Rotten Crew into `R.enemies` (via `R.defineEnemy`) the moment it is required: `lemon` (Sour Squad skater punk, the Undercroft: fast and fragile) and `chili` (Smoothie Syndicate dock enforcer: tough, with a burning fire punch). Their bodies live in `crew.module` (`BUILD.lemon` / `BUILD.chili`). The `CrewDirector` requires it, so any encounter can list `{ kind = "lemon" | "chili", x, z }`. Extra optional spec fields: `knockbackMult`, `punchElement`, `punchBonus`.
▲ 0↑ born
▣
module · born here
❒asset
# game.enemies.slicer Cuts closed procedural meshes along planes and caps the cut, so the katana leaves clean pieces. Used by `CrewDirector` when a katana kills a fruit thug, and again when a lying piece is slashed. - `S.cut(parts, n, p)` → `neg, pos`: split a solid (a list of `{ mat, geo }` parts in one frame) by the plane through `p` with unit normal `n`. Crossed triangles are split with interpolated normals and UVs; the cut edges of all parts are welded by position and chained into loops, and every closed loop gets a cap on both pieces. - `S.cutAll(parts, { {n, p}, ... })` → every piece after cutting by each plane. - `S.bounds(parts)` → centre, half extents, triangle count. - `S.CUT` maps a flesh material to the cut-face material that shows its cross-section (`tomato` → `cut_tomato`, ...). Loops through flesh cap with it, UV-mapped to the loop's bounds so the texture's round slice fills the section; other loops (eyes, buckles) cap in their own material 1.5 mm inward.
▲ 0↑ born
▣
module · born here
❒asset
# game.enemies.crew Procedural builder for every fruit-and-veg character in Banana 2077: the Rotten Crew thugs (tomato, broccoli punk, pineapple bruiser), the boss Don Aubergine, and the five Peel Kabuki civilians (orange, strawberry, carrot vendor, watermelon NCPD cop, grape kid). It also builds the drop and effect meshes: banana coins, snacks, juice droplets, splats and glow rings. `Crew.build(kind, parent)` returns a rig of pivot entities (root, body, armL/armR, legL/legR) plus every Model entity, so a director can animate, tint and outline it. Meshes are generated once per kind and shared between instances. Called by `game.enemies.CrewDirector`, which spawns, animates and fights with these rigs.
▲ 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
# 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
backing path · game/enemies/CrewDirector.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.