Skip to content

Instantly share code, notes, and snippets.

@roxwize
Last active June 25, 2026 02:30
Show Gist options
  • Select an option

  • Save roxwize/c7c1ef07f83dafdcb6f557073d3351c6 to your computer and use it in GitHub Desktop.

Select an option

Save roxwize/c7c1ef07f83dafdcb6f557073d3351c6 to your computer and use it in GitHub Desktop.

Can I Build Cung/???

The idea

  1. You don't need to build ICU

THAT IS ALL !

For the game to work only the topmost dependencies are necessary. Audio requires building libsndfile, maybe also speexdsp but iam notsure.

Since we are targeting emscripten you need to build every single one of these dependencies yourself. Most of them will take only five minutes tops to build and install. Go ahead and get your working directory ready.

You can build into your working directory, but I like to have a separate directory named /out/ in the root of the directory where the compiled libraries and etc. go, just to separate them from the source code.

The first thing you should do is set some environment variables.

export WORKSPACE=$PWD
export PLATFORM_PREFIX=$WORKSPACE
export PATH="$PATH:$PLATFORM_PREFIX/bin/out" # for icu-config
export CFLAGS="-O2 -g0 -sUSE_SDL=0 -msimd128"
export CXXFLAGS="$CFLAGS"
export CPPFLAGS="-I$PLATFORM_PREFIX/out/include"
export LDFLAGS="-L$PLATFORM_PREFIX/out/lib -sEXPORT_ALL=1"
export EM_CFLAGS="-Wno-warn-absolute-paths"
export EMCC_CFLAGS="$EM_CFLAGS"
export EM_PKG_CONFIG_PATH="$PLATFORM_PREFIX/out/lib/pkgconfig"
export CMAKE_EXTRA_ARGS="-DCMAKE_FIND_ROOT_PATH=$PLATFORM_PREFIX/out"
export C_INCLUDE_PATH="$PLATFORM_PREFIX/out/include"

Patches

Some things need to be patched... YOU DO NEED PERL !!! Although some of these just look like simple sed commands to me.....

# libpng
cd libpng-1.6.58/
perl -pi -e 's#DESTINATION lib/libpng#DESTINATION lib/cmake/libpng#' CMakeLists.txt
patch -Np1 < ../libpng-custom-cc.patch
cd ../

# pixman
cd pixman-0.46.4/
patch -Np2 < ../pixman-wasm.patch
cd ../

# json
cd json-3.12.0/
perl -pi -e 's/CMAKE_INSTALL_DATADIR/CMAKE_INSTALL_LIBDIR/' CMakeLists.txt
cd ../

dependencies

These are all of the dependencies minnaengine needs as far as i'm aware:

zlib 1.3.2
	[https://zlib.net/fossils/zlib-1.3.2.tar.gz]
	<cmake>
	-DZLIB_BUILD_TESTING=OFF -DZLIB_BUILD_SHARED=OFF -DZLIB_BUILD_STATIC=ON
libpng 1.6.58
	[https://download.sourceforge.net/libpng/libpng-1.6.58.tar.xz]
	<cmake>
	-DPNG_SHARED=OFF -DPNG_TOOLS=OFF -DPNG_TESTS=OFF
pixman 0.46.4
	[https://cairographics.org/releases/pixman-0.46.4.tar.gz]
	<meson>
	tests=disabled
	demos=disabled
	libpng=disabled
	-Dsse2=enabled
fmt 12.1.0
	[https://github.com/fmtlib/fmt/releases/download/12.1.0/fmt-12.1.0.zip]
	<cmake>
	FMT_DOC=OFF
	FMT_TEST=OFF
nlohmann_json 3.12.0
	[https://github.com/nlohmann/json/archive/v3.12.0.tar.gz]
	<cmake>
	JSON_BuildTests=OFF
SDL3 3.4.4
	[https://libsdl.org/release/SDL3-3.4.4.tar.gz]
	<cmake>
	SDL_TEST_LIBRARY=OFF
	SDL_EXAMPLES=OFF
inih 62
	[https://github.com/benhoyt/inih/archive/refs/tags/r62.tar.gz]
	<meson>
liblcf
	<cmake>
	(requires inih & expat)
	-DLIBLCF_UPDATE_MIMEDB=OFF -DLIBLCF_ENABLE_TOOLS=OFF -DLIBLCF_ENABLE_TESTS=OFF
	# optional:
	-DLIBLCF_WITH_ICU=OFF
expat 2.7.5
	[https://github.com/libexpat/libexpat/releases/download/R_2_7_5/expat-2.7.5.tar.bz2]
	<cmake>
	-DEXPAT_BUILD_TOOLS=OFF -DEXPAT_BUILD_EXAMPLES=OFF -DEXPAT_BUILD_TESTS=OFF -DEXPAT_BUILD_DOCS=OFF -DEXPAT_SHARED_LIBS=OFF
icu 78.3
	[https://github.com/unicode-org/icu/releases/download/release-78.3/icu4c-78.3-sources.tgz]
	--enable-strict=no
	--disable-tests
	--disable-samples
	--disable-dyload
	--disable-extras
	--disable-icuio
	--with-data-packaging=static
	--disable-layout
	--disable-layoutex
	--enable-draft=no
icudata
	[https://ci.easyrpg.org/job/icudata/lastSuccessfulBuild/artifact/icudata78_all.tar.gz]

##################
# maybe optional #
##################

freetype 2.14.3
	[https://download.savannah.gnu.org/releases/freetype/freetype-2.14.3.tar.xz]
	<cmake>
	FT_DISABLE_BZIP2=ON
	FT_DISABLE_BROTLI=ON
harfbuzz 14.1.0
	[https://github.com/harfbuzz/harfbuzz/releases/download/14.1.0/harfbuzz-14.1.0.tar.xz]
	<meson>
	freetype=enabled
	icu=disabled
	tests=disabled
	utilities=disabled
	raster=disabled
	vector=disabled
	subset=disabled
speexdsp 1.2.1
	[https://downloads.xiph.org/releases/speex/speexdsp-1.2.1.tar.gz]
	<generic>
	--disable-sse --disable-neon
lhasa 0.5.0
	[https://github.com/fragglet/lhasa/releases/download/v0.5.0/lhasa-0.5.0.tar.gz]

#######################
# apparently optional #
#######################

mpg123 1.33.4
	[https://www.mpg123.de/download/mpg123-1.33.4.tar.bz2]
	--with-cpu=generic
	--disable-fifo
	--disable-ipv6
	--disable-network
	--disable-int-quality
	--with-default-audio=dummy
	--with-optimization=2
	--disable-components
	--enable-libmpg123
libsndfile 1.2.2
	[https://github.com/libsndfile/libsndfile/releases/download/1.2.2/libsndfile-1.2.2.tar.xz]
	<cmake>
	-DBUILD_REGTEST=OFF
	-DBUILD_SHARED_LIBS=OFF
	-DBUILD_TESTING=OFF
	-DENABLE_EXTERNAL_LIBS=OFF
	-DENABLE_MPEG=OFF
	-DINSTALL_MANPAGES=OFF
	--disable-alsa
	--disable-sqlite
	--disable-full-suite
	--disable-external-libs
	--disable-mpeg
FluidSynth 2.5.3
	[https://github.com/FluidSynth/fluidsynth/archive/refs/tags/v2.5.3.tar.gz]
	LIB_SUFFIX=''
	enable-alsa=OFF
	enable-aufile=OFF
	enable-dbus=OFF
	enable-ipv6=OFF
	enable-jack=OFF
	enable-ladspa=OFF
	enable-libinstpatch=OFF
	enable-libsndfile=OFF
	enable-midishare=OFF
	enable-network=OFF
	enable-oss=OFF
	enable-dsound=OFF
	enable-wasapi=OFF
	enable-waveout=OFF
	enable-winmidi=OFF
	enable-sdl3=OFF
	enable-pulseaudio=OFF
	enable-pipewire=OFF
	enable-readline=OFF
	enable-threads=OFF
	enable-openmp=OFF
	enable-unicode=OFF
	enable-native-dls=OFF
libogg 1.3.6
	[https://downloads.xiph.org/releases/ogg/libogg-1.3.6.tar.xz]
libvorbis 1.3.7
	[https://downloads.xiph.org/releases/vorbis/libvorbis-1.3.7.tar.xz]
opus 1.6.1
	[https://downloads.xiph.org/releases/opus/opus-1.6.1.tar.gz]
	OPUS_DISABLE_INTRINSICS=ON
opusfile 0.12
	[https://github.com/xiph/opusfile/releases/download/v0.12/opusfile-0.12.tar.gz]
	--disable-http
	--disable-examples
libxmp-lite 4.7.0
	[https://github.com/libxmp/libxmp/releases/download/libxmp-4.7.0/libxmp-lite-4.7.0.tar.gz]
	BUILD_STATIC=ON
	BUILD_SHARED=OFF

CMake presets

You need to provide these to minnaengine when configuring it with CMake; although some of these can be modified or completely omitted at certain stages, like e.g. you will probably want to change PLAYER_WITH_LIBSNDFILE to ON if you have libsndfile compiled for emscripten.

[yno-simd-release]
	[emscripten-release]
		[emscripten-parent]
			PLAYER_PREFIX_PATH_APPEND=$env{EASYRPG_BUILDSCRIPTS}/emscripten
			PLAYER_FIND_ROOT_PATH_APPEND=ON
			PLAYER_JS_BUILD_SHELL=ON
		[type-release]
			CMAKE_BUILD_TYPE=Release
	[yno-simd-parent]
		[yno-parent]
			CMAKE_FIND_ROOT_PATH_MODE_LIBRARY=BOTH
			CMAKE_FIND_ROOT_PATH_MODE_INCLUDE=BOTH
			CMAKE_FIND_ROOT_PATH_MODE_PACKAGE=BOTH
			CMAKE_CXX_COMPILER_LAUNCHER=ccache
			CMAKE_PREFIX_PATH=$env{EASYRPG_BUILDSCRIPTS}/emscripten
			PLAYER_ENABLE_FMMIDI=OFF
			PLAYER_WITH_MPG123=OFF
			PLAYER_WITH_LIBSNDFILE=OFF
			PLAYER_WITH_OGGVORBIS=OFF
			PLAYER_WITH_WILDMIDI=OFF
			PLAYER_WITH_FLUIDLITE=OFF
			PLAYER_WITH_XMP=OFF
			PLAYER_ENABLE_DRWAV=OFF
			PLAYER_JS_GAME_URL=/data/
			CMAKE_EXPORT_COMPILE_COMMANDS=ON
		PLAYER_JS_OUTPUT_NAME=minnaengine-simd
		CMAKE_CXX_FLAGS=-msimd128

Below is the full configure command with all of the above defaults...

emcmake cmake . -Bbuild -DCMAKE_BUILD_TYPE=Release -DPLAYER_JS_BUILD_SHELL=ON -DPLAYER_FIND_ROOT_PATH_APPEND=ON \
	-DPLAYER_PREFIX_PATH_APPEND=$PLATFORM_PREFIX/out -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=BOTH \
	-DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=BOTH -DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=BOTH -DCMAKE_CXX_COMPILER_LAUNCHER=emcc \
	-DCMAKE_PREFIX_PATH=$PLATFORM_PREFIX/out -DPLAYER_ENABLE_FMMIDI=OFF -DPLAYER_WITH_MPG123=OFF -DPLAYER_WITH_LIBSNDFILE=OFF \
	-DPLAYER_WITH_OGGVORBIS=OFF -DPLAYER_WITH_WILDMIDI=OFF -DPLAYER_WITH_FLUIDLITE=OFF -DPLAYER_WITH_XMP=OFF \
	-DPLAYER_ENABLE_DRWAV=OFF -DPLAYER_JS_GAME_URL=/data/ -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
	-DPLAYER_JS_OUTPUT_NAME=minnaengine-simd -DCMAKE_CXX_FLAGS=-msimd128 -DCMAKE_C_FLAGS="$CFLAGS $CPPFLAGS" \
	-DCMAKE_CXX_FLAGS="$CXXFLAGS $CPPFLAGS" \
	-DPLAYER_TARGET_PLATFORM=SDL3

meson-cross.txt

Meson needs this file to cross-compile.

https://mesonbuild.com/Cross-compilation.html

[binaries]
c = ['emcc']
cpp = ['emcc']
ar = 'ar'
strip = 'emstrip'
pkg-config = 'pkg-config'

[built-in options]
c_args = ['-I/tmp/build-engine/src/out/include',
	'-O2',
	'-g0',
	'-sUSE_SDL=0',
	'-msimd128']
c_link_args = ['-L/tmp/build-engine/src/out/lib',
	'-sEXPORT_ALL=1']
cpp_args = ['-I/tmp/build-engine/src/out/include',
	'-O2',
	'-g0',
	'-sUSE_SDL=0',
	'-msimd128']
cpp_link_args = ['-L/tmp/build-engine/src/out/lib',
	'-sEXPORT_ALL=1']

[host_machine]
system = 'emscripten'
cpu_family = 'wasm32'
cpu = 'wasm32'
endian = 'little'

Building all dependencies

Each dependency uses either CMake, Meson, or the generic ./configure.

Generic CMake build

emcmake cmake . -Bbuild -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBUILD_SHARED_LIBS=OFF \
	-DCMAKE_C_FLAGS="$CFLAGS $CPPFLAGS" -DCMAKE_CXX_FLAGS="$CXXFLAGS $CPPFLAGS" \
	-DCMAKE_INSTALL_LIBDIR=lib $CMAKE_AR $CMAKE_NM $CMAKE_RANLIB $CMAKE_CCACHE \
	-DCMAKE_INSTALL_PREFIX=$PLATFORM_PREFIX/out -DCMAKE_SYSTEM_NAME=$CMAKE_SYSTEM_NAME \
	-DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
	-DCMAKE_PREFIX_PATH=$PLATFORM_PREFIX $CMAKE_EXTRA_ARGS
cmake --build build --target clean
cmake --build build
cmake --build build --target install

Generic Meson build

emconfigure meson setup build --prefix $PLATFORM_PREFIX/out --buildtype=plain \
	-Ddefault_library=static --libdir=lib --cross-file $PLATFORM_PREFIX/meson-cross.txt
meson compile -C build
meson install -C build

Generic GNU Make build

emconfigure ./configure --prefix=$PLATFORM_PREFIX --disable-shared --enable-static \
	--disable-dependency-tracking --enable-silent-rules \
	--host=$TARGET_HOST --cache-file="$PLATFORM_PREFIX/config.cache"
make clean
make
make install

Building ICU

icu-fix-data.patch

curl -O "https://github.com/unicode-org/icu/releases/download/release-78.3/icu4c-78.3-sources.tgz"
tar -xzf icu4c-78.3-sources.tgz && rm icu4c-78.3-sources.tgz
cd icu/

curl -O "https://ci.easyrpg.org/job/icudata/lastSuccessfulBuild/artifact/icudata78_all.tar.gz"
mkdir icudata/
mv icudata78_all.tar.gz icudata/
cd icudata/
tar -xzf icudata78_all.tar.gz
rm icudata_78_all.tar.gz
cp icudt*.dat ../icu/source/data/in/

cd ../icu/source/
chmod +x configure
cp config/mh-linux config/mh-unknown
perl -pi -e 's/SMALL_BUFFER_MAX_SIZE 512/SMALL_BUFFER_MAX_SIZE 2048/' tools/toolutil/pkg_genc.h
# Disable icu components not required for encoding
perl -pi -e 's/LIBCPPFLAGS =/LIBCPPFLAGS = -DUCONFIG_ONLY_COLLATION/' config/mh-unknown
# emscripten patch
cd ../
patch -Np2 < ../icu-fix-data.patch

# install_lib_icu_native
mkdir icu-native/
cd icu-native/
../icu/source/configure --enable-static --disable-shared --enable-strict=no \
	--disable-tests --disable-samples --disable-dyload --disable-extras \
	--disable-icuio --with-data-packaging=static --disable-layout --disable-layoutex \
	--enable-draft=no
make clean
make
cd ../

# install_lib_icu_cross
mkdir icu-cross
cd icu-cross/
emconfigure ../icu/source/configure \
	--enable-static --disable-shared --prefix=$PLATFORM_PREFIX/out \
	--host=$TARGET_HOST --with-cross-build=$PLATFORM_PREFIX/icu-native \
	--disable-tools $ICU_ARGS
make clean
make
make install
cd ../

YOU DID IT!!!

Setup and deployment instructions can be found at https://easyrpg.org/player/guide/webplayer/

Make the following adjustments

- FS.mount(Module.saveFs, {}, 'Save');
+ FS.mount(IDBFS, {}, 'Save');`
<!DOCTYPE html>
<html>
	<head>
		<script src="ynoengine-simd.js"></script>
		<style>
			body {
				align-items: center;
				background-color: #000;
				display: flex;
				height: 100vh;
				justify-content: center;
				margin: 0;
				width: 100vw;
			}
			canvas {
				aspect-ratio: 4 / 3;
				height: 480px;
				image-rendering: pixelated;
				width: 640px;
			}
		</style>
	</head>
	<body>
		<canvas id="canvas"></canvas>
		<script>
			const stub = (name) => {
				return (a) => { console.log(`stub ${name}`, a) };
			};
			const onRequestFile = stub("onRequestFile");
			const onUpdateSystemGraphic = stub("onUpdateSystemGraphic");
			const onUpdateConnectionStatus = stub("onUpdateConnectionStatus");

			window.addEventListener("load", (ev) => {
				createEasyRpgPlayer().then((module) => {
					console.log(module);
				});
			})
		</script>
	</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment