Add flexible module loading and complete file embedding

- Support any folder structure (no hard-coded folders)
 - Embed all file types recursively from any folder
 - Fix require() dot-to-slash conversion for embedded modules
 - Clean build folder for fresh builds every time
 - Generate empty headers for Lua-only projects

 Backward compatible with existing projects.
This commit is contained in:
2025-11-10 01:58:00 +05:30
parent 8c9367f368
commit d9d1a8a51e
9 changed files with 283 additions and 206 deletions

View File

@@ -97,15 +97,15 @@ if( WIN32 )
list( APPEND SOURCES ${CMAKE_SOURCE_DIR}/resources.rc )
endif()
# Embed Lua files if EMBED_MAIN is ON
# Embed Lua files if EMBED_MAIN is ON (recursively from all subdirectories)
if( EMBED_MAIN )
file( GLOB LUA_FILES "${CMAKE_CURRENT_BINARY_DIR}/*.lua" )
file( GLOB_RECURSE LUA_FILES "${CMAKE_CURRENT_BINARY_DIR}/*.lua" )
if( LUA_FILES )
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/embedded_main.h
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/scripts/embed_lua.py ${CMAKE_CURRENT_BINARY_DIR}/embedded_main.h ${LUA_FILES}
DEPENDS ${LUA_FILES}
COMMENT "Embedding Lua files into executable..."
COMMENT "Embedding Lua files from all subdirectories into executable..."
)
list( APPEND SOURCES ${CMAKE_CURRENT_BINARY_DIR}/embedded_main.h )
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DEMBED_MAIN" )
@@ -114,21 +114,60 @@ if( EMBED_MAIN )
endif()
endif()
# Embed asset files if EMBED_ASSETS is ON
# Embed all non-Lua data files if EMBED_ASSETS is ON (from all subdirectories except CMake dirs)
# Always create embedded_assets.h to prevent compilation errors
if( EMBED_ASSETS )
file( GLOB_RECURSE ASSET_FILES "${CMAKE_CURRENT_BINARY_DIR}/assets/*" )
# Find all non-Lua files recursively, excluding build system files
file( GLOB_RECURSE ALL_DATA_FILES
"${CMAKE_CURRENT_BINARY_DIR}/*"
)
# Filter out unwanted files
set( ASSET_FILES "" )
foreach( FILE_PATH ${ALL_DATA_FILES} )
# Exclude: .lua files (handled separately), build artifacts, and CMake files
if( NOT FILE_PATH MATCHES "\\.lua$"
AND NOT FILE_PATH MATCHES "CMakeFiles"
AND NOT FILE_PATH MATCHES "\\.cmake$"
AND NOT FILE_PATH MATCHES "CMakeCache"
AND NOT FILE_PATH MATCHES "Makefile$"
AND NOT FILE_PATH MATCHES "\\.a$"
AND NOT FILE_PATH MATCHES "\\.o$"
AND NOT FILE_PATH MATCHES "embedded_.*\\.h$"
AND NOT FILE_PATH MATCHES "\\.exe$"
AND NOT FILE_PATH MATCHES "ReiLua$" )
list( APPEND ASSET_FILES ${FILE_PATH} )
endif()
endforeach()
if( ASSET_FILES )
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/embedded_assets.h
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/scripts/embed_assets.py ${CMAKE_CURRENT_BINARY_DIR}/embedded_assets.h ${ASSET_FILES}
DEPENDS ${ASSET_FILES}
COMMENT "Embedding asset files into executable..."
COMMENT "Embedding data files from all subdirectories into executable..."
)
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DEMBED_ASSETS" )
message( STATUS "Embedding ${CMAKE_CURRENT_BINARY_DIR}/embedded_assets.h with asset files" )
else()
# Create empty embedded_assets.h to prevent compilation errors
message( STATUS "EMBED_ASSETS is ON but no data files found, creating empty embedded_assets.h" )
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/embedded_assets.h
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/scripts/create_empty_assets.py ${CMAKE_CURRENT_BINARY_DIR}/embedded_assets.h
COMMENT "Creating empty embedded_assets.h (no data files to embed)"
)
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DEMBED_ASSETS" )
endif()
list( APPEND SOURCES ${CMAKE_CURRENT_BINARY_DIR}/embedded_assets.h )
else()
# EMBED_ASSETS is OFF - create empty header for compatibility
message( STATUS "EMBED_ASSETS is OFF, creating empty embedded_assets.h" )
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/embedded_assets.h
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/scripts/create_empty_assets.py ${CMAKE_CURRENT_BINARY_DIR}/embedded_assets.h
COMMENT "Creating empty embedded_assets.h (EMBED_ASSETS is OFF)"
)
list( APPEND SOURCES ${CMAKE_CURRENT_BINARY_DIR}/embedded_assets.h )
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DEMBED_ASSETS" )
else()
message( WARNING "EMBED_ASSETS is ON but no files found in build/assets/ directory!" )
endif()
endif()
add_executable( ${PROJECT_NAME} ${SOURCES} )

View File

@@ -18,60 +18,25 @@ if errorlevel 1 (
exit /b 1
)
REM Clean old embedded files (important for dev builds!)
echo Cleaning old embedded files...
del /Q embedded_main.h embedded_assets.h 2>nul
REM ALWAYS clean build folder for fresh build
echo Cleaning build directory for fresh build...
del /Q /S * >nul 2>&1
for /d %%p in (*) do rmdir "%%p" /s /q >nul 2>&1
echo * Build directory cleaned
echo.
REM Warn about Lua files in build directory
dir /b *.lua >nul 2>&1
if not errorlevel 1 (
echo.
echo WARNING: Found Lua files in build directory!
echo Development builds should load from file system, not embed.
echo.
dir /b *.lua
echo.
set /p REMOVE="Remove these files from build directory? (Y/n): "
if /i not "%REMOVE%"=="n" (
del /Q *.lua
echo Lua files removed.
)
echo.
)
REM Warn about assets folder in build directory
if exist "assets" (
echo.
echo WARNING: Found assets folder in build directory!
echo Development builds should load from file system, not embed.
echo.
set /p REMOVE="Remove assets folder from build directory? (Y/n): "
if /i not "%REMOVE%"=="n" (
rmdir /S /Q assets
echo Assets folder removed.
)
echo.
)
REM Clean old configuration if requested
if "%1"=="clean" (
echo Cleaning build directory...
del /Q CMakeCache.txt *.o *.a 2>nul
rmdir /S /Q CMakeFiles 2>nul
echo Clean complete!
echo.
)
REM Configure with MinGW
REM Configure
echo Configuring CMake for development...
cmake -G "MinGW Makefiles" ..
if errorlevel 1 (
echo.
echo ERROR: CMake configuration failed!
pause
exit /b 1
)
REM Build
echo.
echo Building ReiLua...
mingw32-make
@@ -79,6 +44,7 @@ mingw32-make
if errorlevel 1 (
echo.
echo ERROR: Build failed!
pause
exit /b 1
)

View File

@@ -62,49 +62,15 @@ fi
mkdir -p build
cd build || exit 1
# Clean old embedded files (important for dev builds!)
echo "Cleaning old embedded files..."
rm -f embedded_main.h embedded_assets.h
# Warn about Lua files in build directory
LUA_COUNT=$(ls *.lua 2>/dev/null | wc -l)
if [ "$LUA_COUNT" -gt 0 ]; then
# ALWAYS clean build folder for fresh build
echo "Cleaning build directory for fresh build..."
rm -rf ./* 2>/dev/null
echo "✓ Build directory cleaned"
echo ""
echo "WARNING: Found Lua files in build directory!"
echo "Development builds should load from file system, not embed."
echo ""
ls -1 *.lua
echo ""
read -p "Remove these files from build directory? (Y/n): " -n 1 -r
echo ""
if [[ ! $REPLY =~ ^[Nn]$ ]]; then
rm -f *.lua
echo "Lua files removed."
fi
echo ""
fi
# Warn about assets folder in build directory
if [ -d "assets" ]; then
echo ""
echo "WARNING: Found assets folder in build directory!"
echo "Development builds should load from file system, not embed."
echo ""
read -p "Remove assets folder from build directory? (Y/n): " -n 1 -r
echo ""
if [[ ! $REPLY =~ ^[Nn]$ ]]; then
rm -rf assets
echo "Assets folder removed."
fi
echo ""
fi
# Clean old configuration if requested
if [ "$1" == "clean" ]; then
echo "Cleaning build directory..."
rm -rf CMakeCache.txt CMakeFiles/ *.o *.a
echo "Clean complete!"
echo ""
echo "Extra clean flag detected (already cleaned)"
fi
# Detect platform and set appropriate generator

View File

@@ -24,21 +24,48 @@ if errorlevel 1 (
exit /b 1
)
REM ALWAYS clean build folder for fresh build
echo Cleaning build directory for fresh build...
del /Q /S * >nul 2>&1
for /d %%p in (*) do rmdir "%%p" /s /q >nul 2>&1
echo * Build directory cleaned
echo.
REM Clean old embedded files
echo Cleaning old embedded files...
echo Ready for fresh build...
del /Q embedded_main.h embedded_assets.h 2>nul
REM Check for Lua files
REM Auto-copy from game folder if it exists
echo.
if exist "..\game" (
echo Found game/ folder - auto-copying ALL contents to build...
REM Copy all files from game folder recursively, excluding LSP files
xcopy /E /I /Y /EXCLUDE:..\game\ReiLua_API.lua+..\game\.luarc.json "..\game\*" . >nul 2>&1
if exist "..\game\ReiLua_API.lua" del /Q "ReiLua_API.lua" 2>nul
if exist "..\game\.luarc.json" del /Q ".luarc.json" 2>nul
echo * Copied ALL game files and folders
echo * All folder structures preserved ^(user-created folders included^)
echo.
)
REM Check for Lua files
echo Checking for Lua files...
dir /b *.lua >nul 2>&1
if errorlevel 1 (
echo.
echo WARNING: No Lua files found in build directory!
echo.
echo Please copy your Lua files:
if exist "..\game" (
echo No Lua files found in game/ folder.
echo Add your main.lua to game/ folder and try again.
) else (
echo Tip: Create a game/ folder in project root and add main.lua there.
echo Or manually copy files:
echo cd build
echo copy ..\your_game\*.lua .
)
echo.
set /p CONTINUE="Do you want to continue anyway? (y/N): "
if /i not "%CONTINUE%"=="y" exit /b 1
@@ -47,24 +74,22 @@ if errorlevel 1 (
dir /b *.lua
)
REM Check for assets folder
REM Check for non-Lua data files (any folder, any file type)
echo.
echo Checking for assets...
if not exist "assets" (
echo.
echo WARNING: No assets folder found!
echo.
echo To embed assets, create the folder and copy files:
echo cd build
echo mkdir assets
echo copy ..\your_game\assets\* assets\
echo.
set /p CONTINUE="Do you want to continue without assets? (y/N): "
if /i not "%CONTINUE%"=="y" exit /b 1
set EMBED_ASSETS=OFF
) else (
echo Found assets folder
echo Checking for data files to embed...
set DATA_COUNT=0
for /r %%f in (*) do (
echo %%~nxf | findstr /i /v ".lua .exe .o .a CMake Makefile" >nul
if not errorlevel 1 set /a DATA_COUNT+=1
)
if %DATA_COUNT% GTR 0 (
echo Found data files to embed
echo ^(includes: images, sounds, config, data, and any other files^)
set EMBED_ASSETS=ON
) else (
echo No non-Lua files found ^(only Lua code will be embedded^)
set EMBED_ASSETS=OFF
)
echo.
@@ -72,7 +97,7 @@ echo ================================
echo Build Configuration
echo ================================
echo Lua Embedding: ON
echo Asset Embedding: %EMBED_ASSETS%
echo Data Embedding: %EMBED_ASSETS%
echo Build Type: Release
echo ================================
echo.

View File

@@ -68,38 +68,50 @@ fi
mkdir -p build
cd build || exit 1
# ALWAYS clean build folder for fresh build
echo "Cleaning build directory for fresh build..."
rm -rf ./* 2>/dev/null
echo "✓ Build directory cleaned"
echo ""
# Clean old embedded files
echo "Cleaning old embedded files..."
rm -f embedded_main.h embedded_assets.h
echo "Ready for fresh build..."
rm -f embedded_main.h embedded_assets.h 2>/dev/null
# Auto-copy from game folder if it exists
echo ""
if [ -d "../game" ]; then
echo "Found game/ folder - auto-copying contents to build..."
echo "Found game/ folder - auto-copying ALL contents to build..."
# Copy all Lua files from game folder EXCEPT ReiLua_API.lua
if ls ../game/*.lua 1> /dev/null 2>&1; then
for lua_file in ../game/*.lua; do
filename=$(basename "$lua_file")
if [ "$filename" != "ReiLua_API.lua" ]; then
cp "$lua_file" .
fi
done
LUA_COUNT=$(ls *.lua 2>/dev/null | wc -l)
echo " ✓ Copied $LUA_COUNT Lua file(s)"
# Copy everything from game folder recursively, excluding:
# - ReiLua_API.lua (LSP only)
# - .luarc.json (LSP config)
# - .DS_Store (macOS)
# - Hidden files starting with . (except .gitkeep if present)
# Use rsync if available for better copying, otherwise use cp
if command -v rsync &> /dev/null; then
rsync -av --exclude='ReiLua_API.lua' --exclude='.luarc.json' --exclude='.DS_Store' --exclude='.*' --include='.gitkeep' ../game/ . 2>/dev/null
else
echo " ⚠ No Lua files found in game/"
# Fallback to find + cp - Copy ALL files and directories
(cd ../game && find . -type f \
! -name 'ReiLua_API.lua' \
! -name '.luarc.json' \
! -name '.DS_Store' \
! -path '*/\.*' -o -name '.gitkeep' \
-exec sh -c 'mkdir -p "../build/$(dirname "{}")" && cp -p "{}" "../build/{}"' \; 2>/dev/null)
fi
# Copy assets folder if it exists
if [ -d "../game/assets" ]; then
rm -rf assets
cp -r ../game/assets .
ASSET_COUNT=$(find assets -type f 2>/dev/null | wc -l)
echo " ✓ Copied assets/ ($ASSET_COUNT files)"
else
echo " No assets folder in game/"
fi
# Count what was copied
LUA_COUNT=$(find . -maxdepth 10 -name "*.lua" -type f 2>/dev/null | wc -l)
ASSET_COUNT=$(find assets -type f 2>/dev/null | wc -l || echo "0")
TOTAL_FILES=$(find . -type f ! -path './CMakeFiles/*' ! -path './.cmake/*' ! -name 'CMake*' ! -name '*.a' ! -name '*.o' 2>/dev/null | wc -l)
echo " ✓ Copied ALL game files and folders:"
echo " - $LUA_COUNT Lua file(s) (including all subdirectories)"
echo " - $ASSET_COUNT Asset file(s) (if assets folder exists)"
echo " - $TOTAL_FILES total file(s)"
echo " - All folder structures preserved (user-created folders included)"
echo ""
fi
@@ -131,34 +143,18 @@ else
ls -1 *.lua
fi
# Check for assets folder
# Check for non-Lua data files (any folder, any file type)
echo ""
echo "Checking for assets..."
if [ ! -d "assets" ]; then
echo ""
echo "WARNING: No assets folder found!"
echo ""
if [ -d "../game" ]; then
echo "No assets found in game/assets/ folder."
echo "Add assets to game/assets/ if you need them embedded."
else
echo "Tip: Create game/assets/ in project root for auto-copy."
echo "Or manually:"
echo " cd build"
echo " mkdir assets"
echo " cp ../your_game/assets/* assets/"
fi
echo ""
read -p "Do you want to continue without assets? (y/N): " -n 1 -r
echo ""
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 1
fi
EMBED_ASSETS="OFF"
else
ASSET_FILES=$(find assets -type f 2>/dev/null | wc -l)
echo "Found $ASSET_FILES asset file(s) in assets folder"
echo "Checking for data files to embed..."
NON_LUA_FILES=$(find . -type f ! -name "*.lua" ! -path "./CMakeFiles/*" ! -path "./.cmake/*" ! -name "CMake*" ! -name "Makefile*" ! -name "*.o" ! -name "*.a" 2>/dev/null | wc -l)
if [ "$NON_LUA_FILES" -gt 0 ]; then
echo "Found $NON_LUA_FILES non-Lua file(s) to embed"
echo " (includes: images, sounds, config, data, and any other files)"
EMBED_ASSETS="ON"
else
echo "No non-Lua files found (only Lua code will be embedded)"
EMBED_ASSETS="OFF"
fi
echo ""
@@ -166,7 +162,7 @@ echo "================================"
echo "Build Configuration"
echo "================================"
echo "Lua Embedding: ON"
echo "Asset Embedding: $EMBED_ASSETS"
echo "Data Embedding: $EMBED_ASSETS"
echo "Build Type: Release"
echo "================================"
echo ""

View File

@@ -0,0 +1,24 @@
#!/usr/bin/env python3
"""
Create an empty embedded_assets.h file for compatibility.
Usage: python create_empty_assets.py <output.h>
"""
import sys
if __name__ == '__main__':
if len(sys.argv) < 2:
print('Usage: python create_empty_assets.py <output.h>')
sys.exit(1)
output_file = sys.argv[1]
with open(output_file, 'w') as f:
f.write('#ifndef EMBEDDED_ASSETS_H\n')
f.write('#define EMBEDDED_ASSETS_H\n')
f.write('/* No assets to embed */\n')
f.write('typedef struct { const char* name; const unsigned char* data; unsigned int size; } EmbeddedAsset;\n')
f.write('static const EmbeddedAsset embedded_assets[] = {};\n')
f.write('static const int embedded_asset_count = 0;\n')
f.write('#endif\n')
print(f'Created empty {output_file}')

View File

@@ -40,17 +40,18 @@ def embed_files(output_file, input_files):
data = inf.read()
var_name = sanitize_name(input_file)
# Extract relative path from 'assets/' onwards if present
if 'assets' in input_file.replace('\\', '/'):
parts = input_file.replace('\\', '/').split('assets/')
# Extract relative path from build directory
relative_name = input_file
for prefix in ['build/', 'build\\']:
if prefix in input_file:
parts = input_file.split(prefix, 1)
if len(parts) > 1:
relative_name = 'assets/' + parts[-1]
else:
relative_name = os.path.basename(input_file)
else:
relative_name = os.path.basename(input_file)
relative_name = parts[1]
break
# Normalize path separators
relative_name = relative_name.replace('\\', '/')
f.write(f'/* Embedded asset: {input_file} ({len(data)} bytes) */\n')
f.write(f'/* Embedded file: {relative_name} ({len(data)} bytes) */\n')
f.write(f'static const unsigned char embedded_asset_{idx}_{var_name}[] = {{\n')
for i, byte in enumerate(data):
@@ -78,15 +79,16 @@ def embed_files(output_file, input_files):
f.write('static const EmbeddedAsset embedded_assets[] = {\n')
for idx, input_file in enumerate(input_files):
var_name = sanitize_name(input_file)
# Extract relative path from 'assets/' onwards if present
if 'assets' in input_file.replace('\\', '/'):
parts = input_file.replace('\\', '/').split('assets/')
# Extract relative path from build directory
relative_name = input_file
for prefix in ['build/', 'build\\']:
if prefix in input_file:
parts = input_file.split(prefix, 1)
if len(parts) > 1:
relative_name = 'assets/' + parts[-1]
else:
relative_name = os.path.basename(input_file)
else:
relative_name = os.path.basename(input_file)
relative_name = parts[1]
break
# Normalize path separators
relative_name = relative_name.replace('\\', '/')
f.write(f' {{ "{relative_name}", embedded_asset_{idx}_{var_name}, embedded_asset_{idx}_{var_name}_len }},\n')
f.write('};\n\n')

View File

@@ -27,7 +27,17 @@ def embed_files(output_file, input_files):
data = inf.read()
var_name = sanitize_name(input_file)
f.write(f'/* Embedded file: {input_file} */\n')
# Get relative path for better module loading
# Try to extract path relative to common directories
relative_name = input_file
for prefix in ['build/', 'build\\']:
if prefix in input_file:
parts = input_file.split(prefix, 1)
if len(parts) > 1:
relative_name = parts[1]
break
f.write(f'/* Embedded file: {relative_name} */\n')
f.write(f'static const unsigned char embedded_lua_{idx}_{var_name}[] = {{\n')
for i, byte in enumerate(data):
@@ -55,18 +65,32 @@ def embed_files(output_file, input_files):
f.write('static const EmbeddedLuaFile embedded_lua_files[] = {\n')
for idx, input_file in enumerate(input_files):
var_name = sanitize_name(input_file)
# Store both original filename and basename for require compatibility
basename = os.path.basename(input_file)
f.write(f' {{ "{basename}", embedded_lua_{idx}_{var_name}, embedded_lua_{idx}_{var_name}_len }},\n')
# Store relative path for proper require() support
relative_name = input_file
for prefix in ['build/', 'build\\']:
if prefix in input_file:
parts = input_file.split(prefix, 1)
if len(parts) > 1:
relative_name = parts[1]
break
# Normalize path separators
relative_name = relative_name.replace('\\', '/')
f.write(f' {{ "{relative_name}", embedded_lua_{idx}_{var_name}, embedded_lua_{idx}_{var_name}_len }},\n')
f.write('};\n\n')
f.write(f'static const int embedded_lua_file_count = {len(input_files)};\n\n')
# Main entry point (first file)
var_name = sanitize_name(input_files[0])
# Main entry point (first file with 'main.lua' in name, or first file)
main_idx = 0
for idx, input_file in enumerate(input_files):
if 'main.lua' in input_file.lower():
main_idx = idx
break
var_name = sanitize_name(input_files[main_idx])
f.write('/* Main entry point */\n')
f.write(f'#define embedded_main_lua embedded_lua_0_{var_name}\n')
f.write(f'#define embedded_main_lua_len embedded_lua_0_{var_name}_len\n\n')
f.write(f'#define embedded_main_lua embedded_lua_{main_idx}_{var_name}\n')
f.write(f'#define embedded_main_lua_len embedded_lua_{main_idx}_{var_name}_len\n\n')
f.write('#endif /* EMBEDDED_MAIN_H */\n')

View File

@@ -124,16 +124,31 @@ static int embedded_lua_loader( lua_State* L ) {
const char* name = lua_tostring( L, 1 );
if ( name == NULL ) return 0;
/* Convert module name dots to slashes (e.g., "lib.gamestate" -> "lib/gamestate") */
char converted_name[512];
strncpy( converted_name, name, sizeof(converted_name) - 1 );
converted_name[sizeof(converted_name) - 1] = '\0';
for ( char* p = converted_name; *p; p++ ) {
if ( *p == '.' ) *p = '/';
}
/* Try both converted name and original name */
const char* names_to_try[] = { converted_name, name };
for ( int n = 0; n < 2; n++ ) {
const char* try_name = names_to_try[n];
for ( int i = 0; i < embedded_lua_file_count; i++ ) {
const EmbeddedLuaFile* file = &embedded_lua_files[i];
const char* basename = file->name;
size_t name_len = strlen( name );
size_t name_len = strlen( try_name );
size_t base_len = strlen( basename );
if ( strcmp( basename, name ) == 0 ||
/* Match exactly, or match without .lua extension */
if ( strcmp( basename, try_name ) == 0 ||
( base_len > 4 && strcmp( basename + base_len - 4, ".lua" ) == 0 &&
strncmp( basename, name, base_len - 4 ) == 0 && name_len == base_len - 4 ) ) {
strncmp( basename, try_name, base_len - 4 ) == 0 && name_len == base_len - 4 ) ) {
if ( luaL_loadbuffer( L, (const char*)file->data, file->size, file->name ) == 0 ) {
return 1;
@@ -144,6 +159,7 @@ static int embedded_lua_loader( lua_State* L ) {
}
}
}
}
lua_pushfstring( L, "\n\tno embedded file '%s'", name );
return 1;
@@ -1530,6 +1546,25 @@ bool luaInit( int argn, const char** argc ) {
TraceLog( LOG_WARNING, "%s", "Failed to init Lua" );
return false;
}
/* Configure package.path to include basePath and all subdirectories */
if ( state->basePath != NULL && strlen( state->basePath ) > 0 ) {
lua_getglobal( L, "package" );
lua_getfield( L, -1, "path" );
const char* currentPath = lua_tostring( L, -1 );
lua_pop( L, 1 );
/* Add basePath and recursive subdirectory patterns for flexible module loading */
char newPath[STRING_LEN * 4];
snprintf( newPath, sizeof(newPath),
"%s?.lua;%s?/init.lua;%s?/?.lua;%s?/?/init.lua;%s",
state->basePath, state->basePath, state->basePath, state->basePath, currentPath );
lua_pushstring( L, newPath );
lua_setfield( L, -2, "path" );
lua_pop( L, 1 );
}
/* Define object types. */
defineBuffer();
defineImage();