blog

By
Linda Hong
May 26, 2020

How We Built & Shipped a Cross-platform XR Social App in Less Than 6 Months...

Okay, I exaggerate... it sure took longer than 6 months! 😃

What I’m going to share is my experience of joining Ubiquity6 last July, and how after a super productive 5 months we shipped our Display.Land App across iOS, Android, and web.

Since launch, we’ve seen hundreds of thousands of signups in over 150+ countries.

Let’s review what happened - Chef Style! 👩‍🍳


Recipe

What we have:

Back-end: 

A solid 3D content processing platform, will leave as it is.

Front-end:

🎹 Team size: 10.

🤖 Android App: XR app that allows you to take a 3D capture and upload, working with a few bugs (app crashes, etc.). 

🍎 iOS App: XR app, working nicely. 

🕸 Web: a web interface with limited functionality, lots of potential.

What we Want to Deliver

App-wise: We aimed to make Display.Land a fully-functioning XR App with social elements such as 

  • Comment / Like 
  • Follow
  • @ Mention / Notification
  • Social Share
  • Search

Web-wise:

  • Fulfill some potentials like login/out and allow 3D Mesh Download


Preparation Time 📆

5 months

A few problems you might run into during Preparation:

• PROBLEM 1: Master branch is unstable and prevents faster iterations.

I remember the first bug I looked into was Android capture upload not working as expected. It turned out to be a regression. 


• PROBLEM 2: It takes too long to build & debug something.

Display.land is a React Native app = a native bundle + a JS bundle.

JS: Start the JS bundle server, 1–2 min to compile then start.

Native: Slow, for iOS we build from XCode (ok-ish, 5 min or less), for Android either build from Android Studio or from the command line (slow, 5+ min, can take 10 min or more).

If we are only touching JS side, it doesn’t require a rebuild. However, we still need to build native side approximately once a day (or whenever you need to pick up new native side change). 


• PROBLEM 3:  Sometimes bugs are not addressed in a timely manner.



Now let’s dive into each problem and see what exactly we tried to resolve it!

🤔 PROBLEM 1: Master branch is unstable and prevents faster iterations.

Special Sauce 🥘 : Good coverage of unit test as a gate to code check-in, plus an hourly end to end test that covers core user flow to raise the alarm when something is broken.

The importance of the unit test is easily understood. It’s truly a small investment that yields a massive return.

An end to end test on a mobile device, however, is not easy to write nor is it fast to run. We use detox to build our 1st e2e test, then one by one we increase our coverage to make sure the core user flow is covered.

It takes 10+ minutes to build & run the whole test suite, which is too long to use as a gating mechanism and so we only run it hourly.

Then how do we ensure the failing test/regression is addressed in a timely manner?
Good question! See ‘QA Rotation’ later in the post.

Problem solved?
70% → others are handled by QA rotation, and by adding a Feature Flag to EVERYTHING (I will explain in more detail in a bit!).


🤔 PROBLEM 2: It takes too long to build & debug something.

Special Sauce 🥘: Native side and JS side can be built & shipped separately.

We pack the native side up as a bundle and store it in a S3 bucket, and now all you need to do is download it into the device, get JS bundle server up on your laptop (1–2 min), and you are good to go! 💃

This also enables our Over-the-Air delivery: to ship JS side changes. For any JS-only change, there is no need to create a new build, submit to Apple/Google store, and wait a couple days for review, etc… Instead, we can just ship it Over-the-Air to the end user in minutes!



*The service we use for OTA CodePush is appcenter

Over-the-Air release is a huge bonus point of being a React Native app (vs a purely native app).


Problem solved?
80%
... You still need to build if you change code on native side.


🤔 PROBLEM 3: Bugs raised don’t get addressed in a timely manner.

3.1 First, we need to sort out our priorities: Ask, is this bug high enough of a priority to drop the feature we are currently working on?

3.2 We need to surface bugs as soon as possible. E2e tests won’t cover everything, plus at the time we didn’t have a big enough QA team.

Special Sauce 🥘: I started a QA Rotation (on-call) among engineers. Each rotation lasts 1 week, where the engineer on call allocates some amount of the day to:

  1. Go over incoming bugs, close out non-bugs, and identify bugs that need immediate attention so we can bring them into the current sprint.
  2. Watch over ci/cd where we run tests. Take the e2e test for example... (remember it runs hourly). If there is a failure, the engineer on rotation will do a quick triage to see if it’s a regression. If so, they find the owner of the commit and ask for a fix or revert.


Bonus Flavor 1 ☕️ : After we hit production, the QA Rotation (on-call) can also help engineers understand the impact of bugs on our customers.


Bonus Flavor 2 🍰 : This also helps out Problem #1: when someone breaks the main branch, we need to track it down and fix it asap.

How about the lack of QA? Oh yes, we did hire more QAs! 👏

Problem solved ?
99%! → our QA rotation + bigger QA team works great.


Last but not least, FEATURE FLAG EVERYTHING!

Okay... maybe not everything, but putting new features under development behind Feature Flags is a huge boost to our productivity, plus it helps stabilize the main branch.

We use LaunchDarkly as our feature flag service. As I’m writing this, we have 86 feature flags in total.

With Feature Flags, we completely separate shipping code VS shipping features.

Shipping Code: Developers can check in code that is half-working (or less), as long as it’s behind a feature flag, it won’t impact our customer.

Shipping a Feature: Product and QA are the ones shipping features, not developers. Anything that goes out to our customers needs to be given the green light from both QA and Product. Kudos to LaunchDarkly for providing an easy to use dashboard for non-developers. 😘

With feature flags you can do more: percentage rollout, A/B testing, etc…



Dinner Time 🥘

To recap, we took a barebones app + limited web interfaces, added special sauce 🥘 like OTA/QA rotation/feature flag, and threw in dozen social ingredients like comment/like/mention/…, we baked it for an incredibly productive 5 months, and now we have a fully functioning social XR app across iOS/Android/Web, ready for 🚀!



By
Linda Hong
May 26, 2020

How We Built & Shipped a Cross-platform XR Social App in Less Than 6 Months...

It’s been a wild three months.

From graffiti filled streets in Spain to underground bunkers in Sausalito, subway stations in Tokyo to industrial kitchens in Texas, the Display.land community has been blowing our minds every morning by capturing, sharing and exploring each others’ spaces from around the world during our early access period.


To learn more about our story of getting to here and where we’re going, keep reading, but if you just want to try it out yourself, head on over to the iOS or Android stores to download and start creating!

What You Can do Today

Capture any space with the device you already own — from as small as a courtyard to entire city blocks
Edit insanely fast — changes you make to your spaces are rendered and saved in real time.
Instantly share your spaces via web links and videos, or freely export them as 3D models
Explore the world and join a community of global explorers in 50 countries

How We Got Here

We started U6 with the mission to unlock new ways for people to create and connect in the physical spaces they care about, such as our PlaySFMOMA space last year.
To create that experience, we captured the SF MOMA’s physical space in 3D using a commodity smartphone, edited and authored it remotely in a web browser, and allowed hundreds of people to browse and experience the sandbox together in real time from their own devices onsite in AR, and remotely via desktop and webVR browsers.

With today’s release, we’re beginning to put those same tools in everybody’s hands, with the goal of building and improving our roadmap in public with our community.

Where We’re Going: Editing Reality Together

Unlocking a new digital canvas for creativity and shared experiences.
Our goal is to grow Display.land into a destination where people can create, share and explore together in new, immersive and interactive ways.

We believe the best way to achieve this is by releasing often and publicly, supporting our earliest creators, and constantly increasing access to creative tools only previously available to high end gaming, graphics and 3D professionals. In the coming months, you can expect to see regular updates along this path.

Display.land is for those of us who see art in reality. If this sounds like something you’re interested in working on, shoot us a note! We’re working on some of the hardest challenges in computer vision, graphics and multiplayer networking and are hiring actively.

-Anjney & Ankit
Co-founders, Ubiquity6

By
Linda Hong
May 26, 2020

How We Built & Shipped a Cross-platform XR Social App in Less Than 6 Months...

Creators! Did you know that you can download any of your captures as a 3D model? 

We currently support OBJ, GLTF, and PLY file formats, which make it possible to use captures from Display.land in Blender, Cinema4D, Unity, Unreal, Maya, and most other popular creative software applications.

To download the 3D mesh, just open one of your captures in a desktop web browser, and click the download button in the upper-right corner of the screen. You’ll need to be logged in to see it.

If you are on iOS, the easiest way to open your capture in a browser is through AirDrop. You can AirDrop yourself the link to the desired capture by opening the Share Menu and pressing “More.” From there, a new menu will open giving you the option to airdrop the link. 

If you are on Android, we find it is easiest to email yourself the link. Open the Share Menu and press “More.” From there, choose email or whatever the best option is for you.

Note: Your download will contain the model for your full capture. Any cropping or 3d object additions will not be represented in your mesh download.
Once your 3D mesh has downloaded, this is where the magic begins. You now have the opportunity to create phenomenal artwork using captured physical reality. Try challenging the mundane by drawing in the absurd.

Or, experiment with contrasting elements. The opportunities are endless and the boundaries are limitless. Check out what our creators have made with Display.land below.
We absolutely love to see what our Creators create using their Display.land meshes. In fact, we have an entire Discord channel dedicated to them! You can find this channel here: https://discord.gg/b2vxQpu.
We can’t wait for you to join and to see how Display.land has inspired you. ✨
By
Linda Hong
May 26, 2020

How We Built & Shipped a Cross-platform XR Social App in Less Than 6 Months...

Okay, I exaggerate... it sure took longer than 6 months! 😃

What I’m going to share is my experience of joining Ubiquity6 last July, and how after a super productive 5 months we shipped our Display.Land App across iOS, Android, and web.

Since launch, we’ve seen hundreds of thousands of signups in over 150+ countries.

Let’s review what happened - Chef Style! 👩‍🍳


Recipe

What we have:

Back-end: 

A solid 3D content processing platform, will leave as it is.

Front-end:

🎹 Team size: 10.

🤖 Android App: XR app that allows you to take a 3D capture and upload, working with a few bugs (app crashes, etc.). 

🍎 iOS App: XR app, working nicely. 

🕸 Web: a web interface with limited functionality, lots of potential.

What we Want to Deliver

App-wise: We aimed to make Display.Land a fully-functioning XR App with social elements such as 

  • Comment / Like 
  • Follow
  • @ Mention / Notification
  • Social Share
  • Search

Web-wise:

  • Fulfill some potentials like login/out and allow 3D Mesh Download


Preparation Time 📆

5 months

A few problems you might run into during Preparation:

• PROBLEM 1: Master branch is unstable and prevents faster iterations.

I remember the first bug I looked into was Android capture upload not working as expected. It turned out to be a regression. 


• PROBLEM 2: It takes too long to build & debug something.

Display.land is a React Native app = a native bundle + a JS bundle.

JS: Start the JS bundle server, 1–2 min to compile then start.

Native: Slow, for iOS we build from XCode (ok-ish, 5 min or less), for Android either build from Android Studio or from the command line (slow, 5+ min, can take 10 min or more).

If we are only touching JS side, it doesn’t require a rebuild. However, we still need to build native side approximately once a day (or whenever you need to pick up new native side change). 


• PROBLEM 3:  Sometimes bugs are not addressed in a timely manner.



Now let’s dive into each problem and see what exactly we tried to resolve it!

🤔 PROBLEM 1: Master branch is unstable and prevents faster iterations.

Special Sauce 🥘 : Good coverage of unit test as a gate to code check-in, plus an hourly end to end test that covers core user flow to raise the alarm when something is broken.

The importance of the unit test is easily understood. It’s truly a small investment that yields a massive return.

An end to end test on a mobile device, however, is not easy to write nor is it fast to run. We use detox to build our 1st e2e test, then one by one we increase our coverage to make sure the core user flow is covered.

It takes 10+ minutes to build & run the whole test suite, which is too long to use as a gating mechanism and so we only run it hourly.

Then how do we ensure the failing test/regression is addressed in a timely manner?
Good question! See ‘QA Rotation’ later in the post.

Problem solved?
70% → others are handled by QA rotation, and by adding a Feature Flag to EVERYTHING (I will explain in more detail in a bit!).


🤔 PROBLEM 2: It takes too long to build & debug something.

Special Sauce 🥘: Native side and JS side can be built & shipped separately.

We pack the native side up as a bundle and store it in a S3 bucket, and now all you need to do is download it into the device, get JS bundle server up on your laptop (1–2 min), and you are good to go! 💃

This also enables our Over-the-Air delivery: to ship JS side changes. For any JS-only change, there is no need to create a new build, submit to Apple/Google store, and wait a couple days for review, etc… Instead, we can just ship it Over-the-Air to the end user in minutes!



*The service we use for OTA CodePush is appcenter

Over-the-Air release is a huge bonus point of being a React Native app (vs a purely native app).


Problem solved?
80%
... You still need to build if you change code on native side.


🤔 PROBLEM 3: Bugs raised don’t get addressed in a timely manner.

3.1 First, we need to sort out our priorities: Ask, is this bug high enough of a priority to drop the feature we are currently working on?

3.2 We need to surface bugs as soon as possible. E2e tests won’t cover everything, plus at the time we didn’t have a big enough QA team.

Special Sauce 🥘: I started a QA Rotation (on-call) among engineers. Each rotation lasts 1 week, where the engineer on call allocates some amount of the day to:

  1. Go over incoming bugs, close out non-bugs, and identify bugs that need immediate attention so we can bring them into the current sprint.
  2. Watch over ci/cd where we run tests. Take the e2e test for example... (remember it runs hourly). If there is a failure, the engineer on rotation will do a quick triage to see if it’s a regression. If so, they find the owner of the commit and ask for a fix or revert.


Bonus Flavor 1 ☕️ : After we hit production, the QA Rotation (on-call) can also help engineers understand the impact of bugs on our customers.


Bonus Flavor 2 🍰 : This also helps out Problem #1: when someone breaks the main branch, we need to track it down and fix it asap.

How about the lack of QA? Oh yes, we did hire more QAs! 👏

Problem solved ?
99%! → our QA rotation + bigger QA team works great.


Last but not least, FEATURE FLAG EVERYTHING!

Okay... maybe not everything, but putting new features under development behind Feature Flags is a huge boost to our productivity, plus it helps stabilize the main branch.

We use LaunchDarkly as our feature flag service. As I’m writing this, we have 86 feature flags in total.

With Feature Flags, we completely separate shipping code VS shipping features.

Shipping Code: Developers can check in code that is half-working (or less), as long as it’s behind a feature flag, it won’t impact our customer.

Shipping a Feature: Product and QA are the ones shipping features, not developers. Anything that goes out to our customers needs to be given the green light from both QA and Product. Kudos to LaunchDarkly for providing an easy to use dashboard for non-developers. 😘

With feature flags you can do more: percentage rollout, A/B testing, etc…



Dinner Time 🥘

To recap, we took a barebones app + limited web interfaces, added special sauce 🥘 like OTA/QA rotation/feature flag, and threw in dozen social ingredients like comment/like/mention/…, we baked it for an incredibly productive 5 months, and now we have a fully functioning social XR app across iOS/Android/Web, ready for 🚀!



By
Linda Hong
May 26, 2020

How We Built & Shipped a Cross-platform XR Social App in Less Than 6 Months...

Okay, I exaggerate... it sure took longer than 6 months! 😃

What I’m going to share is my experience of joining Ubiquity6 last July, and how after a super productive 5 months we shipped our Display.Land App across iOS, Android, and web.

Since launch, we’ve seen hundreds of thousands of signups in over 150+ countries.

Let’s review what happened - Chef Style! 👩‍🍳


Recipe

What we have:

Back-end: 

A solid 3D content processing platform, will leave as it is.

Front-end:

🎹 Team size: 10.

🤖 Android App: XR app that allows you to take a 3D capture and upload, working with a few bugs (app crashes, etc.). 

🍎 iOS App: XR app, working nicely. 

🕸 Web: a web interface with limited functionality, lots of potential.

What we Want to Deliver

App-wise: We aimed to make Display.Land a fully-functioning XR App with social elements such as 

  • Comment / Like 
  • Follow
  • @ Mention / Notification
  • Social Share
  • Search

Web-wise:

  • Fulfill some potentials like login/out and allow 3D Mesh Download


Preparation Time 📆

5 months

A few problems you might run into during Preparation:

• PROBLEM 1: Master branch is unstable and prevents faster iterations.

I remember the first bug I looked into was Android capture upload not working as expected. It turned out to be a regression. 


• PROBLEM 2: It takes too long to build & debug something.

Display.land is a React Native app = a native bundle + a JS bundle.

JS: Start the JS bundle server, 1–2 min to compile then start.

Native: Slow, for iOS we build from XCode (ok-ish, 5 min or less), for Android either build from Android Studio or from the command line (slow, 5+ min, can take 10 min or more).

If we are only touching JS side, it doesn’t require a rebuild. However, we still need to build native side approximately once a day (or whenever you need to pick up new native side change). 


• PROBLEM 3:  Sometimes bugs are not addressed in a timely manner.



Now let’s dive into each problem and see what exactly we tried to resolve it!

🤔 PROBLEM 1: Master branch is unstable and prevents faster iterations.

Special Sauce 🥘 : Good coverage of unit test as a gate to code check-in, plus an hourly end to end test that covers core user flow to raise the alarm when something is broken.

The importance of the unit test is easily understood. It’s truly a small investment that yields a massive return.

An end to end test on a mobile device, however, is not easy to write nor is it fast to run. We use detox to build our 1st e2e test, then one by one we increase our coverage to make sure the core user flow is covered.

It takes 10+ minutes to build & run the whole test suite, which is too long to use as a gating mechanism and so we only run it hourly.

Then how do we ensure the failing test/regression is addressed in a timely manner?
Good question! See ‘QA Rotation’ later in the post.

Problem solved?
70% → others are handled by QA rotation, and by adding a Feature Flag to EVERYTHING (I will explain in more detail in a bit!).


🤔 PROBLEM 2: It takes too long to build & debug something.

Special Sauce 🥘: Native side and JS side can be built & shipped separately.

We pack the native side up as a bundle and store it in a S3 bucket, and now all you need to do is download it into the device, get JS bundle server up on your laptop (1–2 min), and you are good to go! 💃

This also enables our Over-the-Air delivery: to ship JS side changes. For any JS-only change, there is no need to create a new build, submit to Apple/Google store, and wait a couple days for review, etc… Instead, we can just ship it Over-the-Air to the end user in minutes!



*The service we use for OTA CodePush is appcenter

Over-the-Air release is a huge bonus point of being a React Native app (vs a purely native app).


Problem solved?
80%
... You still need to build if you change code on native side.


🤔 PROBLEM 3: Bugs raised don’t get addressed in a timely manner.

3.1 First, we need to sort out our priorities: Ask, is this bug high enough of a priority to drop the feature we are currently working on?

3.2 We need to surface bugs as soon as possible. E2e tests won’t cover everything, plus at the time we didn’t have a big enough QA team.

Special Sauce 🥘: I started a QA Rotation (on-call) among engineers. Each rotation lasts 1 week, where the engineer on call allocates some amount of the day to:

  1. Go over incoming bugs, close out non-bugs, and identify bugs that need immediate attention so we can bring them into the current sprint.
  2. Watch over ci/cd where we run tests. Take the e2e test for example... (remember it runs hourly). If there is a failure, the engineer on rotation will do a quick triage to see if it’s a regression. If so, they find the owner of the commit and ask for a fix or revert.


Bonus Flavor 1 ☕️ : After we hit production, the QA Rotation (on-call) can also help engineers understand the impact of bugs on our customers.


Bonus Flavor 2 🍰 : This also helps out Problem #1: when someone breaks the main branch, we need to track it down and fix it asap.

How about the lack of QA? Oh yes, we did hire more QAs! 👏

Problem solved ?
99%! → our QA rotation + bigger QA team works great.


Last but not least, FEATURE FLAG EVERYTHING!

Okay... maybe not everything, but putting new features under development behind Feature Flags is a huge boost to our productivity, plus it helps stabilize the main branch.

We use LaunchDarkly as our feature flag service. As I’m writing this, we have 86 feature flags in total.

With Feature Flags, we completely separate shipping code VS shipping features.

Shipping Code: Developers can check in code that is half-working (or less), as long as it’s behind a feature flag, it won’t impact our customer.

Shipping a Feature: Product and QA are the ones shipping features, not developers. Anything that goes out to our customers needs to be given the green light from both QA and Product. Kudos to LaunchDarkly for providing an easy to use dashboard for non-developers. 😘

With feature flags you can do more: percentage rollout, A/B testing, etc…



Dinner Time 🥘

To recap, we took a barebones app + limited web interfaces, added special sauce 🥘 like OTA/QA rotation/feature flag, and threw in dozen social ingredients like comment/like/mention/…, we baked it for an incredibly productive 5 months, and now we have a fully functioning social XR app across iOS/Android/Web, ready for 🚀!



+ FRAME =

Add a Frame

+ CLIP =

Clips your trailer so you can insert more than one series of frames into your trailer

+ DELETE =

Undoes the last action or series of actions that you took

CLEAR =

Clears everything you have done (you can not undo this action, so be careful!)

PLAY =

At any time during your custom trailer creation, you can hit the play button to see how your trailer is coming together.

SAVE (only shows up once you hit the play button to preview your trailer) =

Saves the progress on your freshly created custom trailer!