Skip to content

A sleek and simple yet challenging mobile puzzle game built with React Native. Now available on the Google Play Store and coming soon to the App Store.

License

Notifications You must be signed in to change notification settings

StefanTodoran/crates-craters

Repository files navigation

Crates and Craters

About

Built with JavaScript and React Native, Crates and Craters is a single player puzzle game built for iOS and Android. Don't let the simple premise and minimalist graphics decieve you, the simple mechanics compound to create challenging and layered gameplay!

Features

  • Dozens of puzzling levels
  • A built in level editor and level sharing
  • Minimalist game design and graphics
  • Small app size
  • Light and dark modes
  • And lots more to come!

The objective of the game is to collect all of the coins and reach the flag. The map is a grid of square tiles, where the player can move vertically and horizontally one tile at a time. The player can walk on any empty floor tile or tiles occupied by coins or keys to collect those items.

There are a number of obstacles in the players way. The first are walls, which cannot be walked through or interacted with in any way. The player cannot walk off the edges of the map either.

The second obstacle are doors, which function the same as a wall unless opened with a key. Any key can open any door, but is used up in the process and the door cannot be re-locked to retrieve the key. Once a door tile is opened with a key, it is just like an empty floor tile. To open a door once you have collected a key, move onto the door tile.

The primary obstacles and namesakes of the game are crates and craters. The player cannot walk on either type of tile, however, if there is an empty tile or a crater behind a crate, the player can push the crate by walking into it. If the tile behind is an empty tile, this simply moves the crate to that tile. Keep in mind that the player needs to be able to get behind the crate to push it!

If the tile the crate is pushed into is a crater, the crate will fall in and fill in the crater, creating a normal, walkable floor space. Crates cannot be pushed onto coins, keys, or into doors or the flag.

Another tile which has interactions with crates are bombs. Bombs display a number representing their fuse. After that number of turns, the bomb will detonate, destorying adjacent crates. Bombs, like crates, can be pushed.

The final tile type are one ways. These tiles are fairly simple, the player can move onto them from any direction, except the direction in which the arrow is pointing. Also, pushables like bombs and crates cannot pass through one ways (in any direction).

In order to successfully complete a level, the player must be able to reach the flag and stand on that tile after having collected all the coins. Not every key need be collected, nor every door opened. Beware of decoy keys, especially if a level contains less doors than keys!

These are all of the basic rules of Crates & Craters. There is a how to play page in the app in case you forget, or you can hop on in and try the tutorial levels to get started!

Running Locally

Running and testing the app locally will require that you possess a phone with Expo Go installed on it and a working internet connection. To work with live refresh, run:
expo start
Since the game is fairly computationally intensive for React Native, to see production accurate performance run:
npx expo start --no-dev --minify


Building APK

Make sure you are logged in to expo with expo whoami. If not logged in, run expo login. Then use this command to build to apk for android:
eas build -p android --profile preview
Or to build app bundle for production:
eas build -p android


TODO

  • Improve VirtualizedList performance especially as content length increases
  • Do benchmarking to determine if the use of useCallback in App.tsx is worthwhile
  • Use cloud service to allow storage and sharing of user-created levels
    • Allow account creation
    • Require a user solves their level to upload it
  • Refactor play and edit screen pause menu container into separate component
    • Menu should close when the user presses on it (not on a button)
  • Design and add many, many more levels, perhaps with new tile types
    • Review level 16, might be too easy for where it is
  • Create a proper tutorial with live instruction, as opposed to simply an easy level
  • Could react native web assembly help improve performance?
  • Add metal crate tile type and associated logic
  • Consider making bombs destroy keys and coins?
  • Use a hitRect to give stepperArrows bigger hitboxes without overlapping SliderBar
  • Make notifications persist using MMKV?

Known Bugs

  • Sometimes the move preview squares animation just stops
    • Was reproducibly happening due to id issues, fixed that bug, now is less frequent
    • Occured when going from level to next level (fixed)
    • See Player.tsx
  • On galaxy s24 the victory screen animation doesn't work
  • Long level names may overflow card title
    • See ManageLevel.tsx
  • There are sometimes tiny 1px gaps between board tiles that vary by screen dimensions
    • Not due to rounding, tile sizes are whole numbers
    • See GameBoard.tsx
  • Board rows have gaps between them (sometimes?)
    • Depends on screen size, but also sometimes it just doesn't happen making it difficult to reproduce
    • There may also be a gap between the rows and the border, see application on Pixel 2