Wow, you did a great job there Floh I guess !

I definitively agree with your approach/ideas, having the granularity at the rigid asset bundle level or at the single file level would not be good enough on huge game use cases.

About the "block-filesystem" I was thinking about something inspired by modern filesystems: for example 128KB compressed blocks like in ZFS.

Along with some background asset prefetching system, that would try to dynamically guess what are the best assets to fetch (during gameplay), based on: what are the next/previous levels/areas, what the last recent autotsaves are pointing to, and on automated analysis of asset dependencies.

I did not thought about the content update issue, this is certainly something to take into consideration too.

The only catch with all of this is that legacy games (= not developed for the Web in mind) are designed around the fact filesystem IO operations are synchronous. It's been like this since 25+ years now... Using a HTTP backend would make it asynchronous. There is big design changes required ahead :/

@Sylvain, the XHR-backed FS is really interesting, but as you mention, it needs to be run in a web worker. So this is moving the "sync/async" issue elsewhere (not between game client and server, but between game main thread and worker)

Le 11/03/2019 à 01:14, Floh a écrit :
What I've done in an F2P game (not a web game, but native PC) is to not use asset bundles, but load each asset file (which are usually somewhere between a few kbytes to dozens of kbytes big) through an HTTP request, with a hierarchical content-hash-based local caching. Basically a read-only content-addressable filesystem working through standard HTTP servers.

We assumed the average player has a 2 MBit/sec connection, and wanted no more than 20 second waiting time between map changes to download critical data needed to start the map, and then continue to stream data as needed while a map was running (this may have the effect that 3D models "plop in" though, but its the same idea as loading a web page).

This works quite well, but could be improved. For instance very small files had a lot of overhead for the HTTP request/response headers, and on the local machine, the cache was made of thousands of small files, which is quite slow on Windows filesystems.

One thing I had in mind to improve this is to turn this into a "block-filesystem". Instead of downloading individual files, merge all files into a single big blob, made of many small (16..64 KBytes?) blocks, and do the whole content-hash-addressing on blocks instead of files. So for a new game session you would start with a "filesystem-file" which is made of empty, invalid blocks, and while the game is running, those blocks get downloaded and "validated" as needed.

One problem with this approach is content updates (when new versions of the game are released, which happens every 2..3 weeks or so). Some of the data gets updated, files are added, or existing files can change, not only the content but also the size. Handling this naively would introduce problems like fragmentation in the cache file... but one could separate "cold data" which hardly changes from "hot data" which very likely changes between updates, and handle those differently (or a new file starts in the "hot data" set, but slowly moves to the "cold data" set)...

All in all I think this approach is better than both granular "single-file downloads" on one extreme, and rigid asset-bundles on the other extreme.

It's basically like one big asset bundle that's downloaded / updated in small pieces as needed.

Cheers,
-Floh.

On Sunday, 10 March 2019 23:13:04 UTC+1, Gabriel CV wrote:

    A technical point of view:

    Games are based since years on the concept of big "Asset Bundles",
    be it .pak/.zip/.bundle/whatever files. So a first option is to
    try to bundle things in a smarter way, that could help improve
    things a bit.

    But in the end, this concept of "Asset Bundle" is probably not the
    way to go for the web.

    The issue with this is that such Bundles are static, and lack
    granularity required by the Web limitations. They are just big
    blobs of data, generally assembled manually by packager/developers
    based on empirical observations and other convenience factors.
    Most of the time you'll have some "common" asset bundles, "map
    specific" asset bundles, etc. And quickly, due to the way games
    are being developed, there is corner cases: a texture is needed,
    but it come from a bundle for which 99% of the content is
    unrelated to the current map/level/whatever. Sometime assets are
    duplicated because of this.

    While on Desktop/Mobile this OK, on the Web this is a killer issue
    due to limited bandwitdth and lack of real Filesystem storage.
    Now, you REALLY want to have only what is necessary at any given
    time, regardless of the empirical packaging work.

    I can see two way to achieve this:

    - Either you have a "Dynamic Asset Bundler" system implemented on
    the server. Basically, there is server code that is able to build
    dependency graphs of all assets. Bundling is no more a
    manual/empirical thing, but follows a precise and formal
    algorithm. So, when the game asks the server that it want some
    asset, the server is automatically replying with the full list of
    dependent assets needed. The game then send a list of assets it
    already have locally, and finally, using both those lists (what is
    needed, and what is already there), the server is building a
    specific bundle for that specific request. Bundles are created
    dynamically and client-dependent, and no more static and
    developer/packager dependent. This is a very different philosophy.

    - Either you have a "Individual Asset Cache" system implemented
    locally. In this case, the game don't cares at all about bundling.
    When the game want an asset, he look for it in a local cache that
    is quite limited in size (either in memory fs, or in Indexed db, I
    don't know). If if it is not in the cache, the game fetch it from
    the server and put it into the cache. If the cache is full, the
    oldest stuff is being removed. And so on, for each individual
    assets and dependencies that might be needed. The major issue with
    this is that such server queries are asynchronous on the web, and
    existing games are used to have synchronous IO operations since
    the dawn of video games. So there is some major design changes
    needed to achieve this.

    So in both cases... there is non trivial work needed to allow
    multi-GB AAA games on the web. That's not impossible though I
    think, it just require some serious design.... and maybe axing a
    bit the texture sizes ;)

    Le dimanche 10 mars 2019 07:51:30 UTC+1,
    [email protected] a écrit :

        Just curious if it's currently too early to deploy
        console-quality PC games to the web using wasm? Seems like
        multithreading and wasm-64 will bring about the biggest
        improvements in this regard.



    Le dimanche 10 mars 2019 13:23:02 UTC+1, Floh a écrit :

        PS: one big problem with streaming assets during gameplay are
        wonky mobile connections of course. The whole idea only works
        if the internet connection doesn't drop every few minutes.

        On Sunday, 10 March 2019 13:17:00 UTC+1, Floh wrote:

            IMHO the most important problem (before all the others) is
            how do you get all that data into your game. Current
            PC/console games are usually downloaded and installed
            upfront before you can start playing. This is a problem
            for web platforms, you don't want to let the player wait
            for half an hour or longer before he can start playing,
            and the browser doesn't allow to store many gigabytes as
            persistent storage anyway.

            Unfortunately most games engines are built around the idea
            that asset data is downloaded is big blobs, and stored in
            a persistent location (of the big ones, Unity may be the
            best fit because it has a long history on the web).

            I've been implementing on-demand-streaming of asset data
            in the past a couple of times.

            It works quite well *if the whole ending *and* all games
            built with this engine are designed around the idea of
            on-demand-data-streaming. The core problem basically moves
            from "how much data do we need for the next level/region"
            to "how much *new* data can we stream per second" (and
            thus present to the user). Download bandwidth dictates
            everything you can do in the game, but if your game is
            built around the idea that you can only present as much
            new (uncached) data to the user as bandwidth allows, the
            overall asset size of the game can be basically infinite.

            Another advantage is that player don't need to download
            data they will never see. Most players only ever see 10%
            of a game until they move on to another game. Why download
            100% of the data upfront if only 10% are needed?

            TL;DR: design your game engine's asset loading strategy
            the same way Google Earth does it.

            The other problems are less of technical nature I think,
            but marketing and monetization. How do you sell an AAA
            game on the web? How do you advertize it? Do you need
            copy-protection? If yes, how would this be implemented?

            That's why I think the open web also needs a new type of
            game, typical console-AAA games are not a good both for
            technical and non-technical reasons. Some variant of the
            current F2P client/server model (give away the client for
            free and control the server), basically "up-ported" mobile
            games, not "down-ported AAA games".

            Cheers,
            -Floh.

            On Sunday, 10 March 2019 07:51:30 UTC+1,
            [email protected] wrote:

                Just curious if it's currently too early to deploy
                console-quality PC games to the web using wasm? Seems
                like multithreading and wasm-64 will bring about the
                biggest improvements in this regard.

--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected] <mailto:[email protected]>.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups 
"emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to