Picking a template
Picking a template can be difficult, that's why this page exists. On this page you can compare the two available templates and pick the best one for you to use in noodling.
The two scripts available on this repo currently are
This one is generally messier and longer to type. This template is designed for people with no prior programming experience. It can get a bit confusing at times and is generally more difficult to read afterwards.
Jevk's script is generally cleaner and it's implemented in a way where you don't have to type as much. This template is a bit more advanced and directed for those who understand programming logic more. However, this can be used by a total beginner. This script is a bit more straight-forward and is easier to read afterwards.
Here are a few examples of the script side by side, both do the exact same thing, just written with different scripts.
StormPacer's script
GiveNotesTrack("foo", 4, 6);
customEvents.push({
_time: 4,
_type: "AnimateTrack",
_data: {
_track: "foo",
_duration: 1,
_scale: [[2, 2, 2, 0], [1, 1, 1, 1, "easeOutCubic"]]
}
});
Jevk's script
noteTrack("foo", 4, 6);
new AnimateTrack(4, {
_track: "foo",
_duration: 1,
_scale: [
[2, 2, 2, 0],
[1, 1, 1, 1, "easeOutCubic"]
]
});
Both of the scripts above make all blocks between beats 4 and 6 double the size and go back to the original size over 1 beat.
StormPacer's script
GiveNotesTrack("foo", 4, 20);
customEvents.push({
_time: 0,
_type: "AssignPathAnimation",
_data: {
_track: "foo",
_position: [[0, 5, 0, 0], [0, 0, 0, 0.45, "easeOutCirc"]]
}
});
Jevk's script
noteTrack("foo", 4, 20);
new AssignPathAnimation(0, {
_track: "foo",
_position: [
[0, 5, 0, 0],
[0, 0, 0, 0.45, "easeOutCirc"]
]
});
Both of the scripts above make all notes between beats 4 and 20 spawn 5 blocks higher than normally and gradually descend back to the player's height.
StormPacer's script
customEvents.push({
_time: 0,
_type: "AssignPlayerToTrack",
_data: {
_track: "playerTrack"
}
});
Jevk's script
new AssignPlayerToTrack(0, "playerTrack");
Both of these assign the player to the track "playerTrack"
on beat 0.
StormPacer's script
customEvents.push({
_time: 0,
_type: "AssignTrackParent",
_data: {
_parentTrack: "parent",
_childrenTracks: ["leftTrack", "centerTrack", "rightTrack"]
}
});
Jevk's script
new AssignTrackParent(0, ["leftTrack", "centerTrack", "rightTrack"], "parent");
Both scripts assign tracks "leftTrack"
, "centerTrack"
and "rightTrack"
to a parent track called "parent"
.
Below are some functions that again do the exact same thing but are just written in different templates.
StormPacer's script
function RandomizePath(Start, End) {
filterednotes = notes.filter(n => n._time >= Start && n._time <= End);
filterednotes.forEach(note => {
if (!note._customData._animation) note._customData._animation = {};
note._customData._noteJumpStartBeatOffset = 2;
note._customData._disableSpawnEffect = true;
note._customData._disableNoteGravity = true;
note._customData._animation._position = [[Random(-10, 10), Random(-1, 10), Random(-15, -5), 0], [Random(-10, 10), Random(-1, 10), Random(0, 10), 0.125, "easeInOutCirc"], [Random(-10, 10), Random(-1, 10), Random(-5, 5), 0.25, "easeInOutCirc", "splineCatmullRom"], [0, 0, 0, 0.45, "easeInOutCirc", "splineCatmullRom"]];
note._customData._animation._dissolve = [[0, 0], [1, 0.125, "easeOutCubic"]];
note._customData._animation._dissolveArrow = [[0, 0], [1, 0.125, "easeOutCubic"]];
});
}
RandomizePath(69, 420);
Jevk's script
function randomizePath(start, end) {
filterNotes(start, end).forEach(n => {
let data = n._customData;
if (!data._animation) data._animation = {};
let anim = data._animation;
data._noteJumpStartBeatOffset = 2;
data._disableSpawnEffect = true;
data._disableNoteGravity = true;
anim._position = [
[random(-10, 10), random(-1, 10), random(-15, -5), 0],
[random(-10, 10), random(-1, 10), random(0, 10), 0.125, "easeInOutCirc"],
[random(-10, 10), random(-1, 10), random(-5, 5), 0.25, "easeInOutCirc", "splineCatmullRom"],
[0, 0, 0, 0.45, "easeInOutCirc", "splineCatmullRom"]
];
anim._dissolve = [
[0, 0],
[1, 0.125, "easeOutCubic"]
];
anim._dissolveArrow = [
[0, 0],
[1, 0.125, "easeOutCubic"]
];
});
}
randomizePath(69, 420);
Both scripts animate all notes between beats 69 and 420 in a way where their movement path is completely randomized. Jevk's script clearly has more lines but is easier to read and it has less manually written characters since it uses variables. Whereas StormPacer's script has less lines but much more to type due to less use of variables and it generally looks messier.
StormPacer's script
function DuplicateNotes(Start, End) {
filterednotes = _notes.filter(n => n._time >= Start && n._time <= End);
filterednotes.forEach(note => {
let dupe = JSON.parse(JSON.stringify(note));
dupe._customData._fake = true;
dupe._customData._interactable = false;
dupe._customData._disableSpawnEffect = true;
notes.push(dupe);
});
}
DuplicateNotes(50, 727);
Jevk's script
function duplicateNotes(start, end) {
filterNotes(start, end).forEach(n => {
let dupe = JSON.parse(JSON.stringify(n));
let data = dupe._customData;
data._fake = true;
data._interactable = false;
data._disableSpawnEffect = true;
_notes.push(dupe);
});
}
duplicateNotes(50, 727);
Both scripts duplicate all notes between beats 50 and 727 once and makes the duplicated note uninteractive and fake, then places the fake note over the real note. This time the line count on both scripts is the same, StormPacer's script however has still more to type.
StormPacer's script
notes.push({
_time: 69,
_type: 0,
_lineIndex: 0,
_lineLayer: 0,
_cutDirection: 8,
_customData: {
_fake: true,
_interactable: false,
_disableSpawnEffect: true,
_disableNoteGravity: true,
_disableNoteLook: true,
_noteJumpStartBeatOffset: 4,
_animation: {
_dissolve: [[0, 0], [1, 0.125, "easeOutCubic"], [1, 0.875], [0, 1, "easeInCubic"]],
_dissolveArrow: [[0, 0], [1, 0.125, "easeOutCubic"], [1, 0.875], [0, 1, "easeInCubic"]],
_definitePosition: [[0, 1, 5, 0]]
}
}
});
Jevk's script
new PointDefinition("disInOut", [
[0, 0],
[1, 0.125, "easeOutCubic"],
[1, 0.875],
[0, 1, "easeInCubic"]
]);
new Note(69, 0, 0, 0, 8, {
_fake: true,
_interactable: false,
_disableSpawnEffect: true,
_disableNoteGravity: true,
_disableNoteLook: true,
_noteJumpStartBeatOffset: 4,
_animation: {
_dissolve: "disInOut",
_dissolveArrow: "disInOut",
_definitePosition: [0, 1, 5]
}
});
Both scripts spawn a red uninteractive note that stays still in the middle of the grid. It also dissolves in and out. StormPacer's script uses a _notes.push()
function, while Jevk's script uses a constructor to do the same thing. StormPacer's _dissolve
animation is done separately on both dissolve types, Jevk's script uses a PointDefinition
to just call the animation using "disInOut"
on both _dissolve
and _dissolveArrow
.
StormPacer's script
for (let i = 69, j = 1; i <= 100; i += 1/8, j *= -1) {
const rotAmount = Random(0, 360);
walls.push({
_time: i,
_type: 1,
_width: 1,
_lineIndex: 0,
_duration: 8,
_customData: {
_fake: true,
_interactable: false,
_rotation: [0, 0, random(-180, 180)],
_scale: [0.1, 0.1, 0.1],
_color: [1, 1, 1, 5],
_animation: {
_dissolve: [[0, 0], [1, 0.125, "easeOutCubic"], [1, 0.875], [0, 1, "easeInCubic"]],
_rotation: [[0, 0, rotAmount * j, 0], [0, 0, rotAmount * j * 0.75, 0.25], [0, 0, rotAmount * j / 2, 0.5], [0, 0, rotAmount * j / 4, 0.75], [0, 0, 0, 1]],
_definitePosition: [0, Random(75, 100) / 10, Random(0, 20)]
}
}
});
}
Jevk's script
new PointDefinition("disInOut", [
[0, 0],
[1, 0.125, "easeOutCubic"],
[1, 0.875],
[0, 1, "easeInCubic"]
]);
for (let i = 69, j = 1; i <= 100; i += 1/8, j *= -1) {
const rotAmount = random(0, 360);
new Wall(i, 8, {
_fake: true,
_interactable: false,
_rotation: [0, 0, random(-180, 180)],
_scale: [0.1, 0.1, 0.1],
_color: [1, 1, 1, 5],
_animation: {
_dissolve: "disInOut",
_rotation: [
[0, 0, rotAmount * j, 0],
[0, 0, rotAmount * j * 0.75, 0.25],
[0, 0, rotAmount * j / 2, 0.5],
[0, 0, rotAmount * j / 4, 0.75],
[0, 0, 0, 1],
],
_definitePosition: [0, random(75, 100) / 10, random(0, 20)]
}
});
}
Both of the scripts generate a tunnel tupe of effect out of small white walls that dissolve in and out. The particles that the tunnel is made out of spin at a random velocity around the Z axis both clockwise and counter-clockwise. A similar effect can be found in conflict by Jevk.
StormPacer's script doesn't support _pointDefinitions
, so the animations have to be written out separately to all use cases of said animation. This makes reusing animations much harder and more unoptimized.
Generally a cleaner and more compact option, requires a bit more understanding but should be easy to learn.
Generally longer lines of code but everything is fairly similar in it. Doesn't require as much understanding as Jevk's script.
Use StormPacer's script if you are creating a short project with not that many effects and don't have logic understanding.
Use Jevk's script if you have experience with programming/logic understanding OR if you are making more advanced scripts.
Table of Contents
StormPacer's script
Jevk's script