A bit of repository cleanup.
This commit is contained in:
@@ -1,229 +0,0 @@
|
||||
# Draugnorak Project Guidelines
|
||||
|
||||
## NVGT Workflow
|
||||
|
||||
- Use the `nvgt-engine-dev` skill for NVGT API behavior, include/module decisions, and engine-source verification.
|
||||
- If API behavior is uncertain, verify against primary sources in `nvgt/` (engine source) and `docs/nvgt/` before coding.
|
||||
- Reuse shared helpers in `libstorm-nvgt/` before creating project-local replacements.
|
||||
|
||||
## libstorm-nvgt Workflow
|
||||
|
||||
- Treat `~/git/libstorm-nvgt` as the canonical repository for shared library changes.
|
||||
- Do not make canonical library changes directly inside this repo's `libstorm-nvgt/` copy first.
|
||||
- Hard stop: do not implement shared-library edits in this repo's `libstorm-nvgt/` submodule copy. Make the change in `~/git/libstorm-nvgt`, commit it there, then update the submodule pointer here.
|
||||
- When shared helper behavior must change:
|
||||
- Implement and commit the change in `~/git/libstorm-nvgt`.
|
||||
- Update this repo to the new `libstorm-nvgt` submodule commit.
|
||||
- Verify Draugnorak still compiles with `./nvgt -c draugnorak.nvgt` after updating the pointer.
|
||||
|
||||
## AGENTS.md Maintenance
|
||||
|
||||
- Keep this file aligned with the real repository layout and active workflows.
|
||||
- Update `AGENTS.md` in the same PR/commit when any of the following change:
|
||||
- Core directories/modules (for example new systems under `src/`, `scripts/`, or `docs/`).
|
||||
- Required build/test/validation commands.
|
||||
- Localization workflow expectations.
|
||||
- Canonical engine/library source locations or skill usage expectations.
|
||||
- If a section is uncertain or outdated, replace it with a short verified statement instead of leaving stale instructions.
|
||||
|
||||
## Project Structure
|
||||
|
||||
Key paths (focused, not exhaustive):
|
||||
- `draugnorak.nvgt` - Main game entry point.
|
||||
- `src/` - Core gameplay systems.
|
||||
- `constants.nvgt`, `player.nvgt`, `time_system.nvgt` - Global state and timing.
|
||||
- `world_state.nvgt`, `src/world/` - World object orchestration and world systems.
|
||||
- `src/enemies/`, `combat.nvgt`, `creature_*` - Enemy and combat behavior.
|
||||
- `inventory.nvgt`, `inventory_items.nvgt`, `inventory_menus.nvgt`, `item_registry.nvgt` - Inventory/equipment/items.
|
||||
- `crafting.nvgt`, `src/crafting/` - Crafting orchestration and recipe categories.
|
||||
- `quest_system.nvgt`, `src/quests/`, `src/bosses/` - Quests, adventures, and boss content.
|
||||
- `base_system.nvgt`, `environment.nvgt`, `weather.nvgt`, `fishing.nvgt`, `pet_system.nvgt`, `fylgja_system.nvgt` - Survival systems.
|
||||
- `i18n.nvgt` - Translation loading and lookup wrappers.
|
||||
- `save_system.nvgt` - Save/load behavior.
|
||||
- `lang/` - Localization catalogs (`en.ini`, `en.template.ini`, and per-language files such as `es.ini`).
|
||||
- `scripts/` - Build and i18n tooling (`generate_i18n_catalog.py`, `validate_i18n_catalog.py`, `audit_untranslated_strings.py`).
|
||||
- `docs/` - Implementation references (`patterns.md`, `rune_system.md`, `localization.md`).
|
||||
- `libstorm-nvgt/` - Shared NVGT helpers reused by this project.
|
||||
- `sounds/` - Game audio assets.
|
||||
|
||||
## Game Mechanics
|
||||
|
||||
### Inventory Limits
|
||||
- Personal inventory stacks are capped at 9
|
||||
- Skin pouches add +2 stack capacity, backpacks add +9
|
||||
|
||||
### Map Layout
|
||||
- Base area: x 0-4 (wood terrain)
|
||||
- Grass area: x 5-19 (grass terrain, contains trees)
|
||||
- Gravel area: x 20-34 (gravel terrain, contains stones)
|
||||
|
||||
### Healing System
|
||||
- Base area provides passive healing when player health < max
|
||||
- Without herb garden: 1 HP every 2.5 minutes (150000ms)
|
||||
- With herb garden: 1 HP every 30 seconds (30000ms)
|
||||
- Herb garden can only be built in base area (x <= 4)
|
||||
- Only one herb garden allowed per base
|
||||
|
||||
### Fire System
|
||||
- Fires require a firepit to build
|
||||
- New fires start with 12 minutes (720000ms) of fuel
|
||||
- Warning at 30 seconds remaining
|
||||
- Fire goes out when fuel depletes
|
||||
- Fire sound plays within 3 tiles distance
|
||||
- Jumping over fire prevents damage
|
||||
- Feeding fire is done from the Action menu (A)
|
||||
|
||||
### Snare System
|
||||
- Snares become active when player moves away
|
||||
- Check every hour for catching/escaping small game
|
||||
- Catch chance starts at 5%, increases by 5% per hour (max 75%)
|
||||
- Escape chance: 0% for first hour after catch, then increases by 2% per hour (max 95%)
|
||||
- Snare sound plays within 2 tiles distance
|
||||
- Residents can retrieve game from snares (daytime only, requires meat in storage)
|
||||
|
||||
### Tree System
|
||||
- Trees regenerate fully after ~5 minutes (minute-by-minute refill logic)
|
||||
- Tree ambient sound plays within 4 tiles distance
|
||||
- Trees only play sound when not chopped
|
||||
- Climb down only when in a tree (Down arrow does nothing during jumps or when not in a tree)
|
||||
- Trees have height; falling damage is applied when falling from height
|
||||
|
||||
### Notification System
|
||||
- Important events use `notify()` function (plays sounds/notify.ogg + speaks message)
|
||||
- Last 10 notifications stored in history
|
||||
- Navigation keys:
|
||||
- `\` - Repeat most recent notification
|
||||
- `]` - Next (newer) notification
|
||||
- `[` (Shift+Comma) - Previous (older) notification
|
||||
- Navigating history speaks message without notification sound
|
||||
- Speech history (screen_reader_speak wrapper) uses `,` and `.` for previous/next message
|
||||
|
||||
### Search System
|
||||
- Hold Shift for 1 second to search
|
||||
- Search completes after 1-second delay
|
||||
|
||||
### Undead System
|
||||
- At night, zombies spawn (5 max) and wander outside the base
|
||||
- Zombies cannot enter the base while barricade health > 0
|
||||
- Zombies attack the barricade for 4-6 damage when they reach it; play `sounds/enemies/zombie_hit.ogg`
|
||||
- Zombies vanish at daybreak
|
||||
- Player can hit zombies with spear (1-tile range) or sling (8-tile range)
|
||||
|
||||
### Barricade System
|
||||
- Base starts with 100 barricade health, capped at 500
|
||||
- In base, press B to report barricade health
|
||||
- Crafting menu includes Barricade category for reinforcement
|
||||
- Reinforcement costs and health: 3 sticks (+10), 5 vines (+15), 1 log (+30), 5 stones (+20)
|
||||
- Barricade health does not reset during gameplay
|
||||
|
||||
### Mountains, Rope Climbing, Falling
|
||||
- Mountain ranges can appear during area expansion with elevation-based terrain
|
||||
- Steep slopes require a rope; the player is prompted to press Up/Down to climb
|
||||
- Moving left/right during rope climb cancels and causes a fall
|
||||
- Falling damage is applied beyond a safe height (10 feet)
|
||||
|
||||
### World Expansion & Invasions
|
||||
- After day 2, bandit invasions can trigger and expand the map to the east
|
||||
- Expansion is either a 30-tile biome strip or a 60-tile mountain range
|
||||
- Invasions last 1 hour and spawn bandits in the expanded area during daytime
|
||||
|
||||
### Weather & Ambience
|
||||
- Weather transitions between clear, windy, rainy, stormy with wind/rain/thunder audio
|
||||
- Day/night ambience crossfades on hour changes
|
||||
|
||||
### Inventory + Equipment
|
||||
- Item definitions live in `src/item_registry.nvgt` (personal + storage inventories)
|
||||
- Equipment includes spear, axe, sling, bow, clothing, pouches, backpacks
|
||||
- Combat logic currently supports spear/axe/sling; bow attacks are not implemented yet
|
||||
- Quivers gate arrow capacity (12 arrows per quiver)
|
||||
- Quick slots (keys 1-0) bind equipment from the Equipment menu
|
||||
|
||||
### Buildings
|
||||
- Firepit, Fire, Herb Garden, Storage, Pasture, Stable, Altar
|
||||
- Storage enables base inventory menus and increases resident recruitment chance
|
||||
|
||||
### Residents and Base Automation
|
||||
- Residents consume meat daily, can repair the barricade, defend with stored weapons, and collect resources
|
||||
- Residents use spears or slings (requires stones) for defense
|
||||
- Daily weapon breakage occurs based on resident count
|
||||
|
||||
### Favor, Altars, Incense, Blessings
|
||||
- Altar sacrifices (S key, base only) convert items to Favor
|
||||
- Burning incense (A key action) grants Favor per hour while active
|
||||
- Blessings can trigger (heal, speed boost, barricade repair) and consume Favor
|
||||
|
||||
### Quests (Mini-Games)
|
||||
- Quest menu (Q, base only) appears after altar/favor requirements
|
||||
- Max 4 active quests; rewards grant Favor and resources
|
||||
|
||||
### Adventures & Bosses
|
||||
- Adventure menu (Tab) available outside base; limited to once per day
|
||||
- Mountain adventure: Unicorn boss; victory grants Favor and unlocks Rune of Swiftness
|
||||
|
||||
### Runes
|
||||
- Rune system in `src/runes/` (data + effects)
|
||||
- Runes are crafted in Crafting > Runes after unlock (requires knife + clay + favor)
|
||||
- Rune of Swiftness grants move speed and gathering bonuses; runed items are tracked separately
|
||||
|
||||
## Menu Structure
|
||||
|
||||
### Crafting Menu (C key, base only)
|
||||
Organized into categories:
|
||||
- **Weapons**: Spear, Sling
|
||||
- **Tools**: Knife, Snare, Stone Axe, Fishing Pole, Rope, Reed Basket, Clay Pot
|
||||
- **Materials**: Butcher Game, Incense
|
||||
- **Clothing**: Skin gear, Moccasins, Pouch, Backpack
|
||||
- **Buildings**: Firepit, Fire, Herb Garden, Storage, Pasture, Stable, Altar
|
||||
- **Barricade**: Reinforcement options
|
||||
- **Runes**: Available after rune unlocks
|
||||
|
||||
### Equipment Menu (E key)
|
||||
- Only shows items player actually has
|
||||
- Shows equipped status
|
||||
- Says "Nothing to equip" if inventory is empty
|
||||
|
||||
### Inventory Menu (I key)
|
||||
- Base + storage built: root menu for personal vs storage
|
||||
- No storage: personal inventory only
|
||||
|
||||
### Action Menu (A key)
|
||||
- Place snares, feed fires, burn incense (context-sensitive)
|
||||
- Tab in menu performs “max” action for the selected option
|
||||
|
||||
### Base Info (B key)
|
||||
- Barricade health, residents, storage totals, base buildings
|
||||
|
||||
### Quest Menu (Q key)
|
||||
- Base-only quest selection for mini-games
|
||||
|
||||
### Adventure Menu (Tab key)
|
||||
- Terrain-based adventures outside the base (once per day)
|
||||
|
||||
## Testing
|
||||
|
||||
- Always run `./nvgt -c draugnorak.nvgt` after code changes
|
||||
- This compiles without opening the game window and prevents it from taking over the terminal
|
||||
- If user-facing text changed, also run:
|
||||
- `python3 scripts/generate_i18n_catalog.py`
|
||||
- `python3 scripts/validate_i18n_catalog.py`
|
||||
- `python3 scripts/audit_untranslated_strings.py`
|
||||
|
||||
## Localization Workflow
|
||||
|
||||
- Any new or changed user-facing string must be localizable; avoid hardcoded UI/gameplay text in NVGT files.
|
||||
- Update the English catalogs in the same change as text changes by running `python3 scripts/generate_i18n_catalog.py`.
|
||||
- Keep `lang/en.ini` and `lang/en.template.ini` in sync with code changes.
|
||||
- Validate all translation catalogs with `python3 scripts/validate_i18n_catalog.py` and fix missing keys/placeholders before merging.
|
||||
- Run `python3 scripts/audit_untranslated_strings.py` after text-heavy changes; keep `scripts/i18n_audit_allowlist.txt` small and commented.
|
||||
- Preserve placeholders exactly as written (for example `{arg1}`, `{language}`) and keep escapes such as `\n` and `\t` intact.
|
||||
- For new translations, copy `lang/en.template.ini` to `lang/<code>.ini`, then update `[meta]` (`code`, `name`, `native_name`) to match the file.
|
||||
- Translator-facing instructions live in `translate.md`; developer-level localization details live in `docs/localization.md`.
|
||||
|
||||
## Code Standards
|
||||
|
||||
- Use `notify()` for important game events that should be reviewable
|
||||
- Use `screen_reader_speak()` for immediate feedback that doesn't need to be stored
|
||||
- All menus must call `menu_background_tick()` each loop to keep game state updating
|
||||
- **Time references**: When discussing time (hours, minutes, days), assume game time unless explicitly stated as "real time". Game time runs at 60x speed: 1 real minute = 1 game hour, 24 real minutes = 1 game day.
|
||||
- See `docs/patterns.md` for module and creature patterns
|
||||
- See `docs/rune_system.md` for rune data/effects/save requirements
|
||||
-223
@@ -1,223 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# create Draugnorak package for all platforms.
|
||||
|
||||
tmpAndroidToolsDir=""
|
||||
tmpAndroidConfigBackup=""
|
||||
createdAndroidConfig="0"
|
||||
tmpAndroidWrapperSource=""
|
||||
tmpAndroidPackFile=""
|
||||
tmpAndroidPackBuilder=""
|
||||
|
||||
trap 'rm -fv README.html; if [[ -n "${tmpAndroidToolsDir}" && -d "${tmpAndroidToolsDir}" ]]; then rm -rf "${tmpAndroidToolsDir}"; fi; if [[ -n "${tmpAndroidConfigBackup}" && -f "${tmpAndroidConfigBackup}" ]]; then mv -f "${tmpAndroidConfigBackup}" draugnorak.properties; elif [[ "${createdAndroidConfig}" == "1" ]]; then rm -f draugnorak.properties; fi; if [[ -n "${tmpAndroidWrapperSource}" && -f "${tmpAndroidWrapperSource}" ]]; then rm -f "${tmpAndroidWrapperSource}"; fi; if [[ -n "${tmpAndroidPackBuilder}" && -f "${tmpAndroidPackBuilder}" ]]; then rm -f "${tmpAndroidPackBuilder}"; fi; if [[ -n "${tmpAndroidPackFile}" && -f "${tmpAndroidPackFile}" ]]; then rm -f "${tmpAndroidPackFile}"; fi' EXIT
|
||||
|
||||
escape_nvgt_string() {
|
||||
local inputValue="$1"
|
||||
inputValue="${inputValue//\\/\\\\}"
|
||||
inputValue="${inputValue//\"/\\\"}"
|
||||
printf '%s\n' "${inputValue}"
|
||||
}
|
||||
|
||||
find_android_sdk_root() {
|
||||
local sdkRoot
|
||||
for sdkRoot in "${ANDROID_HOME:-}" "${ANDROID_SDK_HOME:-}" "/opt/android-sdk" "${HOME}/Android/Sdk" "${HOME}/Android/sdk"; do
|
||||
if [[ -n "${sdkRoot}" && -d "${sdkRoot}" ]]; then
|
||||
printf '%s\n' "${sdkRoot}"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
find_latest_build_tools_dir() {
|
||||
local sdkRoot="$1"
|
||||
local buildToolsDir=""
|
||||
if [[ ! -d "${sdkRoot}/build-tools" ]]; then
|
||||
return 1
|
||||
fi
|
||||
buildToolsDir="$(find "${sdkRoot}/build-tools" -mindepth 1 -maxdepth 1 -type d | sort -V | tail -n 1)"
|
||||
if [[ -z "${buildToolsDir}" ]]; then
|
||||
return 1
|
||||
fi
|
||||
printf '%s\n' "${buildToolsDir}"
|
||||
}
|
||||
|
||||
find_latest_android_jar() {
|
||||
local sdkRoot="$1"
|
||||
local androidJar=""
|
||||
if [[ ! -d "${sdkRoot}/platforms" ]]; then
|
||||
return 1
|
||||
fi
|
||||
androidJar="$(find "${sdkRoot}/platforms" -mindepth 2 -maxdepth 2 -type f -name android.jar | sort -V | tail -n 1)"
|
||||
if [[ -z "${androidJar}" ]]; then
|
||||
return 1
|
||||
fi
|
||||
printf '%s\n' "${androidJar}"
|
||||
}
|
||||
|
||||
setup_android_tools_workaround() {
|
||||
local sdkRoot="$1"
|
||||
local buildToolsDir="$2"
|
||||
local androidJar="$3"
|
||||
local javaBin=""
|
||||
local keytoolBin=""
|
||||
local adbBin=""
|
||||
|
||||
tmpAndroidToolsDir="$(mktemp -d)"
|
||||
|
||||
ln -sf "${buildToolsDir}/zipalign" "${tmpAndroidToolsDir}/zipalign"
|
||||
ln -sf "${buildToolsDir}/lib/apksigner.jar" "${tmpAndroidToolsDir}/apksigner.jar"
|
||||
ln -sf "${androidJar}" "${tmpAndroidToolsDir}/android.jar"
|
||||
|
||||
if command -v java >/dev/null 2>&1; then
|
||||
javaBin="$(command -v java)"
|
||||
ln -sf "${javaBin}" "${tmpAndroidToolsDir}/java"
|
||||
fi
|
||||
|
||||
if command -v keytool >/dev/null 2>&1; then
|
||||
keytoolBin="$(command -v keytool)"
|
||||
ln -sf "${keytoolBin}" "${tmpAndroidToolsDir}/keytool"
|
||||
fi
|
||||
|
||||
if command -v adb >/dev/null 2>&1; then
|
||||
adbBin="$(command -v adb)"
|
||||
ln -sf "${adbBin}" "${tmpAndroidToolsDir}/adb"
|
||||
fi
|
||||
|
||||
cat > "${tmpAndroidToolsDir}/aapt2" <<EOF
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
filteredArgs=()
|
||||
for arg in "\$@"; do
|
||||
if [[ -n "\${arg}" ]]; then
|
||||
filteredArgs+=("\${arg}")
|
||||
fi
|
||||
done
|
||||
|
||||
exec "${buildToolsDir}/aapt2" "\${filteredArgs[@]}"
|
||||
EOF
|
||||
chmod +x "${tmpAndroidToolsDir}/aapt2"
|
||||
|
||||
echo "Using Android SDK at: ${sdkRoot}"
|
||||
echo "Using build-tools: ${buildToolsDir}"
|
||||
echo "Using android.jar: ${androidJar}"
|
||||
}
|
||||
|
||||
build_android_sound_pack() {
|
||||
local outputPackPath="$1"
|
||||
local builderScriptPath="$2"
|
||||
local sourcePath=""
|
||||
local escapedSourcePath=""
|
||||
local escapedOutputPath=""
|
||||
|
||||
escapedOutputPath="$(escape_nvgt_string "${outputPackPath}")"
|
||||
cat > "${builderScriptPath}" <<EOF
|
||||
void main() {
|
||||
pack soundPack;
|
||||
if (!soundPack.open("${escapedOutputPath}", PACK_OPEN_MODE_CREATE)) return;
|
||||
EOF
|
||||
|
||||
while IFS= read -r sourcePath; do
|
||||
escapedSourcePath="$(escape_nvgt_string "${sourcePath}")"
|
||||
printf ' if (!soundPack.add_file("%s", "%s")) return;\n' "${escapedSourcePath}" "${escapedSourcePath}" >> "${builderScriptPath}"
|
||||
done < <(find sounds -type f | sort)
|
||||
|
||||
cat >> "${builderScriptPath}" <<'EOF'
|
||||
soundPack.close();
|
||||
}
|
||||
EOF
|
||||
|
||||
./nvgt "${builderScriptPath}"
|
||||
if [[ ! -f "${outputPackPath}" ]]; then
|
||||
echo "Failed to build Android sound pack: ${outputPackPath}"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Generate documentation
|
||||
pandoc -s files/instructions.md -o README.html
|
||||
|
||||
# Create packages
|
||||
for platformName in linux mac windows android; do
|
||||
echo "Packaging Draugnorak for ${platformName^}..."
|
||||
if [[ "${platformName}" == "android" ]]; then
|
||||
androidKeystorePath="${DRAUGNORAK_ANDROID_KEYSTORE:-${PWD}/.nvgt_android.keystore}"
|
||||
sdkRoot="$(find_android_sdk_root || true)"
|
||||
if [[ -z "${sdkRoot}" ]]; then
|
||||
echo "Android SDK not found. Set ANDROID_HOME or ANDROID_SDK_HOME."
|
||||
exit 1
|
||||
fi
|
||||
buildToolsDir="$(find_latest_build_tools_dir "${sdkRoot}" || true)"
|
||||
if [[ -z "${buildToolsDir}" || ! -x "${buildToolsDir}/aapt2" || ! -x "${buildToolsDir}/zipalign" || ! -f "${buildToolsDir}/lib/apksigner.jar" ]]; then
|
||||
echo "Missing required Android build tools in ${sdkRoot}."
|
||||
exit 1
|
||||
fi
|
||||
androidJar="$(find_latest_android_jar "${sdkRoot}" || true)"
|
||||
if [[ -z "${androidJar}" ]]; then
|
||||
echo "No android.jar found in ${sdkRoot}/platforms."
|
||||
exit 1
|
||||
fi
|
||||
setup_android_tools_workaround "${sdkRoot}" "${buildToolsDir}" "${androidJar}"
|
||||
|
||||
if [[ -f draugnorak.properties ]]; then
|
||||
tmpAndroidConfigBackup="$(mktemp)"
|
||||
cp draugnorak.properties "${tmpAndroidConfigBackup}"
|
||||
cat "${tmpAndroidConfigBackup}" > draugnorak.properties
|
||||
else
|
||||
createdAndroidConfig="1"
|
||||
fi
|
||||
{
|
||||
printf '%s\n' "build.android_install = 0"
|
||||
printf '%s\n' "build.android_signature_cert = ${androidKeystorePath}"
|
||||
printf '%s\n' "build.output_basename = draugnorak"
|
||||
} >> draugnorak.properties
|
||||
|
||||
tmpAndroidPackFile=".draugnorak_android_sounds.dat"
|
||||
tmpAndroidPackBuilder=".draugnorak_make_android_pack.nvgt"
|
||||
build_android_sound_pack "${tmpAndroidPackFile}" "${tmpAndroidPackBuilder}"
|
||||
|
||||
tmpAndroidWrapperSource=".draugnorak_android_bundle_pragmas.nvgt"
|
||||
cat > "${tmpAndroidWrapperSource}" <<'EOF'
|
||||
#pragma embed ".draugnorak_android_sounds.dat"
|
||||
#pragma asset files
|
||||
#pragma document "README.html"
|
||||
|
||||
pack@ androidSoundPack;
|
||||
bool preglobals() {
|
||||
@androidSoundPack = pack();
|
||||
if (androidSoundPack.open("*.draugnorak_android_sounds.dat", PACK_OPEN_MODE_READ)) {
|
||||
@sound_default_pack = @androidSoundPack;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
EOF
|
||||
|
||||
PATH="${tmpAndroidToolsDir}:${PATH}" ./nvgt -c --platform "${platformName}" --include "${tmpAndroidWrapperSource}" draugnorak.nvgt
|
||||
else
|
||||
./nvgt -c --platform "${platformName}" draugnorak.nvgt
|
||||
fi
|
||||
case "${platformName}" in
|
||||
"linux"|"windows")
|
||||
zip -r draugnorak.zip files/ sounds/ README.html
|
||||
mv draugnorak.zip "draugnorak-${platformName}.zip"
|
||||
;;
|
||||
"mac")
|
||||
mkdir -p draugnorak.app/Contents/Resources
|
||||
cp -r files draugnorak.app/Contents/Resources
|
||||
cp -r sounds draugnorak.app/Contents/Resources
|
||||
cp README.html draugnorak.app/Contents/Resources
|
||||
zip -r draugnorak.app.zip draugnorak.app fix_mac.sh
|
||||
rm -rfv draugnorak.app/
|
||||
;;
|
||||
"android")
|
||||
zip -r draugnorak-android.zip draugnorak.apk files/ sounds/ README.html
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo "Packaging complete!"
|
||||
|
||||
exit 0
|
||||
Reference in New Issue
Block a user