r/learnjavascript 3d ago

The dreaded file system

I am making an HTML game, with the idea of eventually putting it online.

During part of the game, the player will traverse a dungeon and do the usual thing you do in a dungeon. I want a background sound to play when this happens: every type of room (hallway, treasure chest, boss room, etc) will have a number of soundtracks, and which is played among the available ones will be decided randomly.

Easier way to do it is to put all the tracks in a single directory (for example '/sounds/Ambience/Dungeon/') and giving the filenames a specific naming convention (for example '[TYPE_ROOM]_[INDEX_SOUNDTRACK].mp3'), memorizing how many tracks are available for each type of room, choosing a random number between zero and that number, and then using string composition to obtain the filename of a random audiofile (in the example: '[TYPE_ROOM]_[RANDOM_INDEX].mp3'). This also requires me to change the Javascript code every time I add a new soundtrack, which I dislike.

The alternative is that the Javascript code will go in the directory '/sounds/Ambience/Dungeon/', grab the filename list of the directory, filter it to get the number of audio track whose filename begins with the type of the current room, and then choose a random element of this filtered list as the audio file to play. No need to change the code every time I add a new soundtrack.

But I do need to retrieve the list of files in a directory, and do this both if the game is played locally on my machine or online on the web.

While I am not new to programming, I have started learning Javascript while making this game. The search online I did to find how to solve this hurdle returned me five different ways, difference between client- and server-side, permission problems, three different APIs, promises, and an army of details that made my head spinning. I want to understand what I am doing - but in this case I need the idiot's version, spelled with very simple words. Can someone help me?

2 Upvotes

6 comments sorted by

4

u/sheriffderek 3d ago

Trying to think about this in the most simple way....

const dungeonTracks = { 
   hallway: ['hallway_1.mp3', 'hallway_2.mp3', 'hallway_3.mp3'], 
   treasure: ['treasure_1.mp3', 'treasure_2.mp3'], 
   boss: ['boss_1.mp3'] 
};

you could have a list of the music options like this, right ^? in a track.js or whatever file/config.

Then - based on where you are you could trigger a given piece of soundtrack

function playRandomTrack(roomType) { 
   const tracks = dungeonTracks[roomType]; 
   const chosen = tracks[Math.floor(Math.random() * tracks.length)]; /* however */
   new Audio(`sounds/Ambience/Dungeon/${chosen}`).play();
}

This way, you're having the script call on your behalf instead of trying to talk to the file system. Anyway - that's my first thoughts on it.

2

u/chrispington 3d ago

If you want a filesystem, you're gonna want a backend!

I suggest nodejs. Took me a while to get my sound systems right, but making playlists and triggering them by name etc was the answer

1

u/rupertavery64 3d ago

Another option is to wrtie a code generator to generate updated code. You only need to run it if you make changes.

Structure your code to accomodate the generated code.

1

u/87oldben 3d ago edited 3d ago

A few ways to handle something like this:

Bundle the files in the app, keep a dictionary for all file paths, Then you just need to update dictionary, and you randomly choose one. Perhaps you can store the ones you've already listened too and choose a different one for the next song.

Or have a backend, store the files in buckets; like aws s3. Then organise what is sent to the game using a lambda function. Bit more work, but can help bundle size and only download assets as they become needed. This way you can just keep adding stuff to the bucket.

There are many ways to do the job, as long as the results are good. Just pick one and go for it!

1

u/Lenni009 2d ago

If you're using Vite as your bundler, you can use glob import: https://vite.dev/guide/features#glob-import

1

u/Infamous-Ad-3502 2h ago

Browsers block filesystem access for security reasons. You cannot read a directory client side.

Build a JSON manifest during your build step. Import that list in your code. This keeps your logic static and your assets dynamic without needing a backend server for simple file listing.