Compare commits

...

37 Commits

Author SHA1 Message Date
Ryan Walters
7ede82cc5d feat: add pacman-common/pacman-server crates 2025-09-16 09:36:12 -05:00
Ryan Walters
d0ee7db2ef fix: update workspace Cargo.toml, README.md workspace distinctions 2025-09-16 09:19:23 -05:00
Ryan Walters
a3c4c94d42 refactor: create workspace, move 'pacman' into pacman/ subfolder as workspace member 2025-09-16 01:07:16 -05:00
Ryan Walters
841cf5b83e feat: implement pause state management and single tick command 2025-09-11 17:03:24 -05:00
Ryan Walters
a887fae00f feat: separate player/ghost collider sizes, move fruit sprite up 1 pixel, add fruit TTL 2025-09-11 14:46:07 -05:00
Ryan Walters
273385dfe4 refactor: improve audio system states, add try_new(), organize constants, volume memory 2025-09-11 14:45:48 -05:00
Ryan Walters
82cedf7e4a fix: remove ConsoleInit condition, add ToggleFullscreen condition, helper 'push' just recipe 2025-09-11 13:49:44 -05:00
Ryan Walters
b58a7a8f63 chore: bump version, add 'dev-release' debug profile 2025-09-11 13:46:05 -05:00
Ryan Walters
f340de80f3 feat: subsystem toggling via feature, release mode console allocation with ANSI, desktop file subscriber 2025-09-11 13:45:01 -05:00
Ryan Walters
d9ea79db74 fix: only run most workflows against 'master' branch 2025-09-11 09:41:21 -05:00
Ryan Walters
126b6ff378 feat: fullscreen toggle key 2025-09-11 09:10:19 -05:00
Ryan Walters
36e9de1a1f chore: bump to v0.80.0, update ROADMAP.md 2025-09-11 02:26:39 -05:00
Ryan Walters
9ad1704806 feat(audio): setup intro jingle, use fruit & ghost sounds, improve AudioEvent 2025-09-11 02:24:15 -05:00
Ryan Walters
86331afd52 refactor(audio): rename eat() to waka(), use play(Sound) for death() instead 2025-09-11 02:11:57 -05:00
Ryan Walters
cca205fe95 chore: compress .ogg audio files 2025-09-11 02:01:44 -05:00
Ryan Walters
00a65954e6 refactor: unify cross-platform asset loading, avoid hard-coding with folder-based asset embedding for desktop 2025-09-11 01:11:00 -05:00
Ryan Walters
43532dac56 feat(audio): centralize sound management with proper enum, improved iterator protocols, introduce new sound files 2025-09-11 00:40:09 -05:00
Ryan Walters
08c964c32e feat: re-implement pausing mechanism with tick-perfect audio & state pauses 2025-09-11 00:03:14 -05:00
Ryan Walters
8b2d18b3da chore: add 'fix' just recipe, remove temp ignore lines 2025-09-10 23:10:27 -05:00
Ryan Walters
46a73c5ace fix: solve audio glitch/crackling on Emscripten via use higher buffer and AUDIO_S16LSB 2025-09-10 23:08:46 -05:00
Ryan Walters
a2783ae62d refactor: refine asset enum, move around audio files, use OGG for death sound 2025-09-10 22:53:19 -05:00
Ryan Walters
83e0d1d737 fix: FruitSprites resource for common tests, disable Exit command bindings on Emscripten, update ROADMAP.md 2025-09-10 22:08:32 -05:00
Ryan Walters
d86864b6a3 feat: fruit display hud 2025-09-10 22:00:11 -05:00
Ryan Walters
d7a6ee7684 fix: flush world after switching to observer-based item collection 2025-09-10 21:45:10 -05:00
Ryan Walters
d84f0c831e feat: proper scheduling via SystemSet, non-conditional game systems, better collision handling 2025-09-10 21:36:51 -05:00
Ryan Walters
ae19ca1795 feat: rewrite ghost/item collision eventing into trigger-based observer 2025-09-10 17:15:15 -05:00
Ryan Walters
abf341d753 fix: avoid constant recalculation of max character height in TtfAtlas 2025-09-10 14:09:07 -05:00
Ryan Walters
7b6dad0c74 refactor: remove unused component, simplify visibility check defaulting behavior, reformat STORY.md 2025-09-10 11:17:12 -05:00
Ryan Walters
5563b64044 refactor: replace immutable Hidden component with mutable Visibility component 2025-09-10 00:45:16 -05:00
Ryan Walters
cb691b0907 refactor: move animation components into new systems/animation submodule 2025-09-10 00:26:49 -05:00
Ryan Walters
ce8ea347e1 refactor: reorganize hud-related elements into systems/hud submodule 2025-09-09 17:00:32 -05:00
Ryan Walters
afae3c5e7b fix: restore target_os for linux linker arg, add documentation detail 2025-09-09 16:49:01 -05:00
Ryan Walters
4f7902fc50 fix: cfg on ConsoleInit for windows/emscripten, use simplified cfg for windows/linux 2025-09-09 16:41:59 -05:00
Ryan Walters
2a2cca675a fix: cfg limit tracing_buffer to windows only 2025-09-09 16:27:35 -05:00
Ryan Walters
f3a6b72931 chore: remove unused tests, fixup README & disable bad markdown lints 2025-09-09 14:22:06 -05:00
Ryan Walters
ca006b5073 refactor: remove dead code, tune lints, remove useless tests 2025-09-09 14:22:06 -05:00
Ryan Walters
139afb2d40 chore: update ROADMAP.md with latest progress, detail core feature targets & mechanics 2025-09-09 11:42:26 -05:00
311 changed files with 5148 additions and 2997 deletions

View File

@@ -1,17 +1,23 @@
[target.'cfg(target_os = "emscripten")']
rustflags = [
# 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/",
"-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 pacman/assets/game/",
]
runner = "node"
# despite being semantically identical to `target_os = "linux"`, the `cfg(linux)` syntax is not supported here. Who knows why...
# https://github.com/Xevion/Pac-Man/actions/runs/17596477856
[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",
"-C",
"link-arg=-lz",
]

View File

@@ -1,5 +1,13 @@
name: Builds
on: ["push", "pull_request"]
on:
push:
branches:
- master
pull_request:
branches:
- master
workflow_dispatch:
permissions:
contents: write
@@ -45,7 +53,7 @@ jobs:
uses: actions/cache@v4
with:
path: target/vcpkg
key: A-vcpkg-${{ runner.os }}-${{ matrix.target }}-${{ hashFiles('Cargo.toml', 'Cargo.lock') }}
key: A-vcpkg-${{ runner.os }}-${{ matrix.target }}-${{ hashFiles('pacman/Cargo.toml', 'pacman/Cargo.lock') }}
restore-keys: |
A-vcpkg-${{ runner.os }}-${{ matrix.target }}-
@@ -59,9 +67,11 @@ jobs:
run: |
cargo install cargo-vcpkg
cargo vcpkg -v build
working-directory: pacman
- name: Build
run: cargo build --release
working-directory: pacman
- name: Acquire Package Version
id: get_version
@@ -69,6 +79,7 @@ jobs:
run: |
set -euo pipefail # exit on error
echo "version=$(cargo metadata --format-version 1 --no-deps | jq '.packages[0].version' -r)" >> $GITHUB_OUTPUT
working-directory: pacman
- name: Upload Artifact
uses: actions/upload-artifact@v4
@@ -123,7 +134,7 @@ jobs:
echo "Build attempt $attempt of $MAX_RETRIES"
# Capture output and check for specific error while preserving real-time output
if bun run -i web.build.ts 2>&1 | tee /tmp/build_output.log; then
if bun run -i pacman/web.build.ts 2>&1 | tee /tmp/build_output.log; then
echo "Build successful on attempt $attempt"
break
else

View File

@@ -1,6 +1,13 @@
name: Checks
on: ["push", "pull_request"]
on:
push:
branches:
- master
pull_request:
branches:
- master
workflow_dispatch:
env:
CARGO_TERM_COLOR: always
@@ -27,7 +34,7 @@ jobs:
uses: actions/cache@v4
with:
path: target/vcpkg
key: A-vcpkg-${{ runner.os }}-${{ hashFiles('Cargo.toml', 'Cargo.lock') }}
key: A-vcpkg-${{ runner.os }}-${{ hashFiles('pacman/Cargo.toml', 'pacman/Cargo.lock') }}
restore-keys: |
A-vcpkg-${{ runner.os }}-
@@ -40,14 +47,18 @@ jobs:
run: |
cargo install cargo-vcpkg
cargo vcpkg -v build
working-directory: pacman
- name: Run clippy
run: cargo clippy -- -D warnings
working-directory: pacman
- name: Check formatting
run: cargo fmt -- --check
working-directory: pacman
- uses: taiki-e/install-action@cargo-audit
- name: Run security audit
run: cargo audit
working-directory: pacman

View File

@@ -1,6 +1,12 @@
name: Code Coverage
on: ["push", "pull_request"]
on:
push:
branches:
- master
pull_request:
branches:
- master
env:
CARGO_TERM_COLOR: always
@@ -26,7 +32,7 @@ jobs:
uses: actions/cache@v4
with:
path: target/vcpkg
key: A-vcpkg-${{ runner.os }}-${{ hashFiles('Cargo.toml', 'Cargo.lock') }}
key: A-vcpkg-${{ runner.os }}-${{ hashFiles('pacman/Cargo.toml', 'pacman/Cargo.lock') }}
restore-keys: |
A-vcpkg-${{ runner.os }}-
@@ -39,6 +45,7 @@ jobs:
run: |
cargo install cargo-vcpkg
cargo vcpkg -v build
working-directory: pacman
- uses: taiki-e/install-action@cargo-llvm-cov
- uses: taiki-e/install-action@nextest
@@ -47,6 +54,7 @@ jobs:
- name: Generate coverage report
run: |
just coverage
working-directory: pacman
- name: Coveralls upload
uses: coverallsapp/github-action@v2

View File

@@ -1,6 +1,13 @@
name: Tests
on: ["push", "pull_request"]
on:
push:
branches:
- master
pull_request:
branches:
- master
workflow_dispatch:
env:
CARGO_TERM_COLOR: always
@@ -26,7 +33,7 @@ jobs:
uses: actions/cache@v4
with:
path: target/vcpkg
key: A-vcpkg-${{ runner.os }}-${{ hashFiles('Cargo.toml', 'Cargo.lock') }}
key: A-vcpkg-${{ runner.os }}-${{ hashFiles('pacman/Cargo.toml', 'pacman/Cargo.lock') }}
restore-keys: |
A-vcpkg-${{ runner.os }}-
@@ -39,8 +46,10 @@ jobs:
run: |
cargo install cargo-vcpkg
cargo vcpkg -v build
working-directory: pacman
- uses: taiki-e/install-action@nextest
- name: Run nextest
run: cargo nextest run --workspace
working-directory: pacman

7
.gitignore vendored
View File

@@ -10,7 +10,7 @@ emsdk/
# Site build f iles
tailwindcss-*
assets/site/build.css
pacman/assets/site/build.css
# Coverage reports
lcov.info
@@ -21,6 +21,5 @@ coverage.html
flamegraph.svg
/profile.*
# temporary
assets/game/sound/*.wav
/*.py
# Logs
*.log

View File

@@ -30,28 +30,14 @@ repos:
- id: cargo-check
name: cargo check
entry: cargo check --all-targets
entry: cargo check --workspace --all-targets
language: system
types_or: [rust, cargo, cargo-lock]
pass_filenames: false
- id: cargo-check-wasm
name: cargo check for wasm32-unknown-emscripten
entry: cargo check --all-targets --target=wasm32-unknown-emscripten
entry: cargo check -p pacman --all-targets --target=wasm32-unknown-emscripten
language: system
types_or: [rust, cargo, cargo-lock]
pass_filenames: false
- id: bump-version
name: bump version based on commit message
entry: python scripts/bump-version.py
language: system
stages: [commit-msg]
always_run: true
- id: tag-version
name: tag version based on commit message
entry: python scripts/tag-version.py
language: system
stages: [post-commit]
always_run: true

306
Cargo.lock generated
View File

@@ -36,9 +36,9 @@ dependencies = [
[[package]]
name = "async-executor"
version = "1.13.2"
version = "1.13.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb812ffb58524bdd10860d7d974e2f01cc0950c2438a74ee5ec2e2280c6c4ffa"
checksum = "497c00e0fd83a72a79a39fcbd8e3e2f055d6f6c7e025f3b3d91f4f8e76527fb8"
dependencies = [
"async-task",
"concurrent-queue",
@@ -228,6 +228,15 @@ dependencies = [
"serde",
]
[[package]]
name = "block-buffer"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"generic-array",
]
[[package]]
name = "bumpalo"
version = "3.19.0"
@@ -248,9 +257,9 @@ checksum = "fdd7a427adc0135366d99db65b36dae9237130997e560ed61118041fb72be6e8"
[[package]]
name = "cfg-if"
version = "1.0.0"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9"
[[package]]
name = "circular-buffer"
@@ -268,6 +277,15 @@ dependencies = [
"portable-atomic",
]
[[package]]
name = "cpufeatures"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
dependencies = [
"libc",
]
[[package]]
name = "critical-section"
version = "1.2.0"
@@ -289,6 +307,16 @@ version = "0.8.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
[[package]]
name = "crypto-common"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
"generic-array",
"typenum",
]
[[package]]
name = "deprecate-until"
version = "0.1.1"
@@ -337,6 +365,16 @@ version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
]
[[package]]
name = "disqualified"
version = "1.0.0"
@@ -357,11 +395,12 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "erased-serde"
version = "0.4.6"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e004d887f51fcb9fef17317a2f3525c887d8aa3f4f50fed920816a688284a5b7"
checksum = "259d404d09818dec19332e31d94558aeb442fea04c817006456c24b5460bbd4b"
dependencies = [
"serde",
"serde_core",
"typeid",
]
@@ -408,6 +447,16 @@ dependencies = [
"pin-project-lite",
]
[[package]]
name = "generic-array"
version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "getrandom"
version = "0.3.3"
@@ -446,9 +495,9 @@ dependencies = [
[[package]]
name = "hashbrown"
version = "0.15.4"
version = "0.15.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5"
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
dependencies = [
"equivalent",
"serde",
@@ -473,9 +522,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "indexmap"
version = "2.10.0"
version = "2.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661"
checksum = "92119844f513ffa41556430369ab02c295a3578af21cf945caa3e9e0c2481ac3"
dependencies = [
"equivalent",
"hashbrown",
@@ -498,9 +547,9 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]]
name = "js-sys"
version = "0.3.77"
version = "0.3.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
checksum = "0c0b063578492ceec17683ef2f8c5e89121fbd0b172cbc280635ab7567db2738"
dependencies = [
"once_cell",
"wasm-bindgen",
@@ -530,9 +579,9 @@ dependencies = [
[[package]]
name = "log"
version = "0.4.20"
version = "0.4.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
[[package]]
name = "matchers"
@@ -663,7 +712,7 @@ checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "pacman"
version = "0.78.4"
version = "0.81.1"
dependencies = [
"anyhow",
"bevy_ecs",
@@ -678,6 +727,7 @@ dependencies = [
"phf",
"pretty_assertions",
"rand",
"rust-embed",
"sdl2",
"serde",
"serde_json",
@@ -696,6 +746,14 @@ dependencies = [
"windows-sys 0.61.0",
]
[[package]]
name = "pacman-common"
version = "0.1.1"
[[package]]
name = "pacman-server"
version = "0.1.1"
[[package]]
name = "parking"
version = "2.2.1"
@@ -784,9 +842,9 @@ dependencies = [
[[package]]
name = "pin-project-lite"
version = "0.2.13"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
[[package]]
name = "portable-atomic"
@@ -830,9 +888,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.95"
version = "1.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de"
dependencies = [
"unicode-ident",
]
@@ -892,9 +950,9 @@ dependencies = [
[[package]]
name = "regex-automata"
version = "0.4.9"
version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6"
dependencies = [
"aho-corasick",
"memchr",
@@ -903,9 +961,43 @@ dependencies = [
[[package]]
name = "regex-syntax"
version = "0.8.5"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001"
[[package]]
name = "rust-embed"
version = "8.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "025908b8682a26ba8d12f6f2d66b987584a4a87bc024abc5bbc12553a8cd178a"
dependencies = [
"rust-embed-impl",
"rust-embed-utils",
"walkdir",
]
[[package]]
name = "rust-embed-impl"
version = "8.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6065f1a4392b71819ec1ea1df1120673418bf386f50de1d6f54204d836d4349c"
dependencies = [
"proc-macro2",
"quote",
"rust-embed-utils",
"syn",
"walkdir",
]
[[package]]
name = "rust-embed-utils"
version = "8.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6cc0c81648b20b70c491ff8cce00c1c3b223bb8ed2b5d41f0e54c6c4c0a3594"
dependencies = [
"sha2",
"walkdir",
]
[[package]]
name = "rustc-hash"
@@ -925,6 +1017,15 @@ version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
[[package]]
name = "same-file"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
dependencies = [
"winapi-util",
]
[[package]]
name = "scopeguard"
version = "1.2.0"
@@ -958,24 +1059,34 @@ dependencies = [
[[package]]
name = "semver"
version = "1.0.26"
version = "1.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0"
checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
[[package]]
name = "serde"
version = "1.0.219"
version = "1.0.225"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
checksum = "fd6c24dee235d0da097043389623fb913daddf92c76e9f5a1db88607a0bcbd1d"
dependencies = [
"serde_core",
"serde_derive",
]
[[package]]
name = "serde_core"
version = "1.0.225"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "659356f9a0cb1e529b24c01e43ad2bdf520ec4ceaf83047b83ddcc2251f96383"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.219"
version = "1.0.225"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
checksum = "0ea936adf78b1f766949a4977b91d2f5595825bd6ec079aa9543ad2685fc4516"
dependencies = [
"proc-macro2",
"quote",
@@ -984,21 +1095,33 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.143"
version = "1.0.145"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a"
checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c"
dependencies = [
"itoa",
"memchr",
"ryu",
"serde",
"serde_core",
]
[[package]]
name = "sha2"
version = "0.10.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "sharded-slab"
version = "0.1.4"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31"
checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
dependencies = [
"lazy_static",
]
@@ -1084,9 +1207,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.104"
version = "2.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6"
dependencies = [
"proc-macro2",
"quote",
@@ -1121,12 +1244,11 @@ checksum = "3bf63baf9f5039dadc247375c29eb13706706cfde997d0330d05aa63a77d8820"
[[package]]
name = "thread_local"
version = "1.1.7"
version = "1.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152"
checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185"
dependencies = [
"cfg-if",
"once_cell",
]
[[package]]
@@ -1254,10 +1376,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c"
[[package]]
name = "unicode-ident"
version = "1.0.11"
name = "typenum"
version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
[[package]]
name = "unicode-ident"
version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d"
[[package]]
name = "unicode-xid"
@@ -1267,9 +1395,9 @@ checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
[[package]]
name = "uuid"
version = "1.18.0"
version = "1.18.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f33196643e165781c20a5ead5582283a7dacbb87855d867fbc2df3f81eddc1be"
checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2"
dependencies = [
"getrandom",
"js-sys",
@@ -1279,9 +1407,9 @@ dependencies = [
[[package]]
name = "valuable"
version = "0.1.0"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
[[package]]
name = "variadics_please"
@@ -1307,31 +1435,57 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29"
[[package]]
name = "wasi"
version = "0.14.2+wasi-0.2.4"
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "walkdir"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
dependencies = [
"wit-bindgen-rt",
"same-file",
"winapi-util",
]
[[package]]
name = "wasi"
version = "0.14.7+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c"
dependencies = [
"wasip2",
]
[[package]]
name = "wasip2"
version = "1.0.1+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7"
dependencies = [
"wit-bindgen",
]
[[package]]
name = "wasm-bindgen"
version = "0.2.100"
version = "0.2.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
checksum = "7e14915cadd45b529bb8d1f343c4ed0ac1de926144b746e2710f9cd05df6603b"
dependencies = [
"cfg-if",
"once_cell",
"rustversion",
"wasm-bindgen-macro",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.100"
version = "0.2.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
checksum = "e28d1ba982ca7923fd01448d5c30c6864d0a14109560296a162f80f305fb93bb"
dependencies = [
"bumpalo",
"log",
@@ -1343,9 +1497,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.100"
version = "0.2.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
checksum = "7c3d463ae3eff775b0c45df9da45d68837702ac35af998361e2c84e7c5ec1b0d"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@@ -1353,9 +1507,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.100"
version = "0.2.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
checksum = "7bb4ce89b08211f923caf51d527662b75bdc9c9c7aab40f86dcb9fb85ac552aa"
dependencies = [
"proc-macro2",
"quote",
@@ -1366,18 +1520,18 @@ dependencies = [
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.100"
version = "0.2.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
checksum = "f143854a3b13752c6950862c906306adb27c7e839f7414cec8fea35beab624c1"
dependencies = [
"unicode-ident",
]
[[package]]
name = "web-sys"
version = "0.3.77"
version = "0.3.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2"
checksum = "77e4b637749ff0d92b8fad63aa1f7cff3cbe125fd49c175cd6345e7272638b12"
dependencies = [
"js-sys",
"wasm-bindgen",
@@ -1396,6 +1550,15 @@ dependencies = [
"web-sys",
]
[[package]]
name = "winapi-util"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
dependencies = [
"windows-sys 0.61.0",
]
[[package]]
name = "windows"
version = "0.62.0"
@@ -1591,21 +1754,18 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "winnow"
version = "0.7.12"
version = "0.7.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95"
checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf"
dependencies = [
"memchr",
]
[[package]]
name = "wit-bindgen-rt"
version = "0.39.0"
name = "wit-bindgen"
version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
dependencies = [
"bitflags 2.9.4",
]
checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
[[package]]
name = "yansi"
@@ -1615,18 +1775,18 @@ checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
[[package]]
name = "zerocopy"
version = "0.8.26"
version = "0.8.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f"
checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.8.26"
version = "0.8.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181"
checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831"
dependencies = [
"proc-macro2",
"quote",

View File

@@ -1,10 +1,10 @@
[package]
name = "pacman"
version = "0.78.4"
[workspace]
members = ["pacman", "pacman-common", "pacman-server"]
resolver = "2"
[workspace.package]
authors = ["Xevion"]
edition = "2021"
rust-version = "1.86.0"
description = "A cross-platform retro Pac-Man clone, written in Rust and supported by SDL2"
readme = true
homepage = "https://pacman.xevion.dev"
repository = "https://github.com/Xevion/Pac-Man"
@@ -12,66 +12,18 @@ license = "GPL-3.0-or-later"
keywords = ["game", "pacman", "arcade", "sdl2"]
categories = ["games", "emulators"]
publish = false
exclude = ["/assets/unpacked/**", "/assets/site/**", "/bacon.toml", "/Justfile"]
default-run = "pacman"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
bevy_ecs = "0.16.1"
glam = "0.30.5"
pathfinding = "4.14"
tracing = { version = "0.1.41", features = ["max_level_trace", "release_max_level_debug"]}
tracing-error = "0.2.0"
tracing-subscriber = {version = "0.3.20", features = ["env-filter"]}
time = { version = "0.3.43", features = ["formatting", "macros"] }
thiserror = "2.0.16"
anyhow = "1.0"
smallvec = "1.15.1"
bitflags = "2.9.4"
micromap = "0.1.0"
circular-buffer = "1.1.0"
parking_lot = "0.12.3"
strum = "0.27.2"
strum_macros = "0.27.2"
thousands = "0.2.0"
num-width = "0.1.0"
# While not actively used in code, `build.rs` generates code that relies on this. Keep the versions synchronized.
phf = { version = "0.13.1", features = ["macros"] }
# Windows-specific dependencies
[target.'cfg(target_os = "windows")'.dependencies]
# Used for customizing console output on Windows; both are required due to the `windows` crate having poor Result handling with `GetStdHandle`.
windows = { version = "0.62.0", features = ["Win32_Security", "Win32_Storage_FileSystem", "Win32_System_Console"] }
windows-sys = { version = "0.61.0", features = ["Win32_System_Console"] }
# Desktop-specific dependencies
[target.'cfg(not(target_os = "emscripten"))'.dependencies]
# On desktop platforms, build SDL2 with cargo-vcpkg
sdl2 = { version = "0.38", default-features = false, features = ["image", "ttf", "gfx", "mixer", "unsafe_textures", "static-link", "use-vcpkg"] }
rand = { version = "0.9.2", default-features = false, features = ["thread_rng"] }
spin_sleep = "1.3.3"
# Browser-specific dependencies
[target.'cfg(target_os = "emscripten")'.dependencies]
# On Emscripten, we don't use cargo-vcpkg
sdl2 = { version = "0.38", default-features = false, features = ["image", "ttf", "gfx", "mixer", "unsafe_textures"] }
# TODO: Document why Emscripten cannot use `os_rng`.
rand = { version = "0.9.2", default-features = false, features = ["small_rng", "os_rng"] }
libc = "0.2.175" # TODO: Describe why this is required.
[dev-dependencies]
pretty_assertions = "1.4.1"
speculoos = "0.13.0"
[build-dependencies]
phf = { version = "0.13.1", features = ["macros"] }
[workspace.dependencies]
# Common dependencies that might be shared across crates
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0.143"
serde_json = "1.0"
tokio = { version = "1.0", features = ["full"] }
axum = "0.7"
tower = "0.4"
tower-http = { version = "0.5", features = ["cors", "trace"] }
tracing = "0.1"
tracing-subscriber = "0.3"
# phf generates runtime code which machete will not detect
[package.metadata.cargo-machete]
ignored = ["phf"]
# Release profile for profiling (essentially the default 'release' profile with debug enabled)
[profile.profile]
@@ -88,16 +40,8 @@ opt-level = "z"
lto = true
panic = "abort"
[package.metadata.vcpkg]
dependencies = ["sdl2", "sdl2-image", "sdl2-ttf", "sdl2-gfx", "sdl2-mixer"]
git = "https://github.com/microsoft/vcpkg"
rev = "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" }
[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(coverage,coverage_nightly)'] }
# This profile is intended to appear as a 'release' profile to the build system due to`debug_assertions = false`,
# but it will compile faster without optimizations. Useful for rapid testing of release-mode logic.
[profile.dev-release]
inherits = "dev"
debug-assertions = false

View File

@@ -35,5 +35,14 @@ samply:
# Build the project for Emscripten
web *args:
bun run web.build.ts {{args}};
caddy file-server --root dist
bun run pacman/web.build.ts {{args}};
caddy file-server --root pacman/dist
# Run cargo fix
fix:
cargo fix --workspace --lib --allow-dirty
cargo fmt --all
push:
git push origin --tags;
git push

View File

@@ -1,5 +1,8 @@
<!-- markdownlint-disable MD033 -->
<!-- markdownlint-disable MD041 -->
<div align="center">
<img src="assets/repo/banner.png" alt="Pac-Man Banner Screenshot">
<img src="assets/banner.png" alt="Pac-Man Banner Screenshot">
</div>
# Pac-Man
@@ -13,7 +16,6 @@
[badge-build]: https://github.com/Xevion/Pac-Man/actions/workflows/build.yaml/badge.svg
[badge-coverage]: https://coveralls.io/repos/github/Xevion/Pac-Man/badge.svg?branch=master
[badge-online-demo]: https://img.shields.io/badge/Online%20Demo-Click%20Me!-brightgreen
[banner-image]: assets/repo/banner.png
[justforfunnoreally]: https://justforfunnoreally.dev
[build]: https://github.com/Xevion/Pac-Man/actions/workflows/build.yaml
[test]: https://github.com/Xevion/Pac-Man/actions/workflows/tests.yaml
@@ -30,7 +32,7 @@ The game includes all the original features you'd expect from Pac-Man:
- [x] Classic maze navigation with tunnels and dot collection
- [ ] Four ghosts with their unique AI behaviors (Blinky, Pinky, Inky, and Clyde)
- [x] Power pellets that allow Pac-Man to eat ghosts
- [ ] Fruit bonuses that appear periodically
- [x] Fruit bonuses that appear periodically
- [ ] Progressive difficulty with faster ghosts and shorter power pellet duration
- [x] Authentic sound effects and sprites
@@ -47,16 +49,16 @@ However, every commit has build artifacts, so you can grab the [latest build art
## Screenshots
<div align="center">
<img src="assets/repo/screenshots/0.png" alt="Screenshot 0 - Starting Game">
<img src="assets/screenshots/0.png" alt="Screenshot 0 - Starting Game">
<p><em>Starting a new game</em></p>
<img src="assets/repo/screenshots/1.png" alt="Screenshot 1 - Eating Dots">
<img src="assets/screenshots/1.png" alt="Screenshot 1 - Eating Dots">
<p><em>Pac-Man collecting dots and avoiding ghosts</em></p>
<img src="assets/repo/screenshots/2.png" alt="Screenshot 2 - Game Over">
<img src="assets/screenshots/2.png" alt="Screenshot 2 - Game Over">
<p><em>Game over screen after losing all lives</em></p>
<img src="assets/repo/screenshots/3.png" alt="Screenshot 3 - Debug Mode">
<img src="assets/screenshots/3.png" alt="Screenshot 3 - Debug Mode">
<p><em>Debug mode showing hitboxes, node graph, and performance details.</em></p>
</div>
@@ -83,7 +85,8 @@ You can read the [roadmap](ROADMAP.md) file for more details on the project's go
Since this project is still in progress, I'm only going to cover non-obvious build details. By reading the code, build scripts, and copying the online build workflows, you should be able to replicate the build process.
- Install `cargo-vcpkg` with `cargo install cargo-vcpkg`, then run `cargo vcpkg build` to build the requisite dependencies via vcpkg.
- Install `cargo-vcpkg` with `cargo install cargo-vcpkg`, then run `cargo vcpkg build --manifest-path pacman/Cargo.toml` to build the requisite dependencies via vcpkg.
- `--manifest-path` is only required if you run it from the root directory; you can omit it if you `cd` into the `pacman` directory first.
- This is only required for the desktop builds, not the web build.
- We use rustc 1.86.0 for the build, due to bulk-memory-opt related issues on wasm32-unknown-emscripten.
- Technically, we could probably use stable or even nightly on desktop targets, but using different versions for different targets is a pain, mainly because of clippy warnings changing between versions.

View File

@@ -1,30 +1,164 @@
# Roadmap
A list of ideas and features that I might implement in the future.
A comprehensive list of features needed to complete the Pac-Man emulation, organized by priority and implementation complexity.
## Debug Tooling
## Core Game Features
### Ghost AI & Behavior
- [x] Core Ghost System Architecture
- [x] Ghost entity types (Blinky, Pinky, Inky, Clyde)
- [x] Ghost state management (Normal, Frightened, Eyes)
- [x] Ghost movement and pathfinding systems
- [ ] Authentic Ghost AI Personalities
- [ ] Blinky (Red): Direct chase behavior
- [ ] Pinky (Pink): Target 4 tiles ahead of Pac-Man
- [ ] Inky (Cyan): Complex behavior based on Blinky's position
- [ ] Clyde (Orange): Chase when far, flee when close
- [x] Mode Switching System
- [ ] Scatter/Chase pattern with proper timing
- [x] Frightened mode transitions
- [ ] Ghost house entry/exit mechanics
- [x] Ghost House Behavior
- [x] Proper spawning sequence
- [ ] Exit timing and patterns
- [ ] House-specific movement rules
### Fruit Bonus System
- [x] Fruit Spawning Mechanics
- [x] Spawn at pellet counts 70 and 170
- [x] Fruit display in bottom-right corner
- [x] Fruit collection and scoring
- [x] Bonus point display system
### Level Progression
- [ ] Multiple Levels
- [ ] Level completion detection
- [ ] Progressive difficulty scaling
- [ ] Ghost speed increases per level
- [ ] Power pellet duration decreases
- [ ] Intermission Screens
- [ ] Between-level cutscenes
- [ ] Proper graphics and timing
### Audio System Completion
- [x] Core Audio Infrastructure
- [x] Audio event system
- [x] Sound effect playback
- [x] Audio muting controls
- [ ] Background Music
- [x] Intro jingle
- [ ] Continuous gameplay music
- [ ] Escalating siren based on remaining pellets
- [ ] Power pellet mode music
- [ ] Intermission music
- [x] Sound Effects
- [x] Pellet eating sounds
- [x] Fruit collection sounds
- [x] Ghost eaten sounds
- [x] Pac-Man Death
- [ ] Ghost movement sounds
- [ ] Level completion fanfare
### Game Mechanics
- [ ] Bonus Lives
- [ ] Extra life at 10,000 points
- [x] Life counter display
- [ ] High Score System
- [ ] High score tracking
- [x] High score display
- [ ] Score persistence
## Secondary Features (Medium Priority)
### Game Polish
- [x] Core Input System
- [x] Keyboard controls
- [x] Direction buffering for responsive controls
- [x] Touch controls for mobile
- [x] Pause System
- [x] Pause/unpause functionality
- [ ] Pause menu with options
- [ ] Input System
- [ ] Input remapping
- [ ] Multiple input methods
## Advanced Features (Lower Priority)
### Difficulty Options
- [ ] Easy/Normal/Hard modes
- [ ] Customizable ghost speeds
### Data Persistence
- [ ] High Score Persistence
- [ ] Save high scores to file
- [ ] High score table display
- [ ] Settings Storage
- [ ] Save user preferences
- [ ] Audio/visual settings
- [ ] Statistics Tracking
- [ ] Game statistics
- [ ] Achievement system
### Debug & Development Tools
- [ ] Game state visualization
- [ ] Game speed controls + pausing
- [ ] Log tracing
- [x] Performance details
- [x] Core Debug Infrastructure
- [x] Debug mode toggle
- [x] Comprehensive game event logging
- [x] Performance profiling tools
- [ ] Game State Visualization
- [ ] Ghost AI state display
- [ ] Pathfinding visualization
- [ ] Collision detection display
- [ ] Game Speed Controls
- [ ] Variable game speed for testing
- [ ] Frame-by-frame stepping
## Customization
## Customization & Extensions
- [ ] Themes & Colors
- Color-blind friendly options
- [ ] Perfected ghost AI algorithms
- [ ] Support for >4 ghosts
- [ ] Custom level generation with multi-map tunneling
### Visual Customization
## Online Features
- [x] Core Rendering System
- [x] Sprite-based rendering
- [x] Layered rendering system
- [x] Animation system
- [x] HUD rendering
- [ ] Display Options
- [x] Fullscreen support
- [x] Window resizing
- [ ] Pause while resizing (SDL2 limitation mitigation)
- [ ] Multiple resolution support
- [ ] Scoreboard system
- Axum server with database and OAuth2 auth
- Authentication via GitHub/Discord/Google
- Profile features:
- [ ] Optional avatars (downscaled to match 8-bit aesthetic)
- Custom names (3-14 chars, filtered for abuse)
- Zero-config client implementation
- Uses default API endpoint
- Manual override available
### Gameplay Extensions
- [ ] Advanced Ghost AI
- [ ] Support for >4 ghosts
- [ ] Custom ghost behaviors
- [ ] Level Generation
- [ ] Custom level creation
- [ ] Multi-map tunneling
- [ ] Level editor
## Online Features (Future)
### Scoreboard System
- [ ] Backend Infrastructure
- [ ] Axum server with database
- [ ] OAuth2 authentication
- [ ] GitHub/Discord/Google auth
- [ ] Profile Features
- [ ] Optional avatars (8-bit aesthetic)
- [ ] Custom names (3-14 chars, filtered)
- [ ] Client Implementation
- [ ] Zero-config client
- [ ] Default API endpoint
- [ ] Manual override available

View File

@@ -412,8 +412,8 @@ The bigger downside was that I had to toss out almost all the existing code for
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
[code-review-video]: https://www.youtube.com/watch?v=OKs_JewEeOo
[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

View File

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

16
pacman-common/Cargo.toml Normal file
View File

@@ -0,0 +1,16 @@
[package]
name = "pacman-common"
version = "0.1.1"
authors.workspace = true
edition.workspace = true
rust-version = "1.86.0"
description = "A meta crate for sharing common code between the `pacman` and `pacman-server` crates"
readme.workspace = true
homepage.workspace = true
repository.workspace = true
license.workspace = true
keywords.workspace = true
categories.workspace = true
publish.workspace = true
[dependencies]

9
pacman-common/README.md Normal file
View File

@@ -0,0 +1,9 @@
# pacman-common
This crate contains common code (mostly API request & response types) for the `pacman` and `pacman-server` (leaderboard API) crates.
You might be more interested in reading the README for the repostiory, the `pacman` crate, or the `pacman-server` crate.
- [README.md](../README.md)
- [pacman/README.md](../pacman/README.md)
- [pacman-server/README.md](../pacman-server/README.md)

View File

@@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}

17
pacman-server/Cargo.toml Normal file
View File

@@ -0,0 +1,17 @@
[package]
name = "pacman-server"
version = "0.1.1"
authors.workspace = true
edition.workspace = true
rust-version = "1.86.0"
description = "A leaderboard API for the Pac-Man game"
readme.workspace = true
homepage.workspace = true
repository.workspace = true
license.workspace = true
keywords.workspace = true
categories.workspace = true
publish.workspace = true
default-run = "pacman-server"
[dependencies]

21
pacman-server/README.md Normal file
View File

@@ -0,0 +1,21 @@
# pacman-server
Despite the naming of this crate, it's not a server for the Pac-Man game allowing multiplayer or anything super interesting.
This crate is a webserver that hosts an OAuth login and leaderboard API for the main `pacman` crate to hook into.
## Features
- [ ] Axum Webserver
- [ ] Database
- [ ] OAuth
- [ ] Discord
- [ ] GitHub
- [ ] Google (?)
- [ ] Leaderboard API
- [ ] Name Restrictions & Flagging
- [ ] Avatars
- [ ] 8-bit Conversion
- [ ] Storage?
- [ ] Common Server/Client Crate
- [ ] CI/CD & Tests

View File

@@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}

1768
pacman/Cargo.lock generated Normal file
View File

File diff suppressed because it is too large Load Diff

95
pacman/Cargo.toml Normal file
View File

@@ -0,0 +1,95 @@
[package]
name = "pacman"
version = "0.81.1"
authors.workspace = true
edition.workspace = true
rust-version = "1.86.0"
description = "A cross-platform retro Pac-Man clone, written in Rust and supported by SDL2"
readme.workspace = true
homepage.workspace = true
repository.workspace = true
license.workspace = true
keywords.workspace = true
categories.workspace = true
publish.workspace = true
exclude = ["/assets/unpacked/**", "/assets/site/**", "/bacon.toml", "/Justfile"]
default-run = "pacman"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
bevy_ecs = "0.16.1"
glam = "0.30.5"
pathfinding = "4.14"
tracing = { version = "0.1.41", features = ["max_level_trace", "release_max_level_debug"]}
tracing-error = "0.2.0"
tracing-subscriber = {version = "0.3.20", features = ["env-filter"]}
time = { version = "0.3.43", features = ["formatting", "macros"] }
thiserror = "2.0.16"
anyhow = "1.0"
smallvec = "1.15.1"
bitflags = "2.9.4"
micromap = "0.1.0"
circular-buffer = "=1.1.0"
parking_lot = "0.12.3"
strum = "0.27.2"
strum_macros = "0.27.2"
thousands = "0.2.0"
num-width = "0.1.0"
# While not actively used in code, `build.rs` generates code that relies on this. Keep the versions synchronized.
phf = { version = "0.13.1", features = ["macros"] }
# Windows-specific dependencies
[target.'cfg(windows)'.dependencies]
# Used for customizing console output on Windows; both are required due to the `windows` crate having poor Result handling with `GetStdHandle`.
windows = { version = "0.62.0", features = ["Win32_Security", "Win32_Storage_FileSystem", "Win32_System_Console"] }
windows-sys = { version = "0.61.0", features = ["Win32_System_Console"] }
# Desktop-specific dependencies
[target.'cfg(not(target_os = "emscripten"))'.dependencies]
# On desktop platforms, build SDL2 with cargo-vcpkg
sdl2 = { version = "0.38", default-features = false, features = ["image", "ttf", "gfx", "mixer", "unsafe_textures", "static-link", "use-vcpkg"] }
rand = { version = "0.9.2", default-features = false, features = ["thread_rng"] }
rust-embed = "8.7.2"
spin_sleep = "1.3.3"
# Browser-specific dependencies
[target.'cfg(target_os = "emscripten")'.dependencies]
# On Emscripten, we don't use cargo-vcpkg
sdl2 = { version = "0.38", default-features = false, features = ["image", "ttf", "gfx", "mixer", "unsafe_textures"] }
# TODO: Document why Emscripten cannot use `os_rng`.
rand = { version = "0.9.2", default-features = false, features = ["small_rng", "os_rng"] }
libc = "0.2.175" # TODO: Describe why this is required.
[dev-dependencies]
pretty_assertions = "1.4.1"
speculoos = "0.13.0"
[build-dependencies]
phf = { version = "0.13.1", features = ["macros"] }
serde = { version = "1.0.225", features = ["derive"] }
serde_json = "1.0.145"
# phf generates runtime code which machete will not detect
[package.metadata.cargo-machete]
ignored = ["phf"]
[package.metadata.vcpkg]
dependencies = ["sdl2", "sdl2-image", "sdl2-ttf", "sdl2-gfx", "sdl2-mixer"]
git = "https://github.com/microsoft/vcpkg"
rev = "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" }
[features]
# Windows-specific features
force-console = []
default = []
[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(coverage,coverage_nightly)', 'cfg(use_console)'] }

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 120 B

After

Width:  |  Height:  |  Size: 120 B

View File

Before

Width:  |  Height:  |  Size: 120 B

After

Width:  |  Height:  |  Size: 120 B

View File

Before

Width:  |  Height:  |  Size: 116 B

After

Width:  |  Height:  |  Size: 116 B

View File

Before

Width:  |  Height:  |  Size: 115 B

After

Width:  |  Height:  |  Size: 115 B

View File

Before

Width:  |  Height:  |  Size: 192 B

After

Width:  |  Height:  |  Size: 192 B

View File

Before

Width:  |  Height:  |  Size: 187 B

After

Width:  |  Height:  |  Size: 187 B

View File

Before

Width:  |  Height:  |  Size: 196 B

After

Width:  |  Height:  |  Size: 196 B

View File

Before

Width:  |  Height:  |  Size: 215 B

After

Width:  |  Height:  |  Size: 215 B

View File

Before

Width:  |  Height:  |  Size: 107 B

After

Width:  |  Height:  |  Size: 107 B

View File

Before

Width:  |  Height:  |  Size: 189 B

After

Width:  |  Height:  |  Size: 189 B

View File

Before

Width:  |  Height:  |  Size: 115 B

After

Width:  |  Height:  |  Size: 115 B

View File

Before

Width:  |  Height:  |  Size: 195 B

After

Width:  |  Height:  |  Size: 195 B

View File

Before

Width:  |  Height:  |  Size: 177 B

After

Width:  |  Height:  |  Size: 177 B

View File

Before

Width:  |  Height:  |  Size: 177 B

After

Width:  |  Height:  |  Size: 177 B

View File

Before

Width:  |  Height:  |  Size: 125 B

After

Width:  |  Height:  |  Size: 125 B

View File

Before

Width:  |  Height:  |  Size: 122 B

After

Width:  |  Height:  |  Size: 122 B

View File

Before

Width:  |  Height:  |  Size: 173 B

After

Width:  |  Height:  |  Size: 173 B

View File

Before

Width:  |  Height:  |  Size: 175 B

After

Width:  |  Height:  |  Size: 175 B

View File

Before

Width:  |  Height:  |  Size: 213 B

After

Width:  |  Height:  |  Size: 213 B

View File

Before

Width:  |  Height:  |  Size: 178 B

After

Width:  |  Height:  |  Size: 178 B

View File

Before

Width:  |  Height:  |  Size: 162 B

After

Width:  |  Height:  |  Size: 162 B

View File

Before

Width:  |  Height:  |  Size: 210 B

After

Width:  |  Height:  |  Size: 210 B

View File

Before

Width:  |  Height:  |  Size: 177 B

After

Width:  |  Height:  |  Size: 177 B

View File

Before

Width:  |  Height:  |  Size: 195 B

After

Width:  |  Height:  |  Size: 195 B

View File

Before

Width:  |  Height:  |  Size: 136 B

After

Width:  |  Height:  |  Size: 136 B

View File

Before

Width:  |  Height:  |  Size: 137 B

After

Width:  |  Height:  |  Size: 137 B

View File

Before

Width:  |  Height:  |  Size: 147 B

After

Width:  |  Height:  |  Size: 147 B

View File

Before

Width:  |  Height:  |  Size: 139 B

After

Width:  |  Height:  |  Size: 139 B

View File

Before

Width:  |  Height:  |  Size: 148 B

After

Width:  |  Height:  |  Size: 148 B

View File

Before

Width:  |  Height:  |  Size: 149 B

After

Width:  |  Height:  |  Size: 149 B

View File

Before

Width:  |  Height:  |  Size: 152 B

After

Width:  |  Height:  |  Size: 152 B

View File

Before

Width:  |  Height:  |  Size: 135 B

After

Width:  |  Height:  |  Size: 135 B

View File

Before

Width:  |  Height:  |  Size: 150 B

After

Width:  |  Height:  |  Size: 150 B

View File

Before

Width:  |  Height:  |  Size: 151 B

After

Width:  |  Height:  |  Size: 151 B

View File

Before

Width:  |  Height:  |  Size: 145 B

After

Width:  |  Height:  |  Size: 145 B

View File

Before

Width:  |  Height:  |  Size: 135 B

After

Width:  |  Height:  |  Size: 135 B

View File

Before

Width:  |  Height:  |  Size: 181 B

After

Width:  |  Height:  |  Size: 181 B

View File

Before

Width:  |  Height:  |  Size: 178 B

After

Width:  |  Height:  |  Size: 178 B

View File

Before

Width:  |  Height:  |  Size: 184 B

After

Width:  |  Height:  |  Size: 184 B

View File

Before

Width:  |  Height:  |  Size: 181 B

After

Width:  |  Height:  |  Size: 181 B

View File

Before

Width:  |  Height:  |  Size: 183 B

After

Width:  |  Height:  |  Size: 183 B

View File

Before

Width:  |  Height:  |  Size: 181 B

After

Width:  |  Height:  |  Size: 181 B

View File

Before

Width:  |  Height:  |  Size: 177 B

After

Width:  |  Height:  |  Size: 177 B

View File

Before

Width:  |  Height:  |  Size: 175 B

After

Width:  |  Height:  |  Size: 175 B

View File

Before

Width:  |  Height:  |  Size: 189 B

After

Width:  |  Height:  |  Size: 189 B

View File

Before

Width:  |  Height:  |  Size: 187 B

After

Width:  |  Height:  |  Size: 187 B

View File

Before

Width:  |  Height:  |  Size: 194 B

After

Width:  |  Height:  |  Size: 194 B

View File

Before

Width:  |  Height:  |  Size: 191 B

After

Width:  |  Height:  |  Size: 191 B

View File

Before

Width:  |  Height:  |  Size: 194 B

After

Width:  |  Height:  |  Size: 194 B

View File

Before

Width:  |  Height:  |  Size: 190 B

After

Width:  |  Height:  |  Size: 190 B

View File

Before

Width:  |  Height:  |  Size: 184 B

After

Width:  |  Height:  |  Size: 184 B

View File

Before

Width:  |  Height:  |  Size: 179 B

After

Width:  |  Height:  |  Size: 179 B

Some files were not shown because too many files have changed in this diff Show More