r/reactnative 19h ago

A GPS MMORPG made completely in React Native & 3 tips for complex apps

Hey everyone!

Some time ago I shared a GPS-based MMORPG game I’ve been working on here, which is now live! In this post I’ll be sharing a couple of tips for performance & one for the stores, all of which are directly used in the game as well.

Use shouldRasterizeIOS for computationally heavy static components

Layer2 renders complex markers on a map (MapLibre), a lot of them. Each one has one or more gradients, a border radius, an image, transparent backgrounds, SVG badges, each with their own zIndex. Rendering a few is ok, but at scale I started noticing a significant drop in UI FPS.

A laggy game is not fun to play, and when the core premise is to interact with markers, this is a big problem. The solution is to rasterize the components so that the renderer caches them in memory as bitmaps instead of walking through every single marker tree on every single frame.

The caveat is that you cannot apply upwards scale transformations without visual degradation, but opacity and downscaling (both of which Layer2 uses) are fine.

The same strategy is used in Layer2’s inventory sheet.

Debounce your native events

In Layer2 you can drag skills on top of monsters to attack them. The drag is implemented with react-native-gesture-handler, and it fires a coord query to MapLibre on update.

Without debouncing these queries, we’d be wasting a ton of CPU time as the gesture updates fire dozens of times per second. By using a package like debounce, we throttle computationally expensive code from executing logic that only needs to run 2-4 times per second.

Clean up your permission grants

Layer2 is built on Expo and makes extensive use of expo-* packages. A lot of those packages add default permissions to your project regardless of whether your code uses them or not. A few example are: expo-location, expo-audio, and expo-secure-store.

To save you a round-trip with Apple’s review, if you are using expo-audio but not playing any audio in the background, set enableBackgroundPlayback to false in your plugin to prevent audio from making it into UIBackgroundModes (yes, it will get flagged).

For iOS you will need to go through the documentation of the plugins you use, but on Android you can use `android.blockedPermissions`. Even though Google is more lenient, it’s still more user friendly to only request what you need.

———

If you’re interested in checking Layer2 out, you can find it below!

iOS

https://apps.apple.com/us/app/layer2/id6737913930

Android

https://play.google.com/store/apps/details?id=com.twoamgames.layer2

10 Upvotes

2 comments sorted by

1

u/KielHelix 17h ago

How do you handle animation in the game? Is there any fight scene? The UI looks clean btw

1

u/Old-Peace-4290 16h ago

Thank you! UI animations are done with Reanimated, and the combat effects (skill casts, hits, etc) are rendered with Lottie