jakubg1 / OpenSMCE

Game engine which allows creating a broad range of marble popper games.
MIT License
14 stars 11 forks source link

Unify the way resources are referred #103

Closed jakubg1 closed 1 month ago

jakubg1 commented 1 year ago

(Consider this issue to be a part of #70.)

Right now, there's a mess with accessing different resources from different locations, most notably whether the extensions are required or when the path should start. Here's a proposed solution to this problem.

Different extensions for different file types

Right now, the Resource Manager loads different files depending on the folders they are contained in. This is required as different file types (for example, sound events and sprites) share a common extension - json. The idea is to break this conundrum, assigning each file of a particular asset type its own extension. This way, the Resource Manager will be able to sweep through all folders looking for a particular extension, instead of scanning just a single folder for a certain resource type. Instead of forcing all files of a certain type to be in a particular folder, exceptions will be able to be made. This allows contextual and more precise file assortment, wherever needed. For example, in a folder for a map which contains a unique effect which needs a single image file, a single sprite file and a single particle file sorting different asset files would be deemed an overkill for someone, because they could be contained in the root map folder as well. Note that making these examples is optional; you will be able to sort the resources as you wish. Every asset type will have its own folder, like right now. For example, here's how will the <game_name>/images/balls/2.png file be accessed: "balls/2.png" If you wish to put this resource in, for example, sprites folder (that would be quite odd, but I can't stop you!), so the absolute resource path would look like this: <game_name>/sprites/balls/2.png, then the path to that resource will need to start with a @ character: "@sprites/balls/2.png" In order to be obvious which asset type a particular resource path is, the extension will need to be included in the string.

Map folders

The Resource Manager loads all global resources (everything but anything inside the maps folder) and keeps them all the time until the game is closed. Local assets (assets inside the maps folder/subfolders) are on the other hand not governed by the Resource Manager and are loaded by the Map class. The assets are unloaded when the Map instance gets garbage collected (which happens soon after the level ends). The solution is to introduce resource batches. In short, all resources which are loaded through the Resource Manager will be able to have a list of batches that particular resource is a part of. When a resource does not have such list, it will be loaded permanently and will stay in the memory until the game is closed. If a resource that a class tries to get is already loaded, then it will have a batch ID to the batch list added (if it's a part of another resource batch, or in other words it's not permanently loaded) and return that resource without loading it the second time. When the resource batch is no longer needed, just simply close the batch through the Resource Manager. All resources which are a part of that batch will have its batch ID removed. If it turns out that there are no more batches this resource was loaded with, it will be unloaded and removed from the Resource Manager. For example, the Map class will generate a batch ID which will be used for all its resources. Then, it will get (or most likely load) the MapConfig class instance from the Resource Manager, and MapConfig initialization will load all necessary items via this batch (Config Classes will load all assets as a part of the batch it was loaded with by forwarding the batch list parameter). Once the Map is unloaded, it will signal the Resource Manager that it can release the batch which has been used to load the assets. The MapConfig instance will just no longer be used.

Accessing the resources that are part of map folders is done by specifying the folder name (namespace) first followed by : and then the resource path. If you're within the same namespace you want to access a resource from, you can omit the namespace, as shown in the example below. Specifying a map folder will not disable searching inside a specified asset folder, like sprites or particles from within the map folder. To suppress that, place the @ character right after the colon. Examples of accessing different files, from within the /maps/Map1 folder (Map1 namespace):

jakubg1 commented 6 months ago

A problem: Visual Studio Code will refuse to format and give hints for files with extensions other than .json, even when they contain valid JSON data. Two proposed solutions emerge:

jakubg1 commented 6 months ago

Partially implemented in https://github.com/jakubg1/OpenSMCE/commit/ff71f3437097891e973a201f0a93bc8b73a8b145.

TODO:

jakubg1 commented 1 month ago

First two have been implemented in https://github.com/jakubg1/OpenSMCE/commit/270a2f6521865ea5f11ceaa6e7f5253d53abbd3c. The third one is directly correlated with #70, hence I'm closing this as implemented.