Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extract all JSON structures to their own classes #70

Open
jakubg1 opened this issue Aug 4, 2022 · 5 comments
Open

Extract all JSON structures to their own classes #70

jakubg1 opened this issue Aug 4, 2022 · 5 comments
Labels
A: Documentation Issue with documentation. A: Game Data Issue with game data. D: Organization A change that will not impact the end-user, but may be helpful for simplifying/documenting the code. R: WIP The resolution is in progress.

Comments

@jakubg1
Copy link
Owner

jakubg1 commented Aug 4, 2022

All JSON structures that exist should be given their own classes. This will greatly improve code clarity and will make development easier.

Some insights:

  • All structure-related classes should be in a separate folder.
  • Some JSON files should have not just one class representation, but a few, due to some microstructures being bundled inside.
  • Introduce all needed getters and setters, but also some useful functions. For example, in a collectible generator data class, we could define a function which evaluates it and returns a randomly selected output.
@jakubg1 jakubg1 added D: Organization A change that will not impact the end-user, but may be helpful for simplifying/documenting the code. A: Code labels Aug 4, 2022
@jakubg1
Copy link
Owner Author

jakubg1 commented Aug 10, 2022

We need to consider migrating some classes, too.
Here's a list of the more important resource types used in the engine:

Name Extension Located in Stored as Class name Loaded by Notes
Image *.png /images Class Essentials/Image ResourceManager
Sprite *.json /sprites Class Essentials/Sprite ResourceManager
Sound *.wav/ogg/... /sounds Class Essentials/Sound ResourceManager
Sound Event *.json /sound_events Class Essentials/SoundEvent ResourceManager
Music *.wav/ogg/... /music Class Essentials/Music ResourceManager
Font *.json /fonts Class Essentials/Font ResourceManager
Font File *.ttf /font_files LOVE2D Object (none) Font This is an example of very bad implementation!
Particle *.json /particles Table (none) ResourceManager
Color Palette *.png --- Class Essentials/ColorPalette ResourceManager Stored and loaded in Load List
Sphere *.json /config/spheres Table (none) ConfigManager
Sphere Effect *.json /config/sphere_effects Table (none) ConfigManager
Collectible *.json /config/collectibles Table (none) ConfigManager
Collectible Generator *.json /config/collectible_generators Class CollectibleGenerator/Entry CollectibleGeneratorManager
Color Generator *.json /config/color_generators Table (none) ConfigManager
Level *.json /config/levels Table (none) ConfigManager
Map *.json /maps/<map name>/config.json Table (none) ConfigManager Load list defined by Levels

Some insights I can see from the table:

  • Font files should be given their own resource and class, and be properly loaded by ResourceManager.
  • Collectible Generators should get rid of its manager and be handled like other similar structures.
  • Color Palettes should get their own folder.

Ideally, either:

  • everything should be stored in the ResourceManager, except for files and structures which appear exactly once in the config,
  • or everything what isn't JSON should be stored in the ResourceManager, and everything what is JSON should be stored in ConfigManager.

Also:

  • All resources should be accessed by just name, not the path such as sound_events/button_hover.json -> button_hover. Currently, ConfigManager does that but ResourceManager does not.
    • Rebuild ResourceManager so resources stored inside are keyed by names, not whole file paths.

@jakubg1
Copy link
Owner Author

jakubg1 commented Dec 27, 2022

Additional key benefits by introducing this change:

  • Data can be easily validated in a clean way, without messing with game classes themselves.
  • Data can be also patched over time, prepending or changing certain variables as they change their format over time.

jakubg1 added a commit that referenced this issue Dec 28, 2022
The new `src/Configs` folder includes two classes which serve as an
additional layer between raw data coming from JSON files and the game
elements themselves.

This layer is intended to be a simple yet efficient way to maintain
game compatibility across different versions.

You can read more about it in the following issue:
Extract all JSON structures to their own classes #70
@jakubg1
Copy link
Owner Author

jakubg1 commented Dec 28, 2022

An example involving the shooter data structure has been added in commit 77cf19b.
A few notable observations one can see in my approach:

  • All resource paths/Vector structures are immediately converted to a more useful form.
  • The structure of the original file is preserved.
  • Most of the variable types are rectified using the ---@type tags.
  • There are no getters. It's stupid as it doesn't add any value while adding lots of not-very-useful boilerplate code.
  • There is no data verification, as this would double the JSON schema checks performed by VS Code.
    • However, some checks can exist if for example an illegal type is provided.

@jakubg1 jakubg1 added the R: WIP The resolution is in progress. label Dec 28, 2022
@jakubg1 jakubg1 added this to the Full 1.0 release milestone Dec 28, 2022
@jakubg1 jakubg1 added the ! Beginner Friendly Simple task for first-time contributors. label Dec 28, 2022
@jakubg1 jakubg1 mentioned this issue Jul 9, 2023
10 tasks
@jakubg1
Copy link
Owner Author

jakubg1 commented Nov 6, 2023

API draft for the new Resource Manager:

  • ResourceManager:resolveAssetPath(path, [namespace]): Resolves and outputs the entire asset path starting from the game folder. As per Unify the way resources are referred #103.
    • Example: resolveAssetPath(":flame.spr", "Map1") will return "maps/Map1/sprites/flame.spr".
  • ResourceManager:resolveAssetType(path): Resolves and outputs the resource type of this file, based on its extension.
    • Example: resolveAssetType(":flame.spr") will return "sprite".
  • ResourceManager:getAsset(path, [namespace], [batches]): If the resource has been already loaded earlier, returns this resource. If not, immediately loads it in, optionally as a part of designated batches. (TODO: Decide whether to make variants for different asset types or not. LDoc might have a problem with this.)
  • ResourceManager:loadAsset(path, [namespace], [batches]): If the resource has been already loaded earlier, do nothing. Otherwise, load this asset (not immediately - treat this as queueing the resource to be loaded soon!), optionally as a part of designated batches. If many calls are performed in a quick succession, the load order will be preserved. This function will never return anything.
  • ResourceManager:loadAssetFromServer(path, [namespace], [batches], [cache]): Proposed way of loading resources from the server, for use in Cosmic Crash.
  • ResourceManager:releaseAssetBatch(batch): Removes all mentions of the given batch from all the loaded resources. For any resource, if that was the only batch, unloads it completely.
  • ResourceManager:startLoadCounter(name): Creates a counter which will be counting all resources queued from this point onwards. The total number of resources and the number of resources already loaded will be tracked.
  • ResourceManager:stopLoadCounter(name): Stops counting the resources that are queued. Does not destroy the counter: the counter will be hanging around forever. The number of loaded resources will still rise when they are loaded afterwards.
  • ResourceManager:getLoadProgress(name): Returns the percentage of loaded resources out of queued resources (between the startLoadCounter and stopLoadCounter calls).
    • Example of all three:
    function loadGame()
        resourceManager:startLoadCounter("main")
        resourceManager:loadAsset(...)
        resourceManager:loadAsset(...)
        resourceManager:loadAsset(...)
        ...
        resourceManager:stopLoadCounter("main")
    end
    
    function draw()
        local progress = resourceManager:getLoadProgress("main")
        if progress == 1 then
            drawStartButton()
        else
            drawProgressBar(progress)
        end
    end

Notes:

  • Use getAsset for loading the maps and the splash screen itself, and loadAsset for all game resources which are loaded during the splash screen.

@jakubg1 jakubg1 added A: Game Data Issue with game data. and removed ! Beginner Friendly Simple task for first-time contributors. A: Code labels May 19, 2024
@jakubg1
Copy link
Owner Author

jakubg1 commented May 19, 2024

A few Config Classes have been added which follow the most recent style:

@jakubg1 jakubg1 added the A: Documentation Issue with documentation. label May 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A: Documentation Issue with documentation. A: Game Data Issue with game data. D: Organization A change that will not impact the end-user, but may be helpful for simplifying/documenting the code. R: WIP The resolution is in progress.
Projects
None yet
Development

No branches or pull requests

1 participant