Documentation Index Fetch the complete documentation index at: https://mintlify.com/ivan-1f/phichain/llms.txt
Use this file to discover all available pages before exploring further.
Overview
LineEvents control how judgment lines move, rotate, and change appearance over time. Each event has a type (kind), a time range (start_beat to end_beat), and a value that can either transition smoothly or remain constant.
Types
LineEvent
An animation event that modifies a line property.
Which property this event affects (X, Y, Rotation, Opacity, or Speed)
When the event begins taking effect
When the event stops taking effect
The value(s) for this event - either a transition or constant
LineEventKind
The type of property being animated.
Horizontal position (screen coordinates, 0 = center)
Vertical position (screen coordinates, 0 = center)
Rotation angle in degrees
Line visibility (0.0 = invisible, 1.0 = fully visible)
Note movement speed multiplier
LineEventValue
The value that the event applies to the line property.
Smoothly interpolates between start and end values using an easing function. LineEventValue :: Transition {
start : f32 ,
end : f32 ,
easing : Easing ,
}
Starting value at start_beat
Easing function for interpolation (see the Phichain format documentation for easing details)
Maintains a constant value throughout the event duration. LineEventValue :: Constant ( f32 )
The constant value to maintain
Creating Events
Position Animation
Rotation Animation
Opacity and Speed
Constant Values
use phichain_chart :: event :: { LineEvent , LineEventKind , LineEventValue };
use phichain_chart :: easing :: Easing ;
use phichain_chart :: beat :: Beat ;
// Move line horizontally from left to right
let x_event = LineEvent {
kind : LineEventKind :: X ,
start_beat : Beat :: ZERO ,
end_beat : Beat :: from ( 4.0 ),
value : LineEventValue :: transition ( - 0.5 , 0.5 , Easing :: Linear ),
};
// Move line vertically with smooth easing
let y_event = LineEvent {
kind : LineEventKind :: Y ,
start_beat : Beat :: from ( 4.0 ),
end_beat : Beat :: from ( 8.0 ),
value : LineEventValue :: transition ( 0.0 , 0.3 , Easing :: EaseInOutSine ),
};
Event Evaluation
Events can be evaluated at any beat to get the current value:
Basic Evaluation
Evaluation Results
use phichain_chart :: event :: { LineEvent , EventEvaluationResult };
let event = LineEvent {
kind : LineEventKind :: X ,
start_beat : Beat :: ZERO ,
end_beat : Beat :: from ( 4.0 ),
value : LineEventValue :: transition ( 0.0 , 1.0 , Easing :: Linear ),
};
// Evaluate at different beats
let result = event . evaluate ( 2.0 ); // halfway through
match result {
EventEvaluationResult :: Affecting ( value ) => {
println! ( "Current value: {}" , value ); // 0.5
}
_ => {}
}
Helper Methods
LineEventValue Helpers
LineEventKind Helpers
use phichain_chart :: event :: LineEventValue ;
use phichain_chart :: easing :: Easing ;
// Create values
let transition = LineEventValue :: transition ( 0.0 , 1.0 , Easing :: Linear );
let constant = LineEventValue :: constant ( 0.5 );
// Check type
if transition . is_transition () {
println! ( "This is a transition" );
}
if constant . is_constant () {
println! ( "This is a constant" );
}
// Get start/end values
let start = transition . start (); // 0.0
let end = transition . end (); // 1.0
// For constants, start and end are the same
assert_eq! ( constant . start (), constant . end ());
// Convert between types
let as_constant = transition . into_constant (); // uses start value
let as_transition = constant . into_transition (); // start = end = value
// Negate values
let negated = transition . negated (); // start: 0.0, end: -1.0
JSON Serialization
Transition Event
Constant Event
With Custom Easing
{
"kind" : "x" ,
"start_beat" : [ 0 , 0 , 1 ],
"end_beat" : [ 4 , 0 , 1 ],
"value" : {
"transition" : {
"start" : -0.5 ,
"end" : 0.5 ,
"easing" : "linear"
}
}
}
Event Coordination
Multiple Events on Same Line
Sequential Events
use phichain_chart :: serialization :: SerializedLine ;
use phichain_chart :: line :: Line ;
let line = SerializedLine :: new (
Line { name : "Animated Line" . to_string () },
vec! [],
vec! [
// Move horizontally
LineEvent {
kind : LineEventKind :: X ,
start_beat : Beat :: ZERO ,
end_beat : Beat :: from ( 8.0 ),
value : LineEventValue :: transition ( - 0.5 , 0.5 , Easing :: Linear ),
},
// Move vertically at same time
LineEvent {
kind : LineEventKind :: Y ,
start_beat : Beat :: ZERO ,
end_beat : Beat :: from ( 8.0 ),
value : LineEventValue :: transition ( - 0.3 , 0.3 , Easing :: Linear ),
},
// Rotate while moving
LineEvent {
kind : LineEventKind :: Rotation ,
start_beat : Beat :: ZERO ,
end_beat : Beat :: from ( 8.0 ),
value : LineEventValue :: transition ( 0.0 , 360.0 , Easing :: Linear ),
},
// Keep visible
LineEvent {
kind : LineEventKind :: Opacity ,
start_beat : Beat :: ZERO ,
end_beat : Beat :: from ( 8.0 ),
value : LineEventValue :: constant ( 1.0 ),
},
],
vec! [],
vec! [],
);
Notes
Events of the same kind can overlap - the game typically uses the most recent active event
Speed events affect how fast notes approach the line, not the line’s movement speed
Opacity affects both the line and notes on it
Position coordinates: (0, 0) is screen center, positive X is right, positive Y is up
Rotation is in degrees, clockwise
After an event ends, its end value is typically inherited until another event of the same kind begins