DestinyItemManager / DIM

Destiny Item Manager
https://destinyitemmanager.com
MIT License
2.07k stars 644 forks source link

A new Destiny 2 Client for DIM #2076

Closed SunburnedGoose closed 6 years ago

SunburnedGoose commented 7 years ago

I know that we're going to get a version of DIM to work with Destiny 2 using the existing v4 client. That's a great solution to solve the near term. Long term, let's start with a clean slate and bring features from DIM v4 to a new client that is built with the experience we've gained from the last three years into a client that will target mobile platforms first, and web second.

  1. Build for player experiences.
    1. Players playing the game and they need an item now.
    2. Players with downtime and they want to explore the possibilities of their items, ie min/max.
    3. Suggest items that match the scenarios in the current gametypes (nightfall burns, etc) with dynamic loadouts.
  2. Build for Mobile, then Tablet, then Desktop
    1. Players need DIM where they play.
    2. Phones are ubiquitous but we also have features that need more real-estate in the UI.
    3. Performant features will help all platforms such as loading on demand items in the UI while scrolling.
    4. Take advantage of native features such as sqlite on phones to store manifest file. Much faster experience for mobile clients than a PWA/DIM's D1 client.
  3. Refactoring based on Experience
    1. DIM's AngularJS client has some flaws in how the data was built and stored wtihin the client and how it relied on scope.
    2. Tune the manipulation of items on the screen for speed, even when it is viewed as speed, ie moving items in the UI before the request completes to give the user a sense of action.
    3. Review item transfer throttles to make sure we're moving as quick as we can within the limitations of the throttle from Bungie. For example, Is it better to have a strategy that uses a self-throttle that rate-limits requests in the client, or a strategy that reacts to the throttle responses?

My suggestion is that we Ionic v3 to build up a new client that can scale between mobile and tablet native clients easily, and then produce the PWA version from the client to run on the web. The only plugins we'll need are the InAppBrowser, GooglePlus Login, and Ionic Storage.

  1. InAppBrowser will be used to let the client authenticate with Bungie's OAuth feature & Google Drive on desktop.
  2. GooglePlus Login plugin will let the client authenticate with Google Drive on hybrid clients.
  3. Ionic Storage lets us save the manifest data to sqlite, local storage, indexdb etc. We can choose which storage engine to use based on client capabilities.

The components in Ionic are malleable via themes. We can consider Angular Material. The Ionic Android theme is Material Design inspired.

We could even take the Ionic PWA dist and wrap that in Electron for a native desktop experience. We would want to make sure that we're using sqlite in that experience.

Thoughts?

joshmedeski commented 7 years ago

Great thoughts here. Sounds like it's going to be a lot of work. I'll be on the lookout to figure out how to help out!

p.s. I'd highly recommend you add Ngrx (or something like it) to the new project, if you haven't heard of state management with redux it's really powerful!

SunburnedGoose commented 7 years ago

I'm a big fan of it and how it helps ngx based apps. Use it in my day job products On Thu, Aug 31, 2017 at 7:49 PM Josh Medeski notifications@github.com wrote:

p.s. I'd highly recommend you add Ngrx https://github.com/ngrx/platform (or something like it) to the new project, if you haven't heard of state management with redux it's really powerful!

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/DestinyItemManager/DIM/issues/2076#issuecomment-326457723, or mute the thread https://github.com/notifications/unsubscribe-auth/AA8GINfmnxpJrHVewZolX5Vd6Ukoxsutks5sd1SIgaJpZM4PITUQ .

bhollis commented 7 years ago

Thanks for writing this up! It's well thought out, and I think there's a lot of good ideas in here.

I haven't been able to work on DIM for quite a while due to other demands on my time, but I'm excited to get back into it full time with the release of D2. I've put a ton of work into DIM for the last two years, and in the last 6 months or so I've been working hard to move DIM in roughly the direction you're describing. I'm going to go through what you've written point by point with my own take on it.

I know that we're going to get a version of DIM to work with Destiny 2 using the existing v4 client. That's a great solution to solve the near term. Long term, let's start with a clean slate and bring features from DIM v4 to a new client that is built with the experience we've gained from the last three years into a client that will target mobile platforms first, and web second.

This is definitely an option. I know Ishtar Commander is going this way. It may actually be the right decision - we'd get to ditch a lot of old code and start fresh. However, I think there's going to be significant overlap, and that we can pretty easily support both D1 and D2 in the same app long term. I know not many people will be playing D1, but I honestly don't think the overhead of continuing to support it will be significant. I also plan on chunking the app and lazy-loading routes, so there will be zero cost to D2-only players for us to support D1 as well. Personally, I view supporting both games in the same app as a fun challenge.

target mobile platforms first, and web second

My goal has been to build an experience that feels great on both desktop/web AND mobile. I don't think we need to put one in front of the other. To date, our mobile experience hasn't been good only because there's lots of work yet to do (both in code and design) to make things great for mobile. We're [not too far off]() and I'm hoping to close the gap significantly this weekend.

  1. Build for player experiences.
  2. Players playing the game and they need an item now.
  3. Players with downtime and they want to explore the possibilities of their items, ie min/max.
  4. Suggest items that match the scenarios in the current gametypes (nightfall burns, etc) with dynamic loadouts.

I love the idea of going after a ranked set of user scenarios. These can be really helpful in helping us decide on whether to include a feature or not (or where to put a feature). My only caution would be to avoid driving design solely from these scenarios. My ideal is an app that has a handful of core features that are well-thought out both in their individual design and the design of their interactions, such that the sum of a few individual features satisfies needs across a range of scenarios. To me features like Search, Compare and Loadouts fit that bill - they complement each other. I'd have a tough time trying to rank those individual "feature components" against our user scenarios. But I think we have a lot of room for great design improvements (especially on mobile) and I'm excited to really get into that, especially where we let our designs deviate from the game UI.

  1. Build for Mobile, then Tablet, then Desktop
  2. Players need DIM where they play.
  3. Phones are ubiquitous but we also have features that need more real-estate in the UI.
  4. Performant features will help all platforms such as loading on demand items in the UI while scrolling.
  5. Take advantage of native features such as sqlite on phones to store manifest file. Much faster experience for mobile clients than a PWA/DIM's D1 client.

What I take away from this is that performance is a huge priority, and I agree. We should be using whatever tricks we can in order to make sure DIM works well on a range of devices. I suspect the biggest value we can get today is to move from AngularJS to Angular 4.

  1. Refactoring based on Experience
  2. DIM's AngularJS client has some flaws in how the data was built and stored wtihin the client and how it relied on scope.

There are certainly some dark spots in the code, and opportunities for refinement, but I'm not sure exactly what you're referring to here. Have you seen the code recently? Things have been straightened out a lot.

  1. Tune the manipulation of items on the screen for speed, even when it is viewed as speed, ie moving items in the UI before the request completes to give the user a sense of action.

I've thought about this a bunch, and I'm not sure I agree that this is a problem. I've spawned off a separate issue to dig into it, but I suspect if we fixed the item throttles, nobody would notice much lag. For reference, Bungie.net usually completes moves in ~75ms.

  1. Review item transfer throttles to make sure we're moving as quick as we can within the limitations of the throttle from Bungie. For example, Is it better to have a strategy that uses a self-throttle that rate-limits requests in the client, or a strategy that reacts to the throttle responses?

This is a great idea and should yield an immediate quality of life improvement (assuming it's possible). I've filed https://github.com/DestinyItemManager/DIM/issues/2079 to track it.

My suggestion is that we Ionic v3 to build up a new client that can scale between mobile and tablet native clients easily, and then produce the PWA version from the client to run on the web. The only plugins we'll need are the InAppBrowser, GooglePlus Login, and Ionic Storage.

Ionic looks really cool, and I'm sure it would be nice to use. However, I don't think we need it, and we certainly don't need to rewrite to get its benefits (or even to switch to it). I haven't dug into Ionic super deep, but it appears to be a boilerplate of Angular 4, Cordova, some Angular UI components, and some Cordova plugins. We are moving to Angular 4 already, and I have a [Cordova shell for DIM]() running on my laptop (I haven't finished it just because our UI isn't phone-ready yet, and Apple would reject our app). Regarding the UI components, I think they'd be nice, but when I look at DIM, I don't see a lot of places where standard UI libraries help a lot. Aside from a few buttons and form controls, most of our UI is (and should be) highly customized to our specific needs. I don't see a ton of value in adding a "framework" on top of what we're using today, which is mostly basic web standards.

  1. InAppBrowser will be used to let the client authenticate with Bungie's OAuth feature & Google Drive on desktop.
  2. GooglePlus Login plugin will let the client authenticate with Google Drive on hybrid clients.
  3. Ionic Storage lets us save the manifest data to sqlite, local storage, indexdb etc. We can choose which storage engine to use based on client capabilities.

All of these are great, and we should use them (or the base components they're built on) to make our Cordova wrapper great. The direct sqlite access will be particularly great, though I think the performance impact of our WASM SQLite library has been generally overstated (it's pretty dang fast - it compares well to native SQLite, and the site loads to inventory in ~6s on my machine, which could be faster, but after that SQLite latency doesn't affect much).

The components in Ionic are malleable via themes. We can consider Angular Material. The Ionic Android theme is Material Design inspired.

This is a matter of taste, but I despise Material Design. I strongly dislike using apps and platforms that use it. We can get into it offline, but I think Material Design is a failure for both mobile and desktop.

p.s. I'd highly recommend you add Ngrx (or something like it) to the new project, if you haven't heard of state management with redux it's really powerful!

This is another taste thing, but having used Redux, it makes my skin crawl. Maybe ngrx is way better, and maybe if I just got used to it I'd love it, but right now I look at Redux style code and I think "I work on DIM for fun, and if we used this it wouldn't be fun anymore."

We could even take the Ionic PWA dist and wrap that in Electron for a native desktop experience. We would want to make sure that we're using sqlite in that experience.

Electron is a great choice, and having a standalone desktop app would be cool. I've filed [a tracking issue](). I'd suggest MacGap instead for macOS (it uses the system web browser instead of having to ship 150MB of Chromium per app - this is what Slack uses). For Windows, we may want to go with Hosted Web Apps which again are more lightweight and have better system API access.


My personal priorities for DIM, which I've been working towards for a while, are as follows, in order:

  1. Make DIM work for D2.
  2. Make DIM work great on phones.
  3. Upgrade to Angular 4.
  4. Build "native app" wrappers. https://github.com/DestinyItemManager/DIM/issues/2082, https://github.com/DestinyItemManager/DIM/issues/2083
  5. Make D1 and D2 routes lazy load independent of each other so users who only use one don't pay any extra cost.

I think this lines up pretty well with what you're suggesting here, though I'm not interested in the step of starting fresh, and I don't think we need to adopt new frameworks (beyond upgrading to Angular and introducing Cordova). My high level view for the future of the app is that we live and die on feature design, and no amount of prebuilt libraries and frameworks are going to help with that. We should focus on building out the parts of DIM that users love, and only mess around with the "guts" when it affects the experience (such as upgrading to Angular for performance reasons).

SunburnedGoose commented 7 years ago

The AngularJS comments about storage and scope was reference to the original architecture that I built. It was rough, but also my learning experience. It just lived too long.

I don't want to see DIM's D1 and D2 code bases sharing much of their code. The API is now using this component/socket/plug setup, and there are going to be many more features on items in D2... I don't want to make views that are full of D1/D2 discriminators that show different parts based on the character. It's going to be by far and by large a separate application internally.

I see there being changes to the main application UI to remove progression out of the long list of character items, and them in their own section. How does that affect D1? How are we going to test D1 for unintentional changes when we make updates to the client? I see it as a messy adventure to try and make D1/D2 agnostic components. D1 isn't going to last, and investing in this hybrid application is not a good place to put time into the app. I'd rather just clone the repo, and make a D2 client. Have the automation push D1 to its own app folder on the server, and likewise for D2. This way any changes we make to D2 are going to be isolated to that platform with its own unique behaviors, layout, and features specific to D2. When D1 is done, we just switch off the automated updates, and delete that directory from the server.

Hybrid apps will need things like crosswalk for android, removing the click timeout, infinite lists that load on demand. These help with performance and smooth out the bumpy landscape that is Android's version history. They are all baked into Ionic. Native optimized components are baked into Ionic. Don't like Material, that's fine. I don't want FABs all over the screen either, but their components are really well made and work with many form factors out of the box. Tweak the theme to make it more like our style. It's kind of like Bootstrap. There are a lot of terrible Bootstrap sites that look like Bootstrap, but the good ones were able to use the baseline to make some interesting UIs. I just don't want to invest in making good components for mobile when they already exist.

I don't know what your redux apps looked like, but both ngrx and redux are very similar. I do not expose the store/composers to the components. I hide as much as I can in the services and just emit ngrx store observables from the service methods. I also use service methods to dispatch actions. Cuts down the complexity because users don't have to look all over creation for actions/composers/reducers/etc. Much of the heavy lifting (async) occurs in the effects (sagas) services.

The phone version of the app will be different than the web version and we won't be able to just wrap the website into cordova. We have to auth differently with Bungie since we can't redirect to Bungie and back to the page in the app. We'll have to invoke the cordova inappbrowser to authenticate. Likewise with Google Drive. They don't let you authenticate from hybrid apps anymore. You have to use the native client.

If we want to get something made quickly for D2, then trying to squeeze D2 endpoints into the D1 client is fine and a short term solution to let users make loadouts, see their items, and perform some limited inspection. Long term, I don't see this being a good desktop->mobile strategy. It's clunky and if it were easy, we would have done it by now. Let's look at it the other way around with building a good mobile client towards the desktop with native wrapper strategies like electron and ionic from the beginning.

bhollis commented 7 years ago

Chatted with @SunburnedGoose for quite a while offline. After going over it, we're in broad agreement on the right path forward, and that involves a separate app based on Ionic framework much as described in the original comment.

bhollis commented 6 years ago

Latest update: we decided to experiment with React for the new client.