gvc_bubble
The bubble the Bubblewright carries, and the juice around it.
gvc_bubble
The bubble the Bubblewright carries, and the juice around it.
CONFECTION owns exactly one piece of the player's own presentation: the translucent iridescent sphere that appears as motes land, grows per mote, and pops when the bubble is released over a well. This module also owns the effects that sell the moment, because they all key off the same beats.
Surface
M.ensure() -- spawn everything; safe to call repeatedly
M.teardown() -- despawn everything, restore the borrowed FOV
M.tick(dt, charge01, playing) -- called once per HUD tick by confection.module
M.onMote(x, y, z, charge, needed)
M.onBloom(x, y, z)
M.onWin() / M.onLose()
M.play(key, volume?, pitch?) -- "mote" | "bloom" | "win" | "lose"
M.clips() / M.popPhase() / M.punchPhase()
It keeps no task of its own — confection.module drives it from the one loop it
owns, so there is a single place that can leak and a single place that cancels.
What it spawns
gv_bubble (sphere + confection.gvc_bubble material), gv_bubble_halo (the
shimmer that trails a charged bubble), gv_fx_mote and gv_fx_bloom (the two
burst emitters, moved to the beat and fired with :emit(n) rather than
respawned), and gv_confection_audio, which carries both the Audio source and
an AudioListener so the slice never has to attach a component to an entity the
scene owns.
All of them are marked temporary: they are presentation rebuilt from scratch
on every boot, and without the flag an accepted scene review bakes them into
scenes/main.scene.
Where the bubble floats
Over the local player's shoulder, re-resolved every tick — the world is always multiplayer and there is no "the player" to stash. With no local player yet, it parks in front of the viewport camera (derived from row 3 of the view-projection matrix) so the bubble stays inspectable in edit mode.
Sound
The four clips are generated into /source/generated/audio and resolved by a
distinctive fragment of their prompt-derived identity, so a re-generation under a
slightly different name still binds. The mote chime pitches up with the charge,
so the third mote lands at the top of a short scale.
The lens kick
A bloom adds up to +13° of FOV on camera.main() over 0.7 s and returns it to
the value it borrowed. Both that window and the pop are generous on purpose: the
HUD loop runs at 12 Hz and the scene can drop to 10 FPS with three slices live,
so a 0.4 s effect would get three or four samples.
Scoped to this part · feeds back into the world's score.