0
\$\begingroup\$

I am currently making a game in HTML5 using canvas, and it is currently just 1 js script and HTML file with references to png files for assets. Right now, I have the level data baked into the script, which works for now, but as I build up the game more and more, I am starting to use more and more lines in the code. Right now, I have ~300 lines of code dedicated to level data, and that's only about 1/50th of the planned size of the game map (It's a REALLY big game). I've considered having txt files with level data stored on the web server, and using the fetch function, but the act of obtaining it has to be asynchronous from the rest of the code, which I might be able to code around, but I don't even know if that's how actual web devs do it.

\$\endgroup\$
2
  • \$\begingroup\$ Store your data as JSON files. Use the fetch API to load and decode the JSON directly into JS objects. It is promise-based (asynchronous) and can easily be integrated into service workers so that you game can run as a web app (off line). The fetch API can load any data not just JSON as long as your server is serving the files the API can load them. \$\endgroup\$
    – Blindman67
    Commented Jun 8, 2023 at 5:56
  • \$\begingroup\$ @Blindman67 Please don't use comments to answer the question. If you would like to answer, please write a real answer. \$\endgroup\$
    – Philipp
    Commented Jun 8, 2023 at 11:55

2 Answers 2

2
\$\begingroup\$

There is no "best" way. Only the way that works best for your game.

But loading data from files via fetch at runtime is certainly not the worst idea. Working with asynchronous calls might seem a bit intimidating at first, but as a JavaScript web application developer there is no way around getting used to that. You are working with asynchronous processes all the time in JavaScript, so promises, callback functions and asnc/await are the daily bread and butter of web development.

This also applies to games, because every image and every sound file gets loaded asynchronously. If you use them before they are loaded, bad stuff can happen. So having a solid strategy for asset loading is important for any JavaScript+HTML game. The simplest solution is usually to have some form of "preloader" that receives a list of assets the game uses, loads them all, waits for their respective onload callback functions to run, and then starts the actual game when they all completed loading.

Regarding the format: JSON is certainly convenient, because you can just turn the string into a JavaScript object via JSON.parse. Some people might inject that the verbosity of the JSON format could lead to long load times. But keep in mind that most webservers will use HTTP-level compression automatically (which you as a JS developer don't even notice), and all the "bloat" of JSON is pretty compressible. But you can of course use any other format as well. If you really want to optimize and take full control over every single byte, then you could use your own file format and parse it via a FileReader.

\$\endgroup\$
1
\$\begingroup\$

Files

The are many ways to move data between the server and client. Modern web APIs provide all the behaviours you may want.

Moving data is the bread and butter of the internet and thus there is a plethora of options open to you.

JSON

Store your data as JSON files. JSON file format is specifically designed to transfer data structures across networks.

Any

However any file can be transferred, the general rule is if it has a Media type AKA MIME type (Multipurpose Internet Mail Extensions), it's a file format that you can use to move data between server and client.

Moving data

Fetch API

Use the fetch API to load and decode the JSON directly into JS objects.

It is promise-based (asynchronous) and can easily be integrated into service workers so that your game can run as a web-app AKA PWA (Progressive Web application (offline)).

The fetch API can load any data not just JSON as long as your server is serving the files the API can load them.

Fetch JSON Example

Very basic example loading JSON data with load animation loop, It's so very easy...

   const myData = {mapData: null};
   fetch("./myData/myJSONFile.json")              // Absolute or relative URI
      .then(data => data.json())                  // Decode data as JSON
      .then(mapData => myData.mapData = mapData)  // Assign data to local object
      .catch(e => console.error(e));              // Handle any and all
                                                  // possible data errors

   loadLoop();           // In load loop wait for data
                         // Show loading animation in this loop
   function loadLoop() {
       if (myData.mapData) { // data has loaded
           RequestAnimationFrame(mainLoop);  // start game
       } else {
           RequestAnimationFrame(loadLoop);  // still loading
       }
   }

Streaming

You can also consider streaming data via the Streams API, Web Sockets API or modern Web Transport API if you have data content that is very large and impractical to wait to load.

At a low level you can use the Web RTC API (Web Real-Time Communication) to move streaming content between client server or even client client data streams.

You may have a huge map, use a stream to fetch map content as needed, rather than have to load and store the whole map client side.

And much more.

Be creative

The web is an evolving entity and as such your imagination on how to use the latest API / technology may well be the next best practice.

After all writing games is all about being creative!

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .