Skip to content

Commit

Permalink
Finish v6.0
Browse files Browse the repository at this point in the history
  • Loading branch information
hsandt committed Aug 19, 2021
2 parents 5a40436 + 060d3af commit 6e1ff84
Show file tree
Hide file tree
Showing 108 changed files with 11,467 additions and 9,842 deletions.
20 changes: 11 additions & 9 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ language: python # Can use any language here, but if it's not 'python'
python: "3.6"

env:
- LUA_VERSION=5.3 BUILD_VERSION=`cat data/version.txt` ENABLE_RENDER=1
- LUA_VERSION=5.3 BUILD_VERSION=`cat data/version.txt` CARTRIDGES=`cat data/cartridges.txt` ENABLE_RENDER=1

cache:
directories:
Expand Down Expand Up @@ -69,14 +69,16 @@ script:
# we *do* want to ignore WIP tests flagged #mute
# test: all utests
- ITEST_CARTRIDGE_SUFFIX=ignore ./test.sh
# test: all headless itests for titlemenu (ENABLE_RENDER set in env)
- ITEST_CARTRIDGE_SUFFIX=titlemenu ./test.sh -f headless_itests
# test: all headless itests for stage_intro (ENABLE_RENDER set in env)
- ITEST_CARTRIDGE_SUFFIX=stage_intro ./test.sh -f headless_itests
# test: all headless itests for stage (ENABLE_RENDER set in env)
- ITEST_CARTRIDGE_SUFFIX=ingame ./test.sh -f headless_itests
# test: all headless itests for stage_clear (ENABLE_RENDER set in env)
- ITEST_CARTRIDGE_SUFFIX=stage_clear ./test.sh -f headless_itests
# test: all headless itests for each cartridge (ENABLE_RENDER set in env)
- |
for cartridge in $CARTRIDGES; do
ITEST_CARTRIDGE_SUFFIX="$cartridge" ./test.sh -f headless_itests
if [[ $? -ne 0 ]]; then
echo ""
echo "Headless itests failed for cartridge "$cartridge", STOP."
exit 1
fi
done
# coverage
- bash <(curl -s https://codecov.io/bash)

Expand Down
32 changes: 31 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,35 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [6.0] - 2021-08-17
### Added
- Character physics: spin dash (includes crouching)
- Character physics: allow late jump up to 6 frames after leaving ground, to mimic modern platformer physics (can be disabled in pause menu)
- Animation: crouch and spin dash animations, using new dynamic sprite reloading system to allow even more sprites on a single spritesheet (unfortunately smoke PFX was cut from Release as it took too many characters, although still present in code)
- Camera: spin dash lag
- Stage visual: added animated waterfalls at the beginning of the level (they actually use color palette swapping as in the original game)
- Attract mode: added Attract mode when player waits for end of intro BGM on the title screen. This is played inside a new cartridge that is mostly a stripped version of the ingame cartridge + a puppet sequence to make Sonic move by himself

### Changed
- Application: upgraded to PICO-8 0.2.2c with full binary patching and upgraded custom web template to integrate latest improvements
- UI: press O on title menu before menu appears to make it appear immediately
- Credits: add mention of SAGE and itch.io URL
- Camera: use small vertical window even on ground to avoid moving when character just moves by 1px up and down (due to new bumps)
- Stage physics: fixed last descending slope tile connecting slope and loop having no collision
- Stage physics/visual: reworked rock sprites to be smaller
- Stage physics/visual: offset last emerald (orange) by 5px to the right
- Stage physics/visual: replaced very low slopes with 1px bumps that are still considered flat ground to avoid slowing down character when running on them, while keeping the funny up-and-down motion
- Stage visual: hide emerald behind leaves to make harder to find
- Stage visual: improved forest hole lightshaft in background (now sprite instead of procedurally generated)
- Stage visual: fixed one-way platform grass appearing in front of character
- Stage visual: fixed background parallax to only move when camera moves by an integer pixel, not pixel fractions
- Character physics: fixed detecting flat ground when running down slopes where some columns of the collision mask are empty
- Character physics & Optimization: big overhaul with switch to "big steps" method instead of the expensive "pixel step" method. This applies to both grounded and airborne motion. First move by the full motion you'd expect on a single frame, ignoring obstacles. Then detect wall, ground and ceiling, if meaningful considering the current speed (with an extra final wall check if grounded). This effectively reduced complexity from O(speed) to O(1) and allows the game to run at 60 FPS consistently (with only a few 30 FPS drops when reloading memory e.g. to change region)
- Optimization: optimized the sprite rotation method to use efficient code specific for 90-degree rotations, instead of general trigonometry with backward approach (particularly slow due to iterating on all pixels inside the bounding box containing a given disc).
- Compressed characters: various refactoring and replacement of every constant with hardcoded strings/values (as pre-build step) to reduce compressed characters size and allow exporting cartridge again despite adding new features
- Debug: fix and improve debug rays (development only)
- Export: merged audio data with built-in ingame data cartridge to avoid going over the limit of 16 cartridges per export (attract mode cartridge). Also offset BGM tracks by 8 tracks to allow custom instruments to be used ingame. This was required for the new spin dash SFX.

## [5.4] - 2021-04-17
### Added
- Audio: added "got all emeralds" jingle with delay
Expand Down Expand Up @@ -247,7 +276,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Game: in-game: debug character flies X/Y on directional input, go back to title menu on reach goal
- Test: all busted unit tests in separator folder tests

[Unreleased]: https://github.com/hsandt/sonic-pico8/compare/v5.3...HEAD
[Unreleased]: https://github.com/hsandt/sonic-pico8/compare/v6.0...HEAD
[6.0]: https://github.com/hsandt/sonic-pico8/compare/v5.3...v6.0
[5.3]: https://github.com/hsandt/sonic-pico8/compare/v5.2...v5.3
[5.2]: https://github.com/hsandt/sonic-pico8/compare/v5.1...v5.2
[5.1]: https://github.com/hsandt/sonic-pico8/compare/v5.0...v5.1
Expand Down
25 changes: 23 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ develop

![The 8 Pico Emeralds displayed in circle, each color corresponding to a color on the PICO-8 logo](doc/all_emeralds.png?raw=true)

**pico sonic** is a partial demake of Sonic the Hedgehog 3 made with PICO-8. It features a simplified version of Angel Island Act 1 with some tweaks. Various classic Sonic games were used as reference, including the 8-bit games (Game Gear and Master System) which have sprites closer to what PICO-8's resolution and color palette, and the GBA titles which have more clear-cut graphics.
**pico sonic** is a partial demake of Sonic the Hedgehog 3 made with [PICO-8](https://www.lexaloffle.com/pico-8.php). It features a simplified version of Angel Island Act 1 with some tweaks. Various classic Sonic games were used as reference, including the 8-bit games (Game Gear and Master System), which have sprites closer to PICO-8's resolution and color palette, and the GBA titles, which have more clear-cut graphics.

The project was started as a personal challenge and was meant to be a fully-fledged fan game, but I eventually dropped many features to focus on Sonic's main movements and the exploration of the stage. Consider it a technical demo with some exploration challenge.

Expand All @@ -28,7 +28,7 @@ pico sonic is a fan game distributed for free and is not endorsed by Sega. Sega

## Compatibility

Works with PICO-8 0.2.0i ~ 0.2.1b.
Works with PICO-8 0.2.2.

## Features

Expand Down Expand Up @@ -76,6 +76,26 @@ Version: 5.3
* Spin dash
* When you collect all emeralds...

### Notable physics differences

* Preservation of velocity when landing on slopes is more organic and uses vector projection, while the [SPG](https://info.sonicretro.org/SPG:Slope_Physics#Reacquisition_Of_The_Ground) denotes different formulas based on the slope angle and the relationship between horizontal and vertical speed. This is very perceptible when jumping on the first two slopes.
* It is possible to control horizontal acceleration after jumping out of a roll. This was considered to be a better user experience, and actually recommended by the Sonic Physics Guide despite being unlike the original games.
* Late jump: as in modern platforms, the character can jump up to 6 frames after falling off ground, for more permissive jumps from a platform ledge. This can be disabled in the Pause menu for a more "classic" experience.
* Pixel step-by-step approach: currently, character motion is computed pixel by pixel. This is very precise and avoids relying on ground escape, but is also very CPU expensive (the main reason behind FPS dropping to 30) and can get the character stuck if one calculation is wrong. It will probably be replaced with bigger steps and ground escape in the future.

### Notable camera differences

Because PICO-8 has a square view of 128x128 pixels, and the game is more about exploration than moving toward the right, camera was adjusted to make navgiation a little easier.

* Camera is fundamentally centered on X, but moves toward the direction Sonic is facing. When Sonic is running, camera moves even more forward to show what is ahead
* Spin dash lag is implemented by freezing then releasing the camera, instead of the more complex recording and playing of character positions during the start of the spin dash

### Notable sprite differences

* Sonic uses the "jump fall" sprite from Sonic CD/Mania as spring jump sprite (although it's not technically correct since it shouldn't be used for upward motion)

* I reversed the order the Brake sprites so it made more sense visually. Now, Sonic just plays a short 2-sprite brake animation when you start moving in the opposite direction of running. If you keep moving in the opposite direction, it shows the "reverse brake" sprite, which gives more the impression than Sonic is doing a complete turn and sprinting in the opposite direction.

## Content

There is a single demo stage which covers the first part of Angel Island Act 1. Scale is close to 1:1, but Sonic is slightly smaller (relatively to the environment) than in the original game.
Expand Down Expand Up @@ -108,6 +128,7 @@ If you gamepad mapping is not correct, you can customize it with [SDL2 Gamepad T

In the pause menu (toggled with Enter/Start), if you are in-game, you can select the following options:

* Late jump: press left/right to toggle the Late jump feature ON/OFF (default: ON)
* Warp to start: restart stage from beginning keeping collected emeralds
* Retry from zero: restart stage losing emeralds collected so far
* Back to title: go back to title menu
Expand Down
6 changes: 5 additions & 1 deletion build_all_cartridges.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

# Configuration: paths
game_scripts_path="$(dirname "$0")"
data_path="$(dirname "$0")/data"

help() {
echo "Build a PICO-8 cartridge with the passed config."
Expand Down Expand Up @@ -57,7 +58,10 @@ if [[ ${#positional_args[@]} -ge 1 ]]; then
config="${positional_args[0]}"
fi

cartridge_list="titlemenu stage_intro ingame stage_clear"
# cartridges.txt lists cartridge names, one line per cartridge
# newlines act like separators for iteration just like spaces,
# so this is equivalent to `cartridge_list="titlemenu stage_intro ..."`
cartridge_list=`cat "$data_path/cartridges.txt"`

for cartridge in $cartridge_list; do
"$game_scripts_path/build_single_cartridge.sh" "$cartridge" "$config"
Expand Down
20 changes: 17 additions & 3 deletions build_and_install_all_cartridges.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@ help() {
}

usage() {
echo "Usage: build_and_install_all_cartridges.sh [CONFIG]
echo "Usage: build_and_install_all_cartridges.sh [CONFIG] [OPTIONS]
ARGUMENTS
CONFIG Build config. Determines defined preprocess symbols.
(default: 'debug')
-i, --itest Pass this option to build an itest instead of a normal game cartridge.
-h, --help Show this help message
"
}
Expand All @@ -30,6 +32,10 @@ config='debug'
# https://stackoverflow.com/questions/192249/how-do-i-parse-command-line-arguments-in-bash
while [[ $# -gt 0 ]]; do
case $1 in
-i | --itest )
itest=true
shift # past argument
;;
-h | --help )
help
exit 0
Expand Down Expand Up @@ -57,5 +63,13 @@ if [[ ${#positional_args[@]} -ge 1 ]]; then
config="${positional_args[0]}"
fi

"$game_scripts_path/build_all_cartridges.sh" "$config"
"$game_scripts_path/install_all_cartridges.sh" "$config"
if [[ "$itest" == true ]]; then
# itest cartridges enforce special config 'itest' and ignore passed config
config='itest'
options='--itest'
else
options=''
fi

"$game_scripts_path/build_all_cartridges.sh" "$config" $options
"$game_scripts_path/install_all_cartridges.sh" "$config" $options
20 changes: 17 additions & 3 deletions build_and_install_single_cartridge_with_data.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ usage() {
ARGUMENTS
CARTRIDGE_SUFFIX Cartridge to build for the multi-cartridge game
'titlemenu', 'stage_intro', ingame' or 'stage_clear'
See data/cartridges.txt for the list of cartridge names
CONFIG Build config. Determines defined preprocess symbols.
(default: 'debug')
-i, --itest Pass this option to build an itest instead of a normal game cartridge.
-h, --help Show this help message
"
}
Expand All @@ -34,6 +36,10 @@ config='debug'
# https://stackoverflow.com/questions/192249/how-do-i-parse-command-line-arguments-in-bash
while [[ $# -gt 0 ]]; do
case $1 in
-i | --itest )
itest=true
shift # past argument
;;
-h | --help )
help
exit 0
Expand Down Expand Up @@ -65,13 +71,21 @@ if [[ ${#positional_args[@]} -ge 2 ]]; then
config="${positional_args[1]}"
fi

if [[ "$itest" == true ]]; then
# itest cartridges enforce special config 'itest' and ignore passed config
config='itest'
options='--itest'
else
options=''
fi

# Immediately export to carts to allow multi-cartridge loading
"$game_scripts_path/build_single_cartridge.sh" "$cartridge_suffix" "$config"
"$game_scripts_path/build_single_cartridge.sh" "$cartridge_suffix" "$config" $options

if [[ $? -ne 0 ]]; then
echo ""
echo "build_single_cartridge.sh failed, STOP."
exit 1
fi

"$game_scripts_path/install_single_cartridge_with_data.sh" "$cartridge_suffix" "$config"
"$game_scripts_path/install_single_cartridge_with_data.sh" "$cartridge_suffix" "$config" $options
2 changes: 1 addition & 1 deletion build_itest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# This is essentially a proxy script for pico-boots/scripts/build_cartridge.sh with the right parameters.

# Usage: build_itest.sh cartridge_suffix
# cartridge_suffix 'titlemenu', 'stage_intro', 'ingame' or 'stage_clear'
# See data/cartridges.txt for the list of cartridge names

# Configuration: paths
picoboots_scripts_path="$(dirname "$0")/pico-boots/scripts"
Expand Down
Loading

0 comments on commit 6e1ff84

Please sign in to comment.