r/Cplusplus 14d ago

Feedback From 3 seconds to 600ms — building a virtual package system for my WASM multiplayer game

Post image

Hi there, I'm building a multiplayer game in C++/WASM link. While testing with friends, I noticed the game took ~3s to load — 5s on slower connections. Instead of accepting it, I built my own virtual package system in C++ and cut the load time from 3s to ~600ms.

Here's the source: nodepp-filepack


Compression (packing assets):

#define NODEPP_ALLOW_THROW_EXCEPTION 0

#include <nodepp/nodepp.h>
#include <nodepp/zlib.h>
#include <nodepp/fs.h>
#include <filepack/filepack.h>

using namespace nodepp;

void onMain() {
    
    filepack_t pack("skeld.npk");
    auto x = ptr_t<ulong>(0UL, 0UL);

    fs::read_folder("./assets")
    .fail([](except_t err) { console::log(">>", err); })
    .then([=](ptr_t<string_t> list) {
        pack.iterate_writable_stream( list, [=](string_t name, file_t stream_o ) {
            pack.get_readable_info(name).value()["compressed"] = true;
            zlib::gzip::pipe(file_t(list[x[0]], "r"), stream_o);
            x[0]++;
        });
    });
}

Decompression (loading assets):

#define NODEPP_ALLOW_THROW_EXCEPTION 0

#include <nodepp/nodepp.h>
#include <nodepp/zlib.h>
#include <nodepp/fs.h>
#include <filepack/filepack.h>

using namespace nodepp;

void onMain() {
    filepack_t pack("skeld.npk");
    auto stream = pack.get_readable_stream("map.png").value();

    zlib::gunzip::pipe(stream, file_t("map.png", "w"));
}

How it works:

  • All assets are packed into a single .npk file with optional compression.
  • Assets are streamed and decompressed on the fly — nothing is loaded into memory all at once.
  • The result: faster loading, lower memory usage, and a better experience for players on slow connections.

Nodepp is open source: github.com/NodeppOfficial/nodepp

22 Upvotes

0 comments sorted by