extends Node2D # Same informal interface as GasGiantVisual/RockyPlanetVisual - configure(), # extractor_anchor(), animates via its own _process(). No solid body: the # core stays genuinely empty (nothing drawn inside CORE_RADIUS), and an # accretion disc of rotating arc segments - not closed rings - stands in # for a surface, brighter and thicker toward the centre. var disc_phase: float = 0.0 const CORE_RADIUS: float = 46.0 const RING_COUNT: int = 5 const RING_STEP: float = 16.0 const DISC_COLOR: Color = Color(0.55, 0.15, 0.85) const DISC_HOT_COLOR: Color = Color(0.9, 0.6, 1.0) func configure(_shape_seed: int) -> void: queue_redraw() func extractor_anchor() -> Vector2: return Vector2(0.0, -(CORE_RADIUS + float(RING_COUNT - 1) * RING_STEP + 12.0)) func _process(delta: float) -> void: disc_phase += delta queue_redraw() func _draw() -> void: for i in range(RING_COUNT): var radius: float = CORE_RADIUS + float(i) * RING_STEP # 1.0 at the innermost ring, fading to 0.0 at the outermost - drives # both colour (hotter inward) and stroke weight/brightness. var t: float = 1.0 - float(i) / float(maxi(RING_COUNT - 1, 1)) var ring_color: Color = DISC_COLOR.lerp(DISC_HOT_COLOR, t * 0.65) # Alternating spin direction per ring and a speed tied to t reads as # genuine turbulence rather than one disc rotating as a rigid whole. var spin: float = disc_phase * (0.12 + t * 0.22) * (1.0 if i % 2 == 0 else -1.0) for arc_i in range(2): var start: float = spin + float(arc_i) * PI + 0.15 var end: float = start + PI - 0.3 var points := PackedVector2Array() var steps: int = 24 for j in range(steps + 1): var angle: float = lerpf(start, end, float(j) / float(steps)) points.append(Vector2(cos(angle), sin(angle)) * radius) NeonDraw.draw_glowing_path(self, points, ring_color, 0.5 + t * 0.5, 0.45 + t * 0.35)