Skip to content

Picking a template

StormPacer edited this page Jul 11, 2022 · 5 revisions

Information

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.

Scripts

The two scripts available on this repo currently are

StormPacer's Script

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

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.

Usage Difference

Here are a few examples of the script side by side, both do the exact same thing, just written with different scripts.

Generating animation events.

AnimateTrack

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.

AssignPathAnimation

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.

AssignPlayerToTrack

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.

AssignTrackParent

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".

Functions

Below are some functions that again do the exact same thing but are just written in different templates.

Randomizing movement path

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.

Duplicating notes

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.

Generating new objects

Notes

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.

Walls

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.

Overview

Jevk's script

Generally a cleaner and more compact option, requires a bit more understanding but should be easy to learn.

StormPacer's script

Generally longer lines of code but everything is fairly similar in it. Doesn't require as much understanding as Jevk's script.

Conclusion

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.