#How would I make a script that loops music after a set delay?

153 messages · Page 1 of 1 (latest)

misty obsidian
#

Hi, I'm new to kubejs, and coding in general. I've been trying to figure out how to get Gateways to Eternity portals play music to make it feel special and intense.

I eventually got the basic script for getting music to play when a specific gateway is spawned, however I am stumped on the remaining things I am aiming for for this script:

  • 1: After a set delay, play a separate audio track.
  • 2: After another set delay, have that separate audio track be looped (the first track is the the beginning of a song, the 2nd track is the loop).
  • 3: When the gateway closes (whether its failed or completed) stop the music.

How would I go about doing this?

Here is what I have so far:

    if (event.entity.nbt.gate == "gateways:basic/blaze") {
        event.server.runCommand(`execute in ${event.entity.level.dimension} positioned ${event.entity.x} ${event.entity.y} ${event.entity.z} run playsound kubejs:music.song_1 ambient @e[type=player] ~ ~ ~ 1 1`)
    };
    if (event.entity.nbt.gate == "gateways:basic/enderman") {
        event.server.runCommand(`execute in ${event.entity.level.dimension} positioned ${event.entity.x} ${event.entity.y} ${event.entity.z} run playsound kubejs:music.song_2 ambient @e[type=player] ~ ~ ~ 1 1`)
    };
    if (event.entity.nbt.gate == "gateways:basic/slime") {
        event.server.runCommand(`execute in ${event.entity.level.dimension} positioned ${event.entity.x} ${event.entity.y} ${event.entity.z} run playsound kubejs:music.song_3 ambient @e[type=player] ~ ~ ~ 1 1`)
    }
})```
chilly jungleBOT
#

Once your ticket has been resolved, please close it with </ticket close:1054771505520717835> command!

runic thicket
# misty obsidian Hi, I'm new to kubejs, and coding in general. I've been trying to figure out how...

sound is a client thing, try this in your client script. This should make a glass broken sound when an armor stand spawn, and loop amethyst broken sound 5 sec later, and stop the looping sound when armor stand is broken.

/**
 * 
 * @param {Internal.SoundEvent_} sound 
 * @param {Internal.SoundSource_} source 
 * @param {number} volume 
 * @param {number} pitch 
 * @param {boolean} loop 
 * @param {number} delay 
 * @param {Internal.SoundInstance$Attenuation_} attenuation 
 * @param {BlockPos} pos 
 * @param {boolean} relative 
 * @returns {Internal.SoundInstance}
 */
const createSoundInstance = (sound, source, volume, pitch, loop, delay, attenuation, pos, relative) => {
    const $SimpleSoundInstance = Java.loadClass("net.minecraft.client.resources.sounds.SimpleSoundInstance")
    const soundInstance = new $SimpleSoundInstance(sound, source, volume, pitch, Client.level.random, loop, delay, attenuation, pos.x, pos.y, pos.z, relative)
    return soundInstance
}


const soundInstances = {}
EntityEvents.spawned("minecraft:armor_stand", event => {
    const {entity, entity:{block:{pos}}} = event
    const soundManager = Client.soundManager
    const/**@type {Internal.SoundInstance} */ instance = soundInstances["armorStandLooping"] || createSoundInstance("block.amethyst_cluster.break", "master", 2, 1, true, 0, "none", pos, false)
    if(!soundInstances["armorStandLooping"]) soundInstances["armorStandLooping"] = instance
    if(!soundManager.isActive(instance)) {
        soundManager.play(createSoundInstance("minecraft:block.glass.break", "master", 2, 1, false, 0, "none", pos, false))
        soundManager.playDelayed(instance, 100)
    }
    const checkArmorStandAlive = 
    Client.scheduleRepeatingInTicks(100, _ => {
        if(!entity.alive){
            soundManager.stop(instance)
            checkArmorStandAlive.clear()
            delete checkArmorStandAlive
        }
    })

})
misty obsidian
#

That works nearly flawlessly, however I have 2 questions.

1: How would I go about using gateways as opposed to armor stands? They use a specific nbt tag to determine what gateway it is.
2: How would I go about having this script play different sounds for different gateways? Do I just copy/paste the script per each gateway I want to use?

As for why I chose server script. My knowledge wanted to use simple solutions that would easily work and make sense, and the modpack I'm working on is being geared towards playing on a server, so I assumed it would be easier to setup and less of a hassle?

#

Another thing I have noticed. If I place 2 or more armor stands, the script sorta breaks and only plays one instance of the script at a time as opposed to 2. If one of the stands is broken, the script stops running, as opposed to all of them

#

the glass break sound effect is played, but the amethyst one is not

#

Attempting to use the nbt check from the server script I did earlier, and it doesnt seem to work here.

runic thicket
misty obsidian
#

Im not entirely sure how the script would run on a server, where there might be people trying to use multiple gates at once

runic thicket
#

I think this script can only run in server script when it's single player world

#

Because iirc in a multiplayer server, server script could not access Client

#

And sound is a client thing

misty obsidian
#

couldn't I use the playsound and stopsound commands in place of the sound events?

#

if placed in a server script?

runic thicket
#

The problem is that there's no loop field in the playsound command, so you might need to do something ugly to make it loop if you want to use command for that

misty obsidian
#

That might be fine? im aware the command doesnt have a loop field. Is there a thing to schedule something x time later for server scripts potentially?

#

otherwise, if it works easier as a client script, how would I go about checking the entity's nbt data, then proceeding with executing the script?

runic thicket
#

This is for thing to repeat on server

    const repeatingSchedule = event.server.scheduleRepeatingInTicks(interval, _ => {
        //things repeats here
        //use repeatingSchedule.clear() to stop it.
    })
runic thicket
misty obsidian
#

I added the if statement from the script I originally sent earlier:

    if (event.entity.nbt.gate == "gateways:basic/blaze") {
        const {entity, entity:{block:{pos}}} = event
        const soundManager = Client.soundManager
        const/**@type {Internal.SoundInstance} */ instance = soundInstances["armorStandLooping"] || createSoundInstance("block.amethyst_cluster.break", "master", 2, 1, true, 0, "none", pos, false)
        if(!soundInstances["armorStandLooping"]) soundInstances["armorStandLooping"] = instance
            if(!soundManager.isActive(instance)) {
                soundManager.play(createSoundInstance("minecraft:block.glass.break", "master", 2, 1, false, 0, "none", pos, false))
                soundManager.playDelayed(instance, 20)
            }
            const checkArmorStandAlive =
            Client.scheduleRepeatingInTicks(20, _ => {
                if(!entity.alive){
                    soundManager.stop(instance)
                    checkArmorStandAlive.clear()
                    delete checkArmorStandAlive
                }
            })
    }      
})```

What happens is that no sound gets played at all
#

now I'm confused. just tried again and it works?

runic thicket
#

sometimes things just need some more reload I guess

misty obsidian
#

wait no it didnt work. I forgot to apply the changes on reload. whoops

runic thicket
#

Lemme guess, there's redeclaration error in your client log

misty obsidian
#

gimme a second to check. had to restart my instance

#

where would I find the client log?

quartz pantherBOT
#

Please send your KubeJS client log. It can be found at /minecraft/logs/kubejs/client.log.
If you are on 1.18 or 1.16 it will be called client.txt.
Please send the file directly, without links or snippets.

misty obsidian
#

I see no errors

runic thicket
#

do you spawn a gate after restarting?

misty obsidian
#

yes

runic thicket
#

No error and nothing happens?

misty obsidian
#
[05:29:10] [INIT] Loaded plugins:
[05:29:10] [INIT] - dev.latvian.mods.kubejs.forge.BuiltinKubeJSForgePlugin
[05:29:10] [INIT] - dev.latvian.mods.kubejs.forge.BuiltinKubeJSForgeClientPlugin
[05:29:10] [INIT] - dev.ftb.mods.ftbxmodcompat.ftbquests.kubejs.KubeJSIntegration
[05:29:10] [INIT] - dev.ftb.mods.ftbxmodcompat.ftbteams.kubejs.FTBTeamsKubeJSPlugin
[05:29:10] [INIT] - dev.ftb.mods.ftbxmodcompat.ftbfiltersystem.kubejs.FFSKubeJSPlugin
[05:29:10] [INIT] - com.bobvarioa.kubejsarsnouveau.KubeJSArsNouveauPlugin
[05:29:10] [INIT] - dev.latvian.mods.kubejs.create.KubeJSCreatePlugin
[05:29:10] [INIT] - pie.ilikepiefoo.AdditionsPlugin
[05:29:10] [INIT] - pie.ilikepiefoo.compat.jei.JEIKubeJSPlugin
[05:29:10] [INIT] - qinomed.kubejsdelight.KubeJSDelightPlugin
[05:29:10] [INFO] Loaded script client_scripts:jei_hide.js in 0.001 s
[05:29:10] [INFO] Loaded script client_scripts:test.js in 0.006 s
[05:29:10] [INFO] example.js#5: Hello, World! (Loaded client scripts)
[05:29:10] [INFO] Loaded script client_scripts:example.js in 0.0 s
[05:29:10] [INFO] Loaded 3/3 KubeJS client scripts in 0.019 s with 0 errors and 0 warnings
[05:29:15] [INFO] Client resource reload complete!```
#

this is all im getting

#

and yeah nothing is happening

runic thicket
#

hmm, lemm test it.

misty obsidian
#

If i copy and paste the entity event stuff and dont use the nbt check, that entity works.

#

Wait, are clients allowed to check an entity's nbt data? if not, that might be why its not working?

#

or is there a different event for checking nbt on clients specifically?

runic thicket
#

It's able to check the nbt data. Just the gate seems a little wonky, the nbt is not accessible at the same tick when the gate spawns

misty obsidian
#

ahhhh

runic thicket
#

Not a big deal, just need to add a one tick delay

misty obsidian
#

how would I add that tick of delay?

runic thicket
# misty obsidian how would I add that tick of delay?
const soundsMap = {
    "gateways:basic/blaze": {
        opening: "minecraft:block.glass.break",
        looping: "minecraft:block.amethyst_cluster.break"
    }
}

const soundInstances = {}
/** @param {Internal.EntitySpawnedEventJS} event */
const loopMusicForEntity = (event) => {
    const {entity, entity:{block:{pos}}} = event
    const gateType = entity.nbt.getString("gate")
    const {opening, looping} = soundsMap[gateType]
    const soundManager = Client.soundManager
    const/**@type {Internal.SoundInstance} */ instance = soundInstances["armorStandLooping"] || createSoundInstance(looping, "master", 2, 1, true, 0, "none", pos, false)
    if(!soundInstances["armorStandLooping"]) {
        soundInstances["armorStandLooping"] = instance
        soundManager.play(createSoundInstance(opening, "master", 2, 1, false, 0, "none", pos, false))
        soundManager.playDelayed(instance, 100)
    }
    const checkArmorStandAlive = 
    Client.scheduleRepeatingInTicks(100, _ => {
        if(!entity.alive){
            soundManager.stop(instance)
            checkArmorStandAlive.clear()
            delete soundInstances["armorStandLooping"]
            delete checkArmorStandAlive
        }
    })
}
EntityEvents.spawned("gateways:normal_gateway", event => {
    Client.scheduleInTicks(1, _ => loopMusicForEntity(event))
})

#

And you can add different sounds for different gate type

misty obsidian
#

So, replace the current client script with this one?

misty obsidian
#

Attempting to add more gateway types, and its throwing errors

#

I assume if that adding another gateway type, it would go along the lines of this?

    "gateways:basic/blaze": {
        opening: "minecraft:block.glass.break",
        looping: "minecraft:block.amethyst_cluster.break"
    };
    "gateways:basic/slime": {
    opening: "minecraft:block.glass.break",
    looping: "minecraft:block.amethyst_cluster.break"
    }
}```
misty obsidian
#

This works perfectly now. Thanks for the help

misty obsidian
#

wait, new issue came up

#

Trying to use custom sounds, and its causing the entire script to break. no errors or anything however

#

reloading again fixed it, but now another issue came up. the custom sound doesnt seem to be clearing on gateway being deleted?

#

specifically, the opening is not being cleared.

misty obsidian
#

Another potential issue. How would I go about setting different tick delays for different gates? For example: the blaze gate would have a different track to play, and would have a different duration for the opening track compared to the slime gate.

runic thicket
# misty obsidian Another potential issue. How would I go about setting different tick delays for ...
const soundsMap = {
    "gateways:basic/blaze": {
        opening: "minecraft:block.glass.break",
        looping: "minecraft:block.amethyst_cluster.break",
        openingDuration: 100
    }
}

const soundInstances = {}
/** @param {Internal.EntitySpawnedEventJS} event */
const loopMusicForEntity = (event) => {
    const {entity, entity:{block:{pos}}} = event
    const gateType = entity.nbt.getString("gate")
    const soundType = soundsMap[gateType]
    if(!soundType) return;
    const {opening, looping, openingDuration} = soundType
    const soundManager = Client.soundManager
    const/**@type {Internal.SoundInstance} */ openingSound = soundInstances["gateStarting"] || createSoundInstance(opening, "master", 2, 1, false, 0, "none", pos, false)
    const/**@type {Internal.SoundInstance} */ loopingSound = soundInstances["gateLooping"] || createSoundInstance(looping, "master", 2, 1, true, 0, "none", pos, false)
    if(!soundInstances["gateLooping"]) {
        soundInstances["gateOpening"] = openingSound
        soundInstances["gateLooping"] = loopingSound
        soundManager.play(openingSound)
        soundManager.playDelayed(loopingSound, openingDuration)
    }
    const checkArmorStandAlive = 
    Client.scheduleRepeatingInTicks(100, _ => {
        if(!entity.alive){
            if(soundManager.isActive(openingSound)) soundManager.stop(openingSound)
            if(soundManager.isActive(loopingSound)) soundManager.stop(loopingSound)
            checkArmorStandAlive.clear()
            delete soundInstances["gateOpening"]
            delete soundInstances["gateLooping"]
            delete checkArmorStandAlive
        }
    })
}

EntityEvents.spawned("gateways:normal_gateway", event => {
    Client.scheduleInTicks(1, _ => loopMusicForEntity(event))
})
#

Although we could theoretically get the length of an ogg file, I am not sure how to do it through kubejs, so you might need to specify the duration manually

misty obsidian
#

Ahhh

#

but yeah, im used to translating the length of a track. so im fine with doing it manually

misty obsidian
#

one quick question. Is there a distance limit to this? if not, How would I go about adding one to this? thinking how this would work on a multiplayer server, and if someone spawned a gate within your render distance, would the music be played still even if you were not near it?

runic thicket
# misty obsidian one quick question. Is there a distance limit to this? if not, How would I go ab...

The distance limit is currently the render distance as entities outside of render distance is considered not alive. If you want to have a distance limit lesser than render distance, you'd need to replace the if(!entity.alive) with some other logic and add limit to whether the music should start. As for distance greater than render distance, you might need to utilize network event to handle server-client coummunication.

misty obsidian
#

Alright. I'll see what I can do. I'll re-open this if I cant seem to figure it out on my own. thanks again for the help

chilly jungleBOT
misty obsidian
#

So, a few small issues cropped up.

1: If the gateway ends before the opening track finished, the loop track will still play, and will go on for infinity until you manually reload assets via f3+t.
2: The script requires the user to manually reload their assets upon loading to the world (single player or multiplayer)

runic thicket
misty obsidian
#

for #2, the script doesnt play any audio until you reload client sided assets

runic thicket
#

Is the sound playable without reloading when using command to play?

misty obsidian
#

gimme a sec to check

#

yes. it plays just fine without reloading

runic thicket
#

Is there error in log when the client unable to play sound?

misty obsidian
#

nope

runic thicket
#

how do you define the custom sounds

misty obsidian
#

in the kubejs assets folder, i believe exactly just like a resource pack?

    "music.sound_1": {
        "sounds": [
            {
                "name": "kubejs:sound_1",
                "stream": true
            }
        ]
    },
    "music.sound_2": {
        "sounds": [
            {
                "name": "kubejs:sound_2",
                "stream": true
            }
        ]
    }
}```
runic thicket
misty obsidian
#

exactly my thoughts. only solution i can think of, is seeing if there is a way to have something like a server script reload a player's resources on world join? i remember seeing a few threads here asking for something similar

runic thicket
misty obsidian
#

i am now confused. the reload script doesnt fix the issue, but doing /kubejs reload client_scriptsmakes it work?????????

#

when it didnt before?

#

oh ok wait

#

so the reload script seems to fail

#

but doing either the command, or still manually reloading resource packs fixes it?

runic thicket
#

send the client log, the one before reloading.

misty obsidian
#
[22:35:00] [INIT] Loaded plugins:
[22:35:00] [INIT] - dev.latvian.mods.kubejs.forge.BuiltinKubeJSForgePlugin
[22:35:00] [INIT] - dev.latvian.mods.kubejs.forge.BuiltinKubeJSForgeClientPlugin
[22:35:00] [INIT] - dev.ftb.mods.ftbxmodcompat.ftbquests.kubejs.KubeJSIntegration
[22:35:00] [INIT] - dev.ftb.mods.ftbxmodcompat.ftbteams.kubejs.FTBTeamsKubeJSPlugin
[22:35:00] [INIT] - dev.ftb.mods.ftbxmodcompat.ftbfiltersystem.kubejs.FFSKubeJSPlugin
[22:35:00] [INIT] - com.bobvarioa.kubejsarsnouveau.KubeJSArsNouveauPlugin
[22:35:00] [INIT] - dev.latvian.mods.kubejs.create.KubeJSCreatePlugin
[22:35:00] [INIT] - pie.ilikepiefoo.AdditionsPlugin
[22:35:00] [INIT] - pie.ilikepiefoo.compat.jei.JEIKubeJSPlugin
[22:35:00] [INIT] - qinomed.kubejsdelight.KubeJSDelightPlugin
[22:35:00] [INFO] Loaded script client_scripts:jei_hide.js in 0.001 s
[22:35:00] [INFO] Loaded script client_scripts:test.js in 0.007 s
[22:35:00] [INFO] example.js#5: Hello, World! (Loaded client scripts)
[22:35:00] [INFO] Loaded script client_scripts:example.js in 0.001 s
[22:35:00] [INFO] Loaded 3/3 KubeJS client scripts in 0.03 s with 0 errors and 0 warnings
[22:35:06] [INFO] Client resource reload complete!
[22:35:38] [INFO] Client resource reload complete!```
#

this is what it looks like after the script auto reloads

runic thicket
#

Nothing pop out when creating a gate?

misty obsidian
#

nope

runic thicket
#

I don't really know what's happening there, but iirc the Client can also execute command

misty obsidian
#

how would executing that command look?

#

actually, i wonder. How does the schedule in ticks work exactly? i wonder if delaying the resource pack reload might be the solution?

#
    Client.scheduleInTicks(500, Client.reloadResourcePacks())
})``` seeing if this works
#

syntax error

#

fixing that rq

#

trying to find the sweet spot of what i think is fully loading into a world, then shortly after initiating the reload

#

it seems to not be reloading after a set delay???? its always seemingly reloading just as its displaying "loading terrain", even if i set the tick delay to something like 6000

#
    Client.scheduleInTicks(6000, _ => Client.reloadResourcePacks())
})``` seemingly isnt working
#

script runs, but seems to ignore the scheduled tick delay

runic thicket
#

This seems to be beyond my knowledge. You might need to find someone else for help.

misty obsidian
#

well, ill keep this thread open then incase someone comes along that might know the solution

#

imma try some ideas in the mean time. is there any way to change the scheduleInTicks to count seconds instead of ticks? i am curious to see if that might help

#

cause the schedule in ticks is definetly being delayed to some degree, but not the full extent

#

otherwise, only reason i can think of for that specific script not waiting the full duration, is that it forces the script to run when the client is loading the terrain?

#

maybe? im not sure if thats how it works

runic thicket
#

the setTimeout of regular js uses system timer and doesn't rely on schedule. maybe you could try that.

misty obsidian
#

whats the syntax for that?

runic thicket
misty obsidian
#

ight. ill see if this works at all

#

nope. does the exact same thing as tick delay

#

hmmm

#

how would the client go about executing the /kubejs reload client_scripts?

#

thats my only other idea i got

misty obsidian
#

seeing if maybe setting a delay on the server script might work, as thats another idea i just had

#

anything i try to do, it keeps bringing up "undefined" on the first thing i put down

misty obsidian
#

finally managed to figure out how to get it to function on the server script. sadly, its the same result as the client script. trying out other ideas

misty obsidian
#

I SOLVED IT

#
    event.server.scheduleInTicks(20 * 30, _ => event.player.runCommand(`kubejs reload client_scripts`))
})``` this made it work
#

im not sure if this runs the command on that player who just logged in, or if it runs on all players

#

if its all players..... then yeah i would need to fix that. but if its just the one player, then sweet

runic thicket
#

The event.player is only the player related to that event, so it's only the player who just logged in

misty obsidian
#

sweet

runic thicket
#

glad you make it

misty obsidian
#

how would i go about preventing the chat message about the script being reloaded?

runic thicket
#

try runCommandSilent

misty obsidian
#

that worked. it even had the unintended effect of playing the sound effect as soon as the player logs in. not something i was after, but hey, ill take that

#

well, not the silent part of it, but yeah

runic thicket
#

sounds like player spawning also triggers the sound playing? that'd be weird

misty obsidian
#

Actually wait, this would make more sense. Would entities being loaded in on the client be considered spawning?

#

also, i did not end up figuring out how to limit the distance of the gateway

misty obsidian
misty obsidian
#

currently trying to utilize the setTimeout function to more acurately control when the song loops:

            if(entity.alive) soundManager.play(loopingSound)
        }, openingDuration)```

however doing so seems to cause everything else (except for starting the opening track) to break. any ideas?
runic thicket
misty obsidian
#

Just left for work. But that code block was as far as I got. It made the rest of the script outside of starting the track non-functional however

#

The setTineout function in general doesn't seem to play very well with things like event.player and the like

runic thicket
#

well, it's something outside of game schedule so it can break things if not handled properly. I still need to see the actual code to know what's happening there.

misty obsidian
#

Ight. Gimme a sec to see if I can do this on mobile

#

Gaah. I can't. Gimme about..... 6-7ish hours to get home from work

runic thicket
#

Don't worry. You can ping me when you send the script

misty obsidian
#
 *
 * @param {Internal.SoundEvent_} sound
 * @param {Internal.SoundSource_} source
 * @param {number} volume
 * @param {number} pitch
 * @param {boolean} loop
 * @param {number} delay
 * @param {Internal.SoundInstance$Attenuation_} attenuation
 * @param {BlockPos} pos
 * @param {boolean} relative
 * @returns {Internal.SoundInstance}
 */
const createSoundInstance = (sound, source, volume, pitch, loop, delay, attenuation, pos, relative) => {
    const $SimpleSoundInstance = Java.loadClass("net.minecraft.client.resources.sounds.SimpleSoundInstance")
    const soundInstance = new $SimpleSoundInstance(sound, source, volume, pitch, Client.level.random, loop, delay, attenuation, pos.x, pos.y, pos.z, relative)
    return soundInstance
}


const soundsMap = {
    //"gateways:basic/blaze": {
       //opening: "kubejs:song_3_intro", ---Placeholder until i turn this into a custom gate
        //looping: "kubejs:song_3_loop",
        //openingDuration: 1807
    //},
    "gateways:basic/blaze": {
        opening: "kubejs:song_1_intro",
        looping: "kubejs:song_1_loop",
        openingDuration: 128
    },
    "gateways:basic/enderman": {
        opening: "kubejs:song_1_intro",
        looping: "kubejs:song_1_loop",
        openingDuration: 128
    },
    "gateways:basic/slime": {
        opening: "kubejs:song_1_intro",
        looping: "kubejs:song_1_loop",
        openingDuration: 128
    },
    "gateways:emerald_grove": {
        opening: "kubejs:song_1_intro",
        looping: "kubejs:song_1_loop",
        openingDuration: 128
    },
    "gateways:hellish_fortress": {
        opening: "kubejs:song_1_intro",
        looping: "kubejs:song_1_loop",
        openingDuration: 128
    },
    "gateways:overworldian_nights": {
        opening: "kubejs:song_1_intro",
        looping: "kubejs:song_1_loop",
        openingDuration: 128
    },
    "modpack:custom_gate_1": {
        opening: "kubejs:song_2_intro",
        looping: "kubejs:song_2_loop",
        openingDuration: 4554
    },
    "gateways:endless/blaze": {
        opening: "kubejs:song_2_intro",
        looping: "kubejs:song_2_loop",
        openingDuration: 4554
    }
}

const soundInstances = {}
/** @param {Internal.EntitySpawnedEventJS} event */
const loopMusicForEntity = (event) => {
    const {entity, entity:{block:{pos}}} = event
    const gateType = entity.nbt.getString("gate")
    const soundType = soundsMap[gateType]
    if(!soundType) return;
    const {opening, looping, openingDuration} = soundType
    const soundManager = Client.soundManager
    const/**@type {Internal.SoundInstance} */ openingSound = soundInstances["gateStarting"] || createSoundInstance(opening, "master", 2, 1, false, 0, "none", pos, false)
    const/**@type {Internal.SoundInstance} */ loopingSound = soundInstances["gateLooping"] || createSoundInstance(looping, "master", 2, 1, true, 0, "none", pos, false)
    if(!soundInstances["gateLooping"]) {
        soundInstances["gateOpening"] = openingSound
        soundInstances["gateLooping"] = loopingSound
        soundManager.play(openingSound)
        Client.setTimeout(function(){
            if(entity.alive) soundManager.play(loopingSound)
        }, openingDuration)
    }
    const checkArmorStandAlive =
    Client.scheduleRepeatingInTicks(1, _ => {
        if(!entity.alive){
            if(soundManager.isActive(openingSound)) soundManager.stop(openingSound)
                if(soundManager.isActive(loopingSound)) soundManager.stop(loopingSound)
                    checkArmorStandAlive.clear()
                    delete soundInstances["gateOpening"]
                    delete soundInstances["gateLooping"]
                    delete checkArmorStandAlive
        }
    })
}

EntityEvents.spawned("gateways:normal_gateway", event => {
    Client.scheduleInTicks(1, _ => loopMusicForEntity(event))
})
EntityEvents.spawned("gateways:endless_gateway", event => {
    Client.scheduleInTicks(1, _ => loopMusicForEntity(event))
})```
#

@runic thicket

#

just BARELY enough space to fit this into a single message with nitro

#

i only need the function that sets the delay for the song intro to be a setTimeout, since i can specify up to a 1/100th of a millisecond, which is exactly what my audio editing program goes up to

#

and that prevents the very very brief audio cutout, or audio overlap since ticks are 50 milliseconds per tick

runic thicket
misty obsidian
misty obsidian
#

yeah that worked. sweet. i was using the client method since when i was trying to use the setTimeout on the server script, it kept screaming that the function was not defined unless i put that stuff down, so i sorta assumed it would be the same way with client

#

one last thing now, and the script is good as gold. How would i go about setting a max distance limit that can change depending on the gateway, and will keep music going if you leave the boundaries while the portal is still alive/rendered?

runic thicket
#

So you want a lower distance range for the music to start and not touch the distance for the music to stop?

misty obsidian
#

i want to lower the range yes. so people that are like 200ish blocks away wont hear it, but people withing... like 40-50 can

#

but once they get in range, it activates and stays active, since ill presume that people will only approach an active gate that close to engage with it instead of walking away

runic thicket
#

Maybe this

const portalMusicDistanceLimit = 40
EntityEvents.spawned("gateways:normal_gateway", event => {
    const portal = event.entity
    const checkPortalDistance = Client.scheduleRepeatingInTicks(100, _ => {
        if(!portal.alive){
            checkPortalDistance.clear()
            delete checkPortalDistance
            return
        }
        const disctance = Client.player.position().distanceTo(event.entity.position())
        if(disctance > portalMusicDistanceLimit) return;
        else{
            Client.scheduleInTicks(1, _ => loopMusicForEntity(event))
            checkPortalDistance.clear()
            delete checkPortalDistance
            return
        }
    })
})
misty obsidian
#

Just to clarify, where would that go in the script? i replaced the

    Client.scheduleInTicks(1, _ => loopMusicForEntity(event))
})``` with the one you sent and it seemed to break. no errors though
runic thicket
#

Idk. It works fine with vanilla sounds

#

Maybe change the tick interval from 100 to 5?

misty obsidian
#

ok yeah that fixed it. if any more issues crop up, ill re-open the ticket. thanks for the help again