Compare commits
129 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 59aba9f691 | |||
| 199b4dc939 | |||
| 2edd23cfbb | |||
| 464d6f9ca6 | |||
| 413f9f156f | |||
| 4f87a116d5 | |||
| 86ffc931e8 | |||
| d72f47d66c | |||
| 7a6182cb85 | |||
| a1d37a1a0b | |||
| 9066b2cdbc | |||
| 238b5aac6a | |||
| 8e5ec9fef0 | |||
| 6ca2e01fba | |||
| 8cf30cd78d | |||
| 9b441fa35c | |||
| 61ca537909 | |||
| 0a82aea922 | |||
| f41c550bb8 | |||
| 829462d3b6 | |||
| 002da46045 | |||
| cfa73c58a8 | |||
| 5728effcc6 | |||
| fa1a0175b0 | |||
| 85edb18380 | |||
| 3a535ee04f | |||
| 9b31b392d2 | |||
| 999fa14059 | |||
| e925376b7a | |||
| 2596034365 | |||
| 163855b6e7 | |||
| 645d48aeae | |||
| ec800a88fc | |||
| abc37dee4e | |||
| 1ae7839275 | |||
| d976d1bc59 | |||
| 531a5b5d05 | |||
| 67713fab06 | |||
| b572729e9d | |||
| cdc6979458 | |||
| 564f88fee5 | |||
| 00c99dc05f | |||
| 1e12940445 | |||
| dc3c4a7580 | |||
| 434b62b036 | |||
| 2bd523e58a | |||
| 7cd6e8005e | |||
| a8a3745ca1 | |||
| cfa26bf146 | |||
| bfbbb71752 | |||
| 979f736f54 | |||
| 5a7f6a4c10 | |||
| b66c9ce135 | |||
| f5363516c3 | |||
| 320da36b83 | |||
| b68813cf5b | |||
| 0806fc744c | |||
| eead31d7fc | |||
| eaa4ab37f9 | |||
| 076275158e | |||
| 9f9ace0b16 | |||
| 2cc47d5904 | |||
| 11e89a63d0 | |||
| 50afd8c09f | |||
| 06841fd0d7 | |||
| 4365639a1d | |||
| 7744c06046 | |||
| 978752f0f3 | |||
| f024ce7a54 | |||
| 0196282a78 | |||
| 785a760343 | |||
| de1a89b9b0 | |||
| 66b6cdf01b | |||
| 5a48e83b1a | |||
| df8f858651 | |||
| 1fa7a0807f | |||
| 6d3d3bf49c | |||
| 0a46f64866 | |||
| fd7eecf53e | |||
| f540dc5373 | |||
| f51a3ddeb0 | |||
| 9f7c460369 | |||
| 2c0df99dea | |||
| cf12a04c69 | |||
| fa7e985c0d | |||
| f5ff90cb11 | |||
| a0f65b551c | |||
| 8808a1aa3b | |||
| 62b2c607a9 | |||
| 14b34db6de | |||
| 9238b53c40 | |||
| 3e498ee5c3 | |||
| 715eeb6296 | |||
| 682ce059fa | |||
| c8314b23dd | |||
| 40acffafd1 | |||
| 2187212b7c | |||
| 229d2242ef | |||
| 00c4c76299 | |||
| 8b30a602bf | |||
| 83a5ccdb8e | |||
| 44d8184d8b | |||
| 0630fc56ec | |||
| 98d8960c57 | |||
| 394344c11f | |||
| 93ba470ce9 | |||
| 129aed0ffb | |||
| e062ada301 | |||
| af57199915 | |||
| 538cf1efb5 | |||
| 03b2c5a659 | |||
| 64e226be70 | |||
| f998ddd344 | |||
| b2ad8e7afe | |||
| 799d5d85e8 | |||
| 9730d02da5 | |||
| f634beffee | |||
| d15dbe3982 | |||
| de5cddd9b6 | |||
| e3f37ab48e | |||
| 3dd8d5aff7 | |||
| ad084d1cd8 | |||
| 852e54f1bf | |||
| a62ddab9af | |||
| 50d0bc7d5f | |||
| 2c6045aa1b | |||
| bf8370ef35 | |||
| c71b6d69ab | |||
| a7e87c18a3 |
@@ -1,4 +1,16 @@
|
||||
[target.wasm32-unknown-emscripten]
|
||||
[target.'cfg(target_os = "emscripten")']
|
||||
rustflags = [
|
||||
"--use-preload-plugins --preload-file assets -s USE_SDL=2 -s USE_SDL_IMAGE=2 -s ASSERTIONS=1",
|
||||
# Stack size is required for this project, it will crash otherwise.
|
||||
"-C", "link-args=-sASYNCIFY=1 -sASYNCIFY_STACK_SIZE=8192 -sALLOW_MEMORY_GROWTH=1",
|
||||
"-C", "link-args=-sUSE_SDL=2 -sUSE_SDL_IMAGE=2 -sUSE_SDL_MIXER=2 -sUSE_OGG=1 -sUSE_SDL_GFX=2 -sUSE_SDL_TTF=2 -sSDL2_IMAGE_FORMATS=['png']",
|
||||
"-C", "link-args=--preload-file assets/game/",
|
||||
]
|
||||
|
||||
[target.'cfg(target_os = "linux")']
|
||||
rustflags = [
|
||||
# Manually link zlib.
|
||||
# The `sdl2` crate's build script uses `libpng`, which requires `zlib`.
|
||||
# By adding `-lz` here, we ensure it's passed to the linker after `libpng`,
|
||||
# which is required for the linker to correctly resolve symbols.
|
||||
"-C", "link-arg=-lz",
|
||||
]
|
||||
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
||||
* text=auto eol=lf
|
||||
135
.github/workflows/build.yaml
vendored
Normal file
@@ -0,0 +1,135 @@
|
||||
name: Build
|
||||
|
||||
on: [push]
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
env:
|
||||
RUST_TOOLCHAIN: 1.86.0
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build (${{ matrix.target }})
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
target: x86_64-unknown-linux-gnu
|
||||
artifact_name: pacman
|
||||
- os: macos-13
|
||||
target: x86_64-apple-darwin
|
||||
artifact_name: pacman
|
||||
- os: macos-latest
|
||||
target: aarch64-apple-darwin
|
||||
artifact_name: pacman
|
||||
- os: windows-latest
|
||||
target: x86_64-pc-windows-gnu
|
||||
artifact_name: pacman.exe
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Rust Toolchain
|
||||
uses: dtolnay/rust-toolchain@master
|
||||
with:
|
||||
target: ${{ matrix.target }}
|
||||
toolchain: ${{ env.RUST_TOOLCHAIN }}
|
||||
|
||||
- name: Rust Cache
|
||||
uses: Swatinem/rust-cache@v2
|
||||
|
||||
- name: Cache vcpkg
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: target/vcpkg
|
||||
key: A-vcpkg-${{ runner.os }}-${{ matrix.target }}-${{ hashFiles('Cargo.toml', 'Cargo.lock') }}
|
||||
restore-keys: |
|
||||
A-vcpkg-${{ runner.os }}-${{ matrix.target }}-
|
||||
|
||||
- name: Vcpkg Linux Dependencies
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libltdl-dev
|
||||
|
||||
- name: Vcpkg
|
||||
run: |
|
||||
cargo install cargo-vcpkg
|
||||
cargo vcpkg -v build
|
||||
|
||||
- name: Build
|
||||
run: cargo build --release
|
||||
|
||||
- name: Acquire Package Version
|
||||
shell: bash
|
||||
run: |
|
||||
PACKAGE_VERSION=$(cargo metadata --format-version 1 --no-deps | jq '.packages[0].version' -r)
|
||||
echo "PACKAGE_VERSION=${PACKAGE_VERSION}" >> $GITHUB_ENV
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: "pacman-${{ env.PACKAGE_VERSION }}-${{ matrix.target }}"
|
||||
path: ./target/release/${{ matrix.artifact_name }}
|
||||
retention-days: 7
|
||||
if-no-files-found: error
|
||||
|
||||
wasm:
|
||||
name: Build (wasm32-unknown-emscripten)
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Emscripten SDK
|
||||
uses: pyodide/setup-emsdk@v15
|
||||
with:
|
||||
version: 3.1.43
|
||||
actions-cache-folder: "emsdk-cache"
|
||||
|
||||
- name: Setup Rust (WASM32 Emscripten)
|
||||
uses: dtolnay/rust-toolchain@master
|
||||
with:
|
||||
target: wasm32-unknown-emscripten
|
||||
toolchain: ${{ env.RUST_TOOLCHAIN }}
|
||||
|
||||
- name: Rust Cache
|
||||
uses: Swatinem/rust-cache@v2
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v3
|
||||
with:
|
||||
version: 8
|
||||
run_install: true
|
||||
|
||||
- name: Build with Emscripten
|
||||
run: |
|
||||
cargo build --target=wasm32-unknown-emscripten --release
|
||||
|
||||
- name: Assemble
|
||||
run: |
|
||||
echo "Generating CSS"
|
||||
pnpx postcss-cli ./assets/site/styles.scss -o ./assets/site/build.css
|
||||
|
||||
echo "Copying WASM files"
|
||||
|
||||
mkdir -p dist
|
||||
cp assets/site/{build.css,favicon.ico,index.html} dist
|
||||
output_folder="target/wasm32-unknown-emscripten/release"
|
||||
cp $output_folder/pacman.{wasm,js} $output_folder/deps/pacman.data dist
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
path: "./dist/"
|
||||
retention-days: 7
|
||||
|
||||
- name: Deploy
|
||||
uses: actions/deploy-pages@v4
|
||||
28
.github/workflows/deploy.yaml
vendored
@@ -1,28 +0,0 @@
|
||||
name: Github Pages
|
||||
|
||||
on: [push]
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
build-github-pages:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2 # repo checkout
|
||||
- uses: mymindstorm/setup-emsdk@v11 # setup emscripten toolchain
|
||||
# with:
|
||||
# version: 3.1.35
|
||||
- uses: actions-rs/toolchain@v1 # get rust toolchain for wasm
|
||||
with:
|
||||
toolchain: stable
|
||||
target: wasm32-unknown-emscripten
|
||||
override: true
|
||||
- name: Rust Cache # cache the rust build artefacts
|
||||
uses: Swatinem/rust-cache@v1
|
||||
- name: Build # build
|
||||
run: ./build.sh
|
||||
- name: Deploy
|
||||
uses: JamesIves/github-pages-deploy-action@v4
|
||||
with:
|
||||
folder: dist
|
||||
5
.gitignore
vendored
@@ -1,4 +1,7 @@
|
||||
/target
|
||||
/dist
|
||||
.idea
|
||||
*.dll
|
||||
*.dll
|
||||
rust-sdl2-emscripten/
|
||||
assets/site/build.css
|
||||
emsdk/
|
||||
|
||||
22
.pre-commit-config.yaml
Normal file
@@ -0,0 +1,22 @@
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v5.0.0
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
- id: end-of-file-fixer
|
||||
- id: check-added-large-files
|
||||
- id: check-merge-conflict
|
||||
- id: check-case-conflict
|
||||
- id: check-toml
|
||||
- id: check-yaml
|
||||
- id: forbid-submodules
|
||||
- id: mixed-line-ending
|
||||
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: cargo-fmt
|
||||
name: cargo fmt
|
||||
entry: cargo fmt --all --
|
||||
language: system
|
||||
types: [rust]
|
||||
pass_filenames: false
|
||||
445
Cargo.lock
generated
@@ -1,22 +1,46 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.0.2"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41"
|
||||
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.98"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
|
||||
|
||||
[[package]]
|
||||
name = "c_vec"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fdd7a427adc0135366d99db65b36dae9237130997e560ed61118041fb72be6e8"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
@@ -24,16 +48,83 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
name = "deprecate-until"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
checksum = "7a3767f826efbbe5a5ae093920b58b43b01734202be697e1354914e862e8e704"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"semver",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"r-efi",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glam"
|
||||
version = "0.30.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50a99dbe56b72736564cfa4b85bf9a33079f16ae8b74983ab06af3b1a3696b11"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.15.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "integer-sqrt"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "276ec31bcb4a9ee45f58bec6f9ec700ae4cf4f4f8f2fa7e06cb406bd5ffdd770"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.147"
|
||||
version = "0.2.174"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
|
||||
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
@@ -52,9 +143,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.5.0"
|
||||
version = "2.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
|
||||
|
||||
[[package]]
|
||||
name = "nu-ansi-term"
|
||||
@@ -67,10 +158,19 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.18.0"
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.21.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||
|
||||
[[package]]
|
||||
name = "overload"
|
||||
@@ -80,14 +180,38 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
|
||||
|
||||
[[package]]
|
||||
name = "pacman"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"glam",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"pathfinding",
|
||||
"rand",
|
||||
"sdl2",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"spin_sleep",
|
||||
"thiserror 1.0.69",
|
||||
"tracing",
|
||||
"tracing-error",
|
||||
"tracing-subscriber",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pathfinding"
|
||||
version = "4.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59ac35caa284c08f3721fb33c2741b5f763decaf42d080c8a6a722154347017e"
|
||||
dependencies = [
|
||||
"deprecate-until",
|
||||
"indexmap",
|
||||
"integer-sqrt",
|
||||
"num-traits",
|
||||
"rustc-hash",
|
||||
"thiserror 2.0.12",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -98,32 +222,56 @@ checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.66"
|
||||
version = "1.0.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9"
|
||||
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.33"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.9.1"
|
||||
name = "r-efi"
|
||||
version = "5.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575"
|
||||
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata 0.3.3",
|
||||
"regex-syntax 0.7.4",
|
||||
"regex-automata 0.4.9",
|
||||
"regex-syntax 0.8.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -137,13 +285,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.3.3"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310"
|
||||
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax 0.7.4",
|
||||
"regex-syntax 0.8.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -154,17 +302,30 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.7.4"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2"
|
||||
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
|
||||
|
||||
[[package]]
|
||||
name = "sdl2"
|
||||
version = "0.35.2"
|
||||
version = "0.38.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7959277b623f1fb9e04aea73686c3ca52f01b2145f8ea16f4ff30d8b7623b1a"
|
||||
checksum = "2d42407afc6a8ab67e36f92e80b8ba34cbdc55aaeed05249efe9a2e8d0e9feef"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"c_vec",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"sdl2-sys",
|
||||
@@ -172,15 +333,54 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sdl2-sys"
|
||||
version = "0.35.2"
|
||||
version = "0.38.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3586be2cf6c0a8099a79a12b4084357aa9b3e0b0d7980e3b67aaf7a9d55f9f0"
|
||||
checksum = "3ff61407fc75d4b0bbc93dc7e4d6c196439965fbef8e4a4f003a36095823eac0"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"vcpkg",
|
||||
"version-compare",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.219"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.219"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.141"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30b9eff21ebe718216c6ec64e1d9ac57087aad11efc64e32002bce4a0d4c03d3"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sharded-slab"
|
||||
version = "0.1.4"
|
||||
@@ -192,31 +392,70 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.11.0"
|
||||
version = "1.15.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
|
||||
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
||||
|
||||
[[package]]
|
||||
name = "spin_sleep"
|
||||
version = "1.1.1"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cafa7900db085f4354dbc7025e25d7a839a14360ea13b5fc4fd717f2d3b23134"
|
||||
checksum = "14ac0e4b54d028c2000a13895bcd84cd02a1d63c4f78e08e4ec5ec8f53efd4b9"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"winapi",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.31"
|
||||
version = "2.0.104"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398"
|
||||
checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
|
||||
dependencies = [
|
||||
"thiserror-impl 1.0.69",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "2.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
|
||||
dependencies = [
|
||||
"thiserror-impl 2.0.12",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "2.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.1.7"
|
||||
@@ -229,11 +468,10 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.37"
|
||||
version = "0.1.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
|
||||
checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"pin-project-lite",
|
||||
"tracing-attributes",
|
||||
"tracing-core",
|
||||
@@ -241,9 +479,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tracing-attributes"
|
||||
version = "0.1.26"
|
||||
version = "0.1.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab"
|
||||
checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -252,9 +490,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.31"
|
||||
version = "0.1.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a"
|
||||
checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"valuable",
|
||||
@@ -262,9 +500,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tracing-error"
|
||||
version = "0.2.0"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e"
|
||||
checksum = "8b1581020d7a273442f5b45074a6a57d5757ad0a47dac0e9f0bd57b81936f3db"
|
||||
dependencies = [
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
@@ -272,20 +510,20 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tracing-log"
|
||||
version = "0.1.3"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922"
|
||||
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"log",
|
||||
"once_cell",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-subscriber"
|
||||
version = "0.3.17"
|
||||
version = "0.3.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77"
|
||||
checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008"
|
||||
dependencies = [
|
||||
"matchers",
|
||||
"nu-ansi-term",
|
||||
@@ -311,12 +549,27 @@ version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
|
||||
[[package]]
|
||||
name = "version-compare"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.14.2+wasi-0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
|
||||
dependencies = [
|
||||
"wit-bindgen-rt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
@@ -338,3 +591,85 @@ name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.60.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.53.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-rt"
|
||||
version = "0.39.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
|
||||
dependencies = [
|
||||
"bitflags 2.9.1",
|
||||
]
|
||||
|
||||
54
Cargo.toml
@@ -1,14 +1,56 @@
|
||||
[package]
|
||||
name = "pacman"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
lazy_static = "1.4.0"
|
||||
sdl2 = { version = "0.35", features = ["image", "ttf", "mixer"] }
|
||||
spin_sleep = "1.1.1"
|
||||
tracing = { version = "0.1.37", features = ["max_level_debug", "release_max_level_warn"]}
|
||||
tracing = { version = "0.1.40", features = ["max_level_debug", "release_max_level_debug"]}
|
||||
tracing-error = "0.2.0"
|
||||
tracing-subscriber = {version = "0.3.17", features = ["env-filter"]}
|
||||
tracing-subscriber = {version = "0.3.17", features = ["env-filter"]}
|
||||
lazy_static = "1.5.0"
|
||||
sdl2 = { version = "0.38.0", features = ["image", "ttf"] }
|
||||
spin_sleep = "1.3.2"
|
||||
rand = { version = "0.9.2", default-features = false, features = ["small_rng", "os_rng"] }
|
||||
pathfinding = "4.14"
|
||||
once_cell = "1.21.3"
|
||||
thiserror = "1.0"
|
||||
anyhow = "1.0"
|
||||
glam = { version = "0.30.4", features = [] }
|
||||
serde = { version = "1.0.219", features = ["derive"] }
|
||||
serde_json = "1.0.141"
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
panic = "abort"
|
||||
opt-level = "z"
|
||||
|
||||
[target.'cfg(target_os = "windows")'.dependencies.winapi]
|
||||
version = "0.3"
|
||||
features = ["consoleapi", "fileapi", "handleapi", "processenv", "winbase", "wincon", "winnt", "winuser", "windef", "minwindef"]
|
||||
|
||||
|
||||
[target.'cfg(target_os = "emscripten")'.dependencies.sdl2]
|
||||
version = "0.38"
|
||||
default-features = false
|
||||
features = ["ttf","image","gfx","mixer"]
|
||||
|
||||
[target.'cfg(not(target_os = "emscripten"))'.dependencies.sdl2]
|
||||
version = "0.38"
|
||||
default-features = false
|
||||
features = ["ttf","image","gfx","mixer","static-link","use-vcpkg"]
|
||||
|
||||
[package.metadata.vcpkg]
|
||||
dependencies = ["sdl2", "sdl2-image", "sdl2-ttf", "sdl2-gfx", "sdl2-mixer"]
|
||||
git = "https://github.com/microsoft/vcpkg"
|
||||
rev = "2024.05.24" # release 2024.05.24 # to check for a new one, check https://github.com/microsoft/vcpkg/releases
|
||||
|
||||
[package.metadata.vcpkg.target]
|
||||
x86_64-pc-windows-msvc = { triplet = "x64-windows-static-md" }
|
||||
x86_64-unknown-linux-gnu = { triplet = "x64-linux" }
|
||||
x86_64-apple-darwin = { triplet = "x64-osx" }
|
||||
aarch64-apple-darwin = { triplet = "arm64-osx" }
|
||||
|
||||
[target.'cfg(target_os = "emscripten")'.dependencies]
|
||||
libc = "0.2.16"
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
# Implementation
|
||||
|
||||
A document detailing the implementation the project from rendering, to game logic, to build systems.
|
||||
|
||||
## Rendering
|
||||
|
||||
1. Map
|
||||
- May require procedural text generation later on (cacheable?)
|
||||
2. Pacman
|
||||
3. Ghosts
|
||||
- Requires colors
|
||||
4. Items
|
||||
5. Interface
|
||||
- Requires fonts
|
||||
|
||||
## Grid System
|
||||
|
||||
1. How does the grid system work?
|
||||
|
||||
The grid is 28 x 36 (although, the map texture is 28 x 37), and each cell is 24x24 (pixels).
|
||||
Many of the walls in the map texture only occupy a portion of the cell, so some items are able to render across multiple cells.
|
||||
24x24 assets include pellets, the energizer, and the map itself ()
|
||||
|
||||
2. What constraints must be enforced on Ghosts and PacMan?
|
||||
|
||||
3. How do movement transitions work?
|
||||
|
||||
All entities store a precise position, and a direction. This position is only used for animation, rendering, and collision purposes. Otherwise, a separate 'cell position' (which is 24 times less precise, owing to the fact that it is based on the entity's position within the grid).
|
||||
|
||||
When an entity is transitioning between cells, movement directions are acknowledged, but won't take effect until the next cell has been entered completely.
|
||||
|
||||
4. Between transitions, how does collision detection work?
|
||||
|
||||
It appears the original implementation used cell-level detection.
|
||||
I worry this may be prone to division errors. Make sure to use rounding (50% >=).
|
||||
@@ -23,6 +23,9 @@ at.
|
||||
- More than 4 ghosts
|
||||
- Custom Level Generation
|
||||
- Multi-map tunnelling
|
||||
- Online Scoreboard
|
||||
- WebAssembly build contains a special API key for communicating with server.
|
||||
- To prevent abuse, the server will only accept scores from the WebAssembly build.
|
||||
|
||||
## Installation
|
||||
|
||||
|
||||
420
STORY.md
Normal file
@@ -0,0 +1,420 @@
|
||||
# Story
|
||||
|
||||
This is living document that describes the story of the project, from inspiration to solution.
|
||||
When a website is available, this document will help curate it's content.
|
||||
|
||||
## Inspiration
|
||||
|
||||
I initially got the idea for this project after finding a video about another Pac-Man clone on YouTube.
|
||||
|
||||
[![Code Review Thumbnail][code-review-thumbnail]][code-review-video]
|
||||
|
||||
This implementation was written in C++, used SDL2 for graphics, and was kinda weird - but it worked.
|
||||
|
||||
- I think it was weird because the way it linked files together is extremely non-standard.
|
||||
Essentially, it was a single file that included all the other files. This is not how C++ projects are typically structured.
|
||||
- This implementation was also extremely dependent on OOP; Rust has no real counterpart for OOP code, so writing my own implementation would be a challenge.
|
||||
|
||||
## Lifetimes
|
||||
|
||||
Rust's SDL2 implementation is a wrapper around the C library, so it's not as nice as the C++ implementation.
|
||||
Additionally, lifetimes in this library are a bit weird, making them quite difficult to deal with.
|
||||
|
||||
I found a whole blog post complaining about this ([1][fighting-lifetimes-1], [2][fighting-lifetimes-2], [3][fighting-lifetimes-3]), so I'm not alone in this.
|
||||
|
||||
## Emscripten & RuggRogue
|
||||
|
||||
One of the targets for this project is to build a web-accessible version of the game. If you were watching at all during
|
||||
the Rust hype, one of it's primary selling points was a growing community of Rust-based web applications, thanks to
|
||||
WebAssembly.
|
||||
|
||||
The problem is that much of this work was done for pure-Rust applications - and SDL is C++.
|
||||
This requires a C++ WebAssembly compiler such as Emscripten; and it's a pain to get working.
|
||||
|
||||
Luckily though, someone else has done this before, and they fully documented it - [RuggRouge][ruggrouge].
|
||||
|
||||
- Built with Rust
|
||||
- Uses SDL2
|
||||
- Compiling for WebAssembly with Emscripten
|
||||
- Also compiles for Windows & Linux
|
||||
|
||||
This repository has been massively helpful in getting my WebAssembly builds working.
|
||||
|
||||
## Key Capturing Extensions in WASM Build
|
||||
|
||||
Some extensions I had installed were capturing keys.
|
||||
The issue presented with some keys never being sent to the application.
|
||||
To confirm, enter safe mode or switch to a different browser without said extensions.
|
||||
If the issue disappears, it's because of an extension in your browser stealing keys in a way that is incompatible with the batshit insanity of Emscripten.
|
||||
|
||||
## A Long Break
|
||||
|
||||
After hitting a wall with an issue with Emscripten where the tab would freeze after switching tabs (making it into a background tab), I decided to take a break from the project. A couple months went by without anything going on.
|
||||
|
||||
## Revisiting
|
||||
|
||||
I decided to revisit the project because I didn't want to see this project die. It's actually a lot of fun, and has a very interesting stack, with a simple premise, and a lot of potential for expansion.
|
||||
|
||||
Unfortunately, the issue above still lingered. I did a lot of testing, and concluded that I needed to create a simple example with as much stripped away as possible. All I learned from this was that the freeze occurred the moment that the 'Hidden' event (for the Window) was fired. After that, the rendered would take 0 nanoseconds to render, and some script for Asyncify would keep spinning in the background.
|
||||
|
||||
I tried to ask around but didn't get anywhere, but one reply on my post gave me the idea to back away from Emscripten 1.39.20 (several years old at this point).
|
||||
|
||||
## Emscripten Callback Main Loop
|
||||
|
||||
I looked into as many examples online (not that many), and came across an Emscripten callback loop exposed in C. Some were basic and all over the place, some were advanced, but also imbibed extremely annoying static lifetime requirements.
|
||||
|
||||
- I tried my best to satisfy and work with these lifetimes, but it was a nightmare.
|
||||
- Instead, I tried to simplify and move away from this annoying Emscripten callback loop, but simpler ones had issues, crashing with `invalid renderer` errors.
|
||||
- This guy named Greg Buchholz apparently was the creator of this special Emscripten bindings with the static lifetimes, and it was done to solve this issue with `invalid renderer`.
|
||||
- [GitHub](https://github.com/gregbuchholz), [Repository](https://github.com/gregbuchholz/RuSDLem), [StackOverflow](https://stackoverflow.com/questions/69748049/rust-sdl2-emscripten-and-invalid-renderer-panic), [Forum Post](https://users.rust-lang.org/t/sdl2-emscripten-asmjs-and-invalid-renderer-panic/66567/2)
|
||||
|
||||
With this in mind, it seemed like I was at a dead end AGAIN; either I had to deal with the static lifetimes (I am not that good at Rust), or I had to deal with Asyncify.
|
||||
|
||||
But this did help me narrow my search even more for a good example. I needed to find a repository with Rust, SDL2, Emscripten, and `TextureCreator`.
|
||||
|
||||
`TextureCreator` was key, as the static lifetimes issue was most encumbering when dealing with borrows and lifetimes of `TextureCreator` inside the `main` loop closure.
|
||||
|
||||
## Return to Asyncify
|
||||
|
||||
I found [one such repository](https://github.com/KyleMiles/Rust-SDL-Emscripten-Template/), and interestingly, it used `latest` Emscripten (not a specific target like 1.39.20), and was new enough (2 years old, but still new enough) to be relevant.
|
||||
|
||||
Even more interesting, it didn't use the `main` loop closure, but instead used Emscripten's _Asyncify_ feature to handle the main loop.
|
||||
|
||||
But, unlike my original project which called `std::thread::sleep` directly, it used bindings into Emscripten's functions like `emscripten_sleep`.
|
||||
|
||||
Even better, it had an example of script execution (JavaScript) bindings, which I could use to handle all sorts of things. I tested it out, and it worked.
|
||||
|
||||
## Instant::now() 32-bit Byte Cutoff
|
||||
|
||||
Unfortunately while trying to get basic FPS timings working, I got divide by zero errors when trying to calculate the time difference between two `Instant` times.
|
||||
|
||||
This was weird, and honestly, I'm confused as to why the 2-year old sample code 'worked' at the time, but not now.
|
||||
|
||||
After a bit of time, I noted that the `Instant` times were printing with only the whole seconds changing, and the nanoseconds were always 0.
|
||||
|
||||
```
|
||||
Instant { tv_sec: 0, tv_nsec: 0 }
|
||||
Instant { tv_sec: 1, tv_nsec: 0 }
|
||||
Instant { tv_sec: 2, tv_nsec: 0 }
|
||||
Instant { tv_sec: 3, tv_nsec: 0 }
|
||||
Instant { tv_sec: 4, tv_nsec: 0 }
|
||||
...
|
||||
```
|
||||
|
||||
This was super weird, but I stumbled upon [an issue on GitHub](https://github.com/rust-lang/rust/issues/113852) that mentioned the exact situation I was in, as well as providing a patch solution (`emscripten_get_now`).
|
||||
|
||||
## VSync Gotcha
|
||||
|
||||
After getting the timing working, I noticed that the rendering was extremely slow. I was getting 60 FPS, but I wasn't sleeping at all.
|
||||
|
||||
Normally when rendering occurs, you want to sleep for the remaining time so that your game calculations can occur at a consistent rate (60 FPS for example).
|
||||
|
||||
If your rendering time is less than the sleep time, you can just sleep for the remaining time. But if your rendering time is greater than the sleep time, you encounter lag, the FPS starts to drop.
|
||||
|
||||
This was a confusing issue as I knew it couldn't be a coincidence that the rendering time was exactly ~16ms (60 FPS) every time.
|
||||
|
||||
After a little bit though, I found the `present_vsync` function in the SDL2 render initialization. This was causing the rendering to try and time the canvas present() to the monitor's refresh rate (60 FPS).
|
||||
|
||||
Maybe I could have skipped my custom timing and just used this, but I don't know if it would be platform-independent, what would happen on 120 FPS displays, etc.
|
||||
|
||||
## Emscripten v.s. SDL2-TTF
|
||||
|
||||
While working on the next extension of SDL2 for my test repository, SDL2-TTF had some pretty annoying issues. It would build fine, but it would raise a runtime error: `indirect call to null`.
|
||||
|
||||
Luckily, I had a recently updated repository to copy off of, and the working fix was to lower the EMSDK version to `3.1.43`.
|
||||
|
||||
[Source](https://github.com/aelred/tetris/blob/0ad88153db1ca7962b42277504c0f7f9f3c675a9/tetris-sdl/src/main.rs#L34)
|
||||
|
||||
```rust
|
||||
static FONT_DATA: &[u8] = include_bytes!("../assets/TerminalVector.ttf");
|
||||
|
||||
#[cfg(not(target_os = "emscripten"))]
|
||||
fn ttf_context() -> ttf::Sdl2TtfContext {
|
||||
ttf::init().unwrap()
|
||||
}
|
||||
|
||||
#[cfg(target_os = "emscripten")]
|
||||
fn ttf_context() -> &'static ttf::Sdl2TtfContext {
|
||||
// Deliberately leak so we get a static lifetime
|
||||
Box::leak(Box::new(ttf::init().unwrap()))
|
||||
}
|
||||
|
||||
const FONT_MULTIPLE: u16 = 9;
|
||||
|
||||
// Funny division is done here to round to nearest multiple of FONT_MULTIPLE
|
||||
const FONT_SIZE: u16 = (WINDOW_HEIGHT / 32) as u16 / FONT_MULTIPLE * FONT_MULTIPLE;
|
||||
|
||||
fn main() {
|
||||
...
|
||||
|
||||
let font_data = RWops::from_bytes(FONT_DATA).unwrap();
|
||||
let font_size = max(FONT_SIZE, FONT_MULTIPLE);
|
||||
let font = ttf_context
|
||||
.load_font_from_rwops(font_data, font_size)
|
||||
.unwrap();
|
||||
}
|
||||
```
|
||||
|
||||
I don't particularly understand why loading from memory is used, but it's a neat trick. I tested normal font loading afterwards, and it seems to be totally fine.
|
||||
|
||||
On to the Mixer extension, then.
|
||||
|
||||
## Mixer and GFX
|
||||
|
||||
Mixer was relatively easy, I don't remember anything special about it.
|
||||
|
||||
As it happens, neither was SDL GFX, except for me finding that getting it compiling on Windows would soon be difficult; `SDL2_gfx` is not currently being updated, nor is it managed by the SDL team. This meant that no releases of development libraries including DLLs or LIB files were going to be available.
|
||||
|
||||
When I added in GFX, I wanted to add some mouse interaction since that currently wasn't being done anywhere in the demo, but I also wanted the ability for the mouse to be hidden until used.
|
||||
|
||||
Detecting whether the mouse was focusing the window or not wasn't super easy, and I'm still not sure that it's working perfectly, but at the very least Emscripten seems to support what I'm trying to do. I should look into asynchronous Javascript callbacks, see what Emscripten supports.
|
||||
|
||||
## Styling with PostCSS + Tailwind
|
||||
|
||||
I'm big on using Tailwind, and while this project probably could have done without it, I didn't want to forego my favorite tool.
|
||||
|
||||
But I also didn't want to include some big framework on this, like Astro, so I looked for the smallest way to include Tailwind.
|
||||
|
||||
After fiddling and failing to find Hugo suitable, I stuck to plain HTML & the PostCSS method, which worked great. It's definitely not that fast for rapid development, but it works well enough.
|
||||
|
||||
The only thing I'm unsatisfied with is why `postcss-cli` wasn't working when executed from `pnpm`. It works just fine from `pnpx`, but it has to download and setup the whole package on _every single invocation_, which is super slow. And probably expensive, in the long run.
|
||||
|
||||
## Cross-platform Builds
|
||||
|
||||
With the next step of the demo project, I needed to get builds for every OS running, that's one down out of the four targets I'm gunning for.
|
||||
|
||||
Linux was the easiest, as usual, with `apt` providing access to all the development libraries of SDL & the associated extensions, including `SDL2_gfx`.
|
||||
|
||||
There's also no requirement for providing sidecar DLLs like Windows needs, so that worked well.
|
||||
The hardest part was figuring out the most satisfying way to zip and load all the assets together, but luckily the artifact uploader provides it's own zip implementation; albeit I may need to modify it to add further system hinting (`.tar.gz` for Linux, `.dmg` for MacOS, `.zip` for Windows).
|
||||
|
||||
## SDL2 on Windows
|
||||
|
||||
SDL2 on Windows has to be one of the least fun development cycles; setting up the environment is pretty painful as there's almost no guides for Rust users to figure out each requirement. You'll learn fast, and this knowledge is hands on experience that will probably be applicable later on in C++ development, but I'm sure a fair number of Rust users like myself have no idea why a DLL or LIB file is necessary at all.
|
||||
|
||||
To be honest, I still don't.
|
||||
|
||||
Regardless, SDL2 needs a LIB file for compliation to be available in the root directory, and each extension has there own.
|
||||
|
||||
Once the EXE is compiled, the working directory needs to contain a DLL file for execution, too. Each extension has it's own as well.
|
||||
|
||||
This sounds easy, but acquiring these DLLs and LIB files is not easy. At the very least, the SDL-supported extensions have releases available containing
|
||||
|
||||

|
||||
|
||||
So I got to creating a build step involving the download of each of these libraries. I'm no expert with `curl`, but I had it figured out eventually.
|
||||
|
||||
```yaml
|
||||
- name: Download SDL2 Libraries
|
||||
run: |
|
||||
curl -L "https://github.com/libsdl-org/SDL/releases/download/release-${{ env.SDL2 }}/SDL2-devel-${{ env.SDL2 }}-VC.zip" -o "sdl2_devel.zip"
|
||||
curl -L "https://github.com/libsdl-org/SDL_mixer/releases/download/release-${{ env.SDL2_MIXER }}/SDL2_mixer-devel-${{ env.SDL2_MIXER }}-VC.zip" -o "sdl2_mixer_devel.zip"
|
||||
curl -L "https://github.com/libsdl-org/SDL_ttf/releases/download/release-${{ env.SDL2_TTF }}/SDL2_ttf-devel-${{ env.SDL2_TTF }}-VC.zip" -o "sdl2_ttf_devel.zip"
|
||||
curl -L "https://github.com/libsdl-org/SDL_image/releases/download/release-${{ env.SDL2_IMAGE }}/SDL2_image-devel-${{ env.SDL2_IMAGE }}-VC.zip" -o "sdl2_image_devel.zip"
|
||||
```
|
||||
|
||||
I did take a lot of care in making sure that versions were specified externally in different variables, which took a couple tries while I learned how interpolation works with GitHub Actions.
|
||||
|
||||
Additionally, I realized that `LIB` files were required for compliation after this, so I had to painfully fix all the files to use the `-devel-` version. Speifically the one with `-VC` appended.
|
||||
|
||||
I still do not know what VC means here. Perhaps it is related to `vcpkg` somehow.
|
||||
|
||||
The next step was to extract the files I needed from the `.zip`s, but that proved quite hard. I'm a lover of precision and using tools to the best of my knowledge, so I wanted to finely take just the DLL and ZIP I needed from these archives, and nothing else.
|
||||
|
||||
While I was able to get working commands to do this on Linux, finely finding the exact DLL and placing it in `pwd`, I was not able to replicate it on the Windows-imaged GitHub Runner;
|
||||
|
||||
When specifying the `-o` flag meaning 'output directory here' like `-o./tmp` (yes, there is no space in between), it would always error with `Too short switch: -o`. I was unable to find meaningful discussions on Google.
|
||||
|
||||
My Linux machine did not complain, and I wasn't yet ready to switch OSes for an error like this, so I just extracted everything and then `mv`'d the items into `pwd`.
|
||||
|
||||
I knew what lay ahead with `SDL2_gfx`, so I tested whether the compilation error changed, and luckily, it was only erroring on the missing `SDL2_gfx.lib` at this point.
|
||||
|
||||
While reading discussions online, I came across [a reddit post](https://www.reddit.com/r/rust_gamedev/comments/am84q9/using_sdl2_gfx_on_windows/efk6uwq/) talking about `vcpkg`. I'd heard of it, but never used the program before. It seemed like it could provide `SDL2_gfx` for me without hassle.
|
||||
|
||||
And that was partly true.
|
||||
|
||||
The primary 'boon' of `vcpkg` here was that it setup and compiled `SDL2_gfx` without the hassle of messing with the compiler, options, or most importantly: dependencies.
|
||||
|
||||
I didn't know it at the time, but `SDL2_gfx` depended on `SDL2` directly, and so I'd have to setup and compile both projects, if I was hoping to do this 'manually'.
|
||||
|
||||
## VCPKG for SDL2_GFX
|
||||
|
||||
I tried to use the GitHub-provided environment variables relating to VCPKG's installation location, but nothing really worked here. I was on the correcti mage (`windows-latest` for Windows 2022 Enterprise on GitHub's Runner Images), but nothing seemed to work.
|
||||
|
||||
[This comment](https://github.com/actions/runner-images/issues/6376#issuecomment-1781269302) seemed to describe the exact same experience I was happening, several months ago.
|
||||
|
||||
Alas, I simply tried `C:\vcpkg\` and it worked, providing me the ability to install `SDL2_gfx`.
|
||||
|
||||
As it were though, the hard part wasn't going to be compiling, but locating the DLLs and LIB files for movement. No matter where I looked online or in the logs, nothing was obvious about the location of my files.
|
||||
|
||||
In retrospect, a recursive `Get-ChildItem` looking for `DLL` or `LIB` files probably would've worked well, but.. yeah...
|
||||
|
||||
After a couple attempts with various test commits, I couldn't find it, and just switched to Windows to install and compile it myself, so I could locate the file manually.
|
||||
|
||||
> Note: VCPKG is annoying to install, the executable provided by Visual Studio Community does not permit classic-mode usage, so you'll still need to clone and bootstrap VCPKG (instructions in the repository README).
|
||||
|
||||
As it happens, they were placed in
|
||||
|
||||
- `$VCPKG_ROOT\packages\sdl2-gfx_x64-windows-release\bin\SDL2_gfx.dll` and
|
||||
- `$VCPKG_ROOT\packages\sdl2-gfx_x64-windows-release\lib\SDL2_gfx.lib` respectively.
|
||||
|
||||
This brings me to one issue, and one fix; while compiling you're required to specify that the build is for 64 bit systems manually, on each invocation of VCPKG (while in classic mode, which I am).
|
||||
|
||||
On top of that, they'll be built in debug mode (with extra symbols and such) by default, which I am not interested in.
|
||||
|
||||
To get the x64 Release build of a package, append `:x64-windows-release` to it, as in `sdl2-gfx:x64-windows-release` for `sdl2-gfx`.
|
||||
|
||||
After getting this sorted, I struggled a little bit in using the `mv` (`Move-Item`) command in Powershell, as I battled with the comma delimited files when moving multiple files to a given destination. Dumb.
|
||||
|
||||
This is also the point at which I renamed the executable from `pacman` to `spiritus` to differentiate the two projects. The name is just my play on the word 'sprite'.
|
||||
|
||||
## Console Window Hiding
|
||||
|
||||
When launching the demo app, I saw a console window pop up, even though I launched it from the File Explorer; this is not the behavior I was interested in.
|
||||
|
||||
I believe that apps launched from File Explorer shouldn't have a console window available unless...
|
||||
|
||||
- It's a CLI app by nature, and it uses the Console Window.
|
||||
- It has a specific debugging flag passed into it, perhaps by a Shortcut file.
|
||||
- The console window is required for the nature of the app, or it is the preferred method of log inspection.
|
||||
- It's a debug build.
|
||||
|
||||
But if it's launched from the console, then it should either
|
||||
|
||||
- Detach and relinquish control of the console back to the user.
|
||||
- Use the console actively in it's logging.
|
||||
|
||||
Most programs I know and use follow this general consensus. Naturally, mine must too.
|
||||
|
||||
But, when searching for a solution online, it seemed what I want doesn't really exist; I implemented the closest approximation.
|
||||
|
||||
If `stdout` is detected to be a `tty` (an active console), the console window won't be hidden. Otherwise, it will be hidden.
|
||||
|
||||
Unfortunately, this results in the millisecond flash of a black console window appearing.
|
||||
|
||||
## Updating Deprecated Actions
|
||||
|
||||
As it were, most of the actions I were using were deprecated in some way. It didn't feel like I was using super old actions, but I guess I was. Luckily, most of them were simply just updating the version (`2` or `3` to `4` or `5`).
|
||||
|
||||
`actions-rs@toolchain` was different though, and was officially deprecated, the GitHub repository archived. Couldn't find a good reason why, but the repository was untouched in 4 years, so maybe that's why...
|
||||
|
||||
I found `dtolnay@rust-toolchain` and switched, it more or less was perfect with no differences. I think it's sorta neat that the Rust version is specified using the version of the action. I'd be worried though of a changing feature set across different action versions...
|
||||
|
||||
I guess a well designed GitHub Action shouldn't change much, including a Rust toolchain action.
|
||||
|
||||
## Artifact Naming
|
||||
|
||||
Perhaps it's super unnecessary and won't be appreciated, but I wanted the artifact files produced by my script to have semantic meaning in it's version and target.
|
||||
|
||||
For each OS, I extracted the targets (`x86_64-unknown-linux-gnu`, `x86_64-apple-darwin`...) into an environment variable scoped at the job level (love that).
|
||||
|
||||
I looked into ways to get the package version, but nothing obvious jumped out at me. I did come across `toml-cli` though, a Rust-based CLI program analogous to `jq` (for JSON).
|
||||
|
||||
It worked great, but it was sorta slow; compiling `toml-cli` added an extra 20-60 seconds for each job. I'd heard of a Rust project to speed up builds by providing prebuilt executables though; it's called `binstall`.
|
||||
|
||||
Even cooler, it was had an action available to easily add it to my build script, and so I had `toml-cli` installing and available 10x faster!
|
||||
|
||||

|
||||
|
||||
Perhaps I could use some special bash commands to acquire the package version, but it'd be a lot of work and maintenance to get it working in both bash and Powershell, maintaining it across four jobs.
|
||||
|
||||
This is both cool, fast, and easy!
|
||||
|
||||

|
||||
|
||||
I was thinking of a github-pages artifact name that aligns with the others, but I think that'd be stupid AND overkill.
|
||||
|
||||
Perhaps at the least I'll look into a 32-bit build for Windows, just for demonstration purposes.
|
||||
|
||||
## My Return to Pac-Man
|
||||
|
||||
It's been 15 months since I last touched the demo codebase, and much longer since I've touched the core Pac-Man project, and I got inspired to look back into it recently. I'm finally touching up on the story document, so if this reads a bit disjointed, that's why.
|
||||
|
||||
- I switched the dependency linking to use the internal statically-linked `vcpkg` feature, which is a lot easier to maintain. It's not perfect, but it's much better than the manual downloads and the dynamically linked `.dll` files I was doing before. With caching, it also tends to be far quicker.
|
||||
- I switched all of the commits to use conventional commit messages, which is easier to read and understand.
|
||||
- I integrated the demo project's emscripten workflow, updated sdl2 and started poking around in the project. I got into adding fonts, adding a reset button, a debug mode, score tracking, pellet consumption, etc.
|
||||
- I spent a lot of time working on the audio timing, getting it to work flawlessly and compare really well with the original Pac-Man; the sound is incredibly important to the game, so I wanted to get it right.
|
||||
|
||||
## Pathfinding and Tunnelling
|
||||
|
||||
Pathfinding was very easy to get working, although tunnelling was a bit more difficult, and unfortunately I never got it working with the way I was doing things at the time. A lot of issues were happening with trying to get the transition between the tunnels to work, I could only get Pac-Man to teleport from one tunnel to the other, but moving smoothly between them was nigh impossible.
|
||||
|
||||
I did however get pathfinding to work between the tunnels, which was very satisfying to see using the debug visuals.
|
||||
|
||||
I ended up using the `pathfinding` crate and it was a breeze to use.
|
||||
|
||||
## Atlas Tiles
|
||||
|
||||
When I was looking around for Pac-Man sprites, I kept coming across atlas images, and I had been noticing for some time how my sprites were not correctly sized, and some of them just didn't match the original Pac-Man. I had been spending a lot of time making this Pac-Man project as close to the original as possible, and I felt like if I didn't use the original sprites, I wasn't doing it justice.
|
||||
|
||||
This had me thinking about how asset loading was a real pain in this project, and how I wanted to look into atlas tiles.
|
||||
|
||||
The arguments for copying between a texture and a canvas/surface/texture were very obviously rigged to allow for this, given that you had to specify the source `Rect`, meaning you could target a specific area of the texture. Such as tiles on an atlas image.
|
||||
|
||||
It didn't take long for me to get it working, I chose an existing crate called `clutterd` which provided a CLI for building atlas images with an metadata file describing the positions and sizes of the tiles.
|
||||
|
||||
Doing so required a full re-work of the animation and texture system, and I ended up making a breakthrough on how I managed lifetimes: lifetime annotations were plaguing the codebase, literally everywhere, and it was super annoying to keep writing and dealing with them.
|
||||
|
||||
So, I ended up using `unsafe` to forcibly cast the lifetimes to `'static`, which was a bit of a gamble, but given that they essentially behave as `'static` in practice, there wasn't much risk as I see it. I might re-look into my understanding of lifetimes and this in the future, but for the time being, it's a good solution that makes the codebase far easier to work with.
|
||||
|
||||
## Cross-platform Builds
|
||||
|
||||
Since the original `rust-sdl2-emscripten` demo project had cross-platform builds, I was ready to get it working for this project. For the most part, it wasn't hard, things tended to click into place, but unfortunately, the `emscripten` os target and somehow, the `linux` os target were both failing.
|
||||
|
||||
I'm still not sure what exactly causes it, but `emscripten` strongly prefers to be built on 1.86 (1.88 does not work, 1.87 might though).
|
||||
Changing the toolchain to 1.86 fixed the issue when it was failing.
|
||||
|
||||
It did turn out though, that despite me getting the `emscripten` target building, it did not mean the application was functioning properly.
|
||||
|
||||
- Upon launch, it was immediately crashing due to issues with the audio subsystem; this was fixed with a simple increase to the audio buffer chunksize, apparently it has a minimum size of 256.
|
||||
- Then, it was failing due to issues with the main loop, referencing the `ASYNCIFY_STACK_SIZE` variable in `.cargo/config.toml`, asking for it to be increased. I really didn't like the idea of increasing it for whatever reason, so I ended up looking into the `emscripten_main_loop` method of looping again, but nothing worked all that well, just like the last time I tried. So I increased the variable, doubling it from the default of 4096 to 8192. Things immediately worked, and the browser build was working.
|
||||
|
||||
Linux however was a far more annoying task, as it was failing to due the `cargo-vcpkg` build step (which built the SDL2 libraries necessary for static linking and building the project). It was hard to pin down at first, but packages seemed to be failing due to system dependencies not being available, so after adding a couple `apt` packages to the steps, things started to work.
|
||||
|
||||
Eventually though, it kept failing at the `sdl2` package, which was failing to build due to the `libpng` package not being able to find a bunch of symbols related to `zlib`. Almost nothing was written about this online, except for one issue on GitHub which hadn't been updated in 2 years.
|
||||
|
||||
I won't lie, Gemini helped me out here, suggesting adding `"-C", "link-arg=-lz",` to the `rustflags` section of `.cargo/config.toml`.
|
||||
It seems like it moved the `zlib` library to the front of the link order, and things started magically working both locally and on the GitHub Actions runner.
|
||||
|
||||
I also added an ARM64 build for MacOS, which worked without any issues. Surprisingly, MacOS is the only platform that I've been able to get working without any issues. At least, I hope it's working; I don't really have a way to test it myself.
|
||||
|
||||
## Caching
|
||||
|
||||
I spent a bit of time after this improving the build process to take advantage of caching so that most builds would fly. The `cargo-vcpkg` was by far the most expensive step, and it unfortunately, despite being in the `target` directory (which is supposed to be cached by the `Swatinem/rust-cache@v2` action), was not being cached.
|
||||
|
||||
I played with the parameters for a bit before giving up and just manually adding a cache step to the workflow. It's expensive, uploading 300MB of artifact data to GitHub, but it works well, and I'm really doubtful it will change that much.
|
||||
|
||||
I also ended up improving the build process to use `cargo metadata` to get the package version, which means I could drop the `toml-cli` dependency and just use the `cargo` command + `jq` (which is already installed on the runner).
|
||||
|
||||
## Atlas Text
|
||||
|
||||
At some point, I wanted to use the original text from the game, so I created a text texture type for rendering text using the existing sprite atlas, which means I wasn't using the `ttf` feature at all. I'm stil unsure whether or not I'll use it, I might keep it because it seems like more hassle to remove it at this point. Perhaps I'll still use normal ttf fonts like Arial for debug-related displays, or maybe I'll create/use a custom font.
|
||||
|
||||
## Node Graph Positioning
|
||||
|
||||
After getting all this working, I was really excited to finally get closer to actually finishing the project. I felt like I had finally started checking a bunch of important boxes, so I started actually working on the 'ghost house' part of Pac-Man.
|
||||
|
||||
The ghost house is very different from the rest of the game as it doesn't render the tiles in the same way, on a static grid.
|
||||
|
||||
It's actually offset by 8 pixels, and the ghosts exit the house between two tiles, requiring a lot more customization and flexibility in my
|
||||
rendering system.
|
||||
|
||||
I spent a fair bit of time trying to implement hacks into this to get it working, but I eventually gave up after realizing that there's no solution here using my existing system.
|
||||
|
||||
I remembered how I was having trouble with the transition states between the two tunnels (still not resolved), and it felt quite similar to my current situation; the inflexibility of my integer grid system was the main cause of the issue.
|
||||
|
||||
I started thinking of different ways to approach movement, and realized that the Pac-Man and Ghost's movement is quite limited and simple like railroad tracks, like nodes on a graph. Both problems could be solved by switching to a graph - most of the maze would look like a grid, each cell connected to eachother.
|
||||
|
||||
By representing one's position as a distance from the start node towards an end node, I could achieve smooth linear movement between nodes
|
||||
that, for the most part, appears to use a cell-based grid, which also allowing more customized offsets.
|
||||
|
||||
The bigger downside was that I had to toss out almost all the existing code for the game, only keeping the audio and most of the texturing system, as well as the initialization code. It also meant I was using floating points for a lot of internal state, which is not ideal.
|
||||
|
||||
This ended up being okay though, as I was able to clean up a lot of gross code, and the system ended up being easier to work with by comparison.
|
||||
|
||||
[code-review-video]: https://www.youtube.com/watch?v=OKs_JewEeOo
|
||||
[code-review-thumbnail]: https://img.youtube.com/vi/OKs_JewEeOo/hqdefault.jpg
|
||||
[fighting-lifetimes-1]: https://devcry.heiho.net/html/2022/20220709-rust-and-sdl2-fighting-with-lifetimes.html
|
||||
[fighting-lifetimes-2]: https://devcry.heiho.net/html/2022/20220716-rust-and-sdl2-fighting-with-lifetimes-2.html
|
||||
[fighting-lifetimes-3]: https://devcry.heiho.net/html/2022/20220724-rust-and-sdl2-fighting-with-lifetimes-3.html
|
||||
[ruggrogue]: https://tung.github.io/ruggrogue/
|
||||
|
Before Width: | Height: | Size: 174 B |
|
Before Width: | Height: | Size: 158 B |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 528 B |
|
Before Width: | Height: | Size: 394 B |
|
Before Width: | Height: | Size: 228 B |
|
Before Width: | Height: | Size: 370 B |
1121
assets/game/atlas.json
Normal file
BIN
assets/game/atlas.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 90 B After Width: | Height: | Size: 90 B |
BIN
assets/game/konami.ttf
Normal file
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
BIN
assets/game/sound/waka/1.ogg
Normal file
BIN
assets/game/sound/waka/2.ogg
Normal file
BIN
assets/game/sound/waka/3.ogg
Normal file
BIN
assets/game/sound/waka/4.ogg
Normal file
BIN
assets/site/TerminalVector.ttf
Normal file
23
assets/site/build.css
Normal file
@@ -0,0 +1,23 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@font-face {
|
||||
font-family: "Liberation Mono";
|
||||
src:
|
||||
url("LiberationMono.woff2") format("woff2"),
|
||||
url("LiberationMono.woff") format("woff");
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
canvas {
|
||||
@apply w-full h-[65vh] min-h-[200px] block mx-auto bg-black;
|
||||
}
|
||||
|
||||
.code {
|
||||
@apply px-1 rounded font-mono bg-zinc-900 border border-zinc-700 lowercase;
|
||||
}
|
||||
|
||||
/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0eWxlcy5zY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBIiwiZmlsZSI6ImJ1aWxkLmNzcyIsInNvdXJjZXNDb250ZW50IjpbIkB0YWlsd2luZCBiYXNlO1xuQHRhaWx3aW5kIGNvbXBvbmVudHM7XG5AdGFpbHdpbmQgdXRpbGl0aWVzO1xuXG5AZm9udC1mYWNlIHtcbiAgICBmb250LWZhbWlseTogXCJMaWJlcmF0aW9uIE1vbm9cIjtcbiAgICBzcmM6XG4gICAgICAgIHVybChcIkxpYmVyYXRpb25Nb25vLndvZmYyXCIpIGZvcm1hdChcIndvZmYyXCIpLFxuICAgICAgICB1cmwoXCJMaWJlcmF0aW9uTW9uby53b2ZmXCIpIGZvcm1hdChcIndvZmZcIik7XG4gICAgZm9udC13ZWlnaHQ6IG5vcm1hbDtcbiAgICBmb250LXN0eWxlOiBub3JtYWw7XG4gICAgZm9udC1kaXNwbGF5OiBzd2FwO1xufVxuXG5jYW52YXMge1xuICAgIEBhcHBseSB3LWZ1bGwgaC1bNjV2aF0gbWluLWgtWzIwMHB4XSBibG9jayBteC1hdXRvIGJnLWJsYWNrO1xufVxuXG4uY29kZSB7XG4gICAgQGFwcGx5IHB4LTEgcm91bmRlZCBmb250LW1vbm8gYmctemluYy05MDAgYm9yZGVyIGJvcmRlci16aW5jLTcwMCBsb3dlcmNhc2U7XG59XG4iXX0= */
|
||||
BIN
assets/site/favicon.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
65
assets/site/index.html
Normal file
@@ -0,0 +1,65 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Pac-Man Arcade</title>
|
||||
<link rel="stylesheet" href="build.css" />
|
||||
<style>
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-black text-yellow-400 text-center">
|
||||
<a
|
||||
href="https://github.com/Xevion/Pac-Man"
|
||||
class="absolute top-0 right-0"
|
||||
aria-label="View source on GitHub"
|
||||
>
|
||||
<svg
|
||||
width="80"
|
||||
height="80"
|
||||
viewBox="0 0 250 250"
|
||||
class="fill-yellow-400 text-black"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
|
||||
<path
|
||||
d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2"
|
||||
class="octo-arm"
|
||||
></path>
|
||||
<path
|
||||
d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z"
|
||||
class="octo-body"
|
||||
></path>
|
||||
</svg>
|
||||
</a>
|
||||
<h1 class="text-4xl mt-10 scaled-text">Pac-Man Arcade</h1>
|
||||
<p class="text-lg mt-5 scaled-text">
|
||||
Welcome to the Pac-Man Arcade! Use the controls below to play.
|
||||
</p>
|
||||
<canvas
|
||||
id="canvas"
|
||||
class="block mx-auto mt-5"
|
||||
width="800"
|
||||
height="600"
|
||||
></canvas>
|
||||
<div class="mt-10">
|
||||
<span
|
||||
class="inline-block mx-2 px-4 py-2 bg-yellow-400 text-black rounded scaled-text"
|
||||
>← ↑ → ↓ Move</span
|
||||
>
|
||||
<span
|
||||
class="inline-block mx-2 px-4 py-2 bg-yellow-400 text-black rounded scaled-text"
|
||||
>Space Change Sprite</span
|
||||
>
|
||||
<span
|
||||
class="inline-block mx-2 px-4 py-2 bg-yellow-400 text-black rounded scaled-text"
|
||||
>Shift + ↑↓ Change Volume</span
|
||||
>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
var Module = {
|
||||
canvas: document.getElementById("canvas"),
|
||||
};
|
||||
</script>
|
||||
<script type="text/javascript" src="pacman.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
21
assets/site/styles.scss
Normal file
@@ -0,0 +1,21 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@font-face {
|
||||
font-family: "Liberation Mono";
|
||||
src:
|
||||
url("LiberationMono.woff2") format("woff2"),
|
||||
url("LiberationMono.woff") format("woff");
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
canvas {
|
||||
@apply w-full h-[65vh] min-h-[200px] block mx-auto bg-black;
|
||||
}
|
||||
|
||||
.code {
|
||||
@apply px-1 rounded font-mono bg-zinc-900 border border-zinc-700 lowercase;
|
||||
}
|
||||
BIN
assets/unpacked/cutscene/general_6_10.png
Normal file
|
After Width: | Height: | Size: 120 B |
BIN
assets/unpacked/cutscene/general_6_11.png
Normal file
|
After Width: | Height: | Size: 120 B |
BIN
assets/unpacked/cutscene/general_6_12.png
Normal file
|
After Width: | Height: | Size: 116 B |
BIN
assets/unpacked/cutscene/general_6_9.png
Normal file
|
After Width: | Height: | Size: 115 B |
BIN
assets/unpacked/cutscene/general_7_10.png
Normal file
|
After Width: | Height: | Size: 192 B |
BIN
assets/unpacked/cutscene/general_7_11.png
Normal file
|
After Width: | Height: | Size: 187 B |
BIN
assets/unpacked/cutscene/general_7_8.png
Normal file
|
After Width: | Height: | Size: 196 B |
BIN
assets/unpacked/cutscene/general_7_9.png
Normal file
|
After Width: | Height: | Size: 215 B |
BIN
assets/unpacked/cutscene/general_8_10.png
Normal file
|
After Width: | Height: | Size: 107 B |
BIN
assets/unpacked/cutscene/general_8_11.png
Normal file
|
After Width: | Height: | Size: 189 B |
BIN
assets/unpacked/cutscene/general_8_8.png
Normal file
|
After Width: | Height: | Size: 115 B |
BIN
assets/unpacked/cutscene/general_8_9.png
Normal file
|
After Width: | Height: | Size: 195 B |
BIN
assets/unpacked/cutscene/general_9_10.png
Normal file
|
After Width: | Height: | Size: 177 B |
BIN
assets/unpacked/cutscene/general_9_11.png
Normal file
|
After Width: | Height: | Size: 177 B |
BIN
assets/unpacked/cutscene/general_9_8.png
Normal file
|
After Width: | Height: | Size: 125 B |
BIN
assets/unpacked/cutscene/general_9_9.png
Normal file
|
After Width: | Height: | Size: 122 B |
BIN
assets/unpacked/edible/apple.png
Normal file
|
After Width: | Height: | Size: 173 B |
BIN
assets/unpacked/edible/bell.png
Normal file
|
After Width: | Height: | Size: 175 B |
BIN
assets/unpacked/edible/cherry.png
Normal file
|
After Width: | Height: | Size: 213 B |
BIN
assets/unpacked/edible/galaxian.png
Normal file
|
After Width: | Height: | Size: 178 B |
BIN
assets/unpacked/edible/key.png
Normal file
|
After Width: | Height: | Size: 162 B |
BIN
assets/unpacked/edible/melon.png
Normal file
|
After Width: | Height: | Size: 210 B |
BIN
assets/unpacked/edible/orange.png
Normal file
|
After Width: | Height: | Size: 177 B |
BIN
assets/unpacked/edible/strawberry.png
Normal file
|
After Width: | Height: | Size: 195 B |
BIN
assets/unpacked/effects/100.png
Normal file
|
After Width: | Height: | Size: 136 B |
BIN
assets/unpacked/effects/1000.png
Normal file
|
After Width: | Height: | Size: 137 B |
BIN
assets/unpacked/effects/1600.png
Normal file
|
After Width: | Height: | Size: 147 B |
BIN
assets/unpacked/effects/200.png
Normal file
|
After Width: | Height: | Size: 139 B |
BIN
assets/unpacked/effects/2000.png
Normal file
|
After Width: | Height: | Size: 148 B |
BIN
assets/unpacked/effects/300.png
Normal file
|
After Width: | Height: | Size: 149 B |
BIN
assets/unpacked/effects/3000.png
Normal file
|
After Width: | Height: | Size: 152 B |
BIN
assets/unpacked/effects/400.png
Normal file
|
After Width: | Height: | Size: 135 B |
BIN
assets/unpacked/effects/500.png
Normal file
|
After Width: | Height: | Size: 150 B |
BIN
assets/unpacked/effects/5000.png
Normal file
|
After Width: | Height: | Size: 151 B |
BIN
assets/unpacked/effects/700.png
Normal file
|
After Width: | Height: | Size: 145 B |
BIN
assets/unpacked/effects/800.png
Normal file
|
After Width: | Height: | Size: 135 B |
BIN
assets/unpacked/ghost/blinky/down_a.png
Normal file
|
After Width: | Height: | Size: 181 B |
BIN
assets/unpacked/ghost/blinky/down_b.png
Normal file
|
After Width: | Height: | Size: 178 B |
BIN
assets/unpacked/ghost/blinky/left_a.png
Normal file
|
After Width: | Height: | Size: 184 B |
BIN
assets/unpacked/ghost/blinky/left_b.png
Normal file
|
After Width: | Height: | Size: 181 B |
BIN
assets/unpacked/ghost/blinky/right_a.png
Normal file
|
After Width: | Height: | Size: 183 B |
BIN
assets/unpacked/ghost/blinky/right_b.png
Normal file
|
After Width: | Height: | Size: 181 B |
BIN
assets/unpacked/ghost/blinky/up_a.png
Normal file
|
After Width: | Height: | Size: 177 B |
BIN
assets/unpacked/ghost/blinky/up_b.png
Normal file
|
After Width: | Height: | Size: 175 B |
BIN
assets/unpacked/ghost/clyde/down_a.png
Normal file
|
After Width: | Height: | Size: 189 B |
BIN
assets/unpacked/ghost/clyde/down_b.png
Normal file
|
After Width: | Height: | Size: 187 B |
BIN
assets/unpacked/ghost/clyde/left_a.png
Normal file
|
After Width: | Height: | Size: 194 B |
BIN
assets/unpacked/ghost/clyde/left_b.png
Normal file
|
After Width: | Height: | Size: 191 B |
BIN
assets/unpacked/ghost/clyde/right_a.png
Normal file
|
After Width: | Height: | Size: 194 B |
BIN
assets/unpacked/ghost/clyde/right_b.png
Normal file
|
After Width: | Height: | Size: 190 B |
BIN
assets/unpacked/ghost/clyde/up_a.png
Normal file
|
After Width: | Height: | Size: 184 B |
BIN
assets/unpacked/ghost/clyde/up_b.png
Normal file
|
After Width: | Height: | Size: 179 B |
BIN
assets/unpacked/ghost/eyes/down.png
Normal file
|
After Width: | Height: | Size: 127 B |
BIN
assets/unpacked/ghost/eyes/left.png
Normal file
|
After Width: | Height: | Size: 135 B |
BIN
assets/unpacked/ghost/eyes/right.png
Normal file
|
After Width: | Height: | Size: 134 B |
BIN
assets/unpacked/ghost/eyes/up.png
Normal file
|
After Width: | Height: | Size: 134 B |
BIN
assets/unpacked/ghost/frightened/blue_a.png
Normal file
|
After Width: | Height: | Size: 190 B |
BIN
assets/unpacked/ghost/frightened/blue_b.png
Normal file
|
After Width: | Height: | Size: 186 B |
BIN
assets/unpacked/ghost/frightened/white_a.png
Normal file
|
After Width: | Height: | Size: 183 B |
BIN
assets/unpacked/ghost/frightened/white_b.png
Normal file
|
After Width: | Height: | Size: 183 B |
BIN
assets/unpacked/ghost/inky/down_a.png
Normal file
|
After Width: | Height: | Size: 177 B |
BIN
assets/unpacked/ghost/inky/down_b.png
Normal file
|
After Width: | Height: | Size: 175 B |
BIN
assets/unpacked/ghost/inky/left_a.png
Normal file
|
After Width: | Height: | Size: 183 B |
BIN
assets/unpacked/ghost/inky/left_b.png
Normal file
|
After Width: | Height: | Size: 180 B |
BIN
assets/unpacked/ghost/inky/right_a.png
Normal file
|
After Width: | Height: | Size: 182 B |
BIN
assets/unpacked/ghost/inky/right_b.png
Normal file
|
After Width: | Height: | Size: 179 B |
BIN
assets/unpacked/ghost/inky/up_a.png
Normal file
|
After Width: | Height: | Size: 173 B |