Skip to content

Built-In Components

Spellbook includes common shapes, transforms, and emitters for Java construction and config parsing.

All shapes write local-space points into a PointBuffer.

ShapeConstructorNotes
LineShapenew LineShape(points)Samples a fixed number of points from origin to target.
LineShapeLineShape.withSpacing(spacing, maxPoints)Adapts the point count to target distance, with a safe cap.
SphereShapenew SphereShape(radius, points)Samples points on a sphere surface centered at local origin.
SphereShapenew SphereShape(radius, points, angularSpeed)Rotates sampling by step * angularSpeed.
CubeShapenew CubeShape(size, pointsPerEdge)Samples the 12 cube edges, centered at local origin.
HelixShapenew HelixShape(strands, particlesPerStrand, radius, height, turns, rotationSpeed)Samples one or more vertical helix strands.
SpiralHelixShapenew SpiralHelixShape(strands, particlesPerStrand, radius, height, curve, rotationSpeed)Samples expanding spiral strands.
SpiralHelixShapenew SpiralHelixShape(strands, particlesPerStrand, radius, height, curve, rotationSpeed, reverse)Optional reverse winding direction.
MovingPointShapenew MovingPointShape(speed, spacing, amountPoints, pingPong)Moves points along origin-to-target over render steps.
MorphShapeMorphShape.between(source, target)...build()Interpolates sampled points between two child shapes.

Use fixed-count sampling when an effect must always emit the same number of points:

Shape fixedLine = new LineShape(16);

Use spacing sampling when the origin-target distance can change. The shape calculates ceil(length / spacing) + 1, includes both endpoints, and limits the result to maxPoints.

Shape spacedLine = LineShape.withSpacing(0.5f, 512);

spacing must be finite and greater than 0. maxPoints must be between 2 and LineShape.MAX_SAFE_SPACING_POINTS. A zero-length spacing line emits one local-origin point; a capped line still includes both endpoints, so its effective spacing can be larger than requested. Both modes emit no points when the origin or target is missing.

Built-in shapes validate constructor arguments early.

Examples:

  • counts must usually be greater than 0
  • CubeShape needs at least 2 points per edge
  • radii and sizes must be greater than 0
  • helix height may be 0, but not negative

Invalid values throw IllegalArgumentException.

Transforms mutate sampled local points before modifiers and emission.

EffectInstance effect = EffectBuilder.create()
.shape(new CubeShape(2.0f, 4))
.transform(new TranslateTransform(0, 1, 0))
.transform(new RotationTransform(0, 45, 0))
.particle(Particle.END_ROD)
.build();
TransformPurpose
TranslateTransformAdds an offset to each point.
RotationTransformRotates each point by Euler angles or a quaternion.
LookAtTransformRotates local points to face the context target.

LookAtTransform needs an origin and target in the EffectContext. If no usable target direction exists, it leaves points unchanged.

StandardParticleEmitter spawns one Bukkit particle call per final point for every viewer.

StandardParticleEmitter<Void> emitter = StandardParticleEmitter.of(Particle.FLAME, 2);

For full particle options, use ParticleSpec.

ParticleSpec<Void> spec = new ParticleSpec<>(
Particle.FLAME,
2,
0.05,
0.05,
0.05,
0.0,
null
);

StandardParticleEmitter does not require direction data, so the render pipeline skips direction-provider calls for it.

Morphs sample two child shapes and interpolate between their points.

Shape morph = MorphShape.between(
new SphereShape(1.0f, 48),
new CubeShape(2.0f, 5)
)
.overSteps(40)
.strategy(MorphPointStrategies.resampleToMax())
.build();

Progress providers:

FactoryMeaning
MorphProgress.fixed(value)same progress every frame
MorphProgress.overSteps(durationSteps)step-based 0..1 from step 0
MorphProgress.afterStep(startStep, durationSteps)delayed step-based progress
MorphProgress.overSeconds(durationSeconds)time-based 0..1 from elapsed 0
MorphProgress.afterSeconds(startSeconds, durationSeconds)delayed time-based progress
MorphProgress.triggeredOverSteps(durationSteps)mutable trigger handle

Point strategies:

StrategyOutput Count
matchIndex()smaller child point count
resampleSourceToTarget()target point count
resampleTargetToSource()source point count
resampleToMax()larger child point count

TriggeredMorphProgress is mutable. Create one instance per independent running effect when each execution needs separate trigger timing.